HLS视频格式剖析(一)基础介绍一文中介绍了HLS的基本字段, 但是要想深入了解HLS, 光了解基本字段是不够,本文带你了解一下HLS的高级字段,让你对HLS有更深的理解.
EXT-X-BYTERANGE
我们知道M3U8需要切片,但是有时候我们不想切片(为什么? 我比较懒), 我只想用一个ts来构建一个类似M3U8的分片索引, 这时候EXT-X-BYTERANGE就派上用场了. 表达的格式如下:
#EXT-X-BYTERANGE:<length>[@<offset>]
其中length表示range的长度, offset表示这个range从分片的什么位置开始读. 据一个例子吧:
#EXTM3U
#EXT-X-TARGETDURATION:11
#EXT-X-MEDIA-SEQUENCE:0
#EXT-X-VERSION:4
#EXTINF:9.009,
#EXT-X-BYTERANGE:12345@0
media.ts
#EXTINF:9.009,
#EXT-X-BYTERANGE:82112@12345
media.ts
#EXTINF:3.003,
#EXT-X-BYTERANGE:69864
media.ts
#EXT-X-ENDLIST
这个M3U8索引文件中,只有media.ts一个分片文件,这个文件可能很大, 第一个指定的分片是从media.ts的0位置开始读12345长度的数据; 第二个指定的分片是从media.ts的12345位置开始读82112长度的数据;第三个没有指定offset, 那么默认从上一个指定分为的结束处开始读. 当然只有VERSION版本不低于4才可以应用这个属性
EXT-X-KEY
M3U8索引文件中有了#EXT-X-KEY 字段,说明当前的M3U8视频片段可能被加密了.这一行是告诉你应该怎么解密这些视频分片. 表达的格式如下:
#EXT-X-KEY:<attribute-list>
这个属性列表中有如下几个字段:
- METHOD 这个是一个枚举值,可以为NONE, AES-128, SAMPLE-AES NONE表述分片并没有被加密,其他的属性集就没有必要出现了,后面介绍如何解密
- URI 密钥的地址存放的地方,也是一个url
- IV 该值是一个十六进制序列, 它指定要与密钥一起使用的128位无符号整数初始化向量
- KEYFORMAT 这个密钥的格式, 可选字段, 默认情况下是"identity", 主要是加强数字证书校验安全性设定的.
M3U8加密和解密非常重要, 是M3U8的优势之一, 毕竟现代社会越来越注重安全,版权意识也非常重要. 解密的流程需要专门写一篇文章介绍了.
EXT-X-MAP
这个字段是视频的初始化片段, 简而言之,有了这个字段,说明后续的每一个分片文件必须和通过这个初始化片段才能完整解读,缺少这个初始化片段, M3U8视频根本播放不了. 表达的格式如下:
#EXT-X-MAP:<attribute-list>
这个属性集有下面这些字段:
- URI 初始化片段的地址, 这个信息是必须的.
- BYTERANGE 这个可以参考 #EXT-X-BYTERANGE 字段
给大家据一个例子: europe.olemovienews.com/hlstimeofff… 其中有一行:
#EXT-X-MAP:URI="init-v1-a1.mp4"
说明后续的每一个分片都需要这个init-v1-a1.mp4才能真正解码播放出来: 取出第一个分片:europe.olemovienews.com/hlstimeofff…
ffprobe version 4.2.4-1ubuntu0.1 Copyright (c) 2007-2020 the FFmpeg developers
built with gcc 9 (Ubuntu 9.3.0-10ubuntu2)
configuration: --prefix=/usr --extra-version=1ubuntu0.1 --toolchain=hardened --libdir=/usr/lib/x86_64-linux-gnu --incdir=/usr/include/x86_64-linux-gnu --arch=amd64 --enable-gpl --disable-stripping --enable-avresample --disable-filter=resample --enable-avisynth --enable-gnutls --enable-ladspa --enable-libaom --enable-libass --enable-libbluray --enable-libbs2b --enable-libcaca --enable-libcdio --enable-libcodec2 --enable-libflite --enable-libfontconfig --enable-libfreetype --enable-libfribidi --enable-libgme --enable-libgsm --enable-libjack --enable-libmp3lame --enable-libmysofa --enable-libopenjpeg --enable-libopenmpt --enable-libopus --enable-libpulse --enable-librsvg --enable-librubberband --enable-libshine --enable-libsnappy --enable-libsoxr --enable-libspeex --enable-libssh --enable-libtheora --enable-libtwolame --enable-libvidstab --enable-libvorbis --enable-libvpx --enable-libwavpack --enable-libwebp --enable-libx265 --enable-libxml2 --enable-libxvid --enable-libzmq --enable-libzvbi --enable-lv2 --enable-omx --enable-openal --enable-opencl --enable-opengl --enable-sdl2 --enable-libdc1394 --enable-libdrm --enable-libiec61883 --enable-nvenc --enable-chromaprint --enable-frei0r --enable-libx264 --enable-shared
libavutil 56. 31.100 / 56. 31.100
libavcodec 58. 54.100 / 58. 54.100
libavformat 58. 29.100 / 58. 29.100
libavdevice 58. 8.100 / 58. 8.100
libavfilter 7. 57.100 / 7. 57.100
libavresample 4. 0. 0 / 4. 0. 0
libswscale 5. 5.100 / 5. 5.100
libswresample 3. 5.100 / 3. 5.100
libpostproc 55. 5.100 / 55. 5.100
[mov,mp4,m4a,3gp,3g2,mj2 @ 0x55fd8bd5ff00] could not find corresponding trex (id 1)
[mov,mp4,m4a,3gp,3g2,mj2 @ 0x55fd8bd5ff00] could not find corresponding track id 0
[mov,mp4,m4a,3gp,3g2,mj2 @ 0x55fd8bd5ff00] trun track id unknown, no tfhd was found
[mov,mp4,m4a,3gp,3g2,mj2 @ 0x55fd8bd5ff00] error reading header
https://europe.olemovienews.com/hlstimeofffmp4/20210226/fICqcpqr/mp4/fICqcpqr.mp4/seg-1-v1-a1.m4s: Invalid data found when processing input
这是因为光解析第一个分片是不行的,因为真正的视频头部信息在init-v1-a1.mp4中.
EXT-X-I-FRAMES-ONLY
这个字段表示每个片段只有一个I帧, I帧是什么大家应该很清楚, 音音视频的兄弟们, 为什么会出现这个字段? 如果做过视频特效处理的同学应该很清楚, 处理视频的时候,如果都是I帧,那么特效/反转/快进/快退非常方便.
当然实际上M3U8上用到 #EXT-X-I-FRAMES-ONLY并不多, 大家了解即可.
EXT-X-MEDIA
这个字段表示针对同一个内容的不同角度的演绎, 例如同一段视频有视频/音频/字幕, 甚至还不止一个音频轨道, 很有很多种语言的字幕, 一段视频有这么多信息, #EXT-X-MEDIA 就是干这个的. 表达的格式如下:
#EXT-X-MEDIA:<attribute-list>
属性集有下面的字段:
- TYPE 这是一个枚举值, 可以是AUDIO, VIDEO, SUBTITLES, CLOSED-CAPTIONS, 这个字段是必须的.
- URI 数据源的url, 如果TYPE是CLOSED-CAPTIONS, URI就没有了
- GROUP-ID 表示源属于的组ID, 这只是一个标识
- DEFAULT YES 或者 NO
- AUTOSELECT YES 或者 NO 举个例子:
#EXTM3U
#EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID="test_audio",LANGUAGE="eng",NAME="Test Audio",AUTOSELECT=NO,DEFAULT=NO,URI="test_audio_aac/index.m3u8"
#EXT-X-MEDIA:TYPE=SUBTITLES,GROUP-ID="subs",NAME="English",DEFAULT=YES,AUTOSELECT=YES,FORCED=NO,LANGUAGE="en",CHARACTERISTICS="public.accessibility.transcribes-spoken-dialog, public.accessibility.describes-music-and-sound",URI="subtitles/eng/index.m3u8"
#EXT-X-STREAM-INF:BANDWIDTH=263851,CODECS="mp4a.40.2, avc1.4d400d",RESOLUTION=416x234,AUDIO="test_audio",SUBTITLES="subs"
high_test/index.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=41457,CODECS="mp4a.40.2",AUDIO="test_audio",SUBTITLES="subs"
middle_test/index.m3u8
HLS例子
1.HLS基础例子:
#EXTM3U
#EXT-X-TARGETDURATION:10
#EXT-X-VERSION:3
#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
2.直播的例子:
#EXTM3U
#EXT-X-VERSION:3
#EXT-X-TARGETDURATION:8
#EXT-X-MEDIA-SEQUENCE:2680
#EXTINF:7.975,
https://priv.example.com/fileSequence2680.ts
#EXTINF:7.941,
https://priv.example.com/fileSequence2681.ts
#EXTINF:7.975,
https://priv.example.com/fileSequence2682.ts
3.master HLS的例子:
#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
4.EXT-X-MEDIA例子:
#EXTM3U
#EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID="aac",NAME="English", \
DEFAULT=YES,AUTOSELECT=YES,LANGUAGE="en", \
URI="main/english-audio.m3u8"
#EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID="aac",NAME="Deutsch", \
DEFAULT=NO,AUTOSELECT=YES,LANGUAGE="de", \
URI="main/german-audio.m3u8"
#EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID="aac",NAME="Commentary", \
DEFAULT=NO,AUTOSELECT=NO,LANGUAGE="en", \
URI="commentary/audio-only.m3u8"
#EXT-X-STREAM-INF:BANDWIDTH=1280000,CODECS="...",AUDIO="aac"
low/video-only.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=2560000,CODECS="...",AUDIO="aac"
mid/video-only.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=7680000,CODECS="...",AUDIO="aac"
hi/video-only.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=65000,CODECS="mp4a.40.5",AUDIO="aac"
main/english-audio.m3u8