文章目录

  • 前言
    • rtmp产生延迟的原因
    • 如何减少播放器播放延迟
    • 追帧策略定义和工程实现细节
      • 直播播放器追帧策略
      • 基于ijkplayer[^1]的工程实现
  • 总结
    • 推荐免费直播学习课程: [c/c++Linux后台服务器开发高级架构师学习视频](https://ke.qq.com/course/417774?flowToken=1040695)

前言

众所周知使用rtmp协议进行直播,在网络不好的情况会累计延迟,网络条件恢复延迟也不降低。因此我们要根据rtmp协议的特性,使用一定的策略,在网络恢复时优化rtmp协议延迟的累计,实现低延迟直播播放器


rtmp产生延迟的原因

rtmp基于tcp协议传输媒体数据,在弱网情况下也不会丢包,所以当网络状态比较差时,流媒体服务器会将数据包缓存起来,导致直播延迟。在网络回复后一起发送给服务端。

如何减少播放器播放延迟

  1. 检测到视频包队列缓冲区超过一定阈值后,播放器断开重连。优点简单粗暴,缺点用户体验不够好,重连会产生卡顿丢失一部分的直播内容。
  2. 检测到视频包队列缓冲区超过一定阈值后,开启倍速播放追赶直播进度,直到控制到延迟在指定时间内。优点过度比较平滑,用户体验比较好。缺点实现相对复杂。

追帧策略定义和工程实现细节

直播播放器追帧策略
  1. 定义播放器视频缓冲区总时长为 video_queue_time
  2. 定义视频缓存区最大时长 max_video_cached_duration
  3. 定义网络抖动大小 network_jitter_time
  4. 如果video_queue_time 大于 max_video_cached_duration + network_jitter_time,设置播放器1.1 or 1.2倍速播放
  5. 如果video_queue_time < max_video_cached_duration,设置播放器1.0倍速播放
基于ijkplayer1的工程实现

修改文件 ijkplayer-android\ijkmedia\ijkplayer\ff_ffplay_def.h

  • MIN_FRAMES 需要改成1000,否则默认的包队列大小不够容纳网络恢复后读取的AVPacket数量
// ffplay.c
//校验是否有必要继续向缓冲区中添加 AVPacket  默认MIN_FRAMES 25
static int stream_has_enough_packets(AVStream *st, int stream_id, PacketQueue *queue)
{return stream_id < 0 ||queue->abort_request ||(st->disposition & AV_DISPOSITION_ATTACHED_PIC) ||queue->nb_packets > MIN_FRAMES && (!queue->duration || av_q2d(st->time_base) * queue->duration > 1.0);
}
  • struct VideoState 添加三个字段,如下所示

#define MIN_FRAMES 1000// struct VideoState 添加三个字段
typedef struct VideoState {...int max_delay_ms;         // 默认: 5000msint network_jitter_ms;  // 默认: 500msfloat new_play_rate;   //默认: 1.2...
}

ff_ffplay.h添加一个接口
ijkplayer-android\ijkmedia\ijkplayer\ff_ffplay.h

// 设置视频缓冲区最大延迟,抖动时长,倍速播放速度
void ffp_set_maxdelay_jitter_palyrate(FFPlayer *ffp, int max_delay_ms, int network_jitter_ms, float new_play_rate)
{assert(ffp);VideoState *is = ffp->is;if (!is)return;is->max_delay_ms = max_delay_ms;is->network_jitter_ms = network_jitter_ms;is->new_play_rate = new_play_rate;
}

ff_ffplay.c添加两个辅助函数
ijkplayer-android\ijkmedia\ijkplayer\ff_ffplay.c

// 获取视频队列缓冲区时长
static int64_t get_video_queue_cached_duration(FFPlayer *ffp)
{return is->videoq.duration;
}// 控制视频缓冲区最大延迟在 [max_delay_ms, max_delay_ms+network_jitter_ms) 区间浮动
// 设置max_delay_ms = 0 不开启追帧策略
static void control_max_delay_duration(FFPlayer *ffp, int max_delay_ms, int network_jitter_ms, float new_play_rate)
{if (max_delay_ms == 0)return;VideoState *is = (VideoState*)handle;uint32_t cached_duration = get_video_queue_cached_duration(is);if (cached_duration > max_delay_ms + network_jitter_ms && ffp->pf_playback_rate == 1.0){//设置倍速播放 建议1.1 or 1.2 倍速ffp_set_playback_rate(ffp, new_play_rate) ; }else if(cached_duration <= max_delay_ms && ffp->pf_playback_rate != 1.0) {//恢复正常播放速度ffp_set_playback_rate(ffp, 1.0);}else{;// do nothing...}
}

read_thread线程控制播放器最大缓冲区大小

//在解封装线程的for循环里面调用 control_max_delay_duration
//========read_thread============
static int read_thread(void *arg)
{...for(;;){...ret = av_read_frame(ic, pkt);...if(is->max_delay_ms > 0){control_max_delay_duration(ffp, is->max_delay_ms, is->network_jitter_ms, is->new_play_rate);}}}

总结

基于ijkplayer播放器只要稍作修改,就可以在网络恢复时减少rtmp的累计延迟。ijkplayer本质上是基于ffplay的二次开发,只要让ffplay支持倍速播放,也可以很容易的添加追帧策略,开发我们的低延迟直播播放器。

推荐免费直播学习课程: c/c++Linux后台服务器开发高级架构师学习视频

音视频流媒体权威资料整理,500+份文章,论文,视频,实践项目,协议,业界大神名单


  1. https://github.com/bilibili/ijkplayer ↩︎

基于ijkplayer实现低延迟直播播放器相关推荐

  1. Android开发-基于ijkplayer框架开发网络电视直播播放器的实现

    https://blog.csdn.net/fukaimei/article/details/80553709 前 言 ijkplayer框架是由B站在GitHub开源的一款比较好用的开源网络播放器框 ...

  2. 技术宝典 | 基于标准 WebRTC 低延迟直播的开源实践

    导读:2020年,新冠疫情爆发并席卷全球,对包括中国在内的全球经济造成了巨大的冲击,同时深刻影响了社会生活.在这一背景下,以消费市场上轰轰烈烈的直播电商为引爆点,直播行业再次掀起热潮.在中国企业数字化 ...

  3. 基于ijkplayer封装的UE4安卓播放器插件

    基于ijkplayer封装的UE4安卓播放器插件 关于 ijkplayerUE4 相关的 Github 地址 使用方法 运行后的demo 关于 ijkplayerUE4 基于bilibili开源项目 ...

  4. GSYVideoPlayer(基于ijkplayer)之rtmp协议播放器的简单应用

    基于ijkplayer的GSYVideoPlayer rtmp协议播放器的简单应用 **添加依赖** **Manifest配置** **Layout布局** activity_start.xml ac ...

  5. 基于OBS超低延迟直播实测(400毫秒左右)超多组图

    阿酷TONY,原创文章,长沙. 文章简述:本文介绍使用OBS无延迟直播插件在第三方云平台,如何实现超低延时直播的完整教程(延迟约为400毫秒左右,通常延迟是3-15秒). OBS简要介绍 OBS(Op ...

  6. 【基于Ijkplayer】安卓机顶盒电视播放器开发

    前言 Ijkplayer是B站开源的一款多媒体播放引擎,其基于ffmpeg开并支持很多的在线媒体播放格式.本文实现了在安卓TV上播放各大电视台的直播,其格式是.m3u8.当然了只要是编译的Ijkpla ...

  7. 基于 RTS 超低延时直播优化强互动场景体验

    RTS 在阿里云视频直播的基础上进行底层技术优化,通过集成阿里云播放器 SDK,支持在千万级并发场景下节点间毫秒级延时直播的能力,弥补了传统直播存在 3~6 秒延时的问题,确保了超低延时.低卡顿.秒开 ...

  8. 跨平台低延迟的RTMP/RTSP直播播放器设计实现

    开发背景 2015年,当我们试图在市面上找一款专供直播播放使用的低延迟播放器,来配合测试我们的RTMP推送模块使用时,居然发现没有一款好用的,市面上的,如VLC或Vitamio,说白了都是基于FFMP ...

  9. [SRS+docker]实现直播服务器 3 基于webRTC协议的srs低延迟直播研究

    目录 前言 低延迟研究 设备兼容性 webRtc调试 播放器 体系结构 结论 问题 rtc_player.html点击播放报错 局域网RTC黑屏 附件 前言 上一篇我们通过单机版的srs服务器,验证了 ...

最新文章

  1. 数论-扩展中国剩余定理
  2. java精准查询mysql时间_在mysql查询中查找与指定日期时间最接近的日期时间
  3. LNCS用户写作指南【 Springer Computer Science Proceedings 】
  4. java怎么调用7zip进行压缩_JAVA使用7-zip解压缩带密码的Zip文件(非Proccess方法)...
  5. 免费开源低代码拖拽开发_资料来源:面向开源开发人员的免费代码搜索工具
  6. EL表达式和JSTL标签库使用
  7. 二维数组 赋值_数组,及二维数组
  8. python not enough arguments_python - not enough arguments for format string
  9. 点云数据格式及处理工具
  10. 嵌入式学习(一)嵌入式c语言
  11. 谷歌VR展示360度全景图
  12. Oracle get、start、edit、spool命令,临时变量、已定义变量
  13. cryEngine5.3打包
  14. 网站的服务器什么意思,网站服务器站点是什么意思
  15. 基于大数据技术对基金分析----By Glorio
  16. HDU 4685. Prince and Princess
  17. 全能水果柠檬的保健功效和食用方法
  18. php 银行支付通道_PHP银联在线支付接口的开发实例
  19. 最新版IAR9.32和注册工具
  20. 增加了网上商品比价搜索功能

热门文章

  1. Java程序员编写代码的技巧
  2. 有 1、2、3、4 四个数字,能组成多少个互不相同且无重复数字的三位数?都是多少?
  3. STEP7 200及其仿真器的使用步骤
  4. 第三章 ContextCapture 19 空三处理
  5. pikachu靶场-5 远程命令,代码执行漏洞(RCE)
  6. 编写函数swap实现两个数据的互换,形参分别指针和引用
  7. 字节流和字符流的应用
  8. 温室大棚冬季增温方案,适合自己的才最好
  9. 自助建站的优缺点总结
  10. 数据标准化的原因和方法