Commit Graph

164 Commits

Author SHA1 Message Date
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
68ad76cbb0 feat(config): add unicode_filenames option to preserve native characters
Add config option to disable ASCII transliteration in filenames, allowing preservation of Korean, Japanese, Chinese, and other native language characters instead of converting them via unidecode.

Closes #49
2026-01-16 13:43:50 +00:00
Andy
d0cefa9d58 fix(drm): include shaka-packager binary in error messages 2026-01-16 13:26:15 +00:00
Andy
a01f335cfc fix(dash): handle N_m3u8DL-RE merge and decryption
- Add skip_merge flag for N_m3u8DL-RE to prevent duplicate init data
- Pass content_keys to N_m3u8DL-RE for internal decryption handling
- Use shutil.move() instead of manual merge when skip_merge is True
- Skip manual decryption when N_m3u8DL-RE handles it internally

Fixes audio corruption ("Box 'OG 2' size is too large") when using N_m3u8DL-RE with DASH manifests that have SegmentBase init data. The init segment was being written twice: once by N_m3u8DL-RE during its internal merge, and again by dash.py during post-processing.
2026-01-16 13:25:34 +00:00
Andy
b01fc3c8d1 fix(dash): handle placeholder KIDs and improve DRM init from segments
- Add CENC namespace support for kid/default_KID attributes
- Detect and replace placeholder/test KIDs in Widevine PSSH:
  - All zeros (key rotation default)
  - Sequential 0x00-0x0f pattern
  - Shaka Packager test pattern
- Change DRM init condition from `not track.drm` to `init_data` to ensure DRM is always re-initialized from init segments

Fixes issue where Widevine PSSH contains placeholder KIDs while the real KID is only in ContentProtection default_KID attributes.
2026-01-15 12:50:22 +00:00
Andy
44acfbdc89 fix(drm): correct PSSH system ID comparison in PlayReady
Remove erroneous `.bytes` accessor from PSSH.SYSTEM_ID comparisons in from_track() and from_init_data() methods. The pyplayready PSSH.SYSTEM_ID is already the correct type for comparison with parsed PSSH box system_ID values.
2026-01-15 12:48:18 +00:00
Andy
d1d3daf750 chore(release): bump version to 2.2.0 2026-01-15 03:07:18 +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
fcd70e5b0f fix(titles): detect HDR10 in hybrid DV filenames correctly
Hybrid DV+HDR10 files were named "DV.H.265" instead of "DV.HDR.H.265" because the HDR10 detection only checked hdr_format_full which contains "Dolby Vision / SMPTE ST 2094". The "HDR10" indicator is in hdr_format_commercial, not hdr_format_full.

Now checks both fields for HDR10 compatibility indicators.
2026-01-14 22:25:58 +00:00
Andy
17a91ee4bb feat(debug): add comprehensive debug logging for downloaders and muxing 2026-01-05 09:50:33 +00:00
Andy
dc9823cd28 chore(release): bump version to 2.1.0 2025-11-27 23:35:56 +00:00
Andy
2d4bf140fa fix(dash): add AdaptationSet-level BaseURL resolution
Add support for BaseURL elements at the AdaptationSet level per DASH spec. The URL resolution chain now properly follows: MPD → Period → AdaptationSet → Representation.
2025-11-25 16:09:28 +00:00
Andy
d0816787ce fix: restrict WindscribeVPN to supported regions 2025-11-24 18:17:00 +00:00
Andy
3d384b8e3e fix(windscribevpn): add error handling for unsupported regions in get_proxy method 2025-11-23 08:06:43 +00:00
Andy
e0a666ada6 fix(utilities): make space-hyphen-space handling conditional on scene_naming 2025-11-21 19:22:20 +00:00
Andy
26c81779fa fix(utilities): handle space-hyphen-space separators in sanitize_filename
Pre-process space-hyphen-space patterns (e.g., "Title - Episode") before other character replacements to prevent creating problematic dot-hyphen-dot (.-.) patterns in filenames.

