转载请把头部出处链接和尾部二维码一起转载,本文出自逆流的鱼yuiop:http://blog.csdn.net/hejjunlin/article/details/57075026
前言:ijkplayer中一些问题记录优化,看下Agenda:

  • 在弱网时如何优化
  • ijkplayer播放卡顿如何优化
  • 如何支持https链接播放?
  • 如何降低ijkplayer延迟效应
  • ijkplayer中音视频同步,是如何做的?

一、在弱网时如何优化

好的网络下视音频能够得到及时的发送,不会造成视音频数据在本地的堆积,直播效果流畅,延时较小。而在弱网网络环境下,视音频数据发送不出去,则需要我们对视音频数据进行处理。差网络环境下对视音频数据一般有四种处理方式:缓存区设计、网络检测、丢帧处理、降码率处理。

1、缓冲区设计
视音频数据传入缓冲区,发送者从缓冲区获取数据进行发送,这样就形成了一个异步的生产者消费者模式。生产者只需要将采集、编码后的视音频数据推送到缓冲区,而消费者则负责从这个缓冲区里面取出数据发送。

视音频缓冲区

上图中只显示了视频帧,显然里面也有相应的音频帧。要构建异步的生产者消费者模式,java中使用LinkedBlockingQueue,可以对之后进行丢帧、插入、取出等处理。

2、网络检测
差网络处理过程中一个重要的过程是网络检测,当网络变差的时候能够快速地检测出来,然后进行相应的处理,这样对网络反应就比较灵敏,效果就会好很多。通过实时计算每秒输入缓冲区的数据和发送出去数据,如果发送出去的数据小于输入缓冲区的数据,那么说明网络带宽不行,这时候缓冲区的数据会持续增多,这时候就要启动相应的机制。

3、丢帧处理
当检测到网络变差的时候,丢帧是一个很好的应对机制。视频经过编码后有关键帧和非关键帧,关键帧也就是一副完整的图片,而非关键帧描述图像的相对变化。
丢帧策略多钟多样,可以自行定义,一个需要注意的地方是:如果要丢弃P帧(非关键帧),那么需要丢弃两个关键帧之间的所有非关键帧,不然的话会出现马赛克。对于丢帧策略的设计因需求而异,可以自行进行设计。如下我一个丢帧实例:
当CPU在处理视频帧的时候处理得太慢,默认的音视频同步方案是视频同步到音频, 导致了音频播放过快,视频跟不上。
在ff_ffplay_options.h中,找到如下代码:

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

默认ijkplayer中是1,你可以自行,修改这个值。

4、降码率
在Android中,如果使用了硬编进行编码,在差网络环境下,我们可以实时改变硬编的码率,从而使直播更为流畅。当检测到网络环境较差的时候,在丢帧的同时,我们也可以降低视音频的码率。在Android sdk版本大于等于19的时候,可以通过传递参数给MediaCodec,从而改变硬编编码器出来数据的码率。

Bundle bitrate = new Bundle();bitrate.putInt(MediaCodec.PARAMETER_KEY_VIDEO_BITRATE, bps * 1024);
mMediaCodec.setParameters(bitrate);

二、ijkplayer播放卡顿如何优化

在做音频播放的时候,使用的是开源的ijkplayer播放器,ijkplayer解码使用的是ffmpeg,声音输出使用的是audiotrack,在某机型上面播放遇到锁屏、返回后台、点击home键的时候会出现声音卡顿的现象,会输出下面的log

W/AudioTrack: releaseBuffer() track 0xcce8b600 disabled due to previous underrun, restarting

我实现播放调用步骤是在AsyncTask中,查阅资料发现是因为在线程中播放造成的问题,经过查看asynctask构造方法发现,asynctask会把线程的优先级设置为THREAD_PRIORITY_BACKGROUND后台线程,于是我将线程的优先级设置为THREAD_PRIORITY_URGENT_AUDIO,解决了播放卡顿的问题,我猜测播放线程优先级降低,系统分配时间片会减少,会导致底层ijk读数据输出数据时得不到及时的回应,audiotrack频繁的releasebuffer,restarting声道,造成卡顿。
本文出自逆流的鱼yuiop:http://blog.csdn.net/hejjunlin/article/details/57075026

三、如何支持https链接播放?

如果你的项目要进行加密播放HLS协议的视频,要想支持https,须要在普通编译的基础上,进行一些配置。

接下来我们来编译openssl

1.init openssl

$ cd ..    进入到ijkplayer的目下
$ ./init-android-openssl.sh   去远程仓库拉取openssl的远程代码,如果是iOS的,这里是init-ios-openssl.h

2.compile openssl

$ cd android/contrib
$ ./compile-openssl.sh clean
$ ./compile-openssl.sh all

经过以上步骤已经编译好openssl了,然后我们执行一下方法

$./compile-ffmpeg.sh clean编译ffmpeg软解码库,这个过程会生成各种架构的ffmpeg 这个过程比较耗时
$./compile-ffmpeg.sh all

