You need to enable JavaScript to run this app. 基于FFmpeg的Android视频播放器音视频不同步(视频快2~3倍)问题求助
优惠活动
大模型
产品
解决方案
定价
更多

基于FFmpeg的Android视频播放器音视频不同步(视频快2~3倍)问题求助

音视频不同步问题排查及解决方案

问题根因定位

  1. 解码流程存在缺失
    现有BaseDecoder::RealDecode仅调用avcodec_receive_frame拉取解码后帧,没有实现从packet队列取包、调用avcodec_send_packet喂包给解码器的逻辑。如果未对avcodec_receive_frame的返回值做错误处理,会导致解码器要么不停返回错误生成无效帧,要么以最大速度拉取内部缓存帧,完全不受控,直接造成视频播放速度异常。
  2. PTS计算逻辑存在隐患
    当前帧PTS计算依赖GetTimeBase()的返回值,如果该方法返回的不是对应流(视频/音频)独立的AVRational参数,比如错误混用音视频流的timebase、或者返回全局AV_TIME_BASE而非流本身的timebase,会导致PTS计算值偏差2~3倍,直接让同步逻辑失效。
  3. 同步逻辑设计错误
    ReceiveVideoFrame中当视频帧PTS和音频PTS差值大于1秒时,仅休眠了视频额外延迟时长,没有对超过1秒的差值做补偿,导致视频始终快于音频;同时当前仅在音频帧进入同步逻辑时更新audio_pts,没有维护实时音频时钟——音频是持续播放的,非喂帧时间段的播放进度没有被统计,会导致同步的时间基准完全不准。
  4. 音频播放配置异常
    如果音频输出模块(如OpenSL ES)的采样率、声道数、采样格式和解码输出的PCM参数不匹配,会导致音频播放速度变慢,体感上就是视频快2~3倍。
  5. 队列无流量控制
    解码器packet队列、Render的frame队列均未设置最大长度阈值,没有堆积保护逻辑,会导致大量帧积压在队列中,同步逻辑无法及时纠正速度偏差。

修复方案

  1. 补全解码流程
    在BaseDecoder::RealDecode循环中增加错误处理逻辑:如果avcodec_receive_frame返回AVERROR(EAGAIN),则从av_packet_queue取出AVPacket调用avcodec_send_packet喂给解码器,处理EOF等异常返回值,避免无效帧输出。
  2. 校准PTS计算逻辑
    打印音视频流的timebase.num、timebase.den参数,确认GetTimeBase()返回对应流自身的timebase值;打印相邻帧的PTS差值,25fps视频相邻帧差值应为0.04s左右,确认PTS计算符合预期。
  3. 修正同步逻辑
  • 维护独立的音频时钟:根据音频输出的已播放样本数实时计算当前音频播放进度,不依赖最后一帧音频的PTS作为同步基准。
  • 调整休眠逻辑:视频帧和音频的差值无论是否超过1秒,都按照实际差值+额外延迟的总时长休眠,不需要单独做1秒阈值的特殊处理。
  1. 校验音频配置
    确认OpenSL ES的输出参数和解码输出的PCM参数完全一致,单独测试音频播放速度是否正常。
  2. 增加队列流量控制
    给packet队列、frame队列设置最大长度(通常视频帧队列不超过10帧,音频packet队列不超过50包),队列满时丢弃非关键帧,避免帧堆积。

内容的提问来源于stack exchange,提问作者ZSpirytus

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.13 06:09:03