播放器技术分享(4):首开时间


搞音视频开发好些年,分享过许多博客文章,比如:前几年发布的《FFmpeg Tips》系列,《Android 音频开发》系列,《直播疑难杂症排查》系列等等。最近想把多年来开发和优化播放器的经验也分享出来,希望能帮助到音视频领域的初学者。第一期文章要推出的内容主要涉及到播放器比较核心的几个技术点,大概的目录如下:1. 播放器技术分享(1):架构设计2. 播放器技术分享(2):缓冲区管理3. 播放器技术分享(3):音画同步4. 播放器技术分享(4):首开时间5. 播放器技术分享(5):延时优化本篇是系列文章的第四篇,主要聊一聊如何优化播放器的首开时间。1 首开时间的定义首开时间:从点击播放到第一帧画面显示出来的耗时。通常大家说的 “首屏秒开” 指的就是播放器的“首开时间”在 1s 以内。首开速度是用户最简单、最直接的体验,所以通常是播放器开发中优化的重点。下面是一个典型的首开速度和用户感受的关系表:2首开时间的影响因子要优化播放器的首开时间,我们得先了解一下影响播放器首开时间的因素有哪些,下图简单展示了播放器向服务器申请播放一个视频流的全过程。想优化播放器的首开时间,首先关注一下播放流程中的每个环节,如图所示,可能的优化点列表如下:申请资源的播放 URL 地址的时机优化 -> 争取在用户点击播放之前拿到 URLDNS 解析优化 -> 提前完成 DNS 解析,并缓存结果服务器的连接和数据传输速度优化 ->主要是服务器节点与播放器之间的网络传输优化视频流的媒体信息解析优化 -> 主要是解析提取算法的优化解码和渲染策略优化 ->GOP 缓存,确保首帧为关键帧解码渲染其他优化手段 -> 测速选线、解码算法性能等在这个过程中,每一个环节都有一些影响因子会决定播放器的首开时间,我们下面详细展开优化思路。3 首开优化方法3.1优化 URL 的获取时机如图是一个播放列表,每个视频都会对应一个资源的 URL 播放地址,如果在用户点击视频后,APP 再去后台业务服务器去申请这个 URL 播放地址,无疑增加了一次 HTTP 请求和应答的耗时,特别是网络不稳定的时候,耗时更加明显。因此,这是一个可以在 APP 层进行的优化点:在拉取视频播放列表的时候,“同时” 把视频的 URL 播放地址也拉取下来,在用户点击视频后无需再向服务器申请播放地址,即可立即开始播放了。3.2优化 DNS 解析时间视频资源的 URL 地址,往往是包含域名的,比如:http://jhuster.com/video/movie.mp4播放器在播放前,需要先进行 DNS 解析,把jhuster.com这个域名解析为一台服务器的 IP 地址,然后才能通过 TCP 连接上去,发送资源请求。我们在 17CE 网站上简单测测这个域名解析的时间:可以看到,平均 DNS 解析时间在 673ms 左右,但是在很多地区(比如:佛山市电信,北京市电信)解析时间都超过 2s 了,可想而知,在这些地区 DNS 解析缓慢对播放器首开时间是致命的伤害。为了确保所有地区的视频播放不过于受 DNS 解析速度的影响,除了为视频资源的域名购买付费的专业 DNS 解析服务外,播放器层面也可以针对性地做一些优化,如下图所示:播放器内部新增一个 DNS 结果缓存模块在异步线程定时执行 DNS 解析,并把“域名 & IP 表” 缓存在内存中视频播放时,直接查表,取出域名对应的 IP 地址,送入播放器注意事项:一个 APP 的资源域名个数是收敛的,不是无限个,所以可以在 APP 启动的时候,送入播放器提前去完成 DNS 解析和缓存未提前配置的域名,在第一次解析的时候,依然会首开慢,但该域名第二次即可从本地缓存中取了需要注意缓存的 IP 地址的刷新:DNS 解析有一个 TTL 超时时间,到期前要记得重新解析刷新监测手机网络切换事件,比如:WiFi 切换到 4G 后,需要清空缓存举个例子:DNS Cache Map: 如果要播放 URL:http://jhuster.com/video/movie.mp4可直接替换为播放:http://185.199.108.153/video/moive.mp4坑在哪 ?当我们真的用 ip 地址去播放的时候,会发现服务器会拒绝访问,例如报如下错误:原因:视频资源的 CDN 服务商需要知道是 “谁” 在申请这个视频资源 -> 为了计量和计费,服务商的判断访问依据是“域名”,所以直接使用 IP 访问会遇到上述问题。怎么解决 ?HTTP协议:有个 HOST 字段,记录了服务器的域名RTMP 协议:有个 tcUrl 参数,记录了完整的播放器地址(含 服务器的域名)其实 CDN 服务商并不是从 URL 取的域名,而是从 HTTP/RTMP开发云主机域名 协议中的上述字段中 “提取” 的域名,因此,我们需要改造播放器底层的 HTTP/RTMP 代码模块,提供一个接口,可以把 URL 中原始的域名填入到上述协议字段中即可。3.3优化服务器连接和数据传输时间播放器通过 DNS 解析拿到了服务器的 IP 地址,下一步就是通过 TCP 连接服务器,然后发送请求读取数据了。在这个过程中,与服务器的连接速度以及数据的传输时间非常重要,直接影响着首开体验。这个因素并不是在播放器层面可以执行的优化,因此就简单提一下,优化的关键因素在于服务器的负载、CDN 的节点分布和带宽情况了。这也是为什么一般的 APP 公司会采购和使用 CDN 服务的原因了。3.4 优化媒体信息的读取策略视频的媒体信息里都有啥 ?是否包含:音频、视频
音频、视频的编码格式,如 H.264,AAC 等
视频的信息,如 分辨率、帧率、码率
音频的信息,如 采样率、位宽、通道数
码流的总时长
其他附加信息,如 作者、日期等可见,媒体信息对于初始化播放器还是非常重要的。不同的音视频封装格式,媒体信息存放的位置也不太一样,像 flv 格式,媒体信息往往直接存放在开头,因此是比较容易第一时间读取到的。而 mp4 格式,常常会遇到 moov 在尾部的情况,这种是播放器优化的重点,如图所示:对于这种把媒体信息存放到了尾部的 mp4 文件,默认的播放器需要把整个 mp4 全部下载下来才能拿到媒体信息,对首开是极其不友好的。如何优化呢 ?—— 双 IO 技术如图所示,对于 moov 媒体信息在尾部的 mp4 文件,播放器读取一定数据后,如果判断 moov 在尾部,则可以暂停这个线程,同时启动第二线程通过 http range 字段读取尾部的 moov,从而拿到关键的媒体信息,这样的技术策略的好处是:无需下载整个 mp4 即可播放 moov 在尾部的视频第一个 IO 已下载的部分可继续利用,不用丢弃3.5 优化媒体信息的解析时间媒体信息解析的工作量在哪 ?判断码流的封装格式,比如 mp4,flv,m3u8 等等根据封装格式的协议约定,提取数据中的媒体信息为了提高对非标准码流的兼容性,ffmpeg 使用了一套非常复杂的解析策略,即使从码流中已经提取到了 metadata,依然会做各种 double check,比如,多次 try_decode_frame 测试是否真的可以成功解码数据,从而导致底层基于 ffmpeg 的播放器,首开速度会在这里降下来。如何优化呢 ?如果是基于 ffmpeg 内核的播放器,那么常用的手段如下:减小 probesize减小 analyzeduration预设码流的音视频格式3.6 优化首帧解码和渲染我们知道,编码后的视频帧是分 I、B、P 帧的,I 帧是关键帧,可独立解码出图像;B/P 帧分别是前向预测帧/双向参考帧,是需要参考 I 帧或前后帧才能解码出图像的。因此,为了尽快解码出首帧画面,需要确保送入编码器的首帧即是 I 帧。
如图所示,在直播场景下,如果观众在 C 时间点拉流,则正好可以拉取到一个 I 帧,迅速完成解码播放,实现秒开。但是如果不巧,正好在 A 时间点或者 B 时间点拉流,则会导致无法解码,一直要等到下一个 I 帧才能完成解码渲染。因此,一般的直播云厂商,都会在服务端缓存一个 GOP 的数据,无论任何时候,播放器申请播放,都会首先下发这样一个以 I 帧开头的 GOP 数据,从而加快了播放器的解码和首开。对于播放器而言,需要注意的时候,当第一帧还没有渲染之前,先不要主动缓冲,而是尽快先渲染首帧。4 总结当然,还有很多其他的播放器首开时间的优化策略,测速选线、解码算法性能等,用的不是很广泛,这里就不展开介绍了。关于播放器的首开时间优化,就分享这么多了,如有疑问的小伙伴欢迎来信 lujun.hust@gmail.com 交流。另外,也欢迎大家关注我的新浪微博 @卢_俊 或者 微信公众号 @Jhuster 获取最新的文章和资讯。

相关推荐: Excel转Json工具(资源配置基础)

① , 支持字段类型( int / float / string / bool / int[] / float[] / string[] / bool[] )② , 支持前端/后端差异配置③ , 支持说明书sheet④ , 支持更改编码方式⑤ , 支持展开/收…

免责声明:本站发布的图片视频文字,以转载和分享为主,文章观点不代表本站立场,本站不承担相关法律责任;如果涉及侵权请联系邮箱:360163164@qq.com举报,并提供相关证据,经查实将立刻删除涉嫌侵权内容。

(0)
打赏 微信扫一扫 微信扫一扫
上一篇 05/06 16:07
下一篇 05/06 16:07