HTTP Live Streaming (HLS)
HTTP Live Streaming 简称为 HLS, 是一个基于 HTTP 的视频流协议,由 APPLE 公司提出和实现。苹果公司的很多产品都支持 HLS 协议,譬如 Mac OS 上的 QuickTime、Safari 以及 iOS 上的 Safari。苹果 2009 年提出该协议,HLS 是 iOS 设备默认要求的视频流标准。安卓也支持HLS,见文章Guide to Mobile Video Streaming with HLS | Mux blog
Since then, Android has added support, as have most other platforms.
HLS 因为以下几个原因比较受欢迎。
HLS 几乎可随处播放。 几个大平台 web、mobile、tv 基本都有免费的HLS 播放器支持。
苹果 要求 HLS。 如果你想在 iOS 设备直播,逃不了的。
HLS 相对简单。 它使用了普遍且已经存储的视频格式(MP4 或 TS,伴随着 H.264 和 AAC 等编解码器), 另外附加了一个丑陋但人类可读的文本格式(m3u8).
它通过 HTTP 工作。 不需要跑特殊的服务(不像老旧校风派的 RTMP 协议或者新潮的 WebRTC 协议). HLS 可以方便的透过防火墙或者代理服务器,而且可以很方便的利用 CDN 进行分发加速,并且客户端实现起来也很方便。
原理
HLS 协议基于 HTTP,而一个提供 HLS 的服务器需要做两件事:
编码: 以 H.264 格式对图像进行编码,以 MP3 或者 HE-AAC 对声音进行编码,最终打包到 MPEG-2 TS(Transport Stream)容器之中;
分割: 把编码好的 TS 文件等长切分成后缀为 ts 的小文件,并生成一个 .m3u8 的纯文本索引文件
HLS 把整个流分成一个个小的基于 HTTP 的文件来下载,每次只下载一些。HLS 协议由三部分组成:HTTP、M3U8、TS。这三部分中,HTTP 是传输协议,M3U8 是索引文件,TS 是音视频的媒体信息。
浏览器使用的是 m3u8 文件。在 HTML5 页面上使用 HLS 非常简单,直接
<video src="example.m3u8" controls></video>
或者
- <video controls>
- <source src="example.m3u8"></source>
- </video>
HLS的index文件就是m3u8的文件,先下载一级index file(master_playlist.m3u8),它里面记录了二级索引文件的地址(Alternate-A、Alternate-B、Alternate-C)的地址,然后客户端再去下载二级索引文件,二级索引文件中又记录了TS文件的下载地址,这样客户端就可以按顺序下载TS视频文件并连续播放。
一个典型的一级索引 m3u8 文件格式如下:
- #EXTM3U
-
- #EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=2000000,CODECS="mp4a.40.2, avc1.4d401f"
- skiing-720p.m3u8
-
- #EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=375000,CODECS="mp4a.40.2, avc1.4d4015"
- skiing-360p.m3u8
-
- #EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=750000,CODECS="mp4a.40.2, avc1.4d401e"
- skiing-480p.m3u8
-
- #EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=3500000,CODECS="mp4a.40.2, avc1.4d401e"
- skiing-1080p.m3u8
【免费分享,私】
资料包括《Andoird音视频开发必备手册+音视频学习视频+学习文档资料包+大厂面试真题+2022最新学习路线图》等
详细介绍如下:
bandwidth指定视频流的比特率
PROGRAM-ID无用无需关注,
每一个#EXT-X-STREAM-INF的下一行是二级index文件的路径,可以用相对路径也可以用绝对路径。例子中用的是相对路径。
一级索引 m3u8 文件中记录了不同比特率视频流的二级index文件路径,客户端可以自己判断自己的现行网络带宽,来决定播放哪一个视频流。也可以在网络带宽变化的时候平滑切换到和带宽匹配的视频流。
一个二级索引文件格式内容如下 (skiing-480p.m3u8):
- #EXTM3U
- #EXT-X-TARGETDURATION:10
- #EXT-X-VERSION:3
- #EXT-X-MEDIA-SEQUENCE:0
- #EXT-X-PLAYLIST-TYPE:VOD
- #EXTINF:9.97667,
- file000.ts
- #EXTINF:9.97667,
- file001.ts
- #EXTINF:9.97667,
- file002.ts
- #EXTINF:9.97667,
- file003.ts
- #EXTINF:9.97667,
- file004.ts
可以简单的认为二级 m3u8 就是包含多个 ts 文件的播放列表。播放器按顺序逐个播放,全部放完再请求一下 m3u8 文件,获得包含最新 ts 文件的播放列表继续播,周而复始。整个直播过程就是依靠一个不断更新的 m3u8 和一堆小的 ts 文件组成,m3u8 必须动态更新,ts 可以走 CDN。
整体架构
HLS的架构分为三部分:Server,CDN,Client 。即服务器、分发组件和客户端。架构图如下:
HLS 不是万能的,它也有一个致命的弱点:延迟现象非常明显。如果每个 ts 按照 5 秒来切分,一个 m3u8 放 6 个 ts 索引,那么至少就会带来 30 秒的延迟。如果减少每个 ts 的长度,减少 m3u8 中的索引数,延时确实会减少,但会带来更频繁的缓冲,对服务端的请求压力也会成倍增加。所以只能根据实际情况找到一个折中的点。
另外一点, HLS 基于短连接 HTTP,HTTP 是基于 TCP 的,这就意味着 HLS 需要不断地与服务器建立连接,TCP 每次建立连接时的三次握手、慢启动过程、断开连接时的四次挥手都会产生消耗。
Real Time Messaging Protocol(简称 RTMP)是 Macromedia 开发的一套视频直播协议,现在属于 Adobe。
协议基于 TCP,是一个协议族,包括 RTMP 基本协议及 RTMPT/RTMPS/RTMPE 等多种变种。RTMP 是一种设计用来进行实时数据通信的网络协议,主要用来在 Flash/AIR 平台和支持RTMP协议的流媒体/交互服务器之间进行音视频和数据通信。
无法支持移动端 WEB 播放是它的硬伤。虽然无法在iOS的H5页面播放,但是iOS原生应用可以写解码去解析的。浏览器端,HTML5 video标签无法播放 RTMP 协议的视频,可以通过 video.js 来实现。
其主要优点:
实时性非常好,延时较小,通常为 1-3s
基于 TCP 长连接,不需要多次建连。
如上所见,两个协议各有所长,所以实际项目中需要自己抉择到底采用哪种方案。直播整体架构如下。