HLS 文档
理解 m3u8 与 HLS 的技术基础
1. HLS 是什么
HLS(HTTP Live Streaming)是苹果公司提出的基于 HTTP 的自适应码率流媒体传输协议。它的核心思路很朴素:把一整段视频切成许多小分片,用一个文本播放列表描述这些分片的顺序与位置,播放器依次下载并连续播放。
因为跑在标准 HTTP 之上,HLS 不需要专用流媒体服务器,能直接利用现有的 CDN 与缓存体系,这也是它被广泛采用的主要原因。
2. m3u8 文件长什么样
m3u8 就是那个「播放列表」,本质是 UTF-8 编码的纯文本文件,用文本编辑器就能打开。一个最简单的点播列表示例:
#EXTM3U #EXT-X-VERSION:3 #EXT-X-TARGETDURATION:10 #EXT-X-MEDIA-SEQUENCE:0 #EXTINF:9.009, seg_000.ts #EXTINF:9.009, seg_001.ts #EXTINF:9.009, seg_002.ts #EXT-X-ENDLIST
每一行 #EXT-X- / #EXT 开头的是标签(指令),其余行是分片地址。
3. 两类播放列表:Master 与 Media
| 类型 | 作用 | 是否含分片地址 |
|---|---|---|
| Master Playlist (主播放列表) |
本身不含分片,而是列出多个不同码率/分辨率的子列表地址,供播放器按网速选择。 | 否 |
| Media Playlist (媒体播放列表) |
真正列出一串分片(.ts 或 .m4s)及其时长。 | 是 |
判断方法:打开 m3u8,如果里面有 EXT-X-STREAM-INF,它就是 Master Playlist。
一个多码率主列表示例:
#EXTM3U #EXT-X-STREAM-INF:BANDWIDTH=1280000,RESOLUTION=720x480 low/index.m3u8 #EXT-X-STREAM-INF:BANDWIDTH=2560000,RESOLUTION=1280x720 mid/index.m3u8 #EXT-X-STREAM-INF:BANDWIDTH=7680000,RESOLUTION=1920x1080 high/index.m3u8
4. 常用标签速查
| 标签 | 含义 |
|---|---|
#EXTM3U |
文件头,必须位于第一行 |
#EXT-X-VERSION |
协议版本号,决定可使用哪些特性 |
#EXT-X-TARGETDURATION |
任意分片的最大时长(秒),取整 |
#EXT-X-MEDIA-SEQUENCE |
第一个分片的序号,直播中随窗口滑动递增 |
#EXTINF |
紧随其后的那个分片的时长 |
#EXT-X-STREAM-INF |
描述一路码率流,带 BANDWIDTH、RESOLUTION、CODECS 等属性 |
#EXT-X-ENDLIST |
表示列表结束——有点播(VOD),无直播 |
#EXT-X-KEY |
分片加密方式与密钥获取地址 |
#EXT-X-MAP |
fMP4 容器的初始化段(init segment)位置 |
一个实用判断:有没有 EXT-X-ENDLIST 可以区分直播与点播。直播列表会不断追加新分片并移除旧分片,永远不写这个标签。
5. 分片格式:TS 与 fMP4
- MPEG-2 TS(.ts):HLS 传统格式,兼容性最好,每个分片可独立解码。
- fMP4(.m4s):较新的封装方式,与 DASH 共用同一套文件,便于一套源同时服务 HLS 与 DASH。使用时需要
EXT-X-MAP指向初始化段。
hls.js 这类库的工作,就是把 TS / fMP4 分片转封装成浏览器能直接喂给 <video> 的格式,并通过 Media Source Extensions 连续播放。Safari 则原生支持 HLS,不需要这层转换。
6. 加密与 DRM
HLS 支持分片级加密。最常见的 AES-128 通过 EXT-X-KEY 声明:
#EXT-X-KEY:METHOD=AES-128,URI="https://example.com/key.bin",IV=0x...
播放器需要先拿到 URI 指向的密钥,才能解密后续分片。需要注意:这只是内容加密,不是强版权保护——密钥获取方式是自定义的,真正的 DRM(如 FairPlay、Widevine)需要额外的授权体系与浏览器支持,本站不涉及。
7. 自适应码率(ABR)
Master Playlist 里列出的每一路 EXT-X-STREAM-INF 都带 BANDWIDTH。播放器会持续测量当前网速与缓冲水位,在多个档位间自动切换:网速好时升到高清,网速变差时降到流畅档,避免卡顿。这也是为什么同一条流在不同网络下清晰度会变。
8. 为什么跨域(CORS)这么关键
浏览器安全策略要求:网页要读取另一个域名的资源,对方必须显式允许。对 HLS 来说,就是 m3u8 与分片文件的响应头里要带上:
Access-Control-Allow-Origin: *
或指定具体来源。少了这个头,浏览器会在网络层直接拦掉请求,播放器只能报「地址不可达」——这是 m3u8 播放失败最常见的原因,且需要在源站侧修复,播放器无法绕过。
9. 延迟从哪来,怎么优化
HLS 的天然延迟主要来自分片时长:播放器通常要等至少一个完整分片下载完才开始播。若分片为 6 秒,叠加缓冲,端到端延迟轻松达到 10–30 秒。
- 缩短分片:把
-hls_time降到 2–4 秒,延迟下降,但请求数上升。 - LL-HLS(低延迟 HLS):引入部分分片(Partial Segment)与预加载提示,可把延迟降到 2–5 秒,但需要源站与播放器同时支持。
- 权衡:延迟越低,对网络抖动的容忍度越差,卡顿风险上升。直播互动类场景才值得为低延迟付出代价。
10. HLS、DASH 与普通 MP4 怎么选
| 方案 | 优点 | 局限 |
|---|---|---|
| HLS | iOS / Safari 原生支持;生态成熟;CDN 友好 | 延迟相对较高(传统模式下) |
| DASH | 国际标准;与 fMP4 天然契合;Android / 智能电视支持好 | 苹果设备支持较弱 |
| 普通 MP4 | 最简单,一个文件丢上去就能播 | 无自适应码率;长视频首播慢;拖动需等缓冲 |
实践中的常见做法是:短视频用 MP4 直传;长视频与直播用 HLS(需要覆盖苹果设备时)或 HLS + DASH 双轨。