This addresses PR #44 by fixing the root cause rather than post-processing the problematic pattern. The fix ensures that titles like "Show - S01E01" become "Show.S01E01"
2025-11-21 19:14:54 +00: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
492134b8ff fix(hls): convert range_offset to int to prevent TypeError
Fixed TypeError in calculate_byte_range where range_offset was a string instead of int. The byte_range.split("-")[0] returns a string, but the calculate_byte_range method expects fallback_offset parameter to be int.
2025-11-14 23:08:13 +00:00
Andy
1ebb62ee91 refactor(tags): remove environment variable fallbacks for API keys 2025-11-09 23:46:31 +00:00
Andy
240c70a2aa fix(tags): skip metadata lookup when API keys not configured 2025-11-09 23:30:33 +00:00
Andy
eef06fb986 fix: suppress verbose fontTools logging when scanning system fonts 2025-11-09 23:19:12 +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
90e4030a88 fix(n_m3u8dl_re): read lang attribute from DASH manifests correctly
The track_selection function was using findall() to search for lang child elements, but in DASH manifests lang is an XML attribute on AdaptationSet. This caused language selection to fail for region-specific codes like es-419.
2025-11-08 06:04:37 +00:00
Andy
11bcca9632 fix(cdm): apply session key fix to custom_remote_cdm
Apply the same partial cached keys fix from decrypt_labs_remote_cdm to custom_remote_cdm. When cached keys don't cover all required KIDs, store them in session["cached_keys"] instead of session["keys"] to allow parse_license() to properly combine vault_keys + cached_keys + license_keys.
2025-11-08 03:02:17 +00:00
Andy
cc7263884f fix(cdm): resolve session key handling for partial cached keys
When decrypt-labs returns cached keys that don't cover all required KIDs, the CDM now properly stores them in session["cached_keys"] instead of session["keys"]. This allows parse_license() to correctly combine vault_keys + cached_keys + license_keys, fixing downloads that previously failed when mixing cached and fresh licenses.
2025-11-08 03:00:19 +00: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
8b0b3045e3 feat(fonts): add Linux font support for ASS/SSA subtitles
Implements cross-platform font discovery and intelligent fallback system for ASS/SSA subtitle rendering on Linux/macOS systems.

Windows support has not been tested
2025-11-03 20:23:45 +00:00
Andy
f979e94235 fix(session): remove padding extension from OkHttp JA3 fingerprints
Remove extension 21 (TLS padding) from okhttp4 and okhttp5 JA3 strings to resolve SSL/TLS handshake failures.
2025-11-03 05:32:57 +00:00
Andy
f1fe940708 fix(session): update OkHttp fingerprint presets 2025-11-03 03:16:54 +00:00
Andy
565b0e0ea7 feat(session): add custom fingerprint and preset support
Add support for custom TLS/HTTP fingerprints to session() function, enabling services to impersonate Android/OkHttp clients instead of just browsers.
2025-11-03 01:15:49 +00:00
Andy
001f6a0146 feat(cache): add TMDB and Simkl metadata caching to title cache 2025-11-02 23:33:24 +00:00
Andy
27d0ca84a3 fix(dash): correct segment count calculation for startNumber=0
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
2025-11-02 20:30:06 +00:00
Andy
597a8b7912 fix(naming): improve HDR detection with comprehensive transfer checks and hybrid DV+HDR10 support
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.
2025-11-02 03:19:14 +00:00
Andy
6ebdfa8818 fix(subtitle): resolve SDH stripping crash with VTT files
Fixes #34
2025-10-31 14:51:25 +00:00
Andy
351a606258 feat(api): add default parameter handling and improved error responses
Add default parameter system to API server that matches CLI behavior, eliminating errors from missing optional parameters.
2025-10-30 05:16:14 +00:00
Andy
504de2197a fix(drm): add explicit UTF-8 encoding to mp4decrypt subprocess calls
Fixes 'charmap' codec can't decode byte error that occurs on Windows
when mp4decrypt outputs non-ASCII characters. Without explicit encoding,
2025-10-28 18:49:13 +00:00
Andy
5c8eb2107a feat(api): complete API enhancements for v2.0.0
- Add missing download parameters (latest_episode, exact_lang, audio_description, no_mux)
- Expand OpenAPI schema with comprehensive documentation for all 40+ download parameters
- Add robust parameter validation with clear error messages
- Implement job filtering by status/service and sorting capabilities
2025-10-26 04:40:55 +00:00
Andy
d0c6a7fa63 feat(api): add url field to services endpoint response 2025-10-26 04:19:43 +00:00
Andy
3571c5eb3c style: apply ruff formatting fixes 2025-10-23 18:11:30 +00:00
Andy
07574d8d02 refactor(binaries): remove unused mypy import 2025-10-22 20:47:46 +00:00
Andy
98d4bb4333 fix(config): support config in user config directory across platforms
Fixes #23
2025-10-22 16:48:03 +00:00
Andy
93debf149a Merge commit 'refs/pull/19/head' of https://github.com/unshackle-dl/unshackle into dev 2025-10-22 01:36:51 +00:00
TPD94
e04399fbce Update binaries.py
Refactor code to search for binaries either in root of binary folder or in a subfolder named after the binary.
2025-10-21 21:18:36 -04:00
TPD94
087df59fb6 Update hls.py 2025-10-21 21:07:24 -04:00
Andy
5384b775a4 refactor(session): modernize type annotations to PEP 604 syntax 2025-10-20 21:09:19 +00:00
Andy
2a90e60a49 Merge PR #31: feat: add retry handler to curl_cffi Session 2025-10-20 19:59:58 +00:00
stabbedbybrick
1409f93de5 feat: add retry handler to curl_cffi Session 2025-10-20 18:28:12 +02:00
Andy
d3ca8e7039 fix(tags): gracefully handle missing TMDB/Simkl API keys
Simkl now requires a client_id from https://simkl.com/settings/developer/
2025-10-20 03:13:30 +00:00