1 概述
HTTP Live Streaming(HLS)是一个由苹果公司提出的基于 HTTP 的流媒体网络传输协议。是苹果公司 QuickTime X 和 iPhone 软件系统的一部分。它的基本原理是在服务端把文件或媒体流分成许多小块的基于 HTTP 的文件或媒体流,客户端在播放码流时,可以根据自身的带宽及性能限制,在同一视频内容的不同码率的备用源中,选择合适码率的码流进行下载播放。在传输会话开始时,客户端首先需要下载描述不同码流元数据的 M3U8 索引文件,用于寻找可用的媒体流。
与基于 UDP 的 实时传输协议(RTP)协议不同,HLS 只请求基本的 HTTP 报文,因此可以穿过任何允许 HTTP 数据通过的防火墙或代理服务器。这也便于使用传统的 HTTP 服务器作为源,并广泛使用基于 HTTP 的内容分发网络来传输媒体流。
2 HLS 协议简介
HLS 协议格式可简单归纳如下:
网络协议: HTTP
封装格式: TS
编码格式: 视频编码格式 -> H.264 音频编码格式 -> MP3、AAC、AC-3
索引文件: M3U8
需要说明的是,目前已有厂家实现了 H.265 的 HLS 编码。在封装层面,除了 MPEG-2 TS 封装外,在 WWDC2016 上,苹果宣布了HLS对分段 MP4(fMP4)文件字节寻址的支持,为 HLS 向 MPEG-DASH 的兼容提供了可能。
根据媒体流的生成及流向,HLS 的结构可划分为如下几个部分:
- Audio/Video inputs 源可以是任意格式,可以是离线文件或实时码流。
- Server 接收到视频源后,Media encoder 将源视频转码成 HLS 支持的编码格式和封装格式,根据需求可输出多个码率分别送至 Stream segmenter。
- 在 segmenter 中被切分成指定大小或时间长度的 TS 切片,并生成索引文件 M3U8。
- Distribution 是一个 HTTP 文件服务器,负责将流媒体文件推送出去或响应客户端的请求。
- 客户端只要访问一级 M3U8 文件路径就能自动播放 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
其中,
#EXTM3U
格式标签,标明该文件是一个 Extended M3U 播放列表文件
#EXT-X-STREAM-INF
特定流标签,指示了该流的格式信息:PROGRAM-ID 节目 ID,一般不用考虑;BANDWIDTH:指定流的带宽;RESOLUTION:视频分辨率;如果存在音频分级,则需指定音频的编码格式 CODECS,如上例中的最后两项。
#EXT-X-STREAM-INF下面紧接的一行,如mid_video_index.m3u8则是对应流的二级索引文件地址,通过下载该二级索引文件,便可得到媒体切片的信息。
客户端可以自己判断自己的现行网络带宽,来决定播放哪一个视频流。也可以在网络带宽变化的时候平滑切换到和带宽匹配的视频流。
二级索引文件格式按照播放模式分类如下:
(1) VOD 模式
点播 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:表示整个码流的结束,不再向后附加新的切片列表。
(2) Live 模式
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 和对应的切片文件,会导致切片丢失,播放卡顿。
2.1. HLS 优势
- HLS 协议本身实现了码率自适应,不同带宽的设备可以自动切换到最适合自己码率的视频播放。
- 解决 RTMP 协议存在的一些问题。比如 RTMP 协议不使用标准的 HTTP 接口传输数据,所以在一些特殊的网络环境下可能被防火墙屏蔽掉。但是 HLS 由于使用的 HTTP 协议传输数据,不会遇到被防火墙屏蔽的情况。
- RTMP 是一种有状态协议,很难对视频服务器进行平滑扩展,因为需要为每一个播放视频流的客户端维护状态。而 HLS 基于无状态协议(HTTP),客户端只是按照顺序使用下载存储在服务器的普通 TS 文件,做负责均衡如同普通的 HTTP 文件服务器的负载均衡一样简单。
2.2. HLS 劣势
HLS 存在延迟过大的劣势。采用 HLS 直播的视频流延时一般在 10 秒以上,使用推荐配置时延迟大概在 30s,而 RTMP 直播的延迟最低可达到 3、4 秒,因此,在对实时性要求较高的场合,如互动直播,就要慎用 HLS 了。