方法:
解析m3u8,获取其中的ts列表,多线程下载所有ts文件。
全部下完之后,用ffmpeg合并成mp4
代码:
python
import requests
import os
import threading
tnum = 64
class Downloader(threading.Thread):
def __init__(self, id, url, ts_list, file_path):
threading.Thread.__init__(self)
self.id = id
self.url = url
self.ts_list = ts_list
self.file_path = file_path
def run(self):
for i in range(self.id, len(self.ts_list), tnum):
ts_url = self.ts_list[i]
r = requests.get(ts_url, stream=True)
if r.status_code == 200:
with open(self.file_path + f'_{i}.ts', 'wb') as f:
for chunk in r.iter_content(chunk_size=1024):
if chunk:
f.write(chunk)
def download_m3u8_video(url, file_path):
r = requests.get(url)
if r.status_code != 200:
print('m3u8视频下载链接无效')
return False
m3u8_list = r.text.split('\n')
m3u8_list = [i for i in m3u8_list if i and i[0] != '#']
ts_list = []
for ts_url in m3u8_list:
ts_url = url.rsplit('/', 1)[0] + '/' + ts_url
ts_list.append(ts_url)
f = open(file_path+'file_list.txt', 'w+')
for i in range(len(ts_list)):
f.write('file \'' + f'_{i}.ts' + "'\n")
f.close()
threads = []
for i in range(0, tnum):
thread = Downloader(i, url, ts_list, file_path.rsplit('.', 1)[0])
thread.start()
threads.append(thread)
for thread in threads:
thread.join()
return not endflag
def merge_file(path, save_path):
ffmpeg_bin_dic = 'C:/ffmpeg-2023-08-07-git-d295b6b693-full_build/bin/'
os.system(ffmpeg_bin_dic+'ffmpeg -f concat -safe 0 -i '+path+'file_list.txt'+' -c '+ ' copy ' +save_path)
def down(url):
name = url[-41:-5]
print(name)
ts_file_path = 'D:/v/' + name+'/'
os.makedirs(ts_file_path)
mp4_file_path = 'D:/v2/'+name+'.mp4'
global endflag
endflag = False
if download_m3u8_video(url, ts_file_path):
print('m3u8视频下载完成')
merge_file(ts_file_path, mp4_file_path)
else :
print('error!!!!')
print(url)
url_list = [
'https://sth.com/videos/202305091/d63b006e-c6fb-4997-8d43-7ebd086e9c75.m3u8',
'https://sth.com/videos/202305081/2c9fa41b-e25b-4371-908f-d246628d7bed.m3u8',
]
for url in url_list:
down(url)