参考文档:https://datatracker.ietf.org/doc/html/rfc8216
一、m3u8协议概述
m3u8 协议是基于 M3U 格式扩展而来的一种多媒体播放列表协议,主要用于流媒体的索引和分发,尤其在 HLS(HTTP Live Streaming)技术中扮演核心角色。它通过文本文件(.m3u8 扩展名)描述媒体片段的地址、时长、编码信息等,让客户端能够按顺序请求并播放流媒体内容。
起源:m3u8 源于传统的 M3U 文件(一种音频播放列表格式,后缀为.m3u),为适应流媒体和 UTF-8 编码需求,扩展出.m3u8 格式(强制使用 UTF-8 编码)。
核心作用:作为流媒体的 “导航地图”,告诉客户端:
- 流媒体包含哪些片段(如.ts 视频切片);
- 每个片段的网络地址、时长、码率;
- 可选的多码率版本(方便客户端根据网络状况切换清晰度)。
二、m3u8文件结构与语法
HLS(HTTP Live Streaming) 把整个流分成⼀个个⼩的基于 HTTP 的⽂件来下载,每次只下载⼀些。HLS 协议由三部分组成:HTTP、M3U8、TS。这三部分中,HTTP 是传输协议,M3U8 是索引⽂件,TS是⾳视频的媒体信息。
HLS 是提供⼀个 m3u8 地址,Apple 的 Safari 浏览器直接就能打开 m3u8 地址,譬如:
http://demo.srs.com/live/livestream.m3u8
Android 不能直接打开,需要使⽤ html5 的 video 标签,然后在浏览器中打开这个⻚⾯即可,譬如:
<!-- livestream.html -->
<video width="640" height="360"
autoplay controls autobuffer
src="http://demo.srs.com/live/livestream.m3u8"
</video>
HLS 的 m3u8,是⼀个 ts 的列表,也就是告诉浏览器可以播放这些 ts ⽂件,譬如:
#EXTM3U
#EXT-X-VERSION:3
#EXT-X-MEDIA-SEQUENCE:64
#EXT-X-TARGETDURATION:12
#EXTINF:11.550
livestream-64.ts
#EXTINF:5.250
livestream-65.ts
#EXTINF:7.700
livestream-66.ts
#EXTINF:6.850
livestream-67.ts
有⼏个关键的参数,这些参数在 SRS 的配置⽂件中都有配置项:
#EXTM3U
:每个M3U⽂件第⼀⾏必须是这个tag,请标示作⽤#EXT-X-VERSION
:该属性可以没有,⽬前主要是version 3,最新的是7#EXT-X-MEDIA-SEQUENCE
:每⼀个media URI在PlayList中只有唯⼀的序号,相邻之间序号+1,⼀个media URI并不是必须要包含的,如果没有,默认为0#EXT-X-TARGETDURATION
:所有切⽚的最⼤时⻓。有些 Apple 设备这个参数不正确会⽆法播放。SRS 会⾃动计算出 ts ⽂件的最⼤时⻓,然后更新 m3u8 时会⾃动更新这个值。⽤户不必⾃⼰配置。#EXTINF
:ts 切⽚的实际时⻓,SRS 提供配置项 hls_fragment,但实际上的 ts 时⻓还受 gop 影响。ts ⽂件的数⽬:SRS 可配置 hls_window(单位是秒,不是数量),指定 m3u8 中保存多少个切⽚,譬如,每个 ts 切⽚为 10 秒,窗⼝为 60 秒,那么 m3u8 中最多保存 6 个 ts 切⽚,SRS 会⾃动清理旧的切⽚。
livestream-67.ts:SRS 会⾃动维护 ts 切⽚的⽂件名,在编码器重推之后,这个编号会继续增⻓,保证流的连续性。直到 SRS 重启,这个编号才重置为 0。
每⼀个 .m3u8 ⽂件,分别对应若⼲个 ts ⽂件,这些 ts ⽂件才是真正存放视频的数据。m3u8 ⽂件只是存放了⼀些 ts ⽂件的配置信息和相关路径,当视频播放时,.m3u8 是动态改变的,video标签会解析这个⽂件,并找到对应的 ts ⽂件来播放,所以⼀般为了加快速度,.m3u8 放在 web 服务器上,ts ⽂件放在 cdn 上。.m3u8 ⽂件,其实就是以 utf-8 编码的 m3u ⽂件,这个⽂件本身不能播放,只是存放了播放信息的⽂本⽂件。
进入SRS服务器对应的视频流路径,可以查看到.m3u8文件
srs/trunk/objs/nginx/html/live
比如这里有个livestream
和livestream2
的视频流,目录下就存在对应的livestream.ts
、livestream2.ts
文件
查看对应的livestream.m3u8
cat livestream.m3u8
m3u8 与 HLS 的关系
- HLS 是苹果公司推出的流媒体传输协议,而 m3u8 是 HLS 协议中用于描述媒体片段的索引文件格式。
- HLS 的工作流程依赖 m3u8:
- 服务器将视频切分为短片段(通常 5-10 秒,格式为.ts);
- 生成 m3u8 文件,列出所有.ts 片段的地址和信息;
- 客户端请求 m3u8 文件,根据其内容依次下载并播放.ts 片段;
- 直播场景中,服务器会定期更新 m3u8 文件(删除旧片段,添加新片段),客户端周期性拉取最新列表。
三、m3u8示例
3.1 简单的点播 m3u8 文件
#EXTM3U
#EXT-X-VERSION:3
#EXT-X-TARGETDURATION:10
#EXT-X-MEDIA-SEQUENCE:0
#EXTINF:10.0,
video_0.ts # 第一个10秒的视频片段
#EXTINF:10.0,
video_1.ts # 第二个10秒的视频片段
#EXTINF:5.0,
video_2.ts # 最后一个5秒的视频片段
#EXT-X-ENDLIST # 标识播放结束
3.2 多码率直播 m3u8 文件(主列表)
主 m3u8 文件(用于选择码率):
#EXTM3U
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=1280000
http://example.com/low.m3u8
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=2560000
http://example.com/mid.m3u8
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=7680000
http://example.com/hi.m3u8
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=65000,CODECS="mp4a.40.5"
http://example.com/audio-only.m3u8
包含多种⽐特率的 Master Playlist。该⽂件是⼀个实际使⽤中的顶级 m3u8 ⽂件,该⽂件中⼜定义了
http://example.com/low.m3u8
、http://example.com/mid.m3u8
等 ⼏ 个 ⼆ 级 ⽂ 件 。 顶 级m3u8 ⽂件主要是做码率适配的,⼆级 m3u8 才是真正的切⽚⽂件,客户端会默认选择码率最⾼的请求如果发现码率达不到,会请求降低码率的流。客户端拿到⼆级 m3u8 ⽂件后,会继续请求⾥⾯的⽂件,这时就可以进⾏播放了。
四、基础概念
4.1 Playlist file
⼀个 m3u 的 Playlist 就是⼀个由多个独⽴⾏组成的⽂本⽂件,每⾏由回⻋/换⾏区分。每⼀⾏可以是⼀个URI、空⽩⾏或是⼀个 以 “#” 号开头的字符串,并且空格只能存在于⼀⾏中不同元素间的分隔。
⼀个 URI 表示⼀个媒体段或是 “variant Playlist file”(最多⽀持⼀层嵌套,即⼀个 m3u8 ⽂件中嵌套另⼀个 m3u8),以 “EXT” 开头的表示⼀个 “tag”,否则表示注释,直接忽略。
4.2 Tags
1. #EXTM3U
每个m3u8文件第一行必须是这个tag,如上述两个示例。
2. #EXT-X-VERSION
- 作用:指定m3u8文件的版本号。
- 格式:
#EXT-X-VERSION:<版本号>
- 示例:
#EXT-X-VERSION:3
3. #EXTINF
- 作用:指定每个媒体段(ts文件)的持续时间,仅对其后的URI有效,每两个媒体段URI间需用此tag分隔。
- 格式:
#EXTINF:<duration>,<title>
- 示例:
#EXTINF:14.357, no desc
- 参数说明:
duration
:表示持续时间(单位:秒)。若协议版本小于3,duration
必须为整数;版本≥3时可使用浮点数。
4. #EXT-X-BYTERANGE
- 作用:表示媒体段是某一媒体URI资源中的一段,仅对其后的media URI有效。
- 格式:
#EXT-X-BYTERANGE:<n>[@o]
- 参数说明:
n
:表示该区间的大小(字节)。o
:表示在URI中的偏移量(可选)。
- 备注:该标签在协议版本4及以上出现。
5. #EXT-X-TARGETDURATION
- 作用:指定当前视频流中单个切片(ts文件)的最大时长(单位:秒)。
#EXTINF
中指定的时间长度必须小于或等于该最大值。 - 格式:
#EXT-X-TARGETDURATION:<s>
- 参数说明:
s
表示最大秒数。 - 备注:在整个Playlist文件中只能出现一次(嵌套场景中,通常包含真实ts url的m3u8文件才会出现此tag)。
6. #EXT-X-MEDIA-SEQUENCE
- 作用:每个media URI在Playlist中拥有唯一序号,相邻序号递增1。
- 格式:
#EXT-X-MEDIA-SEQUENCE:<number>
- 备注:若未包含此tag,默认序号从0开始。
7. #EXT-X-KEY
- 作用:定义对media segments的解码方式,作用范围为下次该tag出现前的所有media URI。
- 格式:
#EXT-X-KEY:<attribute-list>
- 参数说明:
METHOD
:加密方法,可选值为NONE
(不加密)或AES-128
(AES-128加密)。- 若
METHOD=NONE
,则URI
和IV
属性必须不存在。 - 若
METHOD=AES-128
(Advanced Encryption Standard),则URI
必须存在,IV
可选。
- 若
URI
:密钥文件的获取地址(当METHOD=AES-128
时必选)。IV
:初始化向量(Initialization Vector)。若未指定,默认使用媒体序列号(#EXT-X-MEDIA-SEQUENCE
)作为IV(将序列号高位填入16字节buffer,左侧补0);若指定,需为16字节的十六进制字符串。
8. #EXT-X-PROGRAM-DATE-TIME
- 作用:将绝对时间或日期与媒体段中的第一个样本关联,仅对下一个media URI有效。
- 格式:
#EXT-X-PROGRAM-DATE-TIME:<YYYY-MM-DDThh:mm:ssZ>
- 示例:
#EXT-X-PROGRAM-DATE-TIME:2010-02-19T14:54:23.031+08:00
9. #EXT-X-ALLOW-CACHE
- 作用:指定是否允许缓存媒体段,对所有媒体段有效。
- 格式:
#EXT-X-ALLOW-CACHE:<YES|NO>
- 备注:可在Playlist文件中任意位置出现,最多出现一次。
10. #EXT-X-PLAYLIST-TYPE
- 作用:提供关于Playlist可变性的信息,对整个Playlist文件有效(可选标签)。
- 格式:
#EXT-X-PLAYLIST-TYPE:<EVENT|VOD>
- 参数说明:
VOD
:点播视频。服务器不能修改Playlist文件,所有ts文件已生成完毕。EVENT
:实时生成m3u8和ts文件。服务器不能修改或删除Playlist文件中的内容,但可追加新行,播放时需不断下载二级index文件。
11. #EXT-X-ENDLIST
- 作用:表示m3u8文件的结束,直播(live)m3u8文件通常不含此tag。
- 格式:
#EXT-X-ENDLIST
- 备注:可在Playlist中任意位置出现,但仅能出现一次。
12. #EXT-X-MEDIA
- 作用:在Playlist中表示相同内容的不同语种/译文版本(如多语言音频、多视角视频),标签独立存在。
- 格式:
#EXT-X-MEDIA:<attribute-list>
- 属性列表说明:
URI
:若未指定,表明该tag描述的可选版本存在于主Playlist的EXT-X-STREAM-INF
中。TYPE
:类型,可选AUDIO
(音频)或VIDEO
(视频)。GROUP-ID
:具有相同ID的EXT-X-MEDIA
标签组成一组样式。LANGUAGE
:标识该版本使用的主要语言。NAME
:人类可读的描述字符串,若LANGUAGE
存在,描述应使用该语言。DEFAULT
:是否默认选择,可选YES
或NO
(默认NO
)。若为YES
,客户端默认播放此版本(用户手动选择除外)。AUTOSELECT
:是否自动选择,可选YES
或NO
(默认NO
)。若为YES
,客户端在用户未指定偏好时,根据播放环境自动选择。
- 备注:该标签在协议版本4及以上出现。
13. #EXT-X-STREAM-INF
- 作用:指定包含多媒体信息的media URI作为Playlist,通常用于m3u8嵌套,仅对紧跟其后的URI有效。
- 格式:
#EXT-X-STREAM-INF:<attribute-list>
- 常用属性说明:
BANDWIDTH
:带宽(必选)。PROGRAM-ID
:十进制整数,唯一标识Playlist文件范围内的特定描述,可重复。CODECS
:指定流的编码类型(可选)。RESOLUTION
:分辨率(可选)。AUDIO
:值需与AUDIO
类别EXT-X-MEDIA
标签的GROUP-ID
属性匹配(可选)。VIDEO
:同上,与VIDEO
类别EXT-X-MEDIA
标签的GROUP-ID
匹配(可选)。
14. #EXT-X-DISCONTINUITY
- 作用:标识后续媒体段的以下属性发生变化:
- 文件格式(file format)
- 轨道数量和类型(number and type of tracks)
- 编码参数(encoding parameters)
- 编码序号(encoding sequence)
- 时间戳序号(timestamp sequence)
15. #ZEN-TOTAL-DURATION
- 作用:表示该m3u8文件所包含的ts文件总时长。