美文网首页
FFMPEG音视频同步

FFMPEG音视频同步

作者: 明日即是今朝 | 来源:发表于2020-08-06 11:45 被阅读0次

问题

在写ffmpeg音视频同步的时候,我是参考了动脑老师的方法,根据音频的时间来同步视频,写完以后发现播放mp4文件音视频同步,流畅度基本上是没有问题的,但是播放直播流就会有问题,有时候音频和视频的差距很大导致视频根本就出不来(因为视频比音频块了很多,这样会让他睡很久,所以没视频),那这里我自己又没有音视频的经验根本解决不了这个问题,这个时候只能去看下ffmpeg提供的ffplay的源码,看看他的音视频同步是怎么做的,这样来解决我自己音视频同步的问题。ffplay还是挺大的,希望自己花几天时间搞明白他,最起码搞明白他音视频同步的方案,他好像三种方案都写了,以视频为基准,以音频为基准和以外部时间为基准。下面我先贴出我当前有问题的音视频同步代码,如果有知道问题的麻烦能不吝赐教。

  • 视频里面的代码
 //每个画面刷新的时间间隔
    double frameDelays = 1.0 / fps;
    while (isPlaying) {
        frames.pop(frame);
        sws_scale(swsContext, frame->data, frame->linesize, 0, codecContext->height, dst_data,
                  dst_linesize);
        //做音视频同步  获取当前视频的时间
        double clock = frame->best_effort_timestamp * av_q2d(time_base);
        //还有个额外的时间
        double extra_delay = frame->repeat_pict / (2 * fps);
        //真正的延时
        double delays=frameDelays+extra_delay;
        double audioClock = audioChannel->clock;
        double diff=clock-audioClock;
        LOGE("player diff %f audioClock %f  videoclock  %f",diff,audioChannel->clock,clock);
        if(!audioChannel){
//            //如果没有音频  就睡这么长时间
            av_usleep(delays*1000000);
        } else{
            if (clock==0){
                //刚刚开始
                av_usleep(delays*1000000);
            } else {
                //比较音频和视频
                double audioClock = audioChannel->clock;

                double diff=clock-audioClock;
                if(diff>0){
                    //视频比音频快
                    LOGE("player 视频快了");
                    av_usleep((delays+diff)*1000000);
                } else if (diff<0){
                    LOGE("player  音频快了");
                    //视频积压太多  就丢包
                    if(fabs(diff)>=0.05){
                        releaseAvFrame(&frame);
                        frames.sync();
                        continue;
                    } else{
                        //不要睡  赶紧去跟上
                    }
                }
            }
        }
  • 音频里面的相关部分代码
 int datasize = 0;
    AVFrame *avFrame;
    int ret = frames.pop(avFrame);

    //对avframe 进行重采样
    //1、拿到积压的数据
    int64_t delays = swr_get_delay(swrContext, avFrame->sample_rate);

    //最大能返回多少个数据
    int max_samples = av_rescale_rnd(delays + avFrame->nb_samples, out_sample_rate,
                                     avFrame->sample_rate, AV_ROUND_UP);
    //返回每个声道的输出数据
    int samples = swr_convert(swrContext, &data, max_samples, (const uint8_t **) avFrame->data,
                              avFrame->nb_samples);
    datasize=samples*out_samplesize*out_channels;



    //当前音频的时间戳
    clock=avFrame->pts*av_q2d(time_base);

主要是通过音频的clock去同步视频的clock,不知道为什么直播流的播放页面会非常卡。

总结

这次主要是记录当前的问题,和我接下来要做的工作,分析ffplay源码,解决音视频同步问题。

相关文章

  • Ffmpeg音视频常用命令

    播放器架构 同时还有音视频同步,这个是很重要的。 渲染流程 1、FFmpeg常用命令实战 FFmpeg音视频处理流...

  • FFmpeg 音视频同步

    音视频播放器的工作的具体流程如下图所示: 简单的来说包括:解协议,解封装,对音频和视频分别进行解码,音视频同步播放...

  • FFMPEG音视频同步

    问题 在写ffmpeg音视频同步的时候,我是参考了动脑老师的方法,根据音频的时间来同步视频,写完以后发现播放mp4...

  • FFmpeg 音视频同步

    FFmpeg简易播放器的实现5-音视频同步 写的很不错 : https://www.cnblogs.com/lei...

  • FFmpeg音视频同步

    SDL2文章列表 SDL2入门 SDL2事件处理 SDL2纹理渲染 SDL2音频播放 FFmpeg+SDL2实现视...

  • ffmpeg播放器开发 详细记录+代码实现4

    请接上一个简书内容观看,会对上一章的代码进行改进和修改~~~ ffmpeg播放器4-音视频同步 1.ffmpeg ...

  • Qt音视频开发24-ffmpeg音视频同步

    一、前言 用ffmpeg来做音视频同步,个人认为这个是ffmpeg基础处理中最难的一个,无数人就卡在这里,怎么也不...

  • Qt音视频开发09-ffmpeg内核音视频同步

    一、前言 用ffmpeg来做音视频同步,个人认为这个是ffmpeg基础处理中最难的一个,无数人就卡在这里,怎么也不...

  • 执行编译FFmpeg库

    FFmpeg工具 FFmpeg FFplay FFprobe FFmpeg开发库 Libavcodec 音视频编解...

  • FFdynamic - 扩展FFmpeg的音视频处理框架

    FFynamic - 扩展FFmpeg的音视频处理框架 FFdynamic封装了FFmpeg的底层音视频处理,提供...

网友评论

      本文标题:FFMPEG音视频同步

      本文链接:https://www.haomeiwen.com/subject/jhlgrktx.html