Fix off-by-one error in SegmentTemplate segment enumeration when startNumber is 0. Previously, the code would request one extra segment beyond what exists, causing 404 errors on the final segment.
The issue was that end_number was calculated as a segment count via math.ceil(), but then used incorrectly with range(start_number, end_number + 1), treating it as both a count and an inclusive endpoint.
Changed to explicitly calculate segment_count first, then derive end_number as: start_number + segment_count - 1
Example:
- Duration: 3540.996s, segment duration: 4s
- Before: segments 0-886 (887 segments) - segment 886 doesn't exist
- After: segments 0-885 (886 segments) - correct
HDR10/PQ detection now includes:
- PQ (most common)
- SMPTE ST 2084 (CICP value 16)
- BT.2100
- BT.2020-10
- smpte2084 (lowercase variant)
HLG detection now includes:
- HLG
- Hybrid Log-Gamma
- ARIB STD-B67 (CICP value 18)
- arib-std-b67 (lowercase variant)
Hybrid DV+HDR10 detection:
- Now checks full hdr_format field for both "Dolby Vision" AND
("HDR10" OR "SMPTE ST 2086")
- Properly generates filenames like "Movie.2160p.DV HDR H.265.mkv"
- MediaInfo reports: "Dolby Vision / SMPTE ST 2086, HDR10 compatible"
Also adds null safety for transfer characteristics to prevent errors when the field is None.
Add support for downloading audio description tracks via the --audio-description/-ad flag. Previously, descriptive audio tracks were always filtered out. Users can now optionally include them.
Fixes#33
Add validation to check that both HDR10 and DV tracks are available when HYBRID mode is requested. This prevents wasted downloads when the hybrid processing would fail due to missing tracks.
Add support for per-service configuration overrides allowing fine-tuned control of downloader and command options on a service-by-service basis.
Fixes#13
Adds a new CLI option `-le, --latest-episode` that automatically selects and downloads only the single most recent episode from a series, regardless of which season it's in.
Fixes#28
Add new CustomRemoteCDM class to support custom CDM API providers with maximum configurability through YAML configuration alone. This addresses GitHub issue #26 by enabling integration with third-party CDM APIs.
Previously, forced subtitles were incorrectly included when they matched
languages in the lang configuration, even without the --forced-subs flag.
This caused forced subs to appear when using language configs or the -l
parameter, which violated the expected behavior.
Implements a complete structured logging system for troubleshooting and service development.
Features:
- Binary toggle via --debug flag or debug: true in config
- JSON Lines (.jsonl) format for easy parsing and analysis
- Comprehensive logging of all operations:
* Session info (version, platform, Python version)
* CLI parameters and service configuration
* CDM details (Widevine/PlayReady, security levels)
* Authentication status
* Title and track metadata
* DRM operations (PSSH, KIDs, license requests)
* Vault queries with key retrieval
* Full error traces with context
- Configurable key logging via debug_keys option
- Smart redaction (passwords, tokens, cookies always redacted)
- Error logging for all critical operations:
* Authentication failures
* Title fetching errors
* Track retrieval errors
* License request failures (Widevine & PlayReady)
* Vault operation errors
- Removed old text logging system
Fixes#24
When attaching fonts for ASS/SSA subtitles, the Attachment class was being
called with positional arguments instead of keyword arguments. This caused
the font Path object to be incorrectly interpreted, leading to an error:
"Invalid URL 'Arial (arial)': No scheme supplied."
Changed Attachment(font, name) to Attachment(path=font, name=name) to
explicitly pass arguments by keyword, ensuring proper parameter handling.
Revert the warnings filter added in 2d5e807 as it didn't work as expected to suppress the tinycss SyntaxWarning. Also fix isort order in prd.py for pyplayready imports.
New --exact-lang CLI flag that enables exact language code matching instead of fuzzy matching. This allows users to get specific regional variants without matching all related variants.
Examples:
- `-l es-419` normally matches all Spanish (es-ES, es-419, es-MX)
- `-l es-419 --exact-lang` matches ONLY es-419 (Latin American Spanish)
Fixes language detection issue where specific variants like es-419 (Latin American Spanish) would match all Spanish variants instead of just close regional variants.
Add --no-mux command-line option to allow downloading individual track
files without muxing them into a container file (.mkv/.mka/.mks).
This addresses use cases where users want to download tracks separately,
such as:
- Downloading only subtitles as individual .srt/.vtt files
- Keeping audio/video/subtitle tracks as separate files
- Converting subtitle formats without creating container files
When --no-mux is used:
- Tracks are saved as individual files with descriptive suffixes
- Video tracks: filename.{codec}.ext
- Audio tracks: filename.{language}.{codec}.ext
- Subtitle tracks: filename.{language}.forced.sdh.ext (as applicable)
- Folder structure respects --no-folder flag
Resolves#21