M3U8视频封装格式的深度解析
引言
M3U8 作为一种常见的视频封装格式,具有广泛的使用场景,不仅被应用到点播场景中,也被应用到直播场景中。特别是点播场景,目前主流的视频点播网站大多都是使用 M3U8 方案。
格式简介
M3U8 视频封装格式其实是一个统称,它实际上是由 m3u8 索引文件和若干个 ts 分片文件组成的,视频编码为 H264,音频编码为 AAC。很多时候大家可能对 HLS(Http Live Streaming)的说法更加熟悉。是的,HLS 是由苹果公司提出的基于 HTTP 的流媒体网络传输协议,是苹果公司 QuickTime X 和 iPhone 软件系统的一部分。HLS 不仅支持 ts 分片,还支持 mp4 分片,但是后者一般太常见,主流的 HLS 方案使用的还是 ts 分片。
工作原理
M3U8 视频封装格式的工作原理就是把整个流分成一个个小的基于 HTTP 的 ts 视频文件下载下来,每次只下载一部分 ts 视频文件。当媒体流正在播放时,客户端可以选择从许多不同的备用源中以不同的速率下载同样的资源,允许流媒体会话适应不同的数据速率动态切换。在开始一个流媒体会话时,客户端会下载一个包含元数据的 m3u8 文件,用于寻找可用的 ts 媒体流。
结构组成
// 示例1
#EXTM3U
#EXT-X-VERSION:3
#EXT-X-TARGETDURATION:8
#EXT-X-MEDIA-SEQUENCE:0
#EXT-X-DISCONTINUITY
#EXTINF:7.749667,
index_0000.ts
#EXTINF:5.875000,
index_0001.ts
#EXTINF:3.916667,
index_0002.ts
#EXT-X-ENDLIST
// 示例2
#EXTM3U
#EXT-X-STREAM-INF:BANDWIDTH=1280000,AVERAGE-BANDWIDTH=1000000 http://example.com/low.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=2560000,AVERAGE-BANDWIDTH=2000000 http://example.com/mid.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=7680000,AVERAGE-BANDWIDTH=6000000 http://example.com/hi.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=65000,CODECS="mp4a.40.5"
http://example.com/audio-only.m3u8
#EXTM3U
表示这个文件属于 m3u8 类型文件
#EXT-X-VERSION
表示版本号标签
#EXT-X-TARGETDURATION
表示所有分片最大时长的标签,注意这是一个四舍五入的值,如果 m3u8 文件中分片列表中分片最大的时长是 8.02,那么 EXT-X-TARGETDURATION 字段的值是 8。
#EXT-X-MEDIA-SEQUENCE
表示是一个分片参考序列标签,当 m3u8 文件用于直播场景时,会把这个标签的值作为参考,进而播放对应的序列号的分片。但是,这样的话,就要求所有的 ts 分片序号都是动态变化的,且不能重复。
#EXT-X-DISCONTINUITY
表示前一片分片和后一片分片有不连续。当 m3u8 文件列表中的前一个视频分片和下一个视频分片不是连续的时候,使用播放器播放时很可能是失败,这个时候就需要用来一个神奇的字段标签——EXT-X-DISCONTINUITY,它可以轻松解决这个问题。
#EXT-X-ENDLIST
表示结束,该标签一般会用在 m3u8 文件的最后一行,也是用来区分某个 m3u8 文件是用于点播场景还是直播场景的标识。点播场景中的 m3u8 文件包行 EXT-X-ENDLIST 标签,直播场景中的 m3u8 文件没有 EXT-X-ENDLIST 标签。
#EXTINF
表示每个 ts 视频分片时长,单位:秒
#EXT-X-STREAM-INF
表示一个可变视频流的标签
格式
#EXT-X-STREAM-INF:<attribute-list><URI>
attribute-list属性如下
BANDWIDTH 字段用来表示可变视频流的码率。 一般来说,EXT-X-STREAM-INF 标签出现时,这个字段是不可缺少的。 AVERAGE-BANDWIDTH 字段用来表示可变视频流的平均码率,该属性是一个可选属性。 CODECS 字段用来表示可变视频流的媒体编码信息,一般包括视频编码和音频编码信息。 比如,如果是音频编码为 AAC-LC,视频编码为 H.264 Main Profile Level 3.0 的 可变视频流,那么,它的 CODECS 字段的值应该为“mp4a.40.2,avc1.4d401e”。 一般来说,EXT-X-STREAM-INF 标签出现时,这个属性是应该被标明的。 RESOLUTION 字段用来表示可变视频流的分辨率, 一般来说,EXT-X-STREAM-INF 标签出现时,这个属性是推荐使用的。 FRAME-RATE 字段用来表示可变视频流中所有视频的最大帧率, 该属性是一个可选属性。 HDCP-LEVEL 字段用来表示可变视频流的高带宽数字内容保护级别, 该属性的值是一个枚举字符串,可用值为“TYPE-0”和“NONE”。 其中,“TYPE-0” 表示播放的视频内容必须经过高带宽数字内容保护, 否则会播放失败。 “NONE”表示不限制视频内容的保护级别。该属性是一个可选属性。 AUDIO 字段用来表示可变媒体流的媒体类型,用来表示播放的内容是音频格式, 该属性是一个可选属性。 VIDEO 字段用来表示可变媒体流的媒体类型,用来表示播放的内容是视频格式, 该属性是一个可选属性。 SUBTITLES 字段用来表示可变媒体流的媒体类型,用来表示显示的内容是字幕内容, 该属性是一个可选属性。 CLOSED-CAPTIONS 字段用来表示可变媒体流的媒体类型,用来表示显示的内容是旁 白字幕,主要是为了考虑由听力障碍的用户,该属性是一个可选属性。
#EXT-X-BYTERANGE
表示用来表示 URI 对应文件资源的一个子集的标签。
书写格式如下:
#EXT-X-BYTERANGE:<n>[@<o>]
其中,n 表示子集的字节数,o 为可选项,标明子集的起始位置,相当于从资源开始出计算的偏移量。若 o 未定义,则其开始位置为上一个子集的结束位置的下一个字节。注意,这个标签在 M3U8 版本号 4.0 及以上才有。
#EXT-X-PLAYLIST-TYPE
表示用来播放列表的类型信息
书写格式如下:
#EXT-X-PLAYLIST-TYPE:<type-enum>
其中,type-enum 是字符串枚举类型,“EVENT” 或者 “VOD”。该属性是一个可选属性。