Skip to content
 
 

Repository files navigation

M3U8

CI Go License Release

A lightweight M3U8 downloader written in Go (v1.3.0). It parses HLS playlists, downloads TS segments concurrently, decrypts AES-128 and cloud VOD encrypted streams, merges them into a single file, and optionally remuxes to MP4 via ffmpeg.

Two modes are available:

  • CLI — one-shot download from the command line
  • HTTP API — async task server with progress polling and file download

中文说明

Features

  • Parse and download VOD M3U8 playlists
  • Auto-resolve Master playlists (selects the first variant)
  • Concurrent TS segment download with configurable workers
  • Per-segment retry on failure
  • Per-segment resume (re-run with the same -u, -o, and -f to skip completed segments)
  • AES-128 segment decryption
  • Built-in cloud VOD decryption (Tencent SimpleAES, Alibaba HLS standard encryption)
  • Pluggable decrypt scripts (Starlark / external process, configured via decrypt.yaml)
  • Merge TS segments into a single file
  • Remux to MP4 via ffmpeg (stream copy, no re-encoding)
  • Single-line terminal progress bar for download and merge
  • Custom HTTP headers, Cookie, and optional TLS skip-verify
  • HTTP/HTTPS proxy support (CLI -proxy or HTTP_PROXY / HTTPS_PROXY env vars)
  • HTTP API server for remote parsing, async downloads, progress tracking, and cancellation
  • Optional API Key authentication, CORS, task TTL, and automatic cleanup

Requirements

  • Go 1.22+ (for building from source)
  • ffmpeg (optional, required when MP4 output is enabled — enabled by default)

Quick Start

make vendor && make build
./m3u8 -u=https://example.com/index.m3u8 -o=./output

Or run from source:

go run -mod=vendor . -u=https://example.com/index.m3u8 -o=./output

CLI Usage

m3u8 -u <URL> [options]
m3u8 serve [options]          # start HTTP API server

Examples

# Basic download (outputs ./main.mp4 by default)
./m3u8 -u=https://example.com/index.m3u8

# Specify output directory and filename
./m3u8 -u=https://example.com/index.m3u8 -o=./output -f myvideo

# Keep TS output only (skip MP4 conversion)
./m3u8 -u=https://example.com/index.m3u8 -mp4=false

# Sites requiring Referer or Cookie
./m3u8 -u=https://example.com/index.m3u8 \
  -H "Referer: https://example.com/" \
  -cookie "session=abc"

# Self-signed HTTPS certificate
./m3u8 -u=https://self-signed.example.com/index.m3u8 -k

# Download via HTTP proxy
./m3u8 -u=https://example.com/index.m3u8 -proxy http://127.0.0.1:7890

# Custom decryption script
./m3u8 -u=https://example.com/index.m3u8 -decrypt-script scripts/custom.star

# Resume an interrupted download (same -u, -o, -f)
./m3u8 -u=https://example.com/index.m3u8 -o=./output -f myvideo

Platform-specific

Linux & macOS:

./m3u8 -u=https://example.com/index.m3u8 -o=./output

Windows PowerShell:

.\m3u8.exe -u="https://example.com/index.m3u8" -o="D:\data\output"

CLI Flags

