这些协议真正要弄懂挺不容易,这里就记一下我能理解的部分。每部分的参考链接都放在最开头了。

HLS

https://blog.csdn.net/m0_60259116/article/details/124298016

服务器先把视频切片,切成.ts文件。

服务器把Media PlayList发给客户端。Media PlayList相当于索引,保存了.ts文件的位置。Media PlayList就是m3u8文件。一个视频,有不同的m3u8,对应不同的分辨率和比特率(如720p,1080p)。

Master PlayList保存了Media PlayList的位置。Master PlayList也是m3u8文件。

image-20230516210208873.png

media playlist文件格式

样例:

#EXTM3U
#EXT-X-VERSION:3
#EXT-X-PLAYLIST-TYPE:VOD
#EXT-X-TARGETDURATION:11
#EXTINF:10.000,
url_462/193039199_mp4_h264_aac_hd_7.ts
#EXTINF:10.000,
url_463/193039199_mp4_h264_aac_hd_7.ts
#EXTINF:10.000,
url_464/193039199_mp4_h264_aac_hd_7.ts
#EXTINF:10.000,
url_465/193039199_mp4_h264_aac_hd_7.ts
#EXTINF:10.000,
url_466/193039199_mp4_h264_aac_hd_7.ts
#EXTINF:10.000,
url_467/193039199_mp4_h264_aac_hd_7.ts
#EXTINF:10.000,
url_468/193039199_mp4_h264_aac_hd_7.ts
#EXTINF:9.950,
url_469/193039199_mp4_h264_aac_hd_7.ts
#EXTINF:10.050,
url_470/193039199_mp4_h264_aac_hd_7.ts
#EXTINF:10.000,
url_471/193039199_mp4_h264_aac_hd_7.ts
#EXTINF:10.000,
url_472/193039199_mp4_h264_aac_hd_7.ts
#EXT-X-ENDLIST

M3U8 文件的每行的内容只能是以下三种中的其中一种。

除了明确指定的元素之外不能有空格的存在。

以字符“#”开头的行要么是注释,要么是标签。标签以 #EXT 开头,大小写敏感。其他以“#”开头的行都是注释,客户端解析时应该忽略掉。

master playlist文件格式

样例

#EXTM3U
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=2149280,CODECS="mp4a.40.2,avc1.64001f",RESOLUTION=1280x720,NAME="720"
url_0/193039199_mp4_h264_aac_hd_7.m3u8
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=246440,CODECS="mp4a.40.5,avc1.42000d",RESOLUTION=320x184,NAME="240"
url_2/193039199_mp4_h264_aac_ld_7.m3u8
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=460560,CODECS="mp4a.40.5,avc1.420016",RESOLUTION=512x288,NAME="380"
url_4/193039199_mp4_h264_aac_7.m3u8
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=836280,CODECS="mp4a.40.2,avc1.64001f",RESOLUTION=848x480,NAME="480"
url_6/193039199_mp4_h264_aac_hq_7.m3u8
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=6221600,CODECS="mp4a.40.2,avc1.640028",RESOLUTION=1920x1080,NAME="1080"
url_8/193039199_mp4_h264_aac_fhd_7.m3u8

下载视频

这个站开启了 F12自动debug,F12下无法操作页面。操作页面是为了让视频在F12打开状态下播放,方便抓到m3u8。

image-20230516214313557.png
开启这个即可:

image-20230516214410827.png

开启后,F5刷新,视频从头播放。

image-20230516215251818.png
可以看到抓到了m3u8 ↑

有两个m3u8文件:

第一个:

image-20230516220503191.png
image-20230516220050367.png
第二个:

image-20230516220533010.png
image-20230516220054971.png
ts文件名有了,url在哪?看看两个m3u8文件的请求头。第一个m3u8保存第二个m3u8的位置,用的相对路径。第二个m3u8用的应该也是相对路径,所以ts文件放在:

https://cdn14.yzzy-tv-cdn.com/20230110/1013_f4def608/1000k/hls/989d9f248d9000000.ts

访问直接下载:

image-20230516221028930.png
打开就是一个几秒的视频:

image-20230516221059002.png

到时候写脚本批量下载,然后用ffmpeg合并即可

MPEG-DASH

https://juejin.cn/post/7025202048765263886

https://blog.csdn.net/DeliaPu/article/details/79013812

https://blog.csdn.net/qq_31813549/article/details/100132269

DASH (Dynamic Adaptive Streaming over HTTP)

MPD文件

MPD (Media Presentation Description)。本质上是xml文件

<Period>
<AdaptationSet>
<Representation>
<SegmentBase>
</SegmentBase>
</Representation>

<Representation>
<SegmentBase>
</SegmentBase>
</Representation>
</AdaptationSet>

<AdaptationSet>
<Representation>
<SegmentBase>
</SegmentBase>
</Representation>
</AdaptationSet>
</Period>

<Period>
...
</Period>

说实话SegmentBase我不是很理解,List和Template都好理解。

image-20230517161847111.png

一个完整的MPD文件:

MPD.jpg

下B站视频

参考上面链接里面的。

播放视频抓包没抓到MPD文件,看源码,有一个dash,是个json。这个json作用就相当于MPD文件,格式也是一样的。

video和audio都是列表(Adaptation Set),分别保存了不同版本的视频和音频(Representation):

image-20230517163647913.png
image-20230517163719915.png

video和audio是分别请求的,且按字节切片。如A.m4s表示视频,请求时带上请求头Range: 0-8000,表示只取这个量的字节,响应头Byte Range: 0-8000/15556122,告诉客户端,这次拿了哪部分字节,一共有多少字节,客户端再根据这个响应头确定下一次请求头。请求音频时也是一样的道理。

image-20230517164647087.png

直接访问这个m4s,会提示403,需要带上原来的Referer请求头。不带Range请求头,默认传过来的就是完整视频。

image-20230517165152855.png

只有一个视频是没声音的,还需要下音频文件,再用ffmepg合并起来。