四、如何降低ijkplayer延迟效应

通过修改源文件,因为ijkplayer实际上是基于ffplay.c实现的:
ijkmedia>ijkplayer>ff_ffplay.c这个文件

static double vp_duration(VideoState *is, Frame *vp, Frame *nextvp) {if(vp->serial == nextvp->serial) {doubleduration = nextvp->pts - vp->pts;if(isnan(duration) || duration <=0|| duration > is->max_frame_duration)return vp->duration;elsereturn duration;}else{return 0.0;}
}

直接换成:

static double vp_duration(VideoState*is,Frame*vp,Frame*nextvp) {return vp->duration;
}

2、接着改staticintffplay_video_thread这个方法:

static int ffplay_video_thread(void*arg){FFPlayer*ffp = arg;VideoState*is = ffp->is;AVFrame*frame =av_frame_alloc();doublepts;doubleduration;intret;AVRationaltb = is->video_st->time_base;//注释如下一行代码//AVRational frame_rate = av_guess_frame_rate(is->ic, is->video_st, NULL);//......省略部分代码//注释如下一行代码//duration = (frame_rate.num && frame_rate.den ? av_q2d((AVRational)  {frame_rate.den, frame_rate.num}) : 0);//直接这里写出duration=0.01;//........
}

改完后发现延迟明显降低,高分辨率开启硬解码,不支持的话会自动切换到软解,就算开启mediacodec,如果设备不支持,显示的解码器也是avcodec软解。
本文出自逆流的鱼yuiop:http://blog.csdn.net/hejjunlin/article/details/57075026

五、ijkplayer中音视频同步,是如何做的?

对于播放器来说,音视频同步是一个关键点,同时也是一个难点,同步效果的好坏,直接决定着播放器的质量。通常音视频同步的解决方案就是选择一个参考时钟(主 clock),播放时读取音视频帧上的时间戳,同时参考当前时钟参考时钟(主 clock)上的时间来安排播放。如下图所示:

  • 如果音视频帧的播放时间大于当前参考时钟上的时间,则不急于播放该帧,直到参考时钟达到该帧的时间戳;
  • 如果音视频帧的时间戳小于当前参考时钟上的时间,则需要“尽快”播放该帧或丢弃,以便播放进度追上参考时钟。

参考时钟的选择也有多种方式:

  • 选取视频时间戳作为参考时钟源
  • 选取音频时间戳作为参考时钟源
  • 选取外部时间作为参考时钟源

考虑人对视频、和音频的敏感度,在存在音频的情况下,优先选择音频作为主时钟源。

ijkplayer在默认情况下也是使用音频作为参考时钟源,我们可以找到ff_ffplay.c文件中,处理同步的过程主要在视频渲染video_refresh_thread的线程中:

从上述实现可以看出,该方法中主要循环做两件事情:

  • 休眠等待,remaining_time的计算在video_refresh中
  • 调用video_refresh方法,刷新视频帧

可见同步的重点是在video_refresh中,下面看该方法一些关键部分:

lastvp是上一帧,vp是当前帧,last_duration则是根据当前帧和上一帧的pts(Presentation Time Stamp。PTS主要用于度量解码后的视频帧什么时候被显示出来),计算出来上一帧的显示时间,经过compute_target_delay方法,计算出显示当前帧需要等待的时间。

在compute_target_delay函数中,如果发现当前主Clock源不是video,则计算当前视频时钟与主时钟的差值:

  • 如果当前视频帧落后于主时钟源,则需要减小下一帧画面的等待时间;
  • 如果视频帧超前,并且该帧的显示时间大于显示更新门槛,则显示下一帧的时间为超前的时间差加上上一帧的显示时间
  • 如果视频帧超前,并且上一帧的显示时间小于显示更新门槛,则采取加倍延时的策略。

回到video_refresh函数中,有如下逻辑:

frame_timer实际上就是上一帧的播放时间,而frame_timer + delay实际上就是当前这一帧的播放时间,如果系统时间还没有到当前这一帧的播放时间,直接跳转至display,而此时is->force_refresh变量为0,不显示当前帧,进入video_refresh_thread中下一次循环,并睡眠等待。

如果当前这一帧的播放时间已经过了,并且其和当前系统时间的差值超过了AV_SYNC_THRESHOLD_MAX,则将当前这一帧的播放时间改为系统时间,并在后续判断是否需要丢帧,其目的是为后面帧的播放时间重新调整frame_timer,如果缓冲区中有更多的数据,并且当前的时间已经大于当前帧的持续显示时间,则丢弃当前帧,尝试显示下一帧。

否则进入正常显示当前帧的流程,调用video_display2开始渲染。

第一时间获得博客更新提醒,以及更多android干货,源码分析,欢迎关注我的微信公众号,扫一扫下方二维码或者长按识别二维码,即可关注。

如果你觉得好,随手点赞,也是对笔者的肯定,也可以分享此公众号给你更多的人,原创不易