Flag Default Description
-u M3U8 URL (required)
-o . Output directory
-f main Output base name (.ts / .mp4 extension optional)
-c 25 Download concurrency
-r 10 Max retries per segment
-mp4 true Remux merged TS to MP4 via ffmpeg (-mp4=false to disable)
-H Custom HTTP header ("Key: Value"), repeatable
-cookie Cookie request header
-proxy HTTP proxy URL (e.g. http://127.0.0.1:7890)
-k false Skip HTTPS certificate verification (insecure)
-decrypt-script Decrypt script path (.star or .py)
-decrypt-config decrypt.yaml Decrypt config file path
-scripts-dir scripts Decrypt script library directory
-drm-token Tencent Cloud DrmToken (SimpleAES)
-pkey Tencent Cloud SimpleAES playback key
-mts-token Alibaba Cloud MtsHlsUriToken
-h Show help

VOD playlists only. Some sources rate-limit requests — lower -c or raise -r as needed.

When -proxy is not set, HTTP_PROXY / HTTPS_PROXY environment variables are used automatically.

To resume an interrupted download, re-run with the same -u, -o, and -f. Completed segments in ts/ are reused automatically.

Cloud VOD Encryption

Built-in support for Tencent Cloud SimpleAES and Alibaba Cloud HLS standard encryption, including URL preprocessing and secondary key decryption. When cloud VOD signatures are detected, the built-in provider is activated automatically — no -decrypt-script is usually needed.

Provider Auto-detection (either condition) Key handling
Tencent SimpleAES M3U8 host *.vod2.myqcloud.com; or key URI contains drm.vod2.myqcloud.com + drmType=SimpleAES SHA256(pkey) → AES-CBC (zero IV) decrypts ciphertext key
Alibaba HLS standard M3U8 URL contains MtsHlsUriToken=; or key URI contains Ciphertext= 16-byte binary or Base64 response → 16-byte AES key

Credentials are passed via CLI flags only — not stored in config files or decrypt.yaml.

Flag Description
-drm-token Tencent Cloud DrmToken (inserts voddrm.token.{token} into M3U8 path)
-pkey Tencent Cloud SimpleAES playback key
-mts-token Alibaba Cloud MtsHlsUriToken (appended to M3U8 URL query)
# Tencent Cloud SimpleAES
./m3u8 -u "https://1500014561.vod2.myqcloud.com/.../adp.12.m3u8?t=...&sign=..." \
  -drm-token "eyJhbGci..." \
  -pkey "JduzsUuRvGVPRHvIYwLv"

# Alibaba Cloud HLS standard encryption
./m3u8 -u "https://example.aliyundoc.com/test.m3u8?MediaId=xxx" \
  -mts-token "your-token"

Key hook priority: explicit -decrypt-script > built-in provider > decrypt.yaml / auto-discovered script > raw key. URL preprocessing (-drm-token / -mts-token) still runs when -decrypt-script is set.

Reference Starlark scripts for debugging: scripts/tencent-vod-simpleaes.star, scripts/aliyun-hls-standard.star. See scripts/README.md for details.

Scope: Supports standard HLS AES-128, Tencent SimpleAES, and Alibaba HLS standard encryption. Does not support Alibaba private / License encryption (SDK-only) or commercial DRM (FairPlay / Widevine).

Decrypt Scripts

For non-standard encryption (custom key derivation, SAMPLE-AES, etc.), place scripts in scripts/ or configure rules in decrypt.yaml (copy from decrypt.yaml.example).

Script selection priority: CLI -decrypt-scriptdecrypt.yaml rules → auto-discovery by METHOD / hostname.

Flag Description
-decrypt-script Explicit script path (highest priority)
-decrypt-config Config file with host/method matching rules
-scripts-dir Script library directory for auto-discovery
# Use a config file
./m3u8 -u=https://example.com/index.m3u8 -decrypt-config decrypt.yaml

# Auto-match scripts/AES-128.star or scripts/example.com.py
./m3u8 -u=https://example.com/index.m3u8 -scripts-dir scripts

Starlark (.star) runs in a sandbox; other extensions (.py, etc.) use a long-lived external process with JSON stdin/stdout. When no script matches and METHOD is AES-128, built-in decryption is used unchanged.

See scripts/README.md for hook APIs, JSON protocol, and examples.

HTTP API

Run m3u8 serve to start an HTTP API server for parsing playlists, creating async download tasks, polling progress, and downloading finished files.

The server auto-loads decrypt.yaml from the working directory if present (same script matching as CLI). Pending or running tasks are recovered on restart and resume from existing segments in the task directory.

Cloud VOD credentials (-drm-token, -pkey, -mts-token) are CLI-only and not available via the HTTP API. Use CLI mode for Tencent / Alibaba encrypted sources.

Starting the Server

Development (no auth)

make build
./m3u8 serve --port 8080 --data-dir ./data

Production (with API Key auth)

./m3u8 serve \
  --port 8080 \
  --data-dir /var/m3u8/data \
  --auth-enabled \
  --api-key "your-secret-key" \
  --max-tasks 3 \
  --task-ttl 24h

Server Options

Flag Default Description
--port 8080 Listen port
--data-dir ./data Task and output storage directory
--auth-enabled false Enable API Key authentication
--api-key API Key (required when --auth-enabled)
--cors-origins * Allowed CORS origins (comma-separated)
--max-tasks 3 Max concurrent download tasks
--task-ttl 24h Retention period for completed tasks
--cleanup-interval 1h Expired task cleanup interval

When auth is enabled, all endpoints except health check require X-API-Key: <key> or Authorization: Bearer <key>.

Endpoints

Method Path Auth Description
GET /api/v1/health No Health check
POST /api/v1/parse Yes* Parse M3U8 playlist
POST /api/v1/tasks Yes* Create download task
GET /api/v1/tasks Yes* List tasks (status, limit, offset query params)
GET /api/v1/tasks/{taskID} Yes* Get task status and progress
GET /api/v1/tasks/{taskID}/download Yes* Download completed task output
DELETE /api/v1/tasks/{taskID} Yes* Cancel a running task

* Required only when --auth-enabled is set.

Task Status

pendingrunningcompleted | failed | cancelled | expired

API Examples

Parse an M3U8 URL (returns first 5 segments by default; use ?full=true for all):

curl -X POST http://localhost:8080/api/v1/parse \
  -H "Content-Type: application/json" \
  -d '{"url":"https://example.com/index.m3u8","proxy":"http://127.0.0.1:7890"}'

Create a task and poll until complete:

# Create task
curl -X POST http://localhost:8080/api/v1/tasks \
  -H "Content-Type: application/json" \
  -d '{"url":"https://example.com/index.m3u8","filename":"myvideo","concurrency":25,"to_mp4":true,"proxy":"http://127.0.0.1:7890"}'

# Poll status (replace <taskID> with returned task_id)
curl http://localhost:8080/api/v1/tasks/<taskID>

# Download output (when status is completed)
curl -OJ http://localhost:8080/api/v1/tasks/<taskID>/download

# Cancel a running task
curl -X DELETE http://localhost:8080/api/v1/tasks/<taskID>

When auth is enabled, add -H "X-API-Key: your-secret-key" to the requests above.

Parse Request Body

Field Type Description
url string M3U8 URL (required)
proxy string HTTP proxy URL

Create Task Request Body

Field Type Default Description
url string M3U8 URL (required)
filename string main Output base name
concurrency int 25 Download workers
to_mp4 bool true Remux to MP4 after merge
proxy string HTTP proxy URL

Development

Go Modules + vendor mode (-mod=vendor) for reproducible offline builds.

make vendor   # populate vendor/
make build    # build binary
make test     # run tests

Cross-compile:

make build-linux
make build-darwin-arm64
make build-windows

Download

Binary packages

Upstream releases

References

License

MIT License

About

基于 Go 的轻量级 M3U8 下载工具。支持解析 HLS 播放列表、并发下载 TS 分片、AES-128 解密、插件可扩展解密、合并为单个文件,并可通过 ffmpeg 封装为 MP4。 提供两种使用方式: CLI 命令行一次性本地下载 ;HTTP API 服务 — 远程解析、异步任务、进度查询与文件下载

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages