1 HLS的简介
1.1 HLS的背景
从 RTMP(Real-Time Messaging Protocol,实时消息传输协议) 到 HLS(HTTP Live Streaming,HTTP直播流) 的技术演进,本质上是直播协议从 专有协议 向 通用 Web 协议 的转变,也是适应互联网环境(如浏览器支持、移动端普及)的必然结果。
1. RTMP的核心问题
- 依赖Flash Player:RTMP是Adobe开发的专有协议,长期依赖Flash插件实现浏览器播放。但Flash存在安全漏洞多、移动端支持差(如早期iOS不支持)等问题,逐渐被淘汰。
- 防火墙与跨平台限制:RTMP通常使用非标准端口(如1935),容易被防火墙拦截;且无法直接在HTML5中播放,需插件支持。
- 实时性与灵活性的矛盾:RTMP虽实时性强(延迟约1-3秒),但封装格式(FLV)和传输方式难以适应动态网络环境(如弱网、带宽波动)。
2. HLS的设计目标
- 基于HTTP协议:利用HTTP的广泛兼容性(浏览器原生支持)和防火墙友好性,无需额外插件即可播放。
- 分段传输(Chunked Transfer):将直播流分割为小尺寸的媒体片段(如TS/MP4文件),支持动态调整码率,适应不同网络条件。
- 无状态协议:HTTP的无状态特性使服务器架构更简单,易于扩展(如CDN分发),降低直播成本。
HLS的核心问题
HLS 的延迟问题确实是其最被诟病的缺点之一,实际应用中延迟通常在 5-30 秒 之间(不同场景差异较大),极端情况下可能更高。这一现象是由其 设计机制 和 网络传输特性 共同决定的 后面解释
1.2 HLS的工作原理
- 音视频采集
摄像机等设备获取原始的音频和视频信号 ,这些信号是未经处理的模拟或数字信号。比如摄像机捕捉现场画面,麦克风收录现场声音。 - 媒体编码
- 位置与作用:采集到的音视频输入到服务器中的媒体编码器(Media encoder )。媒体编码器会按照特定的编码标准,如视频常用的 H.264、H.265,音频常用的 AAC 等 ,对原始音视频数据进行压缩编码。这一步是为了减小数据量,便于后续的传输和存储 。
- 编码原理:以 H.264 为例,它利用帧间预测、变换编码等技术,去除视频中的冗余信息 。比如对于连续的相似帧,只记录关键帧和帧间差异,大幅降低数据量。
- 流分段
- 处理过程:编码后的音视频数据形成 MPEG - 2 传输流,进入流分段器(Stream segmenter )。流分段器将连续的媒体流切割成一个个小的片段,通常这些片段是.ts(MPEG - 2 传输流格式)格式 ,每个片段时长一般为几秒到十几秒 。例如设置每个片段时长为 5 秒,流分段器就会按时间间隔把流切割成相应的小段。
- 目的:分段是 HLS 的关键特性,便于客户端按顺序下载播放,也利于实现码率自适应等功能 。
- 分发准备
- 索引文件生成:源 Web 服务器(Origin web server )会生成一个索引文件(Index file ,通常是.m3u8 格式 )。索引文件记录了各个媒体片段的信息,包括片段的 URL 地址、时长等 。比如索引文件会明确指出第一个.ts 片段的地址在哪,第二个片段地址在哪等。
- 文件存储:服务器将生成的媒体片段(.ts 文件 )和索引文件存储好,等待客户端请求 。
- 网络传输
最终通过 HTTP 协议,服务器将索引文件和媒体片段传输给客户端 。客户端通过解析索引文件,按顺序下载媒体片段进行播放 。
2 HLS 基本框架
服务器
- 复用与封装
编码后的音视频基本流,会被复用并封装成符合 MPEG - 2 系统层标准的传输流(TS)格式。MPEG - 2 TS 格式能将音视频媒体流严格按时序交织复用 。这样,任意截取和分段后的每个小段,都可独立解码和播放**。每个 TS 文件开头需包含节目关联表(PAT)和节目映射表(PMT) ;含视频的文件,还得有至少一个关键帧及序列头等信息,用于解码器初始化**。 - 流分割处理
流分割器(Stream Segmenter)会将编码器输出的 MPEG - 2 TS 流,分割成一系列连续且长度均等的小 TS 文件(后缀为.ts )。同时,流分割器会创建一个索引文件(采用扩展的 M3U 播放列表格式,后缀名.m3u8 ) ,该文件包含指向小 TS 文件的指针。索引文件类似播放列表滑动窗口,每当生成新 TS 文件,其内容就会更新 ,新文件 URI 添加到末尾,旧的被移除,始终保持固定数量的最新分段信息。此外,流分割器还可对小 TS 文件加密,并生成密钥文件。
之所以采用 MPEG - 2 TS 格式统一封装编码后的媒体流,**是因其具备让各分段独立解码播放的特性。M3U8 索引文件是由若干文本行组成的文本文件 ,每行可能是 URI、**空行或以注释符 “#” 起始的行 。其中,URI 指向分段媒体文件或衍生索引文件;以 “#EXT” 起始的行是标签行,其他 “#” 起始行是可忽略的注释。以下是一个简单.m3u8 索引文件示例,其表示的媒体流由 5 个时长 5秒的未加密 TS 文件构成。
#EXTM3U
#EXT-X-VERSION:3
#EXT-X-MEDIA-SEQUENCE:54
#EXT-X-TARGETDURATION:6
#EXTINF:5.000, no desc
livestream-54.ts
#EXTINF:5.000, no desc
livestream-55.ts
#EXTINF:5.002, no desc
livestream-56.ts
#EXTINF:5.018, no desc
livestream-57.ts
#EXTINF:5.982, no desc
livestream-58.ts
内容分发
HLS 内容分发系统通过 HTTP 协议传输分割后的媒体文件(.ts)和索引文件(.m3u8),可直接使用普通 Web 服务器或 CDN,无需特殊配置,仅需关联 MIME 类型:
.m3u8 → application/vnd.apple.mpegurl
.ts → video/MP2T
关键优化:
.m3u8 文件:设短缓存时间(如 5-10 秒),避免客户端获取旧索引,确保实时性。
.ts 文件:设长缓存时间(如 24 小时),减少重复下载,提升效率。
通过 CDN 加速和合理缓存策略,可高效分发内容,平衡实时性与带宽成本。
客户端
- 获取索引文件(.m3u8)
客户端通过网页 URL 请求服务器获取 HLS 索引文件,文件中包含:
当前可用的 TS 媒体片段 URL 列表
解密密钥地址(若加密)
多码率替换流索引(可选) - 下载与缓冲媒体片段
按索引顺序下载 TS 文件,至少缓冲 1-2 个片段 后开始播放(推荐 2 个以保证无缝衔接)。(这无疑是延时的重要原因)
直播场景中,客户端周期性刷新索引文件,获取最新片段 URL 并添加到下载队列。
点播场景中,遇 #EXT-X-ENDLIST 标签则结束播放。 - 解码与播放
拼装 TS 片段为完整流,送播放器解码。
加密流需通过索引获取密钥,完成用户认证和解密。
⽹络⾃适应的流间切换和故障保护
- 多码率流的预先生成
服务器端对同一音视频源进行不同码率的编码(如 240P/360P/720P/1080P 等),生成多套 TS 媒体片段(每个码率对应独立的 TS 片段序列)。
为每套码率流生成独立的索引文件(.m3u8),记录该码率下 TS 片段的 URL、时长等信息。
** 主索引文件(Master Playlist)** 中包含所有码率流的索引文件地址,格式如下:
plaintext
#EXTM3U
#EXT-X-STREAM-INF:BANDWIDTH=500000,RESOLUTION=854x480 # 低码率流
http://example.com/low.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=2000000,RESOLUTION=1280x720 # 高码率流
http://example.com/high.m3u8
- 客户端动态切换逻辑
实时监测网络带宽:通过下载速度、缓冲状态、RTT(往返时间)等指标估算当前可用带宽。
比较带宽与码率阈值:若当前带宽低于某码率的最低要求(如 720P 需至少 2Mbps),则切换至更低码率;若带宽充足,则切换至更高码率以提升画质。
平滑过渡机制:切换时等待当前片段播放完毕,再从新码率的下一个片段开始加载,避免画面中断。
HLS(HTTP Live Streaming)被称为 “以点播形式实现直播”,核心在于其技术实现逻辑完全基于HTTP 协议的文件分块下载机制,而非传统直播协议的实时数据流传输
- 传统直播与HLS的本质区别
对比维度 | 传统直播协议(如RTMP/RTSP) | HLS |
---|---|---|
数据传输形式 | 基于TCP/UDP的实时数据流,服务器持续推送数据。 | 基于HTTP的文件分块下载,数据封装为独立TS文件。 |
客户端获取方式 | 直接接收连续数据流,边收边解。 | 主动下载分段文件(TS片段),拼装后播放。 |
服务器角色 | 实时生成数据流并推送。 | 提前生成或实时切割TS文件,供客户端拉取。 |
- 为什么说HLS的“直播是点播的变种”?
- 无实时数据流,只有文件序列
- 传统直播协议中,服务器与客户端建立长连接,数据流如“水管放水”般连续传输。
- HLS中,服务器仅提供文件列表和文件资源,客户端通过“下载文件序列”模拟直播,本质是点播技术的时序化应用。
- 延迟来源于文件分块和缓冲
- 直播延迟的核心原因:
- 文件分块时长:每个TS文件至少5秒,服务器生成新文件需要时间。
- 缓冲机制:客户端需下载并缓冲多个片段(如2个10秒片段)才能开始播放。
- 对比传统直播:RTMP协议延迟可低至1-3秒,而HLS典型延迟为20-30秒(因需等待文件生成和下载)。
3 m3u8协议
示例1:单码率媒体流索引
#EXTM3U # M3U8文件标识(必填)
#EXT-X-VERSION:3 # 协议版本号(如3)
#EXT-X-ALLOW-CACHE:YES # 允许缓存(YES/NO)
#EXT-X-MEDIA-SEQUENCE:2 # 起始媒体段序列号(从2开始)
#EXT-X-TARGETDURATION:16 # 单个TS片段最大时长(秒),需≥所有#EXTINF值
#EXTINF:14.357, no desc # 片段时长(秒)+描述(可选)
livestream-2.ts # 媒体段URI(对应TS文件)
#EXTINF:15.617, no desc
livestream-3.ts
#EXTINF:14.358, no desc
livestream-4.ts
- 特点:直接列出TS文件URI,用于单一码率的直播或点播流。
示例2:多码率适配流索引(主索引文件)
#EXTM3U
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=1280000 # 子流带宽(必填)
http://example.com/low.m3u8 # 低码率子索引URI
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=2560000
http://example.com/mid.m3u8 # 中码率子索引URI
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=7680000,RESOLUTION=1080x720
http://example.com/hi.m3u8 # 高码率子索引URI(含分辨率)
- 特点:通过
#EXT-X-STREAM-INF
标签嵌套子M3U8文件,每个子索引对应不同码率流,客户端根据带宽动态选择。
** M3U8核心标签解析**
M3U8是纯文本文件,由标签(Tag)、URI和注释组成,以#
开头的行为标签或注释,其余为URI或空行。以下是关键标签:
标签 | 说明 | 必填性 | 示例 |
---|---|---|---|
#EXTM3U | 文件头,标识为M3U8格式(必填) | 是 | 第一行固定为此标签 |
#EXT-X-VERSION | 协议版本号(如3/4),影响标签兼容性(如#EXT-X-BYTERANGE需版本≥4) | 否 | #EXT-X-VERSION:3 |
#EXTINF | 定义后续URI对应的TS片段时长(秒)和描述(可选) | 是(单码率) | #EXTINF:10.0, Live segment 1 |
#EXT-X-TARGETDURATION | 最大片段时长(秒),需≥所有#EXTINF值,全局唯一 | 是(单码率) | #EXT-X-TARGETDURATION:10 |
#EXT-X-MEDIA-SEQUENCE | 媒体段序列号,后续片段依次递增(默认从0开始) | 否 | #EXT-X-MEDIA-SEQUENCE:1 |
#EXT-X-KEY | 加密配置(NONE/AES-128),指定密钥URI和初始化向量(IV) | 否 | #EXT-X-KEY:METHOD=AES-128,URI=“key.bin”,IV=0x1234… |
#EXT-X-STREAM-INF | 多码率场景下,定义子索引文件的带宽、分辨率等属性(嵌套子M3U8时必填) | 是(多码率) | #EXT-X-STREAM-INF:BANDWIDTH=2000000,RESOLUTION=1080x720 |
#EXT-X-ENDLIST | 标识点播流结束(直播流无此标签) | 否(点播) | #EXT-X-ENDLIST |
** 关键机制说明**
-
单码率与多码率切换
- 单码率:客户端直接下载TS片段,适用于固定网络环境。
- 多码率:
- 主索引文件列出各码率子索引(含带宽、分辨率等信息)。
- 客户端根据实时带宽选择子索引,如带宽不足2Mbps时自动切换至
low.m3u8
。
-
缓存与更新策略
#EXT-X-ALLOW-CACHE:NO
:禁止缓存M3U8文件,确保客户端每次获取最新索引(适用于直播)。- 浏览器对M3U8的缓存由HTTP头(如
Cache-Control
)控制,建议设置短缓存时间(如5秒)。
-
加密与解密
- 通过
#EXT-X-KEY
标签启用AES-128加密:METHOD=NONE
:不加密(默认)。METHOD=AES-128
:需指定密钥文件URI(如http://example.com/key.bin
),IV可选(缺省则用序列号生成)。
- 通过
** 直播与点播场景差异**
场景 | 关键特征 | 标签差异 |
---|---|---|
直播 | 索引文件动态更新,持续追加新TS片段URI,无结束标签 | 无#EXT-X-ENDLIST ,需定期刷新索引 |
点播 | 索引文件固定,包含完整TS列表,末尾需#EXT-X-ENDLIST 标识结束 | 包含#EXT-X-ENDLIST ,无需刷新索引 |
2.5 嵌套层级限制
- M3U8仅支持一层嵌套:主索引文件(多码率)嵌套子索引文件(单码率),子索引文件直接指向TS片段。
- 禁止多层嵌套(如主索引→子索引→孙索引),避免解析复杂度过高。
总结
M3U8文件通过标准化标签体系实现了对TS片段的有序管理,其核心价值在于:
- 单码率场景:提供简单、可靠的片段索引。
- 多码率场景:结合客户端带宽自适应,保障不同网络下的播放体验。
- 扩展性:通过标签支持加密、时间同步、多语言轨道等高级功能。
4 ts协议解析
4.1 基本框架
TS(Transport Stream,传输流)文件的分层结构设计精巧,由下至上可分为三层,这种分层模式使得音视频数据在传输过程中更高效、稳定,各层各司其职,协同保障数据准确无误地流转与处理。
- ES 层(Elementary Stream,基本码流层):这是最底层,处于音视频数据的初始状态,即经过压缩编码后的原始音视频数据。视频编码多采用 H.264、H.265 等格式,音频编码常用 AAC、MP3 等格式。在这一层,数据以连续码流形式存在,一个 ES 流仅包含单一类型数据,如纯视频、纯音频或纯字幕。例如,一个 H.264 编码的视频 ES 流,其中全是按照 H.264 标准编码的视频数据,不掺杂音频等其他类型信息 。其作用是提供最原始的音视频内容素材,是整个 TS 文件数据的基石,后续各层都是基于此进行加工和处理。
- PES 层(Packet Elemental Stream,分组基本码流层):在 ES 层基础上构建,主要工作是在 ES 数据中加入时间戳(PTS/DTS)等关键信息。由于 ES 数据包通常较大,为便于传输与处理,会将 ES 流分割成长度不等的数据包,并为每个数据包添加 PES 包头。其中,PTS(Presentation Time Stamp,显示时间戳)用于指示视频帧或音频样本应在何时显示或播放;DTS(Decoding Time Stamp,解码时间戳)指明数据应在何时进行解码。对于视频数据,I 帧和 P 帧一般同时具备 PTS 和 DTS,而 B 帧只需 PTS(因为其解码顺序与显示顺序不同,I、P 帧的 PTS 等于 DTS,若视频无 B 帧,PTS 与 DTS 始终相同) 。PES 层通过这些时间戳信息,确保音视频数据在解码和播放过程中的时间顺序准确无误,实现音视频的同步播放。例如,在一段包含多个 I、P、B 帧的视频 PES 流中,每个帧对应的 PES 包会携带准确的 PTS 和 DTS,播放器依据这些时间戳来决定何时解码、何时显示每一帧画面。
- TS 层(Transport Stream,传输流层):位于最上层,在 PES 层之上进一步添加了数据流识别信息与传输信息。TS 包大小固定为 188 字节(扩展后为 204 字节,含 16 字节 CRC 校验),由三部分组成:
- TS Header(TS 包头):固定为 4 字节,是每个 TS 包的起始标识,包含诸多关键控制信息。如同步字节(固定值 0x47,用于快速识别 TS 包起始位置)、传输错误指示(1 位,用于标记该包在传输过程中是否出现错误)、负载单元起始指示(1 位,指示包净荷是否为新的存取单元起始,如视频帧起始)、PID(Packet Identifier,包标识符,13 位,是区分不同数据流的关键,0x0000 代表 PAT 表,0x0001 代表条件访问表等)、连续计数器(4 位,每发送一个相同 PID 的 TS 包,计数器递增 1,从 0 到 15 循环,用于检测包丢失)等。
- Adaptation Field(自适应字段):并非每个 TS 包都有,其存在的主要目的是为不足 188 字节的数据进行填充,以及插入节目时钟参考(PCR,Program Clock Reference)等重要信息。PCR 对于恢复与编码端一致的时钟顺序至关重要,通常每隔 100ms 至少传输一次,它作为解码器解码时的时钟参考基准,调整本地时钟以与编码端同步。一般在视频帧的首个和最后一个 TS 包中添加自适应字段,中间的 TS 包若无需求则可不加。
- Payload(有效载荷):承载的数据类型多样,可能是 PES 数据(即音视频数据经 PES 层封装后的结果),也可能是节目专用信息 PSI(如 PAT、PMT 表)。PAT(Program Association Table,节目关联表)用于列出所有节目及对应的 PMT 表 PID;PMT(Program Map Table,节目映射表)针对每个节目,详细定义其包含的音视频流的 PID、编码格式、分辨率等关键参数,是解析 TS 流、分离出音视频流的重要依据。
4.2 重点内容解析
TS 流解析的核心逻辑与 PID 体系
TS 流通过 PID(Packet Identifier) 实现不同类型数据的区分与复用,核心数据类型包括:
- PAT 表(Program Association Table,PID=0x0000):全局索引表,指向各节目的 PMT 表位置。
- PMT 表(Program Map Table):节目映射表,定义特定节目包含的音视频流 PID 及编码参数。
- 音频流 / 视频流:承载实际音视频数据的媒体流。
解析流程:
定位 PAT 表:通过固定 PID(0x0000)获取 PAT 表。
解析 PMT 位置:从 PAT 中提取目标节目的 PMT 表 PID。
获取音视频流:通过 PMT 表找到对应音频流和视频流的 PID。
数据解复用:根据音视频 PID 过滤 TS 包,提取媒体数据
在 TS(Transport Stream)协议和相关流媒体场景中,“节目(Program)” 是一个逻辑概念,用于对音视频内容及相关数据进行分组管理。它可以理解为一个完整的多媒体内容集合,包含了一组相互关联的音视频流、字幕流等,共同构成可供观众观看或收听的完整内容单元
PID 是什么?
就像快递分拣站的 “包裹标签”。
作用:TS 流里有很多种数据(比如视频、音频、节目表等),每个数据都要贴一个 “标签”(PID),这样接收端才能知道 “这个包裹里装的是什么”。
比如:
贴了 “标签 0” 的包裹:里面装的是 “节目总目录”(PAT 表),告诉用户有哪些频道 / 节目。
贴了 “标签 100” 的包裹:里面装的是 “某个频道的视频数据”。
贴了 “标签 200” 的包裹:里面装的是 “这个频道的音频数据”。
特点:
全局唯一:整个 TS 流里,每个标签(PID)只能对应一种数据,不能重复。
必须有:就像快递必须有标签才能分拣,TS 流里的节目表(PAT/PMT)必须用固定标签(如 PID=0)传输,否则接收端看不懂。
自适应区(Adaptation Field)的长度与结构
- 长度要求:
自适应区的总长度需包含 传输错误指示符(1 字节)。若实际数据不足,剩余字节用 0xFF 填充(类似补白)。 - 作用场景:
视频 / 音频流:必须添加自适应区,通常位于帧的首个 TS 包和最后一个 TS 包,用于插入 PCR 时钟或填充数据。
PAT/PMT 表:无需自适应区,直接用 0xFF 补足长度即可。
PCR、DTS、PTS 的关系与作用
-PCR(节目时钟参考)
本质:
对系统时钟的采样值,用于解码器同步本地时钟(类似 “时间基准”)。
特点:
单调递增(不能回退),通常每 100ms 插入一次。
仅视频流需要,音频流通过 PTS 与视频同步,无需 PCR。
-用途:可直接作为 DTS(解码时间戳) 使用,简化时间戳管理。