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
- Upgrade pyplayready from >=0.6.0 to >=0.6.3
- Upgrade subby to 0.3.23 (commit 5a925c36) for lxml 6.x compatibility
- Upgrade lxml from 5.4.0 to 6.0.2
- Fix pyplayready exception imports to use root-level imports (compatible with both 0.6.0 and 0.6.3)
- Suppress SyntaxWarning from unmaintained tinycss dependency
The pyplayready package changed its API between versions:
- v0.6.0: exceptions in pyplayready.exceptions module
- v0.6.3: exceptions in pyplayready.misc.exceptions module
Using root-level imports (from pyplayready import ...) works with both versions.
ref #20
- Update lxml dependency to allow version 6.x (required by subby 0.3.23)
- Fix pyplayready exception import path (moved to misc.exceptions in 0.6.3)
fixes#17
- Update lxml dependency to allow version 6.x (required by subby 0.3.23)
- Fix pyplayready exception import path (moved to misc.exceptions in 0.6.3)
fixes#17
Very early dev work, more changes will be active in this branch.
- Implement download queue management and worker system
- Add OpenAPI/Swagger documentation
- Include download progress tracking and status endpoints
- Add API authentication and error handling
- Update core components to support API integration
Add new session utility with curl_cffi support for anti-bot protection
Update all manifest parsers (DASH, HLS, ISM, M3U8) to accept curl_cffi sessions
Add browser impersonation support (Chrome, Firefox, Safari)
Fix cookie handling compatibility between requests and curl_cffi
Suppress HTTPS proxy warnings for better UX
Maintain full backward compatibility with requests.Session
Creates a copy of the CDM dictionary before modification to prevent the original configuration from being mutated, allowing the same CDM to be selected multiple times within a session without errors.
Implements dynamic CDM selection based on video track resolution to optimize
CDM usage. Automatically selects appropriate security level (L3/SL2K for ≤1080p, L1/SL3K for >1080p) based on content requirements.
Key Features:
- Quality-based CDM configuration with threshold operators (>=, >, <=, <)
- Pre-selection based on highest quality across all video tracks
- Maintains backward compatibility with existing CDM configurations
- Single CDM per session to avoid inefficient switching
- Add intelligent embedded audio language detection at mux stage
- Automatically set audio language metadata when no separate audio tracks exist
- Respect user flags (-V, --no-audio) to avoid unnecessary processing
- Smart video track selection based on title language with fallbacks
- Improved default track selection to prioritize title language matches
- Enhanced FFmpeg repackaging with audio stream metadata injection
- Works automatically for all services without service-specific code
* Added `_truncate_pssh_for_display` method to limit the width of PSSH strings shown in the console.
* Ensures better readability of DRM information by truncating long strings.
* Implemented `_load_vaults` function to load and validate vaults by name.
* Improved `_copy_service_data` to handle key copying with better logging and error handling.
* Updated `copy` command to utilize the new vault loading function and streamline the process.
* Enhanced key insertion logic in MySQL and SQLite vaults to avoid inserting existing keys.
- Add configurable title caching with fallback support
- Cache titles for 30 minutes by default, with 24-hour fallback on API failures
- Add --no-cache and --reset-cache CLI flags for cache control
- Implement region-aware caching to handle geo-restricted content
- Use SHA256 hashing for cache keys to handle complex title IDs
- Add cache configuration variables to config system
- Document new caching options in example config
This caching system significantly reduces redundant API calls when debugging
or modifying CLI parameters, improving both performance and reliability.
Previously, using multiple track selection flags like `-S -A` would not work
as expected. The flags were treated as mutually exclusive, resulting in only
one type of track being downloaded.
This change refactors the track selection logic to properly handle combinations:
- Multiple "only" flags now work together (e.g., `-S -A` downloads both)
- Exclusion flags (`--no-*`) continue to work and override selections
- Default behavior (no flags) remains unchanged
Fixes#10
* Introduced a new configuration option for DRM decryption in `unshackle.yaml`.
* Updated the `decrypt` methods in `PlayReady` and `Widevine` classes to allow using `mp4decrypt`.
* Enhanced the `Config` class to manage decryption methods per service.
* Added `mp4decrypt` binary detection in the binaries module.
* Enhanced the `info` command to support both single `Path` objects and lists of `Path` objects.
* For lists, each path is now displayed on a separate line, improving readability.
* Maintained original logic for single `Path` objects to ensure consistent behavior.
* Introduced `MKVToolNix` and `mkvpropedit` binaries to the project.
* Updated the environment check to include required status for dependencies.
* Enhanced the `Tracks` class to raise an error if `MKVToolNix` is not found.
* Modified the `_apply_tags` function to utilize the `mkvpropedit` binary from the binaries module.