← Blog.backToBlog

Writing a Python Script to Download M3U8 Streams

8 min read

Approach Overview

You can download M3U8 in Python two ways: (1) parse the playlist and fetch segments yourself, or (2) call FFmpeg via subprocess. Self-fetch is educational and flexible; FFmpeg is usually more robust for encryption, edge cases, and remuxing. Prefer legal streams only.

Parse with the m3u8 Library

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)

Install with pip install m3u8 requests.

Multi-threaded Segment Download

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)

Production Path: Call 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")

This reuses battle-tested HLS logic. Command details: FFmpeg download M3U8.

Error Handling Tips

  • Retry failed segment GETs with backoff.
  • Resolve relative URIs against the playlist base.
  • Detect #EXT-X-KEY early — pure Python decrypt is harder than FFmpeg.
  • For live, decide a stop condition (duration/segment count).

When Not to Write a Script

For one-off downloads, use our free online downloader or a single FFmpeg command. Scripts shine for automation and custom pipelines. Batch ideas: batch download.

Frequently Asked Questions

What Python library parses M3U8?
The m3u8 package on PyPI.

Is multi-threading safe?
Yes for independent segment downloads; write merges in order.

Should I shell out to FFmpeg?
Yes for production reliability and encryption edge cases.

Can Python remux to MP4 easily?
Calling FFmpeg is usually simpler than pure Python remux.