前言

网络上的很多视频是m3u8流媒体格式的,有的加密了有的没有加密,手机浏览器比如UC和QQ浏览器都支持将视频缓存到本地

qq浏览器可以下载m3u8

将视频文件导入到电脑,可以看到文件结构是这样的:
m3u8文件和数据文件夹在同一路径,m3u8文件中有加密方式,key的路径,所有的视频路径,但是是手机的绝对路径,电脑上无法播放

深度截图_选择区域_20190918231537.png

m3u8文件内容

可以看到小视频从0编号到11735,一共有11736个加密视频文件

数据文件夹中内容

数据文件夹中的视频全部加密了,所以无法播放
咱们看看,文件夹中一共有11738个文件,除去加密视频11736个,还有一个0-decrypted是0号文件解密后的视频文件,可能是用于验证解密是否出错的,还有一个就是key文件了,key文件就是一个文本文件

notepadqq打开key文件

安装python环境和Crypto.Cipher加密解密模块

为什么不用python2,因为python2到2020年就会停止支持,而且我python2运行通不过
sudo apt-get install python3
安装pip,这是python3的pip
sudo 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还是慢啊),转换成功!!可以正常播放!!!

标签: linux, deepin, aes加密, 解密, m3u8, Crypto.Cipher, python

赞赏排名 赞赏支持

添加新评论