引言
之前写了《web端直播技术初步研究(上)》,本篇继续介绍直播流播放原理。
flv.js 和 dash.js 的原理
在上篇中介绍了flv.js
和dash.js
可以分别播放不同协议的视频流,那么它们的原理是什么呢?
大概流程是:
对于无法直接播放的视频源,先通过异步获取视频源,得到二进制的视频流内容,通过转码成视频可以解析的二进制内容,然后“投喂”给video播放器。
需要涉及几项现代技术(但不是每种协议方式都会用到如下技术):
- MSE(Media Source Extension)
这是一个w3c规范,不做媒体业务开发的同学可能不是非常熟悉这个规范。此规范允许JavaScript动态构建audio
和video
的媒体流。它定义了一个MediaSource
对象,可以作为HTMLMediaElement
的媒体数据源,它是实现“投喂器”的主要技术,简单伪代码示例如下:
1 |
|
- WebSocket
Websocket可以传输文本和二进制内容,主要用来持续接收视频流数据,伪代码示例如下:
1 |
|
- fetch
Fetch api主要用于异步获取视频源的内容,以及对流的处理。
首先我们需要先获取流:
1 |
|
现在我们已经有了流媒体,我们需要一个“阅读器”来读取:
1 |
|
已经获取了“阅读器”,我们通过“阅读器”来读取流内容,并创建自定义可读流(自定义可读流并不是必需的):
1 |
|
- ArrayBuffer | Blob
一般与Fetch api配合使用,用来对流内容进行处理,比如转码等。在将其它格式,比如flv
格式转换成mp4
格式时十分有用,flv.js就是使用这个做法。
至于如何转码,又是另一课题,不是本文主要目标,有机会另作分享。
回头看WebRTC的推流
之前说过webRTC目前还不是一个成熟的可用于商业直播平台的采集方案。但是,如果不考虑前置处理,我们目前是可以尝试使用它结合其它辅助技术进行推流的,主要用到的技术有:
- WebRTC
- MediaRecorder
- WebSocket
- FileReader
- Blob | ArrayBuffer
首先,我们需要使用WebRTC打开客户端媒体硬件(摄像头和麦克风)进行视频录制:
1 |
|
获取了视频流之后,进行流的切分录制:
1 |
|
录制完成一个块之后就开始上传:
1 |
|
服务端通过ws接收数据,并执行解编码后向拉流端传送数据。
服务端
之前我们讲的都是客户端拉流,那服务端呢?
一般大型的应用都使用云平台提供服务,更加稳定高效。也可以自己进行搭建服务,可以使用srs
,livego
,nginx-http-flv-module
等进行搭建。由于服务端搭建不是本文重点阐述目标,下面只是简单介绍一下常用服务端技术:
- Srs(Simple-RTMP-Server)
SRS流媒体服务器定位是运营级的互联网直播服务器集群,追求更好的概念完整性和最简单实现的代码。Srs是跨平台流媒体服务器,支持rtmp/hls/http/hds的协议
- Livego
是使用 Go语言开发的直播服务器,跨平台,支持常用的传输协议,如RTMP, HLS,HTTP-FLV等
- nginx-http-flv-module
是在nginx-rtmp-module基础上实现的一个音视频传输模块,将RTMP转为FLV封装格式,再通过HTTP协议下发。支持HTTP-FLV方式直播,添加了GOP(group of picture)缓存功能,减少了首屏等待时间,对RTMP和HTTP-FLV都有效,添加了VHOST(单IP地址多域名)功能并支持类似Nginx的HTTP模块的通配符配置;修复了nginx-rtmp-module中已知的bug。
小结
以上粗略地描述了如何通过现代web技术搭建直播和点播视频流的功能原理,实际商业操作过程其实比本文描述的更加复杂,比如:如何在基础功能上保证视频流的稳定和性能,webSocket的连接的异常中断如何处理,断点如何续播等。
本人才学有限,如有错误,敬请斧正。
参考文档
调研参考了大量的文章,无法一一列出。列出一部分,表示深深的感谢: