Files
m3u8dl/N_m3u8DL_py/README.md
T
2026-09-26 13:55:43 +08:00

3.0 KiB

N_m3u8DL-PY

N_m3u8DL-PY is a Python reimplementation of the downloader architecture in the parent N_m3u8DL-RE project. It accepts HLS, DASH and Smooth Streaming manifests from HTTP URLs or local files and downloads selected media tracks.

python -m n_m3u8dl_py <input> --auto-select

The command line intentionally follows the original project where practical. Implemented workflows include:

  • HLS master/media playlists, EXT-X-MAP, byte ranges, discontinuities and AES-128/AES-128-ECB decryption through the system openssl command.
  • DASH SegmentTemplate, SegmentTimeline, SegmentList, SegmentBase, BaseURL inheritance and common CENC metadata detection.
  • Smooth Streaming manifest parsing for supported video/audio/text tracks.
  • Parallel segment download, retries, HTTP headers/proxy support, range and ad filtering, binary concat, ffmpeg merge and post-download muxing.

DRM/CENC media cannot be decrypted in Python. The CLI passes supplied keys to the configured external decryption tool (mp4decrypt, shaka-packager, or ffmpeg) after download where possible.

Python API

The package exports a stable synchronous API for integration in another Python application. It never opens an interactive track picker.

from pathlib import Path

from n_m3u8dl_py import DownloadRequest, N_m3u8DL, TrackSelection

client = N_m3u8DL()
media = client.inspect("https://example.com/master.m3u8")

# The default request chooses the best video, the best audio per language,
# and all subtitle tracks. Track IDs can be selected explicitly when needed.
result = client.download(
    media,
    DownloadRequest(output_dir=Path("downloads"), file_name="episode"),
)

# Or use the one-call convenience method when track inspection is unnecessary.
result = client.download_url(
    "https://example.com/master.m3u8",
    DownloadRequest(output_dir=Path("downloads")),
)

video = next(track for track in media.tracks if track.resolution)
video_only = client.download(
    media,
    DownloadRequest(
        output_dir=Path("downloads"),
        selection=TrackSelection(track_ids=(video.track_id,)),
    ),
)

Pass on_event to inspect() or download() for structured progress. A callback may return False to cancel the current task; cancellation raises DownloadCancelledError. Successful calls return MediaInfo and DownloadResult; manifest, selection, and download failures raise the corresponding public exception classes.

from n_m3u8dl_py import DownloadEventKind

def show_progress(event):
    if event.kind is DownloadEventKind.SEGMENT_COMPLETED:
        print(event.track_id, event.completed_segments, event.total_segments)

media = client.inspect("playlist.m3u8", on_event=show_progress)
result = client.download(media, on_event=show_progress)

Create an editable local installation:

python -m venv --system-site-packages .venv
.venv/bin/python -m pip install --no-build-isolation -e .

Run the test suite when pytest is available:

.venv/bin/python -m pytest tests