Photo by Vlada Karpovich from Pexels
视频体验由开始的视频清晰流畅,演变到现在的视频快速响应、即点即放、快速切换等等。基于这些优化林勇平将介绍播放器的一些技巧,使得视频体验在较少改动的情况下就能达到极致体验的效果。
文 / 林勇平
整理 / LiveVideoStack
直播回放
https://www2.tutormeetplus.com/v2/render/playback?mode=playback&token=9761031daf924623a3c92fca9d1da030
本文主要分为四个部分:一是服务端优化;二是播放器优化;三是播放策略优化;四是缓存优化。将这几部分组合起来就可以保视频秒开、无缝滑动等等优化,保证在整体上进行较少改动的情况下达到一个较好的效果。
1. 服务端优化
第一部分提到的是服务端优化,主要分为三个部分,首先是服务数据优化,即服务端数据的基础准备。在格式选择方面,有MP4、FMP4、DASH、HLS和自定义格式,对于短视频类的视频格式大部分是MP4,对于长视频类的格式可能有HLS、DASH、自定义格式。因为长文件的头是比较大的,所以一般用上面说的描述文件,或者是分段MP4及FMP4文件,使MOOV头信息变小,可以保证视频即点即开。
现有的大部分短视频使用的是MP4格式,选择MP4格式主要是文件信息头MOOV的信息应该是前移的而不是在文件末尾,所以需要整个服务端进行一遍转码。对于数目chunk而言,一个chunk可能包含几帧,如果设置不对,对于某些播放器就需要下载一个chunk才可以播放,这就需要下载很多的数据,从而影响第一段的播放或者前面的播放。很多音频特别容易出现这种情况,有些播放器中所有的帧都在一个chunk里面,这就需要下载这个chunk才能播放,就增加了等待的时间。
在编码器的选择上,现在的编码器一般都是H.264或者H.265,这需要根据各家公司的选择。H.264主要是比较通用,H.265则是码率比较好。在数据和信息的预取方面,如果一个页面有很多视频的时候,当点击一个视频时,该视频里面的table等信息是可以预取的,方便后面点开播放进行前期准备。
第二是cdn的调度优化,在视频播放之前,首先要对dns进行解析,通过服务器调度把最近的或者热流地方的IP进行解析。网络切换,就是假如在4G、WiFi之间进行切换的时候,先对IP的解析进行预取,网络切换情况如果是WiFi到4G,需要有一些提示;从4G到WiFi则不需要提示,而是需要及时地将这批IP切下去,因为不同服务商的cdn可能不一样。
第三是P2P的点播,这主要是为了节省cdn费用,一般可以节省25%以上的费用,对于视频和音频公司来说,这些宽带费用是很高的。
这张图展示的是信息的预取,就是获取table里视频页中可以获取的数据,以保证视频秒开,即点即放,即预取一定的数据,点开就播放。48k相当于大概不到一秒的数据,先下载后点开,就直接播放了。
2. 播放器优化
第二部分是播放器优化,首先是点播优化,它主要是各个模块的一些优化。其次是直播优化,它不仅包含各个模块优化,还要有一个播放速率的控制,以保证较低延迟。
直播播放的大体框架就是由下载管理、文件解析、缓存管理、视频解码、视频渲染、音频解码、音频处理、音频渲染这几部分组成。对于直播来说多了“缓存管理”这一模块,当缓存管理大到一定程度,需要进行变速或者丢帧。一般的情况下,如果缓存管理大于两秒,就可以把这个两秒的数据一直丢到I帧,以保证其低延迟。如果缓存管理大过一秒,这时就可以控制播放速率,可以播快一定的速度使其追上来,以保证低延迟。总之,缓存管理就是检查现有的播放器里的缓存的大小,以判断延迟的的大小是否正常,若不正常是否需要丢帧或者加速。
2.1 文件解析优化
对于文件解析优化这部分,首先是缓存管理,有的播放器是解析一帧数据就丢一帧数据,这时若推到后台再推到前台时,对于已经丢弃的数据,当前帧需要返回重新下载,而缓存管理不将过去的数据全部丢弃,至少保留某一个I帧。
其次是时间对齐,MP4 文件有时候音频时间从0开始,但是视频可能是从100ms开始,这时开始播放视频,假如第一帧视频出现,但音频就要从0开始播放到100再播放到33才有第二帧,这时大概有133毫秒的停顿,对于视频来说相当于播第一下的时候就会卡顿一下,所以时间对齐就是MP4在一定时间,即音频大概多于多少的时候,可以把它丢掉,保证一开始播放时视频和音频同时起步,就不会引起第一帧卡顿的感觉。
三是后台播放,它在直播场景中比较常见的,后台播放时无需解码,但需要AV同步,可以用原始帧时间同步,但也要保留至前一个I帧,然后再用解码帧进行AV同步。对于点播,推到后台时一般是暂停的,但是对于后台有些时候不能用硬解码,回到前台的时候,可以直接用seek(getPosition)。
四是断点重连,是直播中常见的一个。点播中断点重连影响不大,直播中断点重连就是在直播中发生连接中断了,重连时的时间戳从0开始下载,新下载的数据需要加一个tag,说明时间已经发生变化,表示这一帧不用保证AV同步,对用户来说是感觉不到是否发生中断的。
图中是一个MP4文件,图中的左边介绍了box类型,右边是对其的说明。文件里的chunk offset表示每个chunk的文件偏移,一般短视频的moov较小,对于MP4来说,其前面的头信息还是较多的,其中ctts是为了I、B、P帧设置的。
图中是一个FLV文件,图中上部是FLV Header,下部是FLV Body。
2.2 解码器优化
关于解码器优化,首先硬件解码主要有MediaCodec、AudioToolbox、后台播放。其次软件解码优化中的多线程优化主要有两种:Frame Module、Slice Module。快速第一帧是第一帧进去之后不会立马出来,这时候就需要不断塞数据让第一帧快速出来,因为视频解码有参考帧概念。
2.3 渲染优化
渲染优化主要体现在一些选择方式上,对于安卓来说有native windows、Opengles、MediaCodec三种;而IOS可以选择Opengles,但要考虑前台、后台播放问题。其中native windows和Opengles相比,Opengles的限制比较多,而native windows没有现成的限制。
3. 播放策略优化
第三部分是播放策略优化,对于直播来说,首先是cdn调度预取,当前页面直播列表要调度所有直播链接,获取直播地址,直接用当前的cdn的IP进行播放。其次翻页播放选择多播放器进行翻页播放,当前页播放时翻到下一页,点击时下一个播放器已经启动播放,相当于两个播放器同时播放,上滑播放上一个播放器,下滑播放下一个播放器,只不过下一个播放器的音量在非当前页面时为0,当点击结束时,下一播放器在当前页面时的音量从0变为1。
对于点播来说,首先页面预取加速就是点播在当前页面会有一个数据的预取,大概500毫秒数据时就可以点击播放,一般需要获取多少数据由服务器决定。其次翻页多播放器,不同于直播时的两个播放器同时进行播放,点播翻页播放在播放当前页面的时候,可以把上一个和下一个直接准备好,上滑时准备好上一个播放器,下滑时准备好下一个播放器,翻页时直接就准备播放。
对于消息返回和打点,首先如果碰到异常情况,播放器不能处理的时候,将消息抛到客户端,由客户端反馈给用户一些提示,如网络或者文件错误等情况。其次打点对于cdn的连接时间、http的请求时间,下载第一帧数据、第一帧解码和展示所有花费的时间都由服务器打点,由服务器统计决定哪些地方还需要再优化,或者哪个cdn需要再进一步优化。直播一般十秒打一个十秒的信息,对当前播放的音频码率、视频码率、原始码率是否有丢帧、卡顿等信息都会进行打点,这对服务器进行后续检查直播或者点播中各种问题和进行各种优化都很有帮助。所以直播和点播打点,就是对各个方面和各个数据进行打点,以便后续的找出合理的方式进行优化。
4. 缓存优化
第四部分是缓存优化,缓存优化优点很明显,首先是节省cdn经费,即边播放边缓存文件,推到前台或者往回seek的时候,边播边存的优势就会显示出来。其次是分块存取,即播放当前页时需要快速拖动,需要保存所拖动地方的文件,保证缓存空间和下载的数据是对应的,以保证回放时节省流量。