现在越来越多的视频网站用加密M3U8来保护内容,防止被轻易下载和传播。普通用户拿到一个加密链接,直接丢进播放器可能播不了,或者播出来是花屏。今天聊聊这背后的原理,以及我们能做些什么。
HLS标准支持AES-128加密。具体来说,视频TS切片在服务器端用AES-128-CBC模式加密,然后M3U8索引文件里多了一行标签,告诉播放器密钥在哪:
#EXT-X-KEY:METHOD=AES-128,URI="https://example.com/key.key"
播放器读到这行之后,会先去下载密钥文件,然后用这个密钥解密TS切片,最后才能正常播放。整个过程对用户是透明的,只要播放器能拿到密钥,你就感觉不到加密的存在。

问题通常出在密钥的获取环节。很多网站虽然把密钥URL写在了M3U8里,但对这个URL做了严格的防盗链限制:必须带特定的Cookie、Referer、或者必须在特定IP下才能访问。
你用VLC或者在线播放器打开M3U8,播放器虽然能读到密钥地址,但请求密钥的时候被服务器拒绝了,拿不到密钥,自然就解不了密,播放失败。
如果你知道需要带什么请求头,可以用支持自定义HTTP Header的播放器。比如nPlayer,可以在设置里手动添加Referer和User-Agent,模拟原网站的请求环境,有时候就能拿到密钥了。
VLC也能改User-Agent,但Referer不太好改,灵活性差一些。PotPlayer在这方面支持得也不够完善。所以遇到加密源,iOS用户上nPlayer,安卓用户试试MX Player Pro的网络设置。
如果你能把密钥文件下载下来,那就好办了。密钥文件一般就16个字节,拿到之后可以用FFmpeg或者Python脚本解密TS切片。
FFmpeg的方式前面讲过,它自动处理。如果是手动解密,OpenSSL一行命令搞定:
openssl aes-128-cbc -d -in encrypted.ts -out decrypted.ts -nosalt -K $(xxd -p key.key) -iv 初始化向量
不过初始化向量(IV)有时候在M3U8里指定,有时候默认用序列号。这个要看M3U8文件的具体写法,不能一概而论。
对于普通用户,我的建议是:如果链接打不开,先确认是不是加密导致的。如果是,而且你没有技术背景,那可能真的没办法。加密存在的意义就是阻止未授权访问,你能轻松绕过的话,说明它的加密做得太烂了。
大部分正规平台的加密都是多套防护措施一起上的,单纯改个请求头未必能解决问题。与其折腾,不如找找有没有官方提供的观看渠道。