M3U8文件简介
M3U(MP3 URL
)是一个以.m3u
扩展名存储的音频播放列表文件,区别在于.m3u8
文件使用UTF-8字符编码。M3U8是Unicode版本的M3U,用UTF-8编码。
M3U8文件其实是HTTP Live Streaming
(缩写为 HLS)协议的部分内容,用文本方式对媒体文件进行描述,由一系列标签组成。HLS 是一个由苹果公司提出的基于 HTTP 的流媒体网络传输协议。
M3U8主要是可以做多码率的适配,根据网络带宽,客户端会选择一个适合自己码率的文件进行播放,保证视频流的流畅。
以字符’#
'开头的行可能是注释或者标签,标签以#EXT
开头,表示一个tag,否则表示注释,直接忽略。
M3U8文件实质是一个播放列表。其可能是一个媒体播放列表(Media Playlist),或者是一个主列表(Master Playlist)。
index.m3u8实例分析
这是一个fragment mp4的主播放列表的代码,通过wget可以直接下载下来:
#EXTM3U
# Created with Bento4 mp4-dash.py, VERSION=1.8.0-628
#
#EXT-X-VERSION:6
# Media Playlists
# Audio
#EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID="audio/dtse",LANGUAGE="en",NAME="English",AUTOSELECT=YES,DEFAULT=YES,URI="audio-en-dtse.m3u8"
# Video
#EXT-X-STREAM-INF:AUDIO="audio/dtse",AVERAGE-BANDWIDTH=699465,BANDWIDTH=744010,CODECS="avc1.42C01E,dtse",RESOLUTION=640x360
video-avc1-1.m3u8
#EXT-X-STREAM-INF:AUDIO="audio/dtse",AVERAGE-BANDWIDTH=856934,BANDWIDTH=839487,CODECS="avc1.4D4820,dtse",RESOLUTION=1280x720
video-avc1-2.m3u8
#EXT-X-STREAM-INF:AUDIO="audio/dtse",AVERAGE-BANDWIDTH=1027637,BANDWIDTH=1003435,CODECS="avc1.640829,dtse",RESOLUTION=1920x1080
video-avc1-3.m3u8
# I-Frame Playlists
#EXT-X-I-FRAME-STREAM-INF:AVERAGE-BANDWIDTH=314664,BANDWIDTH=359228,CODECS="avc1.42C01E",RESOLUTION=640x360,URI="video-avc1-1.m3u8"
#EXT-X-I-FRAME-STREAM-INF:AVERAGE-BANDWIDTH=472133,BANDWIDTH=454705,CODECS="avc1.4D4820",RESOLUTION=1280x720,URI="video-avc1-2.m3u8"
#EXT-X-I-FRAME-STREAM-INF:AVERAGE-BANDWIDTH=642836,BANDWIDTH=618653,CODECS="avc1.640829",RESOLUTION=1920x1080,URI="video-avc1-3.m3u8"
按照文件tag出现的次序,下面依次介绍各个tag的意义。
#EXTM3U
格式:
#EXTM3U
每个M3U文件第一行必须是这个tag,用来表示这个文件属于m3u类型文件。
#EXT-X-VERSION
格式:
#EXT-X-VERSION:<n>
用以标示m3u8文件的版本号
#EXT-X-MEDIA
格式:
#EXT-X-MEDIA:<attribute-list>
- 属性列表中包含:
- TYPE
- GROUP-ID
- LANGUAGE
- NAME
- AUTOSELECT
- DEFAULT
- URI
#EXT-X-MEDIA
的作用是被用来在PlayList中表示相同内容的不用语种/译文的版本,比如可以通过使用3个这种tag表示3中不用语音的音频,或者用2个这个tag表示不同角度的video。- 在PlayLists中,这个标签是独立存在的。
#EXT-X-STREAM-INF
格式:
#EXT-X-STREAM-INF:<attribute-list><URI>
-
用于标识一个可变码流的playlist,该标签的属性列表中包含了可变码流的描述信息。
-
属性列表中包含:
- BANDWIDTH:表示可变码流中的峰值比特率,单位bits/s。
- AVERAGE-BANDWIDTH:表示可变码流中的平均比特率,单位bits/s。
- CODECS:包含可变码流中音视频编码格式相关的信息,比如前面代码段的"avc1.42C01E,dtse",
avc1
代表H.264,42C01E
三个字节codec profile, flags, and level - RESOLUTION:包含可变码流中对应视频流的分辨率。
- FRAME-RATE:表示可变码流中的视频帧率。
#EXT-X-I-FRAME-STREAM-INF
格式:
#EXT-X-I-FRAME-STREAM-INF:<attribute-list>
- 用于指定一个Media Playlist包含媒体的I-frames。
- 需要放到master playlist中。
所以,根据前面index.m3u8的内容,wget可以下载#EXT-X-MEDIA
和#EXT-X-STREAM-INF
指定的几个playlist,下面对video-avc1-1.m3u8文件进行分析。
video-avc1-1.m3u8
完整文件内容如下:
#EXTM3U
# Created with Bento4 mp4-dash.py, VERSION=1.8.0-628
#
#EXT-X-VERSION:6
#EXT-X-PLAYLIST-TYPE:VOD
#EXT-X-INDEPENDENT-SEGMENTS
#EXT-X-TARGETDURATION:3
#EXT-X-MEDIA-SEQUENCE:0
#EXT-X-MAP:URI="media/svk-v001-video-avc1-1.mp4",BYTERANGE="703@0"
#EXTINF:2.002000,
#EXT-X-BYTERANGE:89897@831
media/svk-v001-video-avc1-1.mp4
#EXTINF:2.002000,
#EXT-X-BYTERANGE:74432@90728
media/svk-v001-video-avc1-1.mp4
#EXTINF:2.002000,
#EXT-X-BYTERANGE:72291@165160
media/svk-v001-video-avc1-1.mp4
#EXTINF:2.002000,
#EXT-X-BYTERANGE:72208@237451
media/svk-v001-video-avc1-1.mp4
#EXTINF:2.002000,
#EXT-X-BYTERANGE:72240@309659
media/svk-v001-video-avc1-1.mp4
#EXTINF:2.002000,
#EXT-X-BYTERANGE:72327@381899
media/svk-v001-video-avc1-1.mp4
#EXTINF:2.002000,
#EXT-X-BYTERANGE:73078@454226
media/svk-v001-video-avc1-1.mp4
#EXTINF:0.959292,
#EXT-X-BYTERANGE:62608@527304
media/svk-v001-video-avc1-1.mp4
#EXT-X-ENDLIST
其中文件头部分如下:
#EXT-X-VERSION:6
#EXT-X-PLAYLIST-TYPE:VOD
#EXT-X-INDEPENDENT-SEGMENTS
#EXT-X-TARGETDURATION:3
#EXT-X-MEDIA-SEQUENCE:0
#EXT-X-VERSION
- 版本号,前面已经说过,标示m3u8文件的版本号
#EXT-X-PLAYLIST-TYPE
:
格式:
#EXT-X-PLAYLIST-TYPE:<EVENT|VOD>
- EVENT:表示服务器不能改变或是删除PlayList文件中的任何部分,但是可以向该文件中增加新的一行内容
- VOD:表示播放列表不可变,服务器不能改变PlayList文件。
#EXT-X-INDEPENDENT-SEGMENTS
格式:
#EXT-X-INDEPENDENT-SEGMENTS
- 本标签标明,一个分片可以独立解码而不需要其他分片的信息,本选项作用于列表文件中的所有项目。
#EXT-X-TARGETDURATION
格式:
#EXT-X-TARGETDURATION:<s>
- 指定最大的媒体段时间长,S是一个以秒为单位的整数。
#EXT-X-MEDIA-SEQUENCE
格式:
#EXT-X-MEDIA-SEQUENCE:<Number>
- 每一个media URI在PlayList中只有唯一的序号,相邻之间序号+1
#EXT-X-MAP
格式:
#EXT-X-MAP:<attribute-list>
- 这个字段是视频的初始化片段,简而言之,有了这个字段,说明后续的每一个分片文件必须和通过这个初始化片段才能完整解读,
- 前面m3u8中URI说明后续的每一个分片都需要这个svk-v001-video-avc1-1.mp4才能真正解码播放出来。
- 主要目的:
- 为了安全
- 为了节省存储空间
- 为了减少切片, 减少切片服务器的工作量
#EXTINF
- 表示每个视频分片时长的标签。
格式:
#EXTINF:<duration>,[<title>]
- 每一个Media Segment的duration通过**#EXTINF** tag 指定。
- DURATION:表示其后媒体切片的时长(单位为秒),每个媒体切片之前必须指定该标签。
- 行内逗号后边的剩余部分是媒体文件的名字,该名字是媒体分片的人眼可读的信息标题。
#EXT-X-BYTERANGE
- 表示指定媒体切片是其后 URI 指定的媒体资源的一部分。
格式:
#EXT-X-BYTERANGE:<n>[@o]
uri
- 其中n表示这个区间的大小,o表在URI中的offset
- 在前面的代码中,只有media/svk-v001-video-avc1-1.mp4一个分片文件,第一个指定的分片是从文件的831位置开始读89897字节长度的数据; 第二个指定的分片是从文件的的90728位置开始读74432长度的数据。
- 这个标签在M3U8版本号4.0及以上才有。
#EXT-X-ENDLIST
- 表示 m3u8 文件结束的标签。
格式:
#EXT-X-ENDLIST
- 该标签一般会用在 m3u8 文件的最后一行,也是用来区分某个 m3u8 文件是用于点播场景还是直播场景的标识。点播场景中的 m3u8 文件包行 EXT-X-ENDLIST 标签,直播场景中的 m3u8 文件没有 EXT-X-ENDLIST 标签。
audio-en-dtse.m3u8
这个文件是audio的文件,在master playlist文件中通过#EXT-X-MEDIA
标签指定,文件中用到的标签在前面都有了。所以这里不做展开。
#EXTM3U
# Created with Bento4 mp4-dash.py, VERSION=1.8.0-628
#
#EXT-X-VERSION:6
#EXT-X-PLAYLIST-TYPE:VOD
#EXT-X-INDEPENDENT-SEGMENTS
#EXT-X-TARGETDURATION:3
#EXT-X-MEDIA-SEQUENCE:0
#EXT-X-MAP:URI="media/svk-v001-audio-en-dtse.mp4",BYTERANGE="609@0"
#EXTINF:1.962667,
#EXT-X-BYTERANGE:94400@737
media/svk-v001-audio-en-dtse.mp4
#EXTINF:2.048000,
#EXT-X-BYTERANGE:98500@95137
media/svk-v001-audio-en-dtse.mp4
#EXTINF:1.962667,
#EXT-X-BYTERANGE:94400@193637
media/svk-v001-audio-en-dtse.mp4
#EXTINF:2.048000,
#EXT-X-BYTERANGE:98500@288037
media/svk-v001-audio-en-dtse.mp4
#EXTINF:1.962667,
#EXT-X-BYTERANGE:94400@386537
media/svk-v001-audio-en-dtse.mp4
#EXTINF:2.048000,
#EXT-X-BYTERANGE:98500@480937
media/svk-v001-audio-en-dtse.mp4
#EXTINF:1.962667,
#EXT-X-BYTERANGE:94400@579437
media/svk-v001-audio-en-dtse.mp4
#EXTINF:1.024000,
#EXT-X-BYTERANGE:49436@673837
media/svk-v001-audio-en-dtse.mp4
#EXT-X-ENDLIST