# 1. Download all segments with aria2c, max speed aria2c --check-certificate=false \ --max-connection-per-server=16 \ --split=16 \ --min-split-size=1M \ --console-log-level=error \ --summary-interval=0 \ -i <(curl -s "https://cdn.example/live/stream.m3u8" | grep -E "segment_[0-9]+\.ts" | sed 's|^|https://cdn.example/live/|') \ -d ./live_vid cd live_vid && cat *.ts > complete.ts 3. Convert to MP4 ffmpeg -i complete.ts -c copy -movflags +faststart final.mp4 4. Clean up rm *.ts aria2c vs. Other m3u8 Downloaders | Tool | Concurrency | Resume | Decryption | Best for | |------|-------------|--------|------------|----------| | aria2c | ✅ Up to 16+ | ✅ | ❌ manual | Speed & large files | | ffmpeg | ❌ Single thread | ✅ | ✅ Built-in | Encrypted streams | | youtube-dl / yt-dlp | ✅ Limited | ✅ | ✅ | Sites with DRM | | wget | ❌ | ✅ | ❌ | Simple scripts |
ffmpeg -i "https://example.com/stream.m3u8" -c copy video.mp4 But ffmpeg is single-threaded. aria2c downloads fragments faster; then you decrypt with openssl if needed. 1. Resume an Interrupted Download aria2c saves a control file ( .aria2 ). Just rerun the same command; it resumes automatically. 2. Download with Cookies or Headers Many streams require authentication. Save headers to a file ( headers.txt ): aria2c m3u8
#!/bin/bash M3U8_URL=$1 OUTPUT_NAME=$2:-video TEMP_DIR="hls_temp_$(date +%s)" mkdir -p "$TEMP_DIR" echo "Fetching segments from $M3U8_URL..." curl -s "$M3U8_URL" | grep -E ".ts" | sed "s|^|$(dirname "$M3U8_URL")/|" > "$TEMP_DIR/segments.txt" Clean up rm *
aria2c --header="Referer: https://example.com" \ --header="Cookie: sessionid=abc123" \ -i segment_list.txt -j 16 aria2c --max-download-limit=5M -i playlist.txt 4. Download from Master Playlist (Auto-select highest bitrate) # Fetch master m3u8, extract highest bandwidth variant master_url="https://example.com/master.m3u8" high_url=$(curl -s "$master_url" | grep -E "BANDWIDTH=[0-9]6," | sort -t= -k2 -rn | head -1 | grep -oE "http[^ ]+\.m3u8") curl -s "$high_url" | grep "\.ts" | aria2c -i - -j 16 Common Pitfalls and Solutions | Problem | Likely Cause | Fix | |---------|--------------|-----| | aria2c downloads .ts but not in order | No issue; merge script handles order | Merge after download | | Segments fail with 403 Forbidden | Missing Referer or Origin headers | Add --header="Referer: ..." | | .m3u8 contains AES-128 encryption | Need key file | Use ffmpeg -allowed_extensions ALL -i stream.m3u8 -c copy out.mp4 | | Download stops after 5 seconds | Server rate-limiting | Reduce -j to 4 or 8 | | Merged video has glitches | Missing segments or timestamps | Re-download missing chunks or use ffmpeg -fflags +genpts | Real-World Example: Saving a Live Stream Replay Assume this m3u8 URL: https://cdn.example/live/stream.m3u8 it resumes automatically.
# Extract segment URLs from m3u8 and feed to aria2 curl -s "https://example.com/video.m3u8" | grep -E '^https?://.*\.ts' | \ aria2c -i - -j 16 -d ./video -o "seg_%03d.ts" Method B – For relative URLs (common):