import shutil import requests import os import sys import re import time """ ## 使用说明: 1. 保存文件名为 "名称.机房.m3u8" , 可以保存多个文件,脚本会批量处理 。sz 表示深圳,bj 表示北京,注意修改 2. 执行脚本 "python3 a.py" 格式: "python3 a.py [-mac-crf] [-nv]" 在 mac 下 ,可以增加参数执行命令 -crf 压缩成 720p分辨率 ,-nv 提取音频 ## 常用脚本 合并视频 Terminal 执行,已经包含在自动化脚本里面 ffmpeg -f concat -safe 0 -i file.txt -c copy a.mp4 压缩当前文件下的所有视频的 find ./ -name '*.mp4' -and ! -name '*264].mp4' -exec sh -c 'ffmpeg -i "$0" -c:v libx264 -crf 30 -c:a aac "${0%%.mp4}[x264].mp4"' {} \; """ # sz 表示深圳,bj 表示北京,注意修改 host_room = "bj" # 会重新赋值 cache_dir_base = "[dingtalk-playback]-cache-" # base_url = f"https://dtliving-{jifang}.dingtalk.com/live_hp/" def get_m3u8_list(): file_list = [] path = os.listdir('./') for i in path: if re.match(r".*\.m3u8$", i) and os.path.isfile(i): print(i) file_list.append(i) return file_list def get_url(fileName, host_room="bj"): base_url = f"https://dtliving-{host_room}.dingtalk.com/live_hp/8a0a4b6f-cdc2-4935-9bee-50a492079522/" url_list = [] with open(fileName, "r") as f: s = f.readlines() for i in s: if re.match(r".*?ts.*?", i): url_list.append(base_url + i) return url_list def download(fileName, host_room, cache_dir): urls = get_url(fileName, host_room) sum = len(urls) size = 0 # 单位 B scale = 50 # 进度条长度 print(f"一共{sum}个ts文件下载") print("执行开始,祈祷不报错".center(scale // 2, "-")) start = time.perf_counter() finished_i = 0 if os.path.exists(cache_dir): print("检测到已下载的文件,继续下载。。。") finished_i = max(len(os.listdir(cache_dir)) - 1, 0) else: os.mkdir(cache_dir) for i, url in enumerate(urls): if i < finished_i: # 已下载 continue # 为了展示进度条 a = "*" * round(i / sum * scale) b = "." * round((sum - i)/sum * scale) c = (i / sum) * 100 dur = time.perf_counter() - start speed = float(size / 1024 / dur) db = "KB/s" # 核心代码 start with open(f"{cache_dir}/{i + 1}.ts", "wb") as f: response = requests.get(url[:-1]) # 去掉换行符 if response.headers["Content-Type"] == "video/MP2T": # 判断是否响应成功 size += int(response.headers["Content-Length"]) f.write(response.content) else: print(f"执行到 {i} 发生错误") print( f"\n\nerror: response.Content-Type not 'video/MP2T' \nMaybe {fileName}'s roomID 'bj' or 'sz' miss") raise # end if speed > 1024: speed = float(speed / 1024) db = "MB/s" print( "\r[下载进度] {}/{} {:^3.0f}% [{}->{}] {:.2f}{} {:.2f}s ".format(i+1, sum, c, a, b, speed, db, dur), end="") # print(f"{i}/{sum} 已下载:{round(i/sum*100)}%", "ok") # time.sleep(1) return len(urls) # 整合文件名, 方便FFmpeg合并 def parse_filename(cache_dir, len): base_path = os.getcwd() with open(f"{cache_dir}/file.txt", "w+") as f: for i in range(1, 1 + len): path = f"file '{base_path}/{cache_dir}/{i}.ts'\n" f.write(path) def downloadAndConcat(fileName): cache_dir = cache_dir_base+fileName name = fileName.split('.', 2)[0] host_room = fileName.split('.', 2)[1] if get_url(fileName, host_room) == 0: print("文件内容为空!!") return print(f"\n\n{fileName},准备下载...") for i in range(3): print("倒计时:", 3-i, "s") time.sleep(1) parse_filename(cache_dir, download(fileName, host_room, cache_dir)) print("\ndownload finished,准备合并视频...") time.sleep(3) # 等待喵 os.system( f'ffmpeg -hide_banner -f concat -safe 0 -i {cache_dir}/file.txt -c copy {name}.mp4') os.rename(fileName, fileName+'.ok') # 清除缓存 if os.path.exists(cache_dir): shutil.rmtree(cache_dir) print(f"{fileName} finished") return fileName def extraFFmpeg(fileNames, argv): for fileName in fileNames: name = fileName.split('.', 2)[0] # 压缩视频 if "-mac-crf" in argv: os.system( f"ffmpeg -hide_banner -y -i {name}.mp4 -vf scale=-1:720 -c:v libx264 -crf 30 -c:a aac '{name}[x264].mp4'") # 提取音频 if "-vn" in argv: os.system( f"ffmpeg -hide_banner -y -i {name}.mp4 -vn -c:a copy '{name}.aac'") if __name__ == "__main__": list = get_m3u8_list() finished = [] print("检测到可下载文件: ", list) for fileName in list: finished.append(downloadAndConcat(fileName)) # 对已下载完成的视频进行额外操作 extraFFmpeg(finished, sys.argv)