此文是在项目实践的过程中参考了很多位大佬的文章,加上自己的实践整理而成。
直播协议
国内常见的直播协议有几个:RTMP、HLS、HTTP-FLV。
| 协议 | 原理 | 播放器 | 延时 | 兼容 |
|---|---|---|---|---|
| RTMP | 每个时刻的数据收到后立即转发 | flash | 1-3s | 需要flash播放,H5上依赖第三方插件 |
| HLS | 集合一段时间的数据,生成ts切片文件,播完一个列表的ts文件再更新下一个列表 | <video> |
5-20s | H5上直接可播放 |
| HTTP-FLV | 同RTMP | <video> |
1-3s | 依赖第三方插件,IOS无法播放 |
RTMP
RTMP,全称 Real Time Messaging Protocol,即实时消息传送协议,基于TCP。是 Macromedia 开发的一套视频直播协议,现在属于 Adobe,可用于拉流和推流。基于TCP。协议中的基本数据单元成为消息(Message),传输的过程中消息会被拆分为更小的消息块(Chunk)单元。最后将分割后的消息块通过 TCP 协议传输,接收端再反解接收的消息块恢复成流媒体数据
使用方法
使用第三方插件videoJS,因为videoJS把flash的兼容去掉了,还需使用videojs-flash
优势:
- 延时较低,在1-3s
劣势:
-
使用Flash播放,现在各大浏览器厂商已经默认禁用Flash
-
基于TCP协议,非公共端口,可能会被防火墙阻拦
HLS
HLS全称HTTP Live Streaming,是一个基于http的流媒体通信协议,由Apple公司实现,只能用于拉流,在移动端上的兼容性非常好,是移动端的主流直播解决方案。
HLS的工作原理简单来说就是把一段视频流,分成一个个小的基于HTTP的文件来下载。当媒体流正在播放时,客户端可以根据当前网络环境,方便地在不同的码率流中做切换,以实现更好的观影体验。
使用方法
直接使用标签播放
为更好的兼容性,也可以使用videoJS,但是还需要多引入一个插件 videojs-http-streaming
HLS协议拉到的视频格式是 .m3u8(无法用浏览器直接打开,可以下载VLC这个工具来播放),下图是一个m3u8的文件在浏览器中播放,浏览器获取m3u8的文件后,会再去下载一个.m3u8的文件,注意此时的文件类型是m3u,浏览器会根据这个文件的playlist去下载ts文件,也就是视频切片(这个地址可以直接复制到浏览器打开),然后按顺序播放ts文件。当一个playlist的ts文件播放完后,浏览器会再去下载m3u8文件,获取新的playlist,周而复始。
上图右边的就是这个m3u8文件的playlist。
HLS的延时高的原因之一是,要生成切片才能推送数据,如果每个 ts 按照 5 秒来切分,一个 m3u8 放 6 个 ts 索引,那么至少就会带来 30 秒的延迟。如果减少每个 ts 的长度,减少 m3u8 中的索引数,延时确实会减少,但会带来更频繁的缓冲,对服务端的请求压力也会成倍增加。所以只能根据实际情况找到一个折中的点。
项目中的一个小问题
在项目中,这个m3u8的地址是由前端通过接口请求后端得到的,而我们后端也是需要去像厂家拉流,这就存在一个问题,有可能后端把地址推送给我们了,但是ts文件还未生成,也就是没有playlist,这时候就会导致视频播放错误,可以通过video的onerror事件监听,把m3u8的地址重新赋值给video的src属性。
优势
-
使用H5标签即可播放
-
穿透防火墙。基于 HTTP/80 传输,有效避免防火墙拦截
-
性能高。通过 HTTP 传输, 支持网络分发,CDN 支持良好,且自带多码率自适应,Apple 在提出 HLS 时,就已经考虑了码流自适应的问题
劣势
-
延时较高,HLS 的延迟基本在 10s+ 以上
-
会下载非常多的ts文件
HTTP-FLV
FLV (Flash Video) 是 Adobe 公司推出的另一种视频格式,文件后缀.flv,是一种在网络上传输的流媒体数据存储容器格式。HttpFlv 就是 http+flv,将音视频数据封装成FLV格式,然后通过 HTTP 协议传输给客户端。
使用方法
使用B站的开源方案flv.js插件,该插件依赖于Media Source Extensions,而Media Source Extensions在IOS上兼容性很差,但在ipadOS13以上全支持(这个大家可以持续关注下)
优势
-
延时低
-
基于http协议,可穿透防火墙
-
不依赖Flash
劣势
- 移动端IOS设备兼容性差
DASH
DASH的全称是Dynamic Adaptive Streaming over HTTP,是HLS的一种可替代方案。youtube用的是DASH。DASH会通过media presentation description (MPD)将视频内容切片成一个很短的文件片段,每个切片都有多个不同的码率,DASH Client可以根据网络的情况选择一个码率进行播放,支持在不同码率之间无缝切换。
可使用插件dash.js来播放
未解决难点
因为项目需要,我们是在ipad端的app里嵌入H5播放视频,使用的是HLS,但是在app的webview里获取到视频画面的时间要比直接在浏览器的时间长,我通过抓包看到,是因为在app的webview里,在获取到m3u8文件后,生成playlist的m3u类型的文件要过很久才能有,等到这个文件下载了,ts文件有了,画面就出来了。不知道为什么在app里需要这么长时间,如有知道的大佬,还望告知。