直播技术总结(三)ijkplayer的一些问题优化记录相关推荐

  1. Android直播技术之(三) : 推流

    首先我们先介绍下推流协议以及他们在直播领域的现状和优缺点 *RTMP *WebRTC *基于UDP的私有协议 (1 : RTMP): 它是Real Time Messaging Protocol(实时 ...

  2. 未来的直播技术将会有哪些新的进化形式?

    近5.6年间,直播几乎每一年都在发生着非常大的变化,诞生了不同的玩法.不同的场景,直播形态在持续地丰富.那么未来,直播技术又会有着什么样的"进化"呢? 近日,火山引擎直播技术负责人 ...

  3. 关于移动视频直播技术,关键干货都在这里了(三)编码和封装

    关于直播的技术文章不少,成体系的不多.我们将用七篇文章,更系统化地介绍当下大热的视频直播各环节的关键技术,帮助视频直播创业者们更全面.深入地了解视频直播技术,更好地技术选型. 视频编码是视频直播技术系 ...

  4. 《视频直播技术详解》之(三):编码和封装

    在上一期的处理篇中,我们介绍了讲解常见视频处理功能如美颜.视频水印.滤镜.连麦等. 本篇是<解密视频直播技术>系列之三:编码和封装.视频编码是本系列一个重要的部分,如果把整个流媒体比喻成一 ...

  5. 【移动开发】关于视频直播技术,你想要知道的都在这里了(三)编码和封装

    http://www.jianshu.com/p/b61cd0bc2abe 关于直播的技术文章不少,成体系的不多.我们将用七篇文章,更系统化地介绍当下大热的视频直播各环节的关键技术,帮助视频直播创业者 ...

  6. 视频直播技术详解(0)开篇

    (原标题:<视频直播技术详解>系列之一:开篇) 文|何李石 随着互联网用户消费内容和交互方式的升级,支撑这些内容和交互方式的基础设施也正在悄悄发生变革.手机设备拍摄视频能力和网络的升级催生 ...

  7. 《视频直播技术详解》系列之一:开篇

    随着互联网用户消费内容和交互方式的升级,支撑这些内容和交互方式的基础设施也正在悄悄发生变革.手机设备拍摄视频能力和网络的升级催生了大家对视频直播领域的关注,吸引了很多互联网创业者或者成熟企业进入该领域 ...

  8. 从无到有开发连麦直播技术点整理

    最近在跟老师手下的项目,碰到流媒体,流媒体服务器,视频编码技术,推流,拉流等概念,看到本篇博客整理的概念很全面,很自信,故转发留存,感谢原博主.       关键字 采集.前处理.编码.传输.解码.渲 ...

  9. iOS 直播技术及Demo

    要过年了,新年快乐,今天写一些关于iOS直播技术相关知识,及详细Demo介绍,首先请下载Demo Demo下载地址(点击跳转下载) 一.直播介绍 1.1.直播现状 近年来,直播越来越火,但直播技术却对 ...

最新文章

  1. Debian Security Advisory(Debian安全报告) DSA-4410-1 openjdk-8 security update
  2. vc调试 main的参数
  3. SpringBoot整合RabbitMQ 实现五种消息模型
  4. list转datatable
  5. Java structured lock vs unstructured lock
  6. UWP 开发初阶 Chapter 6 - 简单介绍如何使用 C# 改变 XAML 控件的属性
  7. html怎么关闭组合页面,html - 向HTML页面添加内部包装div [关闭] - 堆栈内存溢出
  8. 解析Pascal赋值语句(洛谷P1597题题解,Java语言描述)
  9. html5系列:notification api升级——从webkitNotifications到Notification
  10. VMware虚拟机12个使用技巧
  11. echarts百分比柱形图
  12. 【Unity3D】人物跟随鼠标位置
  13. Excel以及Tableau作品集
  14. 友推SDK微信分享问题
  15. Google Pixel 2 相机测试
  16. 发布一个记账软件---流水记账
  17. 2018最值得期待:云行业估值最高的独立云服务商金山云
  18. 记一次解决联想笔记本冬天卡顿反应慢的方法
  19. 流式细胞仪荧光补偿调节方法
  20. 在线考试系统全套(任务书+开题报告+外文翻译+毕业论文+项目源代码)

热门文章

  1. IC China展商大唐展讯新潮华虹等2014电子信息百强榜上有名
  2. MySQL DDL Duplicate entry '12' for key 'PRIMARY'
  3. android Web App开发
  4. kudu教程(一)——简介
  5. JBPM工作流(二)——数据库表说明
  6. RGB图像转换为灰度图像的原理
  7. 为什么 4EVERLAND 是 Web 3.0 的最佳云计算平台
  8. Java程序员 面试如何介绍项目经验? Java程序员应该如何介绍自己的项目经验和自我介绍?面试如何突出自己
  9. 移动端h5图片下载-前端小白初长成
  10. PASCAL VOC数据集 生成train.txt、test.txt、tainval.txt、val.txt