M3U8 格式:为什么直播回放都用这个格式?
M3U8 文件是一种纯文本文件,可以指定一个或多个多媒体文件的位置。它的设计初衷是为了播放音频文件,但后来越来越多的用于播放视频文件列表。而 M3U8 则是用 UTF-8 编码的 M3U。M3U、M3U8 文件都是苹果公司使用的 HLS(HTTP Live Streaming) 协议的基础。
M3U8 格式概览
M3U8 文件其实是一个播放列表,这个列表可能是一个媒体播放列表(Media Playlist),也可能是一个主播放列表(Master Playlist)。但无论是哪种播放列表,其内部文字使用的都是 utf-8 编码。
M3U8 的应用场景
在实际应用场景中,由于 HLS/M3U8/TS 这套方案在控制直播延时上不太理想,所以一般实时直播场景不会选择使用 M3U8 媒体格式。但是,对于直播回放这种场景,由于使用 M3U8/TS 这套方案能够在直播过程中就持续生成和存储切片,所以直播回放基本上都会选择 M3U8 媒体格式。
媒体播放列表
当 M3U8 文件作为媒体播放列表(Media Playlist)时,其包含的信息记录的是一系列多媒体资源切片,顺序播放这些切片,即可完整呈现多媒体资源。
#EXTM3U
#EXT-X-TARGETDURATION:10
#EXTINF:9.009,
http://media.example.com/first.ts
#EXTINF:9.009,
http://media.example.com/second.ts
#EXTINF:3.003,
http://media.example.com/third.ts
#EXT-X-ENDLIST
第一行的 #EXTM3U 表示文件格式。第二行的 #EXT-X-TARGETDURATION:10 表示后面的各个资源切片时长都小于或等于 10 秒。接下来,我们看到有 3 个资源切片,时长分别是 9.009 秒、9.009 秒、3.003 秒。
在点播时,客户端首先下载 M3U8 文件,然后按照 M3U8 列表下载各个资源切片依次播放即可。在直播时,客户端则需要定时重新请求 M3U8 文件,从而检查是否有新的媒体切片需要进行下载播放。所有的这些数据都通过 HTTP 协议传输。
主播放列表
当 M3U8 文件作为主播放列表(Master Playlist)时,其包含的信息是同一个媒体资源的多路流资源列表。不同的流可能有着不同的码率,不同的格式,不同的分辨率。不同的流也可以指定不同语言的音频,不同视角的视频等等。
#EXTM3U
#EXT-X-STREAM-INF:BANDWIDTH=150000,RESOLUTION=416x234,CODECS="avc1.42e00a,mp4a.40.2"
http://example.com/low/index.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=240000,RESOLUTION=416x234,CODECS="avc1.42e00a,mp4a.40.2"
http://example.com/lo_mid/index.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=440000,RESOLUTION=416x234,CODECS="avc1.42e00a,mp4a.40.2"
http://example.com/hi_mid/index.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=640000,RESOLUTION=640x360,CODECS="avc1.42e00a,mp4a.40.2"
http://example.com/high/index.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=64000,CODECS="mp4a.40.5"
http://example.com/audio/index.m3u8
客户端应该根据网络状况来选择合适的流来播放,也应该根据用户的偏好来选择合适的语言和视角的流来播放。
M3U8 格式规范
格式要求
- M3U8 播放列表文件必须以 UTF-8 进行编码
- 不能包含任何 Byte Order Mark(BOM)内容
- 除了 CR 和 LF 之外不能包含任何 UTF-8 控制字符
- 所有的字符序列必须遵循 Unicode 规范
文件结构
M3U8 播放列表文件的每一行要么是一个 URI,要么是空行,要么是以 # 开头的字符串。空行会被忽略。以 # 开头的字符串要么是注释,要么是标签。标签以 #EXT 开头,大小写敏感。
媒体切片时长
一个媒体播放列表的时长等于它包含的所有媒体切片时长的总和。每个媒体切片的码率等于切片的大小除以它的时长。
M3U8 标签详解
基础标签
- #EXTM3U:表示文件继承自 M3U 标准,必须放在文件第一行
- #EXT-X-VERSION:表示文件的版本
媒体切片标签
- #EXT-X-TARGETDURATION:每个分片 TS 的最大的时长
- #EXTINF:分片 TS 的信息,如时长、带宽等
- #EXT-X-ENDLIST:M3U8 文件结束符
- #EXT-X-MEDIA-SEQUENCE:第一个 TS 分片的序列号
- #EXT-X-ALLOW-CACHE:是否允许缓存
HLS 协议优势
- HLS 只请求基本的 HTTP 报文,与实时传输协议(RTP)不同,HLS 可以穿过任何允许 HTTP 数据通过的防火墙或者代理服务器
- 很容易使用内容分发网络来传输媒体流,这是 HLS 应用在直播上的一大优势
- 支持多码率自适应,用户可以根据网络状况自动选择合适的清晰度
- 支持加密和 DRM,可以保护内容版权
M3U8 与直播
如何判断 M3U8 是直播还是点播?
1. 判断是否存在 #EXT-X-ENDLIST
对于一个 M3U8 文件,如果结尾不存在 #EXT-X-ENDLIST,那么一定是直播,不是点播。
2. 判断 #EXT-X-PLAYLIST-TYPE 类型
'#EXT-X-PLAYLIST-TYPE' 有两种类型:
- VOD (Video on Demand):表示该视频流为点播源,服务器不能更改该 M3U8 文件
- EVENT:表示该视频流为直播源,服务器可以在文件末尾添加新内容
总结
M3U8 作为 HLS 协议的核心组成部分,在直播回放和点播场景中有着广泛的应用。虽然在实时直播方面由于延迟问题不如其他协议,但在需要高可靠性、易于 CDN 分发和自适应码率的场景中,M3U8 仍然是最佳选择之一。