# 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. ```bash python -m n_m3u8dl_py --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. ```python 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. ```python 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: ```bash 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: ```bash .venv/bin/python -m pytest tests ```