大家好,欢迎来到停止重构的频道。
我们之前讨论过直播协议,本期我们讨论在线点播的视频格式。
也就是网络视频文件、短视频常用的格式 如MP4、FLV、HLS等。
我们将详细讨论在线点播场景下,这些视频格式的优劣以及原因。
我们按这样的顺序讨论 :
1、 封装格式的作用
2、 MP4
3、 FLV
4、 HLS
封装格式的作用
首先我们需要搞清楚一点,MP4、FLV、HLS都是封装格式。
在前面《音视频转码工作原理》中讨论过,一个视频文件实质上是分3层的,封装、编码、基础数据。
播放器需要同时支持这3层格式才能播放视频。
而大部分浏览器支持的编码、基础数据格式是不可扩展的,所以即使同是MP4文件,但编码格式不一样的话,浏览器也是有可能播放不出来的。
另外,大部分的封装格式不限制音视频数据的基础参数,如帧率、分辨率、采样率等。
所以,诸如MP4文件比FLV文件清晰等说法,实质上都是谣言。
那么封装格式有什么用呢?
简单地说,封装格式只是对音频数据、视频数据、基础信息等数据,按一定的结构规则编排成文件。
数据编排虽然对音视频数据本身不会产生影响,但是会对一些特定场景产生影响,如MKV的封装格式支持外接字幕,可切换不同语言字幕。
在线播放视频的场景下,FLV、HLS视频的表现会比MP4文件的表现更优秀。
表现优秀并不是画面、声音质量方面,而是首帧播放所需时间、未加载完跳转等表现更加优秀,下面将详细简介为什么会这样。
MP4
MP4是最常见的封装格式了,应用范围广、灵活性高、兼容性强 。
MP4甚至支持自定义封面图,几乎所有的播放器、甚至是浏览器都支持这个封装格式。
MP4文件是很多个数据块相互嵌套的树状结构,MP4支持的数据块类型有几十种,不同类型的数据块存放的信息不一样。
但是很多数据块都是非必要的,具体MP4文件的数据块结构与数据可以使用mp4info这个工具查看。
我们不需要理解MP4所有的技术细节,但是需要知道ftyb、mdat、moov这三种数据块的作用,这三种数据块是MP4文件必要的数据块。
ftyb数据块存放的是编码格式、标准等信息,播放器需要根据这些信息选择对应的解码器。
mdat数据块存放的是具体的音视频数据,这里记录的音视频数据一般是没有时间戳的。
moov数据块存放的是元数据,包括mdat数据里的映射关系,播放器需要根据moov的数据才能推算出音视频帧的播放时间戳。
常常有这样的情况,网络正常的情况下,在线播放的MP4文件需要一段时间才能播放出来。
往往就是因为moov数据块还没获取到,无法计算出音视频帧的播放时间而无法播放。
所以如果MP4文件是用作在线播放的话 ,一般需要将MOOV数据块放在mdat数据块之前,这样有利于更快速地播放出来,很多工具都可以做这样的操作, FFmpeg命令如图所示。
一些人说MP4文件会比FLV文件大,可能是MP4文件记录了很多不必要的信息导致的,正常情况下,相同的视频,MP4封装的文件与FLV封装的文件大小是差不多的。
如果在线播放不是网站系统主要业务,视频文件不大、时长不长的话,是可以直接使用MP4文件的,毕竟浏览器及很多播放器都支持MP4封装格式,用户上传也不需要太麻烦的处理。
但是如果存在文件很大达到几GB、或时长很长的视频文件,那尽量不要使用MP4格式 :一是CDN加速的效果不佳,二是MP4文件长时间在线播放可能会出现播放中断等不良情况。
FLV
FLV格式与往期《直播协议》中的RTMP、HTTP-FLV是类似的,毕竟都是Adobe公司主导或推出的标准。
FLV是一种为网络视频设计的格式,网页加入flv.js插件就可以播放了。
FLV文件的每个音视频数据块都可以有时间戳标识,所以FLV在首帧播放、未加载跳转等场景表现都更为优秀。
这里需要特别说明的是,有时候在线播放FLV视频文件会出现未加载跳转报错的问题,也就是未加载跳转时会报错中断播放的状况。
一般是因为此FLV文件没建立关键帧索引的原因 ,FFmpeg命令追加关键帧索引如图所示。
一般网络视频都采用FLV格式文件,在我们过去的测试体验中,大文件、长时间播放比MP4更为稳定。当然普通CDN加速对FLV大文件效果也不佳,但可以接入大文件CDN缓解这个问题。
HLS
最后是HLS格式,在往期《直播协议》已经详细讨论过HLS了。
在点播的场景下,HLS实质上就是把一整个大的视频文件分成很多个碎片视频文件。
HLS格式的文件由两部分组成,一是多个只有几秒长度的.ts碎片视频文件,另一个是记录这些视频文件地址的.m3u8索引文件。
HLS观看地址实质上是.m3u8索引文件,客户端获取到索引文件后,就可以下载对应的碎片视频文件并开始播放了。
HLS的.m3u8索引文件支持二级索引,就是高清、标清、流畅等多个观看地址可以整合到一个索引文件,播放器可以根据当前带宽自动切换不同的观看地址,大部分网页播放器的“自动”也是因为这个。
由于HLS把一个视频文件切为很多段碎片文件,在线播放长视频场景下,相对于FLV格式,HLS的未加载跳转、CDN加速、多线程预加载等方面更为优秀。
但是在短视频场景下,HLS的优势并不明显,而且视频碎片ts文件本身也是完整的视频封装格式,也是能单独播放的,所以会额外产生一些不必要的流量。
另外,由于HLS视频实质上是很多个文件组成的,HLS视频一般需要网站系统自己转封装,这也是HLS视频比较麻烦的地方,不过公有云也有视频文件转码服务 一般提供自动转封装的功能。
补充说明一下, HLS协议是苹果推出的标准,与HLS协议类似的还有MPEG-DASH协议。 HLS、MPEG-DASH的工作原理都是差不多的,只是局部标准不一样,这里不作展开。
总结
总的来说 如果是网站系统的视频不多,在线播放不是主要业务,那么视频文件使用常规的MP4格式就可以了。
如果在线播放视频是主要业务,则需要考虑FLV、HLS格式。
短视频偏多的话,则推荐采用FLV格式,长视频、大文件偏多的话,则推荐采用HLS格式。