HTTP Live Streaming(HLS)是一个由苹果公司提出的基于 HTTP 的流媒体网络传输协议。是苹果公司 QuickTime X 和 iPhone 软件系统的一部分。它的基本原理是在服务端把文件或媒体流分成许多小块的基于 HTTP 的文件或媒体流,客户端在播放码流时,可以根据自身的带宽及性能限制,在同一视频内容的不同码率的备用源中,选择合适码率的码流进行下载播放。在传输会话开始时,客户端首先需要下载描述不同码流元数据的 M3U8 索引文件,用于寻找可用的媒体流。
与基于 UDP 的 实时传输协议(RTP)协议不同,HLS 只请求基本的 HTTP 报文,因此可以穿过任何允许 HTTP 数据通过的防火墙或代理服务器。这也便于使用传统的 HTTP 服务器作为源,并广泛使用基于 HTTP 的内容分发网络来传输媒体流。
HLS 协议格式可简单归纳如下:
网络协议: HTTP
封装格式: TS
编码格式: 视频编码格式 -> H.264 音频编码格式 -> MP3、AAC、AC-3
索引文件: M3U8
需要说明的是,目前已有厂家实现了 H.265 的 HLS 编码。在封装层面,除了 MPEG-2 TS 封装外,在 WWDC2016 上,苹果宣布了HLS对分段 MP4(fMP4)文件字节寻址的支持,为 HLS 向 MPEG-DASH 的兼容提供了可能。
根据媒体流的生成及流向,HLS 的结构可划分为如下几个部分:
那么,M3U8 到底是个什么文件呢?
M3U8 文件其实就是以 UTF-8 编码的 M3U 文件,该文件本身不能播放,只是用于存放待播放视频流的基本信息。下图表示了 M3U8 文件的结构。
HLS 有两级索引,第一级索引存放的是不同码率的 HLS 源的 M3U8 地址,也就是二级索引文件的地址;第二级索引则记录了同一码率下 TS 切片序列的下载地址。客户端获取一级 M3U8 文件后,根据自己的带宽,去下载相应码率的二级索引文件,然后再按二级索引文件的切片顺序下载并播放 TS 文件序列。
一个典型的一级索引文件如下:
#EXTM3U
#EXT-X-STREAM-INF:PROGRAM-ID=1, BANDWIDTH=500000, RESOLUTION=720x480
mid_video_index.M3U8
#EXT-X-STREAM-INF:PROGRAM-ID=1, BANDWIDTH=800000, RESOLUTION=1280x720
wifi_video_index.M3U8
#EXT-X-STREAM-INF:PROGRAM-ID=1, BANDWIDTH=3000000, CODECS="avc1.4d001e,mp4a.40.5", RESOLUTION=1920x1080
h264main_heaac_index.M3U8
#EXT-X-STREAM-INF:PROGRAM-ID=1, BANDWIDTH=64000, CODECS="mp4a.40.5"
aacaudio_index.M3U8
其中,
格式标签,标明该文件是一个 Extended M3U 播放列表文件
特定流标签,指示了该流的格式信息:PROGRAM-ID 节目 ID,一般不用考虑;BANDWIDTH:指定流的带宽;RESOLUTION:视频分辨率;如果存在音频分级,则需指定音频的编码格式 CODECS,如上例中的最后两项。
#EXT-X-STREAM-INF下面紧接的一行,如mid_video_index.m3u8则是对应流的二级索引文件地址,通过下载该二级索引文件,便可得到媒体切片的信息。
客户端可以自己判断自己的现行网络带宽,来决定播放哪一个视频流。也可以在网络带宽变化的时候平滑切换到和带宽匹配的视频流。
二级索引文件格式按照播放模式分类如下:
点播 VOD 的特点就是当前时间点可以获取到所有 ts 文件,二级索引文件中记录了所有 ts 文件的地址。这种模式允许客户端访问全部内容。
#EXTM3U
#EXT-X-TARGETDURATION:10
#EXT-X-VERSION:3
#EXTINF:9.009,
http://media.example.com/first.ts
#EXTINF:9.009,
http://media.example.com/second.ts
#EXTINF:3.003,
http://media.example.com/third.ts
#EXT-X-ENDLIST
仍然是以#EXTM3U开头
#EXT-X-TARGETDURATION: 表示切片的最大时长,单位是秒。#EXT-X-TARGETDURATION:10 表示列表中表示的每个切片时长不超过 10 秒。
#EXT-X-VERSION:表示协议兼容性版本。
#EXTINF:切片的实际时长,若要求取整,则其数值不能大于 EXT-X-TARGETDURATION 的值。
http://media.example.com/first.ts:对应的切片文件(路径),可以是绝对路径,也可以是相对路径。
#EXT-X-ENDLIST:表示整个码流的结束,不再向后附加新的切片列表。
Live 模式就是实时生成 M3U8 和 ts 文件。它的索引文件一直处于动态变化的,播放的时候需要不断下载二级索引文件,以获得最新生成的 ts 文件播放视频。如果一个二级索引文件的末尾没有 #EXT-X-ENDLIST 标志,说明它是一个 Live 视频流。
#EXTM3U
#EXT-X-VERSION:3
#EXT-X-TARGETDURATION:8
#EXT-X-MEDIA-SEQUENCE:2680
#EXTINF:7.975,
https://priv.example.com/fileSequence2680.ts
#EXTINF:7.941,
https://priv.example.com/fileSequence2681.ts
#EXTINF:7.975,
https://priv.example.com/fileSequence2682.ts
#EXT-X-MEDIA-SEQUENCE:媒体序列号,表示出现在当前 M3U8 文件中的第一个 Segment 的序列号。
Live 模式的 M3U8 一般用于直播,列表中的文件数有限制,推荐配置中是 3 个,服务端会实时更新该列表,删除最开始的 Segment,并向后面添加新生成的 Segment。因此,这种模式下,当网络带宽不足时,客户端来不及下载新的 M3U8 和对应的切片文件,会导致切片丢失,播放卡顿。
HLS 存在延迟过大的劣势。采用 HLS 直播的视频流延时一般在 10 秒以上,使用推荐配置时延迟大概在 30s,而 RTMP 直播的延迟最低可达到 3、4 秒,因此,在对实时性要求较高的场合,如互动直播,就要慎用 HLS 了。