直接用ffmpeg下载合并m3u8最稳定:它原生支持自动处理重定向、cookie、referer、key下载与aes-128解密,避免python解析时因动态参数、iv不匹配或header缺失导致的403/乱码;基础命令为ffmpeg -headers "user-agent:...\r\nreferer:...\r\ncookie:..." -i url -c copy -f mp4 output.mp4。

直接用 ffmpeg 下载并合并,别碰 Python 自己解析 m3u8
Python 本身不擅长处理加密或分段的 m3u8 流(尤其是带 AES-128 密钥、动态 key URI、EXT-X-KEY 变化的情况),硬写 requests + re 解析容易卡在跳转、签名、Referer、Cookie 或 IV 不匹配上。真正稳定的做法是交由 ffmpeg 全权处理——它原生支持 m3u8,能自动处理重定向、cookie 携带、key 下载、解密和拼接。
实操建议:
- 确保系统已安装
ffmpeg(>= 4.3),运行ffmpeg -version可验证 - 若 m3u8 地址需要鉴权,先用浏览器拿到完整请求头(特别是
Cookie、Referer、User-Agent),转成-headers参数传给 ffmpeg - 不要用 Python 调
os.system("ffmpeg ...")拼接字符串——易被空格/特殊字符截断,改用subprocess.run传列表
ffmpeg 命令必须带的参数有哪些?
一个能跑通的基础命令长这样:
ffmpeg -headers "User-Agent: Mozilla/5.0; Referer: https://example.com/; Cookie: sessionid=abc123;" -i "https://example.com/index.m3u8" -c copy -f mp4 "output.mp4"
关键点说明:
调用 Cutout.Pro 视觉处理 API 进行背景移除、人像抠图和照片增强,支持文件上传与图片 URL 输入。
-
-headers必须是单个字符串,各 header 用\r\n分隔(Python 中写成"User-Agent: ...\r\nReferer: ...") -
-c copy表示不重新编码,纯封装,快且无画质损失;但要求所有 ts 片编码一致(H.264+AAC),否则会报错“incompatible stream” - 如果遇到
Unable to open key file,说明 key URI 不可达或没带必要 header,此时需单独下载 key 并用-allowed_extensions ALL -protocol_whitelist file,http,https,tcp,tls,crypto
Python 调用时怎么安全传参并捕获失败?
用 subprocess.run 配合 timeout 和 check=True,避免卡死或静默失败:
import subprocess<br><br>cmd = [<br> "ffmpeg",<br> "-headers", "User-Agent: Mozilla/5.0\r\nReferer: https://example.com/\r\nCookie: token=xyz;",<br> "-i", "https://example.com/playlist.m3u8",<br> "-c", "copy",<br> "-f", "mp4",<br> "out.mp4"<br>]<br><br>try:<br> result = subprocess.run(cmd, capture_output=True, text=True, timeout=600)<br> if result.returncode != 0:<br> print("ffmpeg failed:", result.stderr[:500])<br>except subprocess.TimeoutExpired:<br> print("ffmpeg timed out — check network or m3u8 validity")
注意:
- 不要省略
timeout,m3u8 若含无效 segment 或 key 返回 404,ffmpeg 默认会无限重试 -
capture_output=True才能拿到 stderr 里的关键错误(如Connection refused、Invalid data found when processing input) - Windows 用户注意路径分隔符不影响 ffmpeg,但 Python 的
subprocess对可执行文件名敏感,确保ffmpeg在 PATH 中,或写绝对路径如r"C:\tools\ffmpeg.exe"
遇到 AES-128 加密但 key URI 是相对路径怎么办?
ffmpeg 不会自动补全 key 的 base URL,比如 m3u8 中写 #EXT-X-KEY:METHOD=AES-128,URI="key.bin",而 m3u8 本身在 https://a.com/path/index.m3u8,那么 key 实际地址是 https://a.com/path/key.bin,不是根目录下的 /key.bin。此时必须手动构造完整 key URL 并告诉 ffmpeg:
- 先用
requests获取 m3u8 内容,正则提取URI="(.+?)",再用urllib.parse.urljoin拼出绝对地址 - 然后加参数:
-cryptokey "0123456789abcdef0123456789abcdef"(十六进制 key)或-iv 00000000000000000000000000000000(如果 IV 固定) - 更稳妥的做法:把 key 下载到本地文件,用
-decryption_key_file key.bin(ffmpeg 5.1+ 支持)
加密流的调试成本远高于明文流,优先确认是否真需要下载——很多网站的 m3u8 本质是防盗链策略,key 有效期极短,录下来也播不了。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!










