python线程池下载m3u8文件视频
一、文件没有key
1.导入所需模块
import requests
import os
from concurrent.futures import ThreadPoolExecutor
2.将m3u8文件中的ts地址存入列表
def m3u8_lst():
lst = []
with open('文件名字.m3u8', 'r', encoding='utf-8') as f:
for line in f:
line = line.strip()
if line.startswith('#'):
continue
url = line # 这个地方需要自己拼接
lst.append(url)
return lst
3.下载单个ts视频函数
def down_ts(name, url):
resp = requests.get(url)
resp.close()
with open(f'video/{name}', 'wb') as f:
f.write(resp.content)
print(f'{name}下载完成')
4.合并所有ts视频
def merge(num):
with open('video/电影名字.mp4', 'wb') as f:
for i in range(num):
with open(f'video/{i}', 'rb') as f1:
f.write(f1.read())
os.remove(f'video/{i}')
print('视频合并完成')
5.主程序
if __name__ == '__main__':
ts_lst = m3u8_lst()
# print(ts_lst)
print('开始下载')
with ThreadPoolExecutor(50) as t:
for index, ts_url in enumerate(ts_lst):
t.submit(down_ts, name=index, url=ts_url)
print('ts视频下载完成,准备开始合并视频')
merge(len(ts_lst))
完整代码
import requests
import os
from concurrent.futures import ThreadPoolExecutor
def m3u8_lst():
lst = []
with open('文件名.m3u8', 'r', encoding='utf-8') as f:
for line in f:
line = line.strip()
if line.startswith('#'):
continue
url = line # 自己拼接
lst.append(url)
return lst
def down_ts(name, url):
resp = requests.get(url)
resp.close()
with open(f'video/{name}', 'wb') as f:
f.write(resp.content)
print(f'{name}下载完成')
def merge(num):
with open('video/电影名字.mp4', 'wb') as f:
for i in range(num):
with open(f'video/{i}', 'rb') as f1:
f.write(f1.read())
os.remove(f'video/{i}')
print('视频合并完成')
if __name__ == '__main__':
ts_lst = m3u8_lst()
# print(ts_lst)
print('开始下载')
with ThreadPoolExecutor(50) as t:
for index, ts_url in enumerate(ts_lst):
t.submit(down_ts, name=index, url=ts_url)
print('ts视频下载完成,准备开始合并视频')
merge(len(ts_lst))
二、文件有key
下载完成所有ts视频后,需要对ts视频解码
接上面第3步骤
4.单个ts解码函数
def de_ts(name):
url = 'key网址'
resp = requests.get(url)
resp.close()
key = resp.content
iv = b'0000000000000000' # 如果没有说明偏移量,就用这个字节作为偏移量
aes = AES.new(key, AES.MODE_CBC, iv)
# aes = AES.new(key, AES.MODE_ECB)
with open(f'video/{name}', 'rb') as f:
de_f = aes.decrypt(f.read())
with open(f'video/{name}_1', 'wb') as f1:
f1.write(de_f)
print(f'{name}解码完成')
5.合并视频,与不含key的略有不同
def merge(num):
with open('video/电影名字.mp4', 'wb') as f:
for i in range(num):
with open(f'video/{i}_1', 'rb') as f1:
f.write(f1.read())
os.remove(f'video/{i}_1')
os.remove(f'video/{i}')
print('视频合并完成')
6.主程序
if __name__ == '__main__':
ts_lst = m3u8_lst()
print('开始下载')
with ThreadPoolExecutor(50) as t:
for index, ts_url in enumerate(ts_lst):
t.submit(down_ts, name=index, url=ts_url)
print('ts视频下载完成')
with ThreadPoolExecutor(50) as t:
for n in range(len(ts_lst)):
t.submit(de_ts, name=n)
print('ts视频解码完成')
merge(len(ts_lst))
完整代码
import requests
import os
from concurrent.futures import ThreadPoolExecutor
from Crypto.Cipher import AES
def m3u8_lst():
lst = []
with open('文件名.m3u8', 'r', encoding='utf-8') as f:
for line in f:
line = line.strip()
if line.startswith('#'):
continue
line = line # 自己拼接
lst.append(line)
return lst
def down_ts(name, url):
resp = requests.get(url)
resp.close()
with open(f'video/{name}', 'wb') as f:
f.write(resp.content)
print(f'{name}下载完成')
def merge(num):
with open('video/电影名字.mp4', 'wb') as f:
for i in range(num):
with open(f'video/{i}_1', 'rb') as f1:
f.write(f1.read())
os.remove(f'video/{i}_1')
os.remove(f'video/{i}')
print('视频合并完成')
def de_ts(name):
url = 'key网址'
resp = requests.get(url)
resp.close()
key = resp.content
iv = b'0000000000000000'
aes = AES.new(key, AES.MODE_CBC, iv)
# aes = AES.new(key, AES.MODE_ECB)
with open(f'video/{name}', 'rb') as f:
de_f = aes.decrypt(f.read())
with open(f'video/{name}_1', 'wb') as f1:
f1.write(de_f)
print(f'{name}解码完成')
if __name__ == '__main__':
ts_lst = m3u8_lst()
print('开始下载')
with ThreadPoolExecutor(50) as t:
for index, ts_url in enumerate(ts_lst):
t.submit(down_ts, name=index, url=ts_url)
print('ts视频下载完成')
with ThreadPoolExecutor(50) as t:
for n in range(len(ts_lst)):
t.submit(de_ts, name=n)
print('ts视频解码完成')
merge(len(ts_lst))