使用python从m3u8解密.ts段

时间:2018-02-08 16:05:04

标签: python encryption aes m3u8

为什么我的代码没有解密ts段?

from Crypto.Cipher import AES
import requests as req
import os
import m3u8
with req.session() as req:
    m3u = m3u8.load('https://svt1-a.akamaized.net/se/svt1/d132b755-8088-475e-91df-2c8f2de9cf6c/hls-v6/v6.m3u8')
    key_url = m3u.keys[0].absolute_uri
    seg = m3u.segments[0].absolute_uri
    key = ''
    for chunk in req.get(key_url,stream=True):
        key+=chunk
    cipher = AES.new(key, AES.MODE_CBC, os.urandom(16))
    data = ''
    for chunk in req.get(seg, stream=True):
        data+=chunk
    data = cipher.decrypt(data)
    with open('ulk.ts','wb') as fil:
        fil.write(data)

m3u8网址是:

  

https://svt1-a.akamaized.net/se/svt1/d132b755-8088-475e-91df-2c8f2de9cf6c/hls-v6/v6.m3u8

来自m3u8的代码:

EXTM3U
#EXT-X-VERSION:4
#EXT-X-TARGETDURATION:4
#EXT-X-MEDIA-SEQUENCE:220662
#EXTINF:3.20000,
#EXT-X-KEY:METHOD=AES-128,URI="../key-d132b755-8088-475e-91df-2c8f2de9cf6c.ts"
v6-220662.ts
#EXTINF:3.20000,
v6-220663.ts
#EXTINF:3.20000,
v6-220664.ts
#EXTINF:3.20000,
v6-220665.ts
#EXTINF:3.20000,
v6-220666.ts
#EXTINF:3.20000,
v6-220667.ts
#EXTINF:3.20000,
v6-220668.ts
#EXTINF:3.20000,
v6-220669.ts
#EXTINF:3.20000,
v6-220670.ts
#EXTINF:3.20000,
v6-220671.ts

KeyString中:

  

'PB {\ XF1 \ xb9 \ xf9。\ XB7 \ X1D \ XEB \ X95 \ X8F = \ XCD \ X93 \ XCE'

1 个答案:

答案 0 :(得分:0)

对于你的小问题,我有一个完美的解决方案。 您的代码很棒,但需要一些小的修复 - 运行起来会很好。

Python venv:

 - python3 -m venv Your-Python-VEnviroment-Name-env
 - cd Your-Python-VEnviroment-Name-env
 - source bin/activate
  • 按照步骤 1..5
  • 停用

步骤 01:模块列表必须安装到 python venv 中:

 - python3 -m pip install m3u8
 - python3 -m pip install requests
 - python3 -m pip install pycryptodome

步骤 02:创建文件 GetSegments.py 步骤 03:用下面的代码框填充它

进口清单:

import os
import m3u8
import requests
from Crypto.Cipher import AES

设置一个自己的 RequestsClient 来让 https 工作。

class MyOwnReqClient():
    def download(self, uri, timeout=None, headers={}, verify_ssl=True):
        result = requests.get(uri, timeout=timeout, headers=headers)
        return result.text, result.url

使用您自己的 RequestsClient.Class 正确设置 m3u8.load。

#Other headers should you look at F12 ;-)
headers = {'host':'Your-Data-Here', 'User-Agent':'Your-Browser-User-Agent-Here-VERY-IMPORTANT'}
url = 'https://YOUR.URL.M3U8.Encrypted-ts-segments.HERE'
m3u = m3u8.load(url, http_client=MyOwnReqClient(), headers=headers)

正确设置关键变量。

key_url = m3u.keys[0].absolute_uri
key = []
for chunk in req.get(url=key_url,stream=True,headers=headers,method="get"):
    key.append(chunk)

为加密设置正确的 IV。

lines = str(m3u.segments[0]).split('\n')
IV = lines[0].split("IV=")[1]
#convert into bytes and remove the first 2 chars
IV = bytes.fromhex(IV.replace("0x",""))

初始化加密。

cipher = AES.new(key[0], AES.MODE_CBC, IV=IV)

至少你必须改变你的数据存储例程。

#Get each segment of m3u8-file        
for single_segment in m3u.segments:
    #Get correct URL for ts-file
    download_url = single_segment.absolute_uri

    #Counter 1..n
    num = 1

    #Write bytes into a file
    with open('Filename.part' + str(num) + '.ts', 'wb') as seg_ts:
        #Get all chunks of current part-file
        for chunk in requests.request(url=download_url, stream=True, headers=headers, method="get"):
            #decrypt it and write it into the file
            seg_ts.write(cipher.decrypt(chunk))

        #Counter increase for the next part number
        num += 1

步骤 04:保存文件并尝试。

第 5 步:python3 GetSegments.py

我希望它可以帮助您和所有其他人。 如果 python 脚本没有完成并且工作,我无法入睡。

我希望我没有错写错别字...;-)