HLS协议简介
HLS是什么
HLS (HTTP Live Streaming) 是 Apple 提出的直播流协议,它诞生于2009年,它的工作原理是把一段视频流切分成一个个的小块,一次传输一小部分,并基于 HTTP 的文件来下载。当媒体流正在播放时,客户端可以根据当前网络环境,方便地在不同的码率流中做切换,以实现更好的观影体验。 下图是苹果官方给出的大体流程图: Server部分接受音视频输入并对其进行编码,将该流分割成一系列短的媒体文件,放在服务器上,还会创建并维护一个包含媒体文件列表的索引文件也就是index file。 客户端读取索引文件,然后按顺序请求列出的媒体文件。每个文件都包含流的一个连续片段。一旦下载了足够的数据,客户端就开始播放视频。
HLS如何播放
HLS提供一个m3u8地址,可以很方便地实现播放:
- Safari浏览器直接能打开m3u8地址,譬如: https://sf1-cdn-tos.huoshanstatic.com/obj/media-fe/xgplayer_doc_video/hls/xgplayer-demo.m3u8 https://v2.h5player.bytedance.com/examples/
- 其他不兼容的浏览器里想播放HLS,可以使用开源的hls.js
HLS协议的组成
HLS 由两部分构成:
- .m3u8 文件:以 UTF-8 编码的 m3u 文件,这个文件本身不能播放,只是存放了播放信息的文本文件
- .ts 视频文件:每一个 m3u8 文件,分别对应若干个 ts 文件, ts 文件才是真正存放视频数的文件
m3u8 文件只是存放了一些 ts 文件的配置信息和相关路径,当视频播放时,m3u8 是动态改变的,video 标签会解析这个文件,并找到对应的 ts 文件来播放,所以一般为了加快速度,m3u8 放在 Web 服务器上,ts 文件放在 CDN 上。
这张图片显示了索引文件(master.m3u8)是如何构建的:
M3U8文件格式解析
简单的M3U8文件包含URL列表或带有一些其他元数据的本地文件路径。元数据行以#开头。 #EXTM3U:表示该播放列表是一个扩展的M3U文件,M3U8文件必须以这个标签开始 #EXT-X-PLAYLIST-TYPE:表示该播放列表是点播还是直播(VOD或EVENT) #EXT-X-TARGETDURATION:.ts文件最大的持续持续时间 #EXT-X-VERSION: HLS协议版本 **#EXT-X-ALLOW-CACHE:**是否允许cache #EXT-X-MEDIA-SEQUENCE: 第一个TS分片的序列号,一个URL的序列号要比它前面的URL的序列号高1。 #EXTINF:指定每个媒体段(ts)的持续时间(秒),仅对其后面的URI有效 #EXT-X-ENDLIST:m3u8文件结束标志 西瓜m3u8文件
复杂的m3u8比上面的简版多了一个 playlist或称master文件。 在 master 中,会根据网速实现不同的 m3u8 文件,比如,3G/4G/wifi 网速等。一个 master 文件中可能是如下内容:
live/high.m3u8(wifi环境,高清)文件里的结构可以如下:
MSE:MediaSource Extenstion
媒体源扩展API(通常简称为MSE)是来自 W3C 的一个规范,目前大多数浏览器都实现了这个规范。MSE实现了基于 Web 的流媒体功能。使用 MSE,媒体流能够通过 JavaScript 创建,并且能通过使用 <audio>
和 <video>
元素进行播放。
Video 、 MediaSource、 SourceBuffers 和实际数据之间的关系:
hls.js
hls.js是基于Http Live Stream协议开发,利用Media Source Extension,用于实现HLS在web上播放的一款js播放库。
核心原理:
- hls.js会先通过loader去拉取.m3u8文件,通过文本正则匹配获取子m3u8文件或者ts地址
- 获取到ts地址后,然后再进行二进制读取,将ts格式中的视频流、音频流进行解封装
- 分流后转封装成mp4格式设置到Media Source Extension,最后通过挂载到video标签进行播放