python 脚本

下载m3u8视频

# 一共可以接受三个参数,第一个参数是m3u8的地址,第二个参数是保存的目录,第三个参数是保存的文件名,如果不传第三个参数,默认是output
# 用法:python3 down.py https://xxx.com/xxx/xxx.m3u8 /Users/xxx/Downloads/ 文件名
# 前提是电脑上已经安装了ffmpeg
import sys
import os
import requests
import subprocess
import random
import string
import time

url = sys.argv[1]
output_dir = sys.argv[2]
domain = url.split("/")[0] + "//" + url.split("/")[2]
mp4name = "output"
if len(sys.argv) == 4:
    mp4name = sys.argv[3]
# 创建保存目录
if not os.path.exists(output_dir):
    os.makedirs(output_dir)
base_domain=url.split("/")[2]
print("开始下载")
headers = {
    "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.81 Safari/537.36 Edg/94.0.992.50",
    "Host": domain,
    "Origin": domain,
    "Referer": f"{domain}/",
    "sec-ch-ua": "\"Google Chrome\";v=\"111\", \"Not(A:Brand\";v=\"8\", \"Chromium\";v=\"111\"",
    "sec-ch-ua-mobile": "?0",
    "sec-ch-ua-platform": "macOS",
    "Sec-Fetch-Dest": "empty",
    "Sec-Fetch-Mode": "cors",
    "Sec-Fetch-Site": "cross-site",
}

response = requests.get(url, headers=headers)
m3u8_text = response.text

ts_list = []
for line in m3u8_text.splitlines():
    if ".ts?" in line or line.endswith(".ts"):
        if line.startswith("http"):
            ts_list.append(line)
        else:
            ts_list.append(domain + line)
# 生成随机字符串
randomStr = ''.join(random.sample(string.ascii_letters + string.digits, 8))
# 下载 TS 文件并保存到指定目录
for i, ts_url in enumerate(ts_list):
    # ToDo可以优化成多线程下载和进度条显示
    print('正在下载第'+str(i)+'个文件'+'共'+str(ts_list.__len__())+'个文件')
    response = requests.get(ts_url)
    filename = os.path.join(output_dir, f"video_{randomStr}_{i}.ts")
    with open(filename, "wb") as f:
        f.write(response.content)

ts_files = [os.path.join(output_dir, f"video_{randomStr}_{i}.ts") for i in range(len(ts_list))]
output_file = os.path.join(output_dir, f"{mp4name}.mp4")

timeString = time.strftime("%Y%m%d%H%M%S", time.localtime())
if os.path.exists(output_file):
    output_file = os.path.join(output_dir, f"{mp4name}_{timeString}.mp4")

subprocess.call(["ffmpeg", "-i", f"concat:{'|'.join(ts_files)}", "-c", "copy", output_file])
for ts_file in ts_files:
    os.remove(ts_file)

print("下载并合并完成")
Last Updated: