前几天想把某视频网站上的视频下载到本地,然后发现该视频网站上的视频被切成了数千个ts文件,并且ts的文件列表中,记录着有key、IV,也就是视频会被网页上的播放器获取,然后在本地完成解密,才显示给用户看,然后自己就写了个小工具,把该网站上所有视频分段都下载到本地,然后完成解密,然后用FFmpeg将ts格式合成mp4格式文件。
后来某次又遇到另外一个网站,发现视频播放的原理也是一样的,网页播放器从服务器获取ts文件清单,然后清单中包含了解密用key和IV,于是就打算把解密方式写成一个方法以供大家以后方便使用。
此处需要安装python的pycrypto库,这个库安装起来似乎不容易,但是因为是以前就装了,细节不再赘述。
此处还是用python调用FFmpeg直接在代码中实现视频合并功能,我试了一下,此方法在windows、Mac下都生效,只要注意好本地保存目录不能用中文字符,一般都没有问题。
以下是下载并解密ts文件的代码
from Crypto.Cipher import AES
import re
import requests
def getVideoFile(directdir:str,url:str,key:str,IV:str)->str:
"""用于下载视频并完成解密
:param directdir: 保存文件的目录
:param url:下载的地址
:param key:ts文件的key
:param IV:ts文件加密的IV向量
:return:
"""
print('准备从',url,'下载文件到',directdir)
# 下载注意开启流
r=requests.get(url,stream=True)
# 从请求头文件中获取文件名
fileNameOriginal=r.headers['Content-Disposition']
searchObj=re.search(r'filename=".+"',fileNameOriginal)
fileName=''
if searchObj:
fileNameMatch=searchObj.group().split('"')
fileName=fileNameMatch[1]
newdir=directdir+"/"+fileName
#开始构建解密方法
mode = AES.MODE_CBC
cryptor=AES.new(key.encode('utf-8'),mode,IV)
with open(newdir,'wb') as f:
f.write(cryptor.decrypt(r.content))
print(newdir,'文件下载成功')
return newdir
将下载好的ts文件的列表保存在一个txt格式文件里。
import os
def creatFile(fileContent:str,path:str,filename=''):
"""保存下载好的文件的储存地址,便于后文中用FFmpeg进行文件合并
:param fileContent: 需要保存的内容
:param path: 保存的地址
:param filename:保存的文件名
:return:
"""
if filename!='':
path=path+os.sep+filename
file = open(path, 'w')
for line in fileContent:
file.write(line)
file.write('\n')
file.close()
假如你的电脑已经安装了FFmpeg了,并且也下载好了ts格式文件了,并且将所有需要合并成一个mp4格式的ts文件地址存在一个txt文件里了(后文用videoOrder.txt)。那么久可以执行以下代码
import os
def mergeFile(file_path,outputfile):
"""用于合并ts文件为一个mp4文件,前提是电脑里安装FFmpeg
:param file_path: 保存ts文件地址列表的txt所在文件夹,转好格式的文件也会保存在这个目录下
:param outputfile: mp4格式文件名
:return:
"""
print("开始合并文件")
str = r'ffmpeg -y -f concat -safe 0 -i '+ file_path +'\\videoOrder.txt -c copy '+ file_path +'\\'+ outputfile + '.mp4'
print(str)
os.system(str)
print("文件合并完成")
最后,下载完视频并完成合并后,本地会留有很多ts格式文件,留着没用纯粹浪费空间,在对应目录下创建一个bat格式文件,保存一下内容,然后执行一下就好了。(批量删除文件有风险哈)
del /a /f /s /q "*.ts"