Lab Projects
PythonReact/Next.jsBlogAbout
Back to List

Download M3U8 Video Files

Learn how to download and merge m3u8 streaming video files using Python. M3U8 is a common video streaming format widely used by online video platforms.

Features:
Parse M3U8 playlist
Multi-threaded segment download
Auto-merge into complete video
Real-time progress tracking
Python Code:
import asyncio
from pathlib import Path
from typing import Optional
import logging

logger = logging.getLogger(__name__)

async def download_m3u8_video(
    url: str,
    output_filename: str,
    referer: Optional[str] = None,
    custom_headers: Optional[dict] = None,
    cookies: Optional[str] = None,
    download_dir: Path = Path("./downloads")
) -> str:
    """
    Download an M3U8 video using yt-dlp asynchronously.

    Args:
        url: The M3U8 video URL.
        output_filename: The output file name without extension.
        referer: Optional HTTP Referer header.
        custom_headers: Optional dictionary of additional HTTP headers.
        cookies: Optional cookie string (semicolon-separated).
        download_dir: Directory to save the downloaded file.

    Returns:
        The full path to the downloaded video file.
    """

    # Ensure download directory exists
    download_dir.mkdir(parents=True, exist_ok=True)
    output_path = download_dir / f"{output_filename}.mp4"

    # Build yt-dlp command
    cmd = [
        "yt-dlp",
        "-o", str(output_path),
        "--newline",           # Print each progress update in a new line
        "--progress",          # Show progress bar
        "--verbose",           # Enable detailed output
        "--console-title",     # Show progress in console title
        "--no-quiet",          # Disable quiet mode
        "--user-agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64)",
        "--no-check-certificates",
        "--retries", "20",
        "--fragment-retries", "20",
    ]

    # Add Referer header if provided
    if referer:
        cmd.extend(["--referer", referer])

    # Add custom HTTP headers if provided
    if custom_headers:
        for key, value in custom_headers.items():
            cmd.extend(["--add-header", f"{key}:{value}"])

    # Add cookies if provided
    if cookies:
        cookies_file = download_dir / f"{output_filename}_cookies.txt"
        with open(cookies_file, 'w', encoding='utf-8') as f:
            f.write("# Netscape HTTP Cookie File\n")
            for cookie in cookies.split(';'):
                cookie = cookie.strip()
                if '=' in cookie:
                    k, v = cookie.split('=', 1)
                    f.write(f".example.com\tTRUE\t/\tFALSE\t0\t{k}\t{v}\n")
        cmd.extend(["--cookies", str(cookies_file)])

    # Append video URL
    cmd.append(url)

    try:
        # Launch yt-dlp process asynchronously
        process = await asyncio.create_subprocess_exec(
            *cmd,
            stdout=asyncio.subprocess.PIPE,
            stderr=asyncio.subprocess.STDOUT
        )

        logs = []
        # Read output lines in real time
        async for line in process.stdout:
            text = line.decode('utf-8', errors='ignore').strip()
            if text:
                logs.append(text)
                logger.info(f"[yt-dlp] {text}")

        await process.wait()

        # Check if download succeeded
        if process.returncode == 0:
            if output_path.exists():
                return str(output_path)
            else:
                raise Exception("Download completed but output file not found")

        # If failed, raise exception with last few log lines
        raise Exception("\n".join(logs[-20:]))

    except FileNotFoundError:
        raise Exception("yt-dlp not installed. Install with: pip install yt-dlp")
Try it out:

Example: my_video.mp4

💡 Learning Points:
  • M3U8 Format: M3U8 is a playlist file used by HLS (HTTP Live Streaming) protocol, containing links to multiple .ts video segments

  • HTTP Requests: Use requests library to download m3u8 file and video segments

  • Multi-threading: Use thread pool to download multiple video segments concurrently for better efficiency

  • Merge Segments: Merge downloaded .ts segments in order into a complete video file