如何进行 M3U8 的解密

Posted on Wed, 25 Dec 2024 10:17:01 +0800 by LiangMingJian


M3U8 的解密

在 M3U8 文件中,存在一些加密文件。要从这些加密文件中获取并下载真实的视频文件,需要进行解密。对应的密钥通常也记录在 M3U8 文件。

如下述 M3U8 文件,注意头信息中第五行内容:#EXT-X-KEY,这行内容指明了文件的加密方式与钥匙所在。

  • METHOD=AES-128:文件使用 AES-128 进行加密。
  • URI= 。。。:密钥需要从这个链接中进行下载。需要注意的是,有时这里会把路径省略写成 URI="key.key"。此时,用户需要根据 M3U8 的下载路径进行补充。比如文件从 http://www.example.com/example.m3u8 下载,那么密钥链接就是http://www.example.com/key.key
#EXTM3U
#EXT-X-VERSION:3
#EXT-X-TARGETDURATION:13
#EXT-X-MEDIA-SEQUENCE:0
#EXT-X-KEY:METHOD=AES-128,URI="http://www.example.com/key.key"
#EXTINF:12.5,
http://www.example.com/GBDYO3576000.ts
#EXTINF:12.5,
http://www.example.com/GBDYO3576001.ts
#EXTINF:12.5,
http://www.example.com/GBDYO3576002.ts

PS:有时 M3U8 文件会出现嵌套,这时建议手动进行下载,直到出现携带真实信息的文件

使用 Python 解密

import requests
from Cryptodome.Cipher import AES

class M3U8:

    _ivx16 = b'0000000000000000'

    def _aes(self, key: bytes, data: bytes):
        # 获取 aes 对象
        cipher_key = AES.new(key, AES.MODE_CBC, self._ivx16)
        # 解密
        decrypt_data = cipher_key.decrypt(data)
        return decrypt_data

    def download(self, base_url: str, ts_list: list, file_name: str, key=None):
        """
        Args:
          base_url: 路径前缀,比如 http://example.com/
          ts_list: ts 文件路径列表,比如 123456.ts
          file_name: 输出文件名
          key: 解密钥匙
        """
        for each in ts_list:
            while True:
                try:
                    content = requests.get(base_url + each, timeout=5).content
                    break
                except BaseException as e:
                        print(e)
            if key:
                content = self._aes(key, content)
            with open(file_name, 'ab+') as file:
                file.write(content)
            time.sleep(1)
        return 0
参考文件 1: 爬虫:解决视频遇到 m3u8 加密