Commit Graph

57 Commits

Author SHA1 Message Date
Andy
df92f9e4b6 refactor(hybrid): replace log.info with console status and add JSONL debug logging 2026-02-16 13:33:11 -07:00
Andy
f96f1f9a95 feat(hybrid): add L5 active area and dynamic L6 luminance metadata
Add crop detection via ffmpeg to generate Level 5 active area metadata, resolving DV/HDR10 black bar mismatches. Update Level 6 to extract actual luminance values from the RPU instead of hardcoding defaults.
2026-02-15 17:38:43 -07:00
Andy
23cc351f77 feat(tracks): prioritize Atmos audio tracks over higher bitrate non-Atmos 2026-02-15 12:08:27 -07:00
Andy
29a697a8e7 fix(tracks): close temp session and improve path type error 2026-02-08 20:04:22 -07:00
Andy
6b8a8ba8a8 feat(cdm): normalize CDM detection for local and remote implementations
Add unshackle.core.cdm.detect helpers to classify CDMs consistently across local and remote backends.

- Add is_playready_cdm/is_widevine_cdm for DRM selection across pyplayready, pywidevine, and wrappers

- Add is_remote_cdm/is_local_cdm/cdm_location so services can branch on CDM execution location

- Switch core DASH/HLS parsing, track DRM selection, and dl CDM switching away from brittle isinstance/DecryptLabs-only checks

- Make unshackle.core.cdm import-light via lazy __getattr__ so optional CDM deps are only imported when needed
2026-02-08 00:37:53 -07:00
Andy
b16610ac63 fix(progress): bind per-track bars and force terminal completion 2026-02-04 12:55:02 -07:00
Andy
6186ff764b fix(progress): force track bar completion on terminal states 2026-02-04 12:31:49 -07:00
Andy
a6494d9b54 fix(dl): prevent attachment downloads during --skip-dl
Set DOWNLOAD_LICENCE_ONLY earlier in the download command so services build tracks in license-only mode.

Update Attachment URL handling to avoid eager downloads in license-only mode while keeping metadata, stable IDs, and safe cleanup behavior.
2026-02-03 21:20:26 -07:00
Andy
cacb695093 fix(subtitles): preserve sidecar originals
Use original subtitle files for sidecar output while keeping muxed conversion behavior.

Fixes #59
2026-02-02 21:43:27 -07:00
Andy
d0d8044fb3 feat(video): detect interlaced scan type from MPD manifests 2026-01-31 23:51:57 -07:00
Andy
d2d86fa6b7 Merge remote-tracking branch 'origin/main' into dev 2026-01-30 15:39:50 -07:00
Andy
cf537891f7 fix(subs): route pycaption-unsupported formats to pysubs2 in auto mode 2026-01-26 10:13:03 -07:00
Andy
af49560345 Merge branch 'main' into dev 2026-01-22 14:47:25 -07:00
stabbedbybrick
a60247f485 add WVTT (WebVTT in MP4) subtitle converter for subby (#61)
* chore(deps): update subby to 0.3.27

* fix(subs): add WVTT (WebVTT in MP4) subtitle converter for subby

- Use WVTTConverter if self.codec == Subtitle.Codec.fVTT
- Read or save files as Paths instead of strings to avoid AttributeErrors
- Add CommonIssuesFixer when stripping SDH
- Set Subtitle.Codec.fVTT to use subby if conversion_method == "auto"
- Silence the underlying srt library logging used by subby to avoid info messages being printed to console
2026-01-22 12:41:41 -07:00
CodeName393
f3cc1d080e Fix Hybrid 2026-01-22 15:27:57 +09:00
CodeName393
28b91fddd3 Merge branch 'main' into main 2026-01-22 02:29:08 +09:00
Andy
766447cd71 fix(hls): prefer media playlist keys over session keys for accurate KID matching
Session keys from master playlists often contain PSSHs with multiple KIDs covering all tracks, causing licensing to return keys for wrong KIDs.

Changes:
- Unified DRM licensing logic for all downloaders
- Prefer media playlist EXT-X-KEY tags which contain track-specific KIDs
- Add filter_keys_for_cdm() to select keys matching configured CDM type
- Add get_track_kid_from_init() to extract KID from init segment with fallback to drm.kid from PSSH
- Track initial_drm_key to prevent double-licensing on first segment
- Simplify n_m3u8dl_re block to reuse common licensing flow
- Use strict PlayReady keyformat matching via PR_PSSH.SYSTEM_ID URN instead of loose substring match
- Fix PlayReady keyformat comparisons that incorrectly compared strings to PlayReadyCdm class
- Fix byterange header format in get_track_kid_from_init() to use HLS.calculate_byte_range()

Also fixes PlayReady keyformat matching in:
- unshackle/core/tracks/track.py
- unshackle/core/drm/playready.py

Fixes download failures where track_kid was null or mismatched, causing wrong content keys to be obtained during PlayReady/Widevine licensing.
2026-01-21 00:20:07 +00:00
Andy
90a7db2e46 fix(subs): update SubtitleEdit CLI syntax and respect conversion_method
- Use lowercase format names (subrip, webvtt, advancedsubstationalpha) to match SubtitleEdit 4.x CLI requirements
- Change /Convert to /convert for consistency with CLI docs
- Convert Path objects to strings explicitly for subprocess calls
- Respect conversion_method config in SDH stripping - skip SubtitleEdit when user has set pysubs2/pycaption/subby as their preferred method
- Add stderr suppression to SubtitleEdit calls
2026-01-19 00:32:19 +00:00
Andy
e99cfddaec fix(subs): handle WebVTT cue identifiers and overlapping multi-line cues
Some services use WebVTT files with:
- Cue identifiers (Q0, Q1, etc.) before timing lines that pysubs2/pycaption incorrectly parses as subtitle text
- Multi-line subtitles split into separate cues with 1ms offset times and different line: positions (e.g., line:77% for top, line:84% for bottom)

Added detection and sanitization functions:
- has_webvtt_cue_identifiers(): detects cue identifiers before timing
- sanitize_webvtt_cue_identifiers(): removes problematic cue identifiers
- has_overlapping_webvtt_cues(): detects overlapping cues needing merge
- merge_overlapping_webvtt_cues(): merges cues sorted by line position
2026-01-18 04:44:08 +00:00
Andy
aec3333888 fix(subs): handle negative TTML values in multi-value attributes
The previous regex only matched negative size values when they were the entire quoted attribute (e.g., "-5%"). This failed for multi-value attributes like tts:extent="-5% 7.5%" causing pycaption parse errors.

The new pattern matches negative values anywhere in the text and preserves the unit during replacement.

Closes #47
2026-01-16 14:16:47 +00:00
Andy
a7b6e9e680 feat(drm): add CDM-aware PlayReady fallback detection
Add PlayReady PSSH/KID extraction from track and init data with CDM-aware ordering. When PlayReady CDM is selected, tries PlayReady first then falls back to Widevine. When Widevine CDM is selected (default), tries Widevine first then falls back to PlayReady.
2026-01-15 02:49:56 +00:00
Andy
17a91ee4bb feat(debug): add comprehensive debug logging for downloaders and muxing 2026-01-05 09:50:33 +00:00
CodeName393
197fe76f7a Replace ffmpeg string with FFMPEG variable 2025-12-31 19:27:10 +09:00
Andy
a7a8c882d8 fix(video): correct CICP enum values to match ITU-T H.273 specification
- Add Primaries.Unspecified (value 2) per user request and H.273 spec
- Rename Primaries value 0 from Unspecified to Reserved for spec accuracy
- Rename Transfer value 0 from Unspecified to Reserved for consistency
- Simplify Transfer value 2 from Unspecified_Image to Unspecified
- Update condition check to use enum values instead of numeric tuple
- Enhance docstring with detailed sources and rationale for changes

All CICP values verified against ITU-T H.273, ISO/IEC 23091-2, H.264/H.265 specifications, and FFmpeg AVColorPrimaries/AVColorTransferCharacteristic enums.
2025-11-16 17:28:32 +00:00
Andy
87ff66f8fe fix: ensure subtitles use requests downloader instead of n_m3u8dl_re if Descriptor.URL
PR #38 refactored n_m3u8dl_re track selection to support DASH/ISM subtitle tracks, but this broke some subtitle downloads. Services that use direct URL downloads (Descriptor.URL) for subtitles, which n_m3u8dl_re does not support.
2025-11-09 21:27:19 +00:00
Andy
55db8da125 refactor: remove unnecessary underscore prefixes from function names 2025-11-08 22:53:47 +00:00
stabbedbybrick
9ed5133c4c N_m3u8DL-RE: Improve track selection, add download arguments and option to load manifest from file (#38)
* feat: Add 'from_file', 'downloader_args' to Track

* feat: Add loading HLS playlist from file

* refactor: Improve track selection, args for n_m3u8dl_re
2025-11-08 13:57:52 -07:00
Andy
8a46655d21 feat(subtitle): preserve original formatting when no conversion requested
Add preserve_formatting config option to prevent automatic subtitle processing that strips formatting tags and styling. When enabled (default: true), WebVTT files skip pycaption read/write cycle to preserve tags like <i>, <b>, positioning, and other formatting.
2025-11-03 23:01:31 +00:00
Andy
6ebdfa8818 fix(subtitle): resolve SDH stripping crash with VTT files
Fixes #34
2025-10-31 14:51:25 +00:00
Andy
3f6a7e1f68 feat: add --exact-lang flag for precise language matching
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.
2025-10-08 01:54:30 +00:00
Andy
acbbe734ab Merge branch 'feature/pysubs2-subtitle conversion' into main 2025-10-01 04:16:06 +00:00
Andy
6d0a210efb fix: (subtitle): Move pysubs2 to not be auto while in "testing" phase. 2025-10-01 04:11:22 +00:00
Sp5rky
26a94b7135 feat: add pysubs2 subtitle conversion with extended format support
- Add pysubs2 as default conversion method for 'auto' mode
- Add support for MicroDVD (.sub), MPL2 (.mpl2), and TMP (.tmp) formats
- Implement convert_with_pysubs2() method with fallback to standard conversion
- Update from_mime() to handle new subtitle format types
- Map all supported formats to pysubs2 format identifiers
- Update docstrings to reflect new capabilities
2025-09-30 14:12:51 -06:00
Andy
e92e5c2ba3 feat: add AC4 codec support in Audio class and update mime/profile handling 2025-09-26 04:42:06 +00:00
Andy
a2c6798fe6 fix: optimize audio track sorting by grouping descriptive tracks and sorting by bitrate, fixes bug that does not identify ATMOS or DD+ as the highest quality available in filenaming. 2025-09-25 23:21:35 +00:00
Andy
35efdbff6d feat: add curl_cffi session support with browser impersonation
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
2025-09-25 06:27:14 +00:00
Andy
63b7a49c1a feat: Add decrypt_labs_api_key to Config initialization and change duplicate track log level to debug 2025-09-25 06:22:50 +00:00
Andy
4006593a8a Fix: Implement lazy DRM loading for multi-track key retrieval
- Add deferred DRM loading to M3U8 parser to mark tracks for later processing
- Optimize prepare_drm to load DRM just-in-time during download process
2025-09-12 06:38:14 +00:00
Andy
a82828768d feat: automatic audio language metadata for embedded audio tracks
- 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
2025-09-10 00:57:14 +00:00
Andy
9fd0895128 feat(cdm): Refactor DecryptLabsRemoteCDM full support for Widevine/Playready and ChromeCDM 2025-09-02 04:02:52 +00:00
Andy
ead05d08ac fix(subtitle): Handle ValueError in subtitle filtering for multiple colons in time references fixes issues with subtitles that contain multiple colons 2025-08-06 01:28:03 +00:00
Andy
8dbdde697d feat(hybrid): Enhance extraction and conversion processes with dymanic spinning bars to follow the rest of the codebase. 2025-08-05 14:57:51 +00:00
Andy
507690834b feat(tracks): Add support for HLG color transfer characteristics in video arguments 2025-08-04 19:28:11 +00:00
Andy
f8a58d966b feat(subtitle): Add filtering for unwanted cues in WebVTT subtitles 2025-08-03 22:10:17 +00:00
Andy
4691694d2e feat: Add Unspecified_Image option to Transfer enum in Video class.
The Transfer enum was missing value 2, which according to ITU-T H.Sup19 standards represents "Unspecified (Image
  characteristics are unknown or are determined by the application)". This value is often used for still image coding systems.
2025-08-01 17:10:55 +00:00
Andy
a07345a0a2 refactor: Replace log.exit calls with ValueError exceptions for error handling in Hybrid class 2025-07-31 23:48:22 +00:00
Andy
67caf71295 Merge branch 'hdr10ptest' 2025-07-30 22:49:01 +00:00
Andy
4de9251f95 feat(tracks): Add duration fix handling for video and hybrid tracks 2025-07-30 21:39:34 +00:00
Andy
d2fb409ad9 feat(hybrid): Add HDR10+ support for conversion to Dolby Vision and enhance metadata extraction 2025-07-30 21:14:50 +00:00
Andy
5d1f2eb458 feat(attachment): Ensure temporary directory is created for downloads 2025-07-30 18:52:36 +00:00