Commit Graph

306 Commits

Author SHA1 Message Date
Andy
4b30090d87 feat(gluetun): improve VPN connection display and Windscribe support 2026-01-24 13:36:04 -07:00
Andy
e77f000494 feat: Gluetun VPN integration and remote service enhancements
Major features:
- Native Docker-based Gluetun VPN proxy provider with multi-provider support
  (NordVPN, Windscribe, Surfshark, ExpressVPN, and 50+ more)
- Stateless remote service architecture with local session caching
- Client-side authentication for remote services (browser, 2FA, OAuth support)

Key changes:
- core/proxies/windscribevpn.py: Enhanced proxy handling
- core/crypto.py: Cryptographic utilities
- docs/VPN_PROXY_SETUP.md: Comprehensive VPN/proxy documentation
2026-01-24 11:23:13 -07:00
Andy
e3767716f3 feat(debug): add download output verification logging
Add comprehensive debug logging to diagnose N_m3u8DL-RE download failures where the process exits successfully but produces no output files.
2026-01-24 10:36:43 -07:00
Andy
6f5f25fa9b refactor(remote_auth): remove unused requests.Session
The session was created with headers but never used. The class saves sessions locally via the cache rather than uploading to a remote server.
2026-01-23 17:20:39 -07:00
Andy
0c7d20c943 fix(api): validate Bearer prefix before extracting API key
The replace("Bearer ", "") approach returned the full Authorization header value when the prefix was not present, incorrectly treating other auth schemes (e.g., "Basic xyz") as API keys.
2026-01-23 17:20:22 -07:00
Andy
6b90a19632 perf(aria2c): improve download performance with singleton manager
- Use singleton _Aria2Manager to reuse one aria2c process via RPC
- Add downloads via aria2.addUri instead of stdin input file
- Track per-GID byte-level progress (completedLength/totalLength)
- Add thread-safe operations with threading.Lock
- Enable graceful cancellation by removing individual downloads via RPC
2026-01-23 17:14:12 -07:00
Andy
b8e2f3da3f feat(titles): use track source attribute for service name in filenames
Allow services to set a custom `source` attribute on tracks, which will be used in the filename instead of the service class name.
2026-01-22 20:21:00 -07:00
Andy
af49560345 Merge branch 'main' into dev 2026-01-22 14:47:25 -07:00
Andy
f0bae6d6b4 fix(cdm): correct error key casing in Decrypt Labs API response parsing
The API returns error details with capital "Error" key, but the code was checking for lowercase "error", causing error details to be ignored.
2026-01-22 14:13:27 -07:00
Sp5rky
acbb92bb82 Merge pull request #46 from MasterOfKay/main
Merging dash-naming feature - adds optional dash separator format for filenames
2026-01-22 13:58:24 -07:00
Sp5rky
73a4bf8764 Merge pull request #53 from CodeName393/main
Merging after code review - fixes binary path handling
2026-01-22 13:53:23 -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
Andy
9463870da7 fix(serve): use correct pywidevine users config format
pywidevine's serve module expects users to be a dict mapping secret keys to user objects with devices and username, not a simple list.
This was causing TypeError when accessing CDM endpoints.
2026-01-22 17:33:19 +00:00
CodeName393
3c049a1fc0 Fix n_m3u8dl_re 2026-01-22 15:28:24 +09:00
CodeName393
f3cc1d080e Fix Hybrid 2026-01-22 15:27:57 +09:00
Andy
eaad0e3cc2 chore(release): bump version to 2.3.1 2026-01-22 00:39:41 +00:00
CodeName393
b384139b41 Fix 2 2026-01-22 02:41:21 +09:00
CodeName393
9cd67568d2 Fix 2026-01-22 02:34:34 +09:00
CodeName393
28b91fddd3 Merge branch 'main' into main 2026-01-22 02:29:08 +09:00
Andy
71bbb27d47 fix(deps): upgrade vulnerable dependencies for security alerts
- urllib3: 2.5.0 -> 2.6.3 (CVE-2025-66418, CVE-2025-66471, CVE-2026-21441)
- aiohttp: 3.13.2 -> 3.13.3 (8 CVEs including CVE-2025-69223, CVE-2025-69227)
- fonttools: 4.60.1 -> 4.61.1 (CVE-2025-66034)
- filelock: 3.19.1 -> 3.20.3 (CVE-2025-68146, CVE-2026-22701)
- virtualenv: 20.34.0 -> 20.36.1 (CVE-2026-22702)
2026-01-21 15:09:51 +00: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
477fd7f2eb fix(n_m3u8dl_re): include language in DASH audio track selection
When DASH manifests have multiple audio AdaptationSets with the same representation IDs (e.g., both English and Japanese having id="0"), N_m3u8DL-RE would download the same track twice.

Now includes the language alongside the ID in selection args to properly disambiguate tracks across adaptation sets.
2026-01-19 20:18:45 +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
abd8fc2eb9 chore(release): bump version to 2.3.0 2026-01-18 19:03:14 +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
4e11f69a58 fix(drm): filter Widevine PSSH by system ID instead of sorting
The previous sorting approach crashed with KeyError when unsupported DRM systems were present in the init segment. Now uses direct filtering
2026-01-17 13:36:57 +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
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
18b0534020 fix(subs): strip whitespace from ASS font names
Use removeprefix instead of removesuffix and add strip() to handle ASS subtitle files that have spaces after commas in Style definitions.

Fixes #57
2026-01-16 13:42:11 +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
415544775b fix(vaults): adaptive batch sizing for bulk key operations 2026-01-14 23:04:54 +00:00
Andy
6740dd3dfa Revert "fix(vaults): batch bulk key operations to avoid query limits"
This reverts commit 7e7bc7aecf.
2026-01-14 23:00:43 +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
7e7bc7aecf fix(vaults): batch bulk key operations to avoid query limits 2026-01-11 08:21:02 +00:00
Andy
ede38648db fix(util): improve test command error detection and add natural sorting 2026-01-07 16:22:45 +00:00
Andy
17a91ee4bb feat(debug): add comprehensive debug logging for downloaders and muxing 2026-01-05 09:50:33 +00:00
CodeName393
450cde7c80 Troubleshooting some string overlap 2025-12-31 19:27:39 +09:00
CodeName393
197fe76f7a Replace ffmpeg string with FFMPEG variable 2025-12-31 19:27:10 +09:00
MasterOfKay
8aec80246a added config.py changes 2025-11-28 16:27:26 +01:00
Andy
dc9823cd28 chore(release): bump version to 2.1.0 2025-11-27 23:35:56 +00:00
Andy
6fa3554b70 fix(dl): preserve attachments when rebuilding track list
Attachments (screenshots, fonts) were being dropped when title.tracks was rebuilt from kept_tracks, causing image files to remain in temp directory after muxing. The cleanup code iterated over an empty attachments list since they were orphaned during track filtering.
2025-11-27 23:03:53 +00:00
Andy
965482a1e4 feat: merge upstream dev branch
- Add Gluetun dynamic VPN-to-HTTP proxy provider
   - Add remote services and authentication system
   - Add country code utilities
   - Add Docker binary detection
   - Update proxy providers
2025-11-25 20:23:06 +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