之前的工作一直是在负责公司直播产品的网页前端开发, 本文是对网页直播的一个总结. 下面我会以直播协议为基础, 以及各个协议在 PC,H5(这里指手机网页)的表现来进行总结.
网页直播常用到的流媒体协议有 RTMP,HDL(HTTP-FLV),HLS 这 3 种.
RTMP
实时消息协议 (英语: Real-Time Messaging Protocol, 缩写 RTMP) 也称实时消息传输协议, 是最初由 Macromedia 为通过互联网在 Flash 播放器与一个服务器之间传输流媒体音频, 视频和数据而开发的一个专有协议. Macromedia 后被 Adobe Systems 收购, 该协议也已发布了不完整的规范供公众使用. wiki
RTMP 协议的延迟较低, 一般都在 3s 左右.
在移动端的 web 端是完全不支持播放 RTMP 的直播流的.
在 pc 端只能在基于 flash 的播放器上播放. pc 网页上支持 rtmp 协议的播放器还不少, 比如 video.JS+falsh plugin, 百度的 cyberplayer, 腾讯的 TCPlayerLite,jwplayer.
虽然这样, 都是由于其低延迟的特点, 并且 RTMP 协议为流媒体而设计, 在推流 (obs 推流) 中用的比较多, 同时大多 CDN 厂商支持 RTMP 协议, 所以目前国内的很多直播产品都会使用这种直播协议, 我们在 pc 网页上的直播也是 rtmp 的协议的.
RTMP 直播示例代码
使用 video.JS 和 videojs-flash 播放 rtmp 直播流, 手机不支持
- <video id="rtmp_player" width="600" height="400" controls class="video-js vjs-default-skin">
- <source src="rtmp://58.200.131.2:1935/livetv/hunantv" />
- </video>
- <script src="//cdn.bootCSS.com/video.js/7.6.0/alt/video.core.min.js"></script>
- <script src="//cdn.bootcss.com/videojs-flash/2.2.0/videojs-flash.min.js"></script>
- <script>
- const player = videojs('rtmp_player', () => {
- console.log('rtmp player init complete');
- });
- </script>
- HDL(HTTP-FLV)
HTTP-FLV, 即将音视频数据封装成 FLV, 然后通过 HTTP 协议传输给客户端. 它使用类似 RTMP 流式的 HTTP 长连接, 需由特定流媒体服务器分发的, 兼顾两者的优点. 以及可以复用现有 HTTP 分发资源的流式协议. 它的实时性和 RTMP 相等, 与 RTMP 相比又省去了部分协议交互时间(可以比 RTMP 做到更低的延迟), 首屏时间更短, 可拓展的功能也更多.
HTTP-FLV 的延迟和 RTMP 差不多, 可以做到比 RTMP 更低一点.
在 pc 网页端, 我们可以通过 flv.JS(flv.JS 需要依赖一些浏览器新特性的, 需要 html5 Video,MSE,WS)来播放 HTTP-FLV 的流. 顺便说一下 flv.JS 的主要原理, 在获取到 FLV 格式的音视频数据后通过原生的 JS 去解码 FLV 数据, 再通过 MSE 把 blob 给原生 HTML5 Video 播放. 同样也可以通过基于 flash 的播放器来兼容播放.(需要注意跨域, http/https 混合使用等问题)
遗憾的是由于 MSE 在移动端的支持较差(目前只有安卓 4.4.4 以上支持, 苹果只有 iPadOS 13 支持 can i use) , 所以 HTTP-FLV 直播在移动网页上的使用也很少(苹果大部分不支持就很悲伤).
目前来讲 HTTP-FLV 在 pc 端的使用还是挺多的, 因为它可以脱离 flash 直接播放(flash 太耗费性能了, 特别是苹果电脑上, 看一下视频风扇就呼呼的), 例如斗鱼, 我们可以打开他的网页 F12 可以看到 video 中的地址是 blob:xxx 这样的形式, 基本可以判断是基于 flv.JS 或者其他类似方案实现的.
斗鱼图片
当然了 b 站也是的, 毕竟 flv.JS 就是 b 站开源的.
b 站图片
HTTP-FLV 直播示例代码
使用 flv.JS 播放
- <video id="flv_player" width="600" height="400" controls></video>
- <script src="//cdn.bootcss.com/flv.js/1.5.0/flv.min.js"></script>
- <script>
- if (flvjs.isSupported()) {
- var flvVideo = document.getElementById('flv_player');
- var flvPlayer = flvjs.createPlayer({
- type: 'flv',
- url: 'http://cyberplayerplay.kaywang.cn/cyberplayer/demo201711-L1.flv'
- });
- flvPlayer.attachMediaElement(flvVideo);
- flvPlayer.load();
- flvPlayer.play();
- }
- </script>
- HLS
HTTP Live Streaming(缩写是 HLS)是一个由苹果公司提出的基于 HTTP 的流媒体网络传输协议. 是苹果公司 QuickTime X 和 iPhone 软件系统的一部分. 它的工作原理是把整个流分成一个个小的基于 HTTP 的文件来下载, 每次只下载一些. 当媒体流正在播放时, 客户端可以选择从许多不同的备用源中以不同的速率下载同样的资源, 允许流媒体会话适应不同的数据速率. 在开始一个流媒体会话时, 客户端会下载一个包含元数据的 extended M3U (m3u8) playlist 文件, 用于寻找可用的媒体流. wiki
HLS 协议是苹果强推的一套协议, 它有 live 和 vod 两种模式(支持直播以及录播视频). 目前在移动端网页支持较好, pc 网页上只有 safrai 和 edge 浏览器支持.
简单介绍下 HLS 直播的工作模式, HLS 协议将视频流 (包含图像以及声音) 编码打包到 MPEG-2 TS 容器中去, 然后将把编码好的 TS 文件等长切分成后缀为 ts 的小文件, 并生成一个. m3u8 的纯文本索引文件; 客户端播放器 HLS 直播就是请求. m3u8 索引文件, 获取到 ts 列表依次播放, 播放结束之后再请求下一个. m3u8 索引文件.
上面讲的可以知道 HLS 的延迟会很高, 直播一般来说一个 m3u8 会包含 3 个切片, 每个切片至少是 2s~3s, 在加上网络延迟, 基本延迟会达到 10s 左右.
虽然延迟很高, 但是移动端网页基本都支持, 所以 HLS 是手机 H5 直播的最佳选择.
pc 上除了 safrai 浏览器和 efge 浏览器可以直接播放, 其他浏览器可以通过 mediaelement,hls.JS,videojs-contrib-hls(这几种是通过 Ajax 请求 hls 流然后来播放的, 所以会有跨域, http/https 不能混合使用等问题, 如果使用基于 flash 的播放器则没有这些问题)等来播放.
HLS 直播示例代码
使用 hls.JS 播放, 手机上直接用 video 播放即可
- <video id="hls_player" width="600" height="400" controls></video>
- <script src="//cdn.bootcss.com/hls.js/8.0.0-beta.3/hls.min.js"></script>
- <script>
- const hlsVideo = document.getElementById('hls_player');
- if (Hls.isSupported()) {
- const hls = new Hls();
- hls.loadSource('xxx.m3u8');
- hls.attachMedia(hlsVideo);
- hls.on(Hls.Events.MANIFEST_PARSED, () => {
- hlsVideo.play();
- });
- }
- </script>
总结
目前网页直播 pc 上主要采用的协议为 RTMP 与 HDL(HTTP-FLV), 手机上主要是 HLS 协议.
此外还有基于 webrtc,ws+canvas 的直播方案, 不过目前应用都不是很广泛, 本文就先不讲了.
参考资料
- RTMP WIKI
- HTTP-FLV WIKI
flv.JS 参考
HLS 协议详解及 HLS 速度优化
H5 直播起航
来源: http://www.jianshu.com/p/7263c50b15fd