ijkplayer音视频不同步解决方案

ljkplayer是一款做视频直播的框架, 网上很多视频项目都使用了这个框架。这里不再讲如何集成ijkplayer,推荐一篇详细的集成文章

一、下载ijkplayer

下载地址:https://github.com/Bilibili/ijkplayer
下载完成后解压,根据github上作者的说明下载ffmpeg,编译ffmpeg:

首先安装环境
然后下载编译ffmpeg

二、不同步的解决方案

我在使用ijkplayer的时候主要遇到了3个问题
1. 音视频不同步
在开始使用过程当中对rtmp视频流进行播放,会出现严重的视频音频不同步现象,并且随着播放的时间越长,视频与音频的差距越大。

解决方案

具体原因是CPU在处理视频帧的时候处理得太慢,默认的音视频同步方案是视频同步到音频, 导致了音频播放过快,视频跟不上。

framedorp 控制着允许丢帧的范围

可以通过修改 framedrop 的数值来解决不同步的问题,framedrop 是在视频帧处理不过来的时候丢弃一些帧达到同步的效果。具体设置:

IJKFFOptions *options = [IJKFFOptions optionsByDefault];
[options setPlayerOptionIntValue:5      forKey:@"framedrop"];

framedrop的具体大小根据实际情况而定, 我这边改成5就已经能够正常播放了。

2. 硬解码模式下, 重复推送同一部电影, 没有画面
客户端在一直接收流进行播放的状态下,在硬解码模式下,推流端的一部电影推流完成,然后继续重新推送这部电影,发现无法显示画面,只有声音

解决方案

原因是pts引起的,上一部电影推流完成时视频的pts很大,而第二次推送的时候pts重新开始计算,在ijk内部IJKVideoToolBox类里面有一个判断阻挡了视频的显示:

新帧的pts小于之前帧的pts

我们只需要在里面简单的处理以下就行了:

        if (ctx->m_sort_queue && newFrame->pic.pts < ctx->m_sort_queue->pic.pts) {
            
            if (newFrame->pic.pts < 500) {
                
                QueuePicture(ctx);
                goto successed;
            }
            else if (ctx->m_sort_queue->pic.pts > newFrame->pic.pts * 20) {
                QueuePicture(ctx);
                goto successed;
            }
            
            goto failed;
        }

里面做了两个简单的判断,一个是如果pts过于太小,视频帧仍然可以推进帧队列里。一个是如果前一个帧的大小是新的帧的几十倍,仍然可以将视频帧推进帧队列里进行处理。这样的话视频就能正常播放了。

3. 硬解码模式下, 改变推流端视频分辨率的大小, 花屏的问题
客户端在一直接收流进行播放的状态下,当我在推流端切换了视频的分辨率,或者换了一部参数不一样的电影进行推流,会出现花屏。

解决方案

这个问题在最新的版本里面作者已经进行了解决,不会在出现这个问题了,如果你是老版本的话,可以在IJKVideoToolBoxl类里面的 decode_video 函数里面将

老版本

改成

            ret = avcodec_decode_video2(new_avctx, frame, &got_picture, avpkt);
            if (ret < 0) {
                avcodec_free_context(&new_avctx);
                return ret;
            } else {
                if (context->codecpar->width  != new_avctx->width &&
                    context->codecpar->height != new_avctx->height) {
                    avcodec_parameters_from_context(context->codecpar, new_avctx);
                    context->refresh_request = true;
                }
            }

这样就能正常播放了

三、结束

在研发过程当中可能会遇见各种问题,希望和大家相互交流,共同成长。最后推荐一个开源的视频直播应用:高仿<喵播APP>。这个用各种开源库(ijkplayer, LFLiveKit, GPUImage)组成的APP再一次证明了轮子的重要性。

希望本文对大家有帮助,任何不足,望指正!

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 教程一:视频截图(Tutorial 01: Making Screencaps) 首先我们需要了解视频文件的一些基...
    90后的思维阅读 4,831评论 0 3
  • 本文转自:[FFmpeg 入门(5):视频同步 | www.samirchen.com][2] 视频如何同步 在之...
    SamirChen阅读 2,862评论 0 5
  • 现今移动直播技术上的挑战要远远难于传统设备或电脑直播,其完整的处理环节包括但不限于:音视频采集、美颜/滤镜/特效处...
    大荣纸阅读 8,242评论 5 22
  • 朋友圈里看到朋友发的一句话“有些人的存在,犹如温茶中的苍蝇,拼命挣扎的一举一动只会增添厌恶的色彩。”乍一看,没太明...
    微笑的百合花阅读 390评论 2 1
  • 第一章 沉思 “菲西,当时旭辉追你时,你为什么拒绝的那么干脆,一点余地都不留。我觉得他还不错,为什么不给他...
    枫残月阅读 326评论 0 1