HLS 与 M3U8 播放列表基础

从媒体列表、主列表到直播更新和标签含义

Posted by Yvain Zhang on April 19, 2022 主题:技术

很多人第一次接触 M3U8,都是因为抓到一个 .m3u8 地址,或者在播放器日志里看到一堆 #EXTINF#EXT-X-KEY#EXT-X-TARGETDURATION
看久了会发现,M3U8 真正有用的地方不是“它是一种文件”,而是它把 HLS 这套流媒体分发方式组织得很规整。

1. M3U8 和 HLS 是什么关系

先把最容易混的两层拆开:

  • HLS 是一种流媒体传输协议
  • M3U8 是 HLS 里最常见的播放列表文件

也就是说,播放器拿到 M3U8,本质上是在拿一份“怎么去请求后续媒体资源”的说明书。

HLS 的核心思路很简单:

  • 把一整段媒体拆成很多小片段
  • 用 HTTP 去拉这些片段
  • 用播放列表描述片段顺序、参数和切换关系

2. 为什么 HLS 适合大规模分发

HLS 常见的几个优势都很实际:

  • 基于 HTTP,容易走 CDN
  • 穿防火墙和代理更自然
  • 客户端可以按网络条件切码率
  • 点播和直播都能统一到一套播放列表思路上

这也是为什么很多在线视频、直播、移动端播放场景会大量使用它。

3. M3U8 文件其实有两类

M3U8 不止一种内容形态,最重要的是区分:

  • Media Playlist
  • Master Playlist

Media Playlist

它里面列的是一段段实际媒体片段,比如 .ts.m4s 等。

播放器拿到它之后,基本就是按顺序去拉这些片段并播放。

Master Playlist

它不直接列媒体片段,而是列出多路可选流,例如:

  • 不同码率
  • 不同分辨率
  • 不同音轨
  • 不同字幕或语言版本

播放器先根据 Master Playlist 选路,再进入对应的 Media Playlist。

4. 点播和直播在列表层面有什么区别

点播和直播都能用 M3U8,但播放列表更新方式不一样。

点播

点播列表通常是完整的,客户端顺着播到结尾就结束。很多点播列表会带:

  • #EXT-X-ENDLIST

告诉客户端这份列表到这里就结束了,不会再长。

直播

直播列表通常会不断更新。客户端不能只请求一次,而是要周期性重新拉取 M3U8,看看有没有新的片段出现。

所以做直播播放时,一个关键点不是“怎么拉第一个片段”,而是“怎么持续刷新列表并衔接新片段”。

5. M3U8 文件最基本的规则

看格式时,先记住几条最基础的约束就够了:

  • 文件一般用 UTF-8
  • 第一行通常是 #EXTM3U
  • 每一行要么是 URI,要么是标签,要么是空行
  • #EXT 开头的是标签

播放器解析时,很多兼容性问题其实就出在:

  • 编码不规范
  • 属性值大小写不对
  • 属性列表里混入非法空格

6. Media Playlist 里最常见的几个标签

#EXTINF

表示后面那个媒体片段的时长。
播放器会用它来估算时间轴、缓冲和播放进度。

#EXT-X-TARGETDURATION

表示切片最大时长。这个值对播放器的缓冲和刷新策略很重要。

#EXT-X-MEDIA-SEQUENCE

表示列表里第一个片段的序号。直播场景里,这个字段尤其关键,因为客户端要靠它判断新旧片段关系。

#EXT-X-ENDLIST

表示播放列表结束。点播常见,直播初期通常不会带。

#EXT-X-DISCONTINUITY

表示前后片段在时间线或编码上下文上存在不连续,比如插广告、切源、编码参数变化等。

7. Master Playlist 里最常见的几个标签

#EXT-X-STREAM-INF

它通常用来描述一条可选码流,比如:

  • BANDWIDTH
  • RESOLUTION
  • CODECS

客户端会根据网络条件和设备能力,从这些候选项里选一条或动态切换。

#EXT-X-MEDIA

常用于音频、字幕、不同语言等替代媒体资源描述。

如果你的播放器要做多语言音轨或字幕切换,这个标签就会变得很重要。

8. 加密和初始化信息怎么描述

HLS 里比较常见的还有:

#EXT-X-KEY

表示后续片段如何解密。做 DRM 或 AES-128 加密时,经常要关注它的:

  • METHOD
  • URI
  • IV

#EXT-X-MAP

表示初始化段的位置。尤其在 fMP4 场景下,这个标签很关键。

也就是说,播放器如果不是纯 TS 场景,而是 CMAF / fMP4 风格的 HLS,MAP 往往不能忽略。

9. 客户端解析 M3U8 时真正该做什么

工程里解析 M3U8,通常不是把所有标签都一口气实现,而是先抓主线:

  1. 判断它是 Master 还是 Media
  2. 如果是 Master,选合适变体流
  3. 如果是 Media,解析片段列表和时长
  4. 对直播定时刷新
  5. 处理加密、切片中断和时间线变化

把这条线跑通后,再逐步补更多标签兼容。

10. 常见问题一般出在哪

播放器拿到 M3U8 但不出画

优先查:

  • 是不是先拿到了 Master 却没继续进 Media
  • URI 是否能正确拼接
  • CODECS 是否超出设备支持范围

直播越播越卡

常见落点:

  • 刷新间隔不合理
  • 片段缓存策略不对
  • TARGETDURATION 和实际切片长度偏差大

时间轴不准或跳变

重点看:

  • EXTINF 是否可信
  • 是否存在 DISCONTINUITY
  • 媒体序号和时间线衔接是否处理正确

11. 总结

如果把 M3U8 只当成“一个文本文件”,很容易看着标签眼花。更好的理解方式是把它当作 HLS 的调度表:

  • Master Playlist 负责选路
  • Media Playlist 负责列片段
  • 标签负责补时长、加密、序号和切换信息

把这三层关系分清之后,后面无论是写解析器、接播放器,还是排查直播问题,都会更容易抓住重点。