对加密的m3u8离散视频文件进行解密合并(python deepin linux)
前言
网络上的很多视频是m3u8流媒体格式的,有的加密了有的没有加密,手机浏览器比如UC和QQ浏览器都支持将视频缓存到本地
将视频文件导入到电脑,可以看到文件结构是这样的:
m3u8文件和数据文件夹在同一路径,m3u8文件中有加密方式,key的路径,所有的视频路径,但是是手机的绝对路径,电脑上无法播放
可以看到小视频从0编号到11735,一共有11736个加密视频文件
数据文件夹中的视频全部加密了,所以无法播放
咱们看看,文件夹中一共有11738个文件,除去加密视频11736个,还有一个0-decrypted是0号文件解密后的视频文件,可能是用于验证解密是否出错的,还有一个就是key文件了,key文件就是一个文本文件
安装python环境和Crypto.Cipher加密解密模块
为什么不用python2,因为python2到2020年就会停止支持,而且我python2运行通不过sudo apt-get install python3
安装pip,这是python3的pipsudo apt-get install python3-pip
用pip3来安装Crypto模块sudo pip3 install crypto
我的电脑是deepin15.11可以正常安装crypto,没有出现网上说的找不到包(pip源在国外网速不行的话另说)
编写脚本实现解密
导入模块和python脚本文件头
#!/usr/bin/env python3
# -*- coding:utf-8 -*-
#加密解密模块
from Crypto.Cipher import AES
#sys模块,用于获得命令行参数
import sys
将key值读取,默认为str类型,而AES.new接受的参数为bytes类型的,因此必须用encode转换
#获得key值,ase128就是16位的key
key='13785608eadfdbbf'
#根据key创建解密对象,python3中使用encode将str转为bytes,否则AES.new报错
cryptor = AES.new(key.encode('utf-8'), AES.MODE_CBC,key.encode('utf-8'))
#打开file合并视频文件,没有则创建
with open(outfile, 'ab') as file:
打开一个加密的小视频
with open(i, 'rb') as inf:
#读取加密视频数据
data=inf.read()
#解密数据并追加写入file中
file.write(cryptor.decrypt(data))
完善脚本,实现读取m3u8数据获取key和视频路径
困难的主要是正则表达式匹配获得key文件,视频文件路径,百度着写了一天
#!/usr/bin/env python3
# -*- coding:utf-8 -*-
#加密解密模块
from Crypto.Cipher import AES
#sys模块,用于获得命令行参数
import sys
#正则表达式模块
import re
#argv[1]:m3u8文件路径
#默认m3u8文件和视频数据文件夹应该在同一路径下
#key文件在数据文件夹中
with open(sys.argv[1]) as m3u8:
list=[]
keyp=absp=datadir=None
while 1:
line = m3u8.readline()
if re.match('#EXT-X-KEY',line) != None:
#正则表达式替换,获得key文件的路径
keyp='.'+re.sub('#EXT-X-KEY.*(/[^/]+/\w+)"','\g<1>',line)
#不知道为什么路径前面有空格,要去除
keyp=re.sub('\s|\n','',keyp)
#匹配获得绝对路径
absp=re.sub('#EXT-X-KEY.*?"(/.*/).*"','\g<1>',line)
#不知道为什么路径前面有空格,要去除
absp=re.sub('\s|\n','',absp)
#获得数据文件夹名字:“./xxx/”的形式
datadir=re.sub('(\./\w+/)\w+','\g<1>',keyp)
print(keyp,absp,datadir)
#break
if keyp and absp and re.match(absp,line):
#去除路径前缀
name=re.sub(absp,'',line)
#去除文件末尾的\n
name=re.sub('\n','',name)
#所有小视频名列表
list.append(name)
if not line:
break
#print(list)
#上面就获得了key和所有文件的路径,然后开始解密
#获得key值
with open(keyp) as keyfp:
key=keyfp.read()
#根据key创建解密对象,python3中使用encode将str转为bytes,否则报错
cryptor = AES.new(key.encode('utf-8'), AES.MODE_CBC,key.encode('utf-8'))
#首先打开大视频
with open(re.sub('.m3u8','.mp4',sys.argv[1]), 'ab') as file:
#循环对每个小视频解密并合并到大视频中
for i in list:
with open(datadir+i, 'rb') as inf:
data=inf.read()
file.write(cryptor.decrypt(data))
运行脚本
./decode.py 法制中国.m3u8
一万多个文件运行了几十秒(python还是慢啊),转换成功!!可以正常播放!!!