← Blog.backToBlog

编写 Python 脚本下载 M3U8 流

8 min read

两种思路

用 Python 下载 M3U8 有两条路:(1) 自己解析播放列表并拉取片段,或 (2) 通过 subprocess 调用 FFmpeg。自拉适合学习与定制;FFmpeg 在加密、边界情况和重封装上通常更稳。请仅用于合法流。

用 m3u8 库解析

import m3u8
import requests

playlist = m3u8.load("https://example.com/stream.m3u8")
parts = []
for segment in playlist.segments:
    uri = segment.absolute_uri or segment.uri
    parts.append(requests.get(uri, timeout=30).content)

with open("output.ts", "wb") as f:
    for p in parts:
        f.write(p)

安装:pip install m3u8 requests

多线程下载片段

from concurrent.futures import ThreadPoolExecutor
import m3u8, requests

def download_m3u8(url, output="output.ts", workers=8):
    pl = m3u8.load(url)
    def fetch(seg):
        u = seg.absolute_uri or seg.uri
        return requests.get(u, timeout=30).content
    print(f"Downloading {len(pl.segments)} segments...")
    with ThreadPoolExecutor(max_workers=workers) as ex:
        data = list(ex.map(fetch, pl.segments))
    with open(output, "wb") as f:
        for chunk in data:
            f.write(chunk)
    print("Saved", output)

生产路径:调用 FFmpeg

import subprocess

def download_m3u8(url, output="output.mp4"):
    cmd = [
        "ffmpeg", "-y", "-i", url,
        "-c", "copy", "-bsf:a", "aac_adtstoasc",
        output,
    ]
    subprocess.run(cmd, check=True)

download_m3u8("https://example.com/stream.m3u8")

这样复用久经考验的 HLS 逻辑。命令细节:FFmpeg 下载 M3U8

错误处理技巧

  • 对失败的片段 GET 做退避重试。
  • 相对 URI 相对播放列表基路径解析。
  • 尽早检测 #EXT-X-KEY——纯 Python 解密比 FFmpeg 难。
  • 直播要设定停止条件(时长/片段数)。

何时不必写脚本

一次性下载用我们免费的在线下载器或单条 FFmpeg 命令即可。脚本适合自动化与自定义流水线。批量思路:批量下载

常见问题解答

哪个 Python 库解析 M3U8?
PyPI 上的 m3u8 包。

多线程安全吗?
独立片段下载可以;合并写入要按顺序。

该不该调用 FFmpeg?
生产环境与加密边界情况建议调用。

Python 容易重封装成 MP4 吗?
调用 FFmpeg 通常比纯 Python 重封装简单。