目前,多数流媒体网站都使用了HLS或DASH技术来部署Stream或VOD业务,本文简单记录下一个HLS VOD视频的手动抓取流程以备忘。
HLS简介
HLS视频通常以TS格式封装,视频流编码为H.264,音频流编码为AAC、MP3、AC-3或EC-3。
服务器会将不同分辨率及码率的视频流、音频流切割为许多等时长的小segments推送给客户端,在此之前客户端需要接收m3u8格式的索引文件。
m3u8索引文件
以音泉为例。
播放一个视频,可以在浏览器的F12-Network中看到客户端接收到了两个m3u8文件:playlist.m3u8与chunklist.m3u8。
playlist.m3u8中,可以看到形如以下字段:
#EXT-X-STREAM-INF:BANDWIDTH=125587,CODECS="mp4a.40.2"
chunklist.m3u8`
这里的意思是:这个视频包含了如下码率及编码格式的音频流(码率未必是真实的),实际的segments索引文件是chunklist.m3u8。
再看chunklist.m3u8。
#EXT-X-KEY:METHOD=AES-128,URI="https://onsen-ma3phlsvod.sslcs.cdngc.net/onsen-ma3pvod/_definst_/mp4:202107/aquatope210702x3ki-1.mp4/key.m3u8key"
EXT-X-KEY是非常重要的字段,这里记录了这个HLS视频的加密方式与key,之后解密视频需要用到。
METHOD是加密方式,最常见的是AES-128-CBC。
URI记录了key文件的链接,这里也可以直接是明文key,长度为16字节。
通常情况下还会有一个16字节的IV字段,URL链接或明文都有可能,记录了初始偏移量,但不是必需。
获取到key文件后,利用winhex等十六进制编辑工具打开即可获取32个字符的key。
#EXTINF:10.0,
media_0.aac
#EXTINF:10.0,
media_1.aac
#EXTINF:10.0,
media_2.aac
……
#EXTINF:10.0,
media_228.aac
#EXTINF:8.381,
media_229.aac
#EXT-X-ENDLIST
这里就记录了segments的文件名,通常情况下序号是不断+1的,可以用通配符替换方便批量下载(遇到奇怪的字符善用HTML转义)
以上是一个简单的m3u8嵌套,通常情况下playlist中也不会只有一种码率,更简单的情况是只会有一个索引文件。
常见的障碍是视频网站会用各种方式隐藏key,这里就需要通过链接等各种方式观察播放视频后接收到的类似授权文件,例如U-NEXT这个网站,key就藏在某个文件的末尾。
视频抓取与解密
1.抓取
抓取通常不会有障碍,通过浏览器F12-Networks工具查看媒体文件链接,利用任意批量下载软件搭配通配符即可抓取下所有segments,例如IDM或shua。
2.合并
抓取下来的是许多segments,这里可以使用Windows自带的copy命令进行二进制连接。
假设segments文件名为:media_0.aac、media_1.aac……media_100.aac。
为了copy命令能够正确识别序号的先后顺序,首先需要用任意批量重命名工具将文件名的序号部分重命名为等长度,如:media_000.aac、media_001.aac……media_100.aac。
然后在cmd中加载到segments存储目录,使用命令:
copy /b media_*.aac media.aac
其中,序号改为通配符,media.aac为输出文件名。这样就得到了被加密的完整音频。
3.解密
这里要用到openssl,自行编译或下载已编译可执行文件加入系统环境变量。
随后cmd定位到待解密文件的目录,执行以下命令:
openssl aes-128-cbc -d -in %oriname% -out %name% -nosalt -iv %iv% -K %key%
%oriname%为待解密文件名,%name%为解密后的输出文件名,%iv%为IV值,没有则填0,%key%为key值。
执行完毕后即可在同文件夹下生成解密后的音频。
以上就是手动抓取并解密HLS VOD视频的流程。
显然这些都可以自动化完成,事实上也有非常多的工具,最简单的利用FFmpeg通常就可以一键下载合并解密,或者手动抓取所有文件到同一文件夹后利用FFmpeg合并解密(可能需要修改m3u8文件)。但需要注意的是一些视频网站的m3u8、segments、key文件可能是需要账号cookies鉴权的,也有可能每次播放都不一样,具体情况具体分析,下载到本地再解密是最稳妥的办法。