Web开发者们一直以来想在Web中使用音频和视频,但早些时候,传统的Web技术不能够在Web中嵌入音频和视频,所以一些像Flash、Silverlight的专利技术在处理这些内容上变得很受欢迎。这些技术能够正常的工作,缺有这一系列问题,包括无法很好的支持HTML/CSS特性、安全问题,以及可行性问题
幸运的是,当HTML5标准公布后,其中包含许多的新特性,包括<video>和<audio>标签,以及一些JavaScript APIS用于对其进行控制。随着通信技术和网络技术的不断发展,目前音视频已经成为大家生活中不可或缺的一部分。此外,伴随着 5G 技术的慢慢普及,实时音视频领域还会有更大的想象空间。
接下来本文将从八个方面入手,全方位带你一起探索前端 Video 播放器和主流的流媒体技术。阅读完本文后,你将了解以下内容:
- 为什么一些网页中的Video元素,其视频源地址是采用Blob URL的形式。
- 什么是HTTP Range请求及流媒体技术相关概念;
- 了解HLS、DASH的概念、自适应比特率流技术及流媒体加密技术
- 了解FLV文件结构、flv.js的功能特性与使用限制及内部的工作原理
- 了解MSE(Media Source Extensions)API及相关的使用
- 了解视频播放器的原理、多每次封装格式以及MP4与Fragmented MP4封装格式的区别
# 一、传统的播放模式
大多数 Web 开发者对 ≶video>都不会陌生,在以下 HTML 片段中,我们声明了一个 ≶video>元素并设置相关的属性,然后通过 ≶source>标签设置视频源和视频格式:
<video id="mse" autoplay=true playsinline controls="controls">
<source src="https://h5player.bytedance.com/video/mp4/xgplayer-demo-720p.mp4" type="video/mp4">
你的浏览器不支持Video标签
</video>
上述代码在浏览器渲染之后,在页面中会显示一个 Video 视频播放器,具体如下图所示:

通过 Chrome 开发者工具,我们可以知道当播放 xgplayer-demo-720p.mp4 视频文件时,发了 3 个 HTTP 请求:

此外,从图中可以清楚看到,头两个HTTP请求响应的状态码是206.这里我们来分析第一个 HTTP 请求的请求头和响应头:

在上面的请求头中,有一个range:bytes=0-首部信息,该信息用于检测服务器是否支持Range请求。如果在响应中存在Accept-Ranges首部(并且它的值不为none),那么表示该服务器支持范围请求
在上面的响应头中,Accept-Ranges:bytes 表示界定范围的单位是butes.这里Content-Length也是有效信息,因为它提供了要下载的视频的完整大小
# 1.1从无服务器端请求特定的范围
假如服务器支持范围请求的话,你可以使用 Range 首部来生成该类请求。该首部指示服务器应该返回文件的哪一或哪几部分。
单一范围
我们可以请求资源的某一部分。这里我们使用 Visual Studio Code (opens new window) 中的 REST Client (opens new window) 扩展来进行测试,在这个例子中,我们使用 Range 首部来请求 www.example.com 首页的前 1024 个字节。

对于使用 REST Client 发起的 单一范围请求,服务器端会返回状态码为 206 Partial Content 的响应。而响应头中的 Content-Length 首部现在用来表示先前请求范围的大小(而不是整个文件的大小)。Content-Range 响应首部则表示这一部分内容在整个资源中所处的位置。
多重范围
Range 头部也支持一次请求文档的多个部分。请求范围用一个逗号分隔开。比如:
$ curl http://www.example.com -i -H "Range: bytes=0-50, 100-150"对于该请求会返回以下响应信息:
因为我们是请求文档的多个部分,所以每个部分都会拥有独立的 Content-Type 和 Content-Range 信息,并且使用 boundary 参数对响应体进行划分。条件式范围请求
当重新开始请求更多资源片段的时候,必须确保自从上一个片段被接收之后该资源没有进行过修改。
If-Range 请求首部可以用来生成条件式范围请求:假如条件满足的话,条件请求就会生效,服务器会返回状态码为 206 Partial 的响应,以及相应的消息主体。假如条件未能得到满足,那么就会返回状态码为 200 OK 的响应,同时返回整个资源。该首部可以与 Last-Modified 验证器或者 ETag 一起使用,但是二者不能同时使用。
范围请求的响应
与范围请求相关的有三种状态:
在请求成功的情况下,服务器会返回 206 Partial Content 状态码。
在请求的范围越界的情况下(范围值超过了资源的大小),服务器会返回 416 Requested Range Not Satisfiable (请求的范围无法满足) 状态码。
在不支持范围请求的情况下,服务器会返回 200 OK 状态码。
剩余的两个请求,阿宝哥就不再详细分析了。感兴趣的小伙伴,可以使用 Chrome 开发者工具查看一下具体的请求报文。通过第 3 个请求,我们可以知道整个视频的大小大约为 7.9 MB。若播放的视频文件太大或出现网络不稳定,则会导致播放时,需要等待较长的时间,这严重降低了用户体验。
那么如何解决这个问题呢?要解决该问题我们可以使用流媒体技术,接下来我们来介绍流媒体。
# 流媒体
流媒体是将一连串的每次数据压缩后,经过网上分段发送数据,在网上及时传输影音以供观赏的一种技术与过程,此技术是的数据包以像流水一样发送;如果不适用次技术,就必须在使用前下载整个媒体文件