python+FFmpeg实现对m3u8文件内的ts视频多线程下载、解密、合并成MP4,并输出。
作者:互联网
需求:把目标网站的电影下载到本地。
目标网站电影:《丛林奇航》电影完整版免费在线观看_天启影院
分析网站:
1,根据网页分析 该电影的m3u8是放在 index.m3u8里,网页里有两个 index.m3u8,选择第二个。(具体怎么分析网页,这里就不讨论了)
下载m3u8文件
# 下载m3u8
def down_m3u8(url):
resp = requests.get(url, headers)
text = resp.text
with open("丛林奇航.m3u8", "w") as f:
f.write(text)
print("丛林奇航.m3u8下载完成")
2,对下载下来的 m3u8 分析,这里会发现是有经过AES-128加密,ts视频下载后会无法播放,所以还需要进行解密。
采用多线程下载ts视频
# 采用线程池下载m3u8里的ts
def down_ts():
with open("./丛林奇航.m3u8", "r", encoding="utf-8") as f:
# n = 0
with ThreadPoolExecutor(10) as t:
for n, line in enumerate(f):
line = line.strip()
if line.startswith("#"):
continue
t.submit(ts_video, n, line)
# 下载ts视频 D:\\data\\movie_ts\\m1 为下载ts视频存放的路径
def ts_video(n, line):
# 下载视频
resp3 = requests.get(line)
with open(f"D:\\data\\movie_ts\\m1\\{n}.ts", "wb") as f:
f.write(resp3.content)
print(n, "下载完成")
3,这里下载好的视频是有经过加密的,无法在播放器是直接看,接下来就要对下载好的加密ts视频进行解密
解密ts视频
# 对下载t好的ts视频进行解密 D:\\data\\video\\m1\\ 为解密后ts存放的路径
def jiemi():
f = open("./丛林奇航.m3u8", "r", encoding="utf-8")
keys = []
for file in f:
key = re.findall(r'URI="(.*?)"', file) # 用正则匹配出 key
if key:
keys.append(key[0])
key_url = keys[0]
resp4 = requests.get(key_url)
key = resp4.text
key = key.encode("utf-8")
aes = AES.new(key=key, IV=b"0000000000000000", mode=AES.MODE_CBC)
download_path = "D:\\data\\movie_ts\\m1"
all_ts = os.listdir(download_path)
li = []
for i in all_ts:
i = i.split(".")[0]
li.append(int(i))
li.sort()
for i in li:
with open(f"D:\\data\\movie_ts\\m1\\{i}.ts", mode="rb") as f1, \
open(f"D:\\data\\video\\m1\\2000{i}.ts", mode="wb") as f2:
bs = f1.read()
f2.write(aes.decrypt(bs))
print(f"第{i}视频处理完毕")
解密好的ts视频
解密好的ts视频是可以直接用播放器看的
4,对解密好的ts视频用 ffmpeg合成MP4视频
这里需要先安装 ffmpeg
Windows:
1. 进入 http://ffmpeg.org/download.html#build-windows,点击 windows 对应的图标,进入下载界面点击 download 下载按钮,
2. 解压下载好的zip文件到指定目录
3. 将解压后的文件目录中 bin 目录(包含 ffmpeg.exe )添加进 path 环境变量中
4. DOS 命令行输入 ffmpeg -version, 出现以下界面说明安装完成:
Mac (打开终端(Terminal), 用 homebrew 安装):
brew install ffmpeg --with-libvorbis --with-sdl2 --with-theora
Linux:
apt-get install ffmpeg libavcodec-extra
ffmpeg合成MP4视频
# 对解密好的ts视频用 ffmpeg合成MP4视频
def movie_video():
filePath = "D:\\data\\video\\m1"
file_list = os.listdir(filePath)
li = []
for file in file_list:
file = file.split(".")[0]
li.append(int(file))
li.sort()
ts_file_name = []
for i in li:
i = str(i) + ".ts"
ts_file_name.append(i)
with open("D:\\data\\video\\m1\\file_list.txt", "w+") as f:
for file in ts_file_name:
f.write("file '{}'\n".format(file))
print("file_list.txt已生成")
txt_file = "D:\\data\\video\\m1\\file_list.txt"
mp4 = "D:\\data\\movies\\丛林奇航.mp4"
cmd = f"ffmpeg -f concat -i {txt_file} -c copy {mp4}"
try:
os.system(cmd)
except Exception as e:
print(e)
print("done")
全部参考代码如下:
import re
import time
import os
import requests
from Crypto.Cipher import AES
from concurrent.futures import ThreadPoolExecutor
# 下载m3u8
def down_m3u8(url):
resp = requests.get(url, headers)
text = resp.text
with open("丛林奇航.m3u8", "w") as f:
f.write(text)
print("丛林奇航.m3u8下载完成")
# 采用线程池下载m3u8里的ts
def down_ts():
with open("./丛林奇航.m3u8", "r", encoding="utf-8") as f:
# n = 0
with ThreadPoolExecutor(10) as t:
for n, line in enumerate(f):
line = line.strip()
if line.startswith("#"):
continue
t.submit(ts_video, n, line)
# 下载ts视频
def ts_video(n, line):
# 下载视频
resp3 = requests.get(line)
with open(f"D:\\data\\movie_ts\\m1\\{n}.ts", "wb") as f:
f.write(resp3.content)
# n += 1
print(n, "下载完成")
# 对下载t好的ts视频进行解密
def jiemi():
f = open("./丛林奇航.m3u8", "r", encoding="utf-8")
keys = []
for file in f:
key = re.findall(r'URI="(.*?)"', file)
if key:
keys.append(key[0])
key_url = keys[0]
resp4 = requests.get(key_url)
key = resp4.text
key = key.encode("utf-8")
aes = AES.new(key=key, IV=b"0000000000000000", mode=AES.MODE_CBC)
download_path = "D:\\data\\movie_ts\\m1"
all_ts = os.listdir(download_path)
li = []
for i in all_ts:
i = i.split(".")[0]
li.append(int(i))
li.sort()
for i in li:
with open(f"D:\\data\\movie_ts\\m1\\{i}.ts", mode="rb") as f1, \
open(f"D:\\data\\video\\m1\\2000{i}.ts", mode="wb") as f2:
bs = f1.read()
f2.write(aes.decrypt(bs))
print(f"第{i}视频处理完毕")
# 对解密好的ts视频用 ffmpeg合成MP4视频
def movie_video():
filePath = "D:\\data\\video\\m1"
file_list = os.listdir(filePath)
li = []
for file in file_list:
file = file.split(".")[0]
li.append(int(file))
li.sort()
ts_file_name = []
for i in li:
i = str(i) + ".ts"
ts_file_name.append(i)
with open("D:\\data\\video\\m1\\file_list.txt", "w+") as f:
for file in ts_file_name:
f.write("file '{}'\n".format(file))
print("file_list.txt已生成")
txt_file = "D:\\data\\video\\m1\\file_list.txt"
mp4 = "D:\\data\\movies\\丛林奇航.mp4"
cmd = f"ffmpeg -f concat -i {txt_file} -c copy {mp4}"
try:
os.system(cmd)
except Exception as e:
print(e)
print("done")
if __name__ == '__main__':
url = "https://pps.sd-play.com/20211127/g8V4A0hE/1000kb/hls/index.m3u8"
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.131 Safari/537.36",
}
t_start = time.time()
print("------------------开始下载m3u8----------------------------")
down_m3u8(url)
time.sleep(1)
print("------------------开始下载ts视频----------------------------")
down_ts()
time.sleep(1)
print("------------------开始下载解密ts视频----------------------------")
jiemi()
time.sleep(1)
print("------------------开始下载合成MP4----------------------------")
movie_video()
t_end = time.time()
t = t_end-t_start
print(t)
提示:当代码运行到 如图 所示,这里是在合成视频,需要一定的时间,耐心等待完成就行。
python 小白一个,不喜勿喷。希望对大家有所帮助 。。。。。。
最后,python大法好!
标签:file,m3u8,ts,key,多线程,data,下载,FFmpeg 来源: https://blog.csdn.net/weixin_44002144/article/details/123036137