Commit Graph

271 Commits

Author SHA1 Message Date
Sp5rky
8d05a8ceb8 Merge pull request #79 from CodeName393/select-title-update
Select title update
2026-02-26 08:02:31 -07:00
CodeName393
c5ef13df5d Update selector.py 2026-02-26 15:25:09 +09:00
CodeName393
0f25b0ce52 Update selector.py 2026-02-26 15:18:21 +09:00
CodeName393
00b4f2cdd1 Update selector.py 2026-02-26 15:16:34 +09:00
Andy
820db5f179 refactor(providers): extract metadata providers into modular system
- Create `unshackle/core/providers/` package with abstract base class, IMDBApi (free, no key), SIMKL, and TMDB provider implementations
- Add consensus-based ID enrichment: cross-references IMDB IDs with TMDB and SIMKL, drops all data from providers that disagree on tmdb_id (likely resolved to wrong title)
- Cache enriched IDs alongside raw provider data so they survive cache round-trips
- Genericize TitleCacher with `cache_provider()`/`get_cached_provider()` replacing provider-specific methods; respect `--no-cache` flag
- Add `--imdb` CLI flag to dl command for direct IMDB ID lookup
2026-02-25 19:02:18 -07:00
Andy
42d6ef5765 fix(n_m3u8dl_re): disable segment count validation for duration-based DASH
N_m3u8DL-RE uses Math.Ceiling to calculate segment counts from SegmentTemplate @duration, which overshoots by 1 when the division has a small fractional remainder. This causes 404 on the phantom last segment and fails with "Segment count check not pass".

Upstream bug: nilaoda/N_m3u8DL-RE#108
2026-02-25 11:11:41 -07:00
CodeName393
772bacfc8f Update selector.py 2026-02-25 19:26:35 +09:00
Andy
86a7a95b6f docs: update and correct configuration documentation 2026-02-24 23:50:33 -07:00
Andy
34f4d6bff7 fix(track): fallback to requests downloader from n_m3u8dl_re for unsupported track types 2026-02-24 12:57:46 -07:00
Andy
b11b23e529 chore(release): bump version to 3.1.0 2026-02-23 16:27:05 -07:00
Andy
d0341f6844 feat(core): add TrackRequest system for multi-codec/multi-range support
Add TrackRequest dataclass to Service base class that centralizes CLI vcodec/range/best_available params. Services read from self.track_request instead of accessing ctx.parent.params directly.

- Add TrackRequest dataclass with codecs, ranges, best_available fields
- Set self.track_request in Service.__init__() from CLI params
- Add _get_tracks_for_variants() helper for per-codec/range API calls
- Update dl.py to detect migrated vs legacy services automatically
- Handle HYBRID+other ranges (e.g. -r HYBRID,SDR) correctly in dl.py
- Support --best-available with multi-range/codec (skip unavailable)
2026-02-23 15:47:27 -07:00
Andy
983fd18d53 fix(session): reduce default max_retries from 10 to 5 for CurlSession
fix(service): reduce max_retries from 15 to 5 for HTTPAdapter
2026-02-23 12:59:07 -07:00
Andy
8b63be4f3e feat(dl): add --repack flag to insert REPACK tag in output filenames 2026-02-22 11:42:35 -07:00
Andy
829ae01000 fix(hybrid): accept HDR10+ tracks as valid base layer for HYBRID mode
HYBRID mode previously required a plain HDR10 track, rejecting HDR10+ (HDR10P) even though it's a perfectly valid (and superior) base layer.
HDR10+ is now preferred over HDR10 when both are available, preserving dynamic metadata in the final DV Profile 8 output.
2026-02-18 15:56:55 -07:00
Andy
e7120bd063 fix(attachment): sanitize filenames with illegal Windows characters 2026-02-17 16:02:59 -07:00
Andy
c10257b8dc Revert "feat(debug): add JSONL debug logging to decryption, muxing, and all downloaders"
This reverts commit cc89f4ca93.
2026-02-17 14:37:50 -07:00
Andy
cc89f4ca93 feat(debug): add JSONL debug logging to decryption, muxing, and all downloaders
Expand debug logging coverage for better diagnostics when investigating download/decryption issues like QUICKTIME/cbcs problem.
2026-02-17 13:58:36 -07:00
CodeName393
d2f221f3fc Restore code comments 2026-02-18 03:36:54 +09:00
CodeName393
57ecddfeeb Delete terminal reset logic 2026-02-18 03:27:35 +09:00
CodeName393
b9bf8fddf5 Selector Update 2026-02-18 02:41:00 +09:00
Andy
0217086abf style: fix ruff E721, E701, and E722 lint errors 2026-02-16 13:37:23 -07:00
Andy
df92f9e4b6 refactor(hybrid): replace log.info with console status and add JSONL debug logging 2026-02-16 13:33:11 -07:00
Andy
9ed56709cd Merge branch 'dev' of https://github.com/unshackle-dl/unshackle into dev 2026-02-15 17:38:52 -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
Sp5rky
9f9a609d71 Merge pull request #77 from CodeName393/Select-Titles
Add Select titles option
2026-02-15 16:19:42 -07:00
Andy
cee7d9a75f fix(n_m3u8dl_re): pass all content keys for DualKey DRM decryption 2026-02-15 13:37:49 -07:00
Andy
bf9087a1ce chore(release): bump version to 3.0.0
BREAKING CHANGE: PlayReady users without explicit playready_devices no longer get access to all devices by default.

Key changes:
- feat(drm): add MonaLisa DRM support to core infrastructure
- feat(cdm): add remote PlayReady CDM support via pyplayready RemoteCdm
- feat(serve): add PlayReady CDM support alongside Widevine
- feat(gluetun): Gluetun VPN integration and Windscribe support
- feat(audio): codec lists and split muxing
- feat(tracks): prioritize Atmos audio tracks over higher bitrate non-Atmos
- feat(video): detect interlaced scan type from MPD manifests
- feat(cdm): normalize CDM detection for local and remote implementations
- fix(serve)!: make PlayReady users config consistently a mapping
- 50+ additional bug fixes across HLS/DASH, proxies, subtitles, and more
2026-02-15 13:04:42 -07:00
Andy
23cc351f77 feat(tracks): prioritize Atmos audio tracks over higher bitrate non-Atmos 2026-02-15 12:08:27 -07:00
Andy
132d3549f9 fix(main): update copyright year dynamically in version display 2026-02-11 16:01:33 -07:00
Andy
3ee554401a feat(HLS): improve audio codec handling with error handling for codec extraction 2026-02-10 08:34:54 -07:00
Andy
29a697a8e7 fix(tracks): close temp session and improve path type error 2026-02-08 20:04:22 -07:00
Andy
5fa0b33664 revert(monalisa): pass key via argv again
Reverts the env/stdin key passing change introduced in 6c83790, since ML-Worker builds in use expect the key as argv[1].
2026-02-08 19:51:22 -07:00
Andy
5650c2b591 fix(hls): remove no-op encryption_data reassignment 2026-02-08 10:43:49 -07:00
Andy
5f49663ea8 fix(monalisa): harden wasm calls and license handling
- Validate _monalisa_context_alloc return and cleanup on init failure
- Derive deterministic KID when DCID missing to avoid collisions
- Ensure stackRestore always runs via try/finally in _ccall
- Log base64 decode failures without leaking license contents
- Add bounds/alignment checks for i32 memory writes
2026-02-08 10:39:23 -07:00
CodeName393
dd19f405a4 Add selector 2026-02-09 02:21:04 +09: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
b9fb928292 fix(service): redact proxy credentials in logs
Proxy URIs may contain embedded userinfo (username/password). Add a small sanitizer helper and use it for proxy mapping and proxy selection logs to avoid leaking credentials.
2026-02-07 20:36:25 -07:00
Andy
984a8b9efa fix(proxies): harden surfshark and windscribe selection 2026-02-07 20:34:31 -07:00
Andy
71adee4ec6 fix(api): log PSSH extraction failures 2026-02-07 20:29:53 -07:00
Andy
d576174f62 fix(naming): keep technical tokens with scene_naming off
Title filenames now include resolution/service/WEB-DL/codecs/HDR tokens in both modes; scene_naming only changes the spacer ('.' vs ' ').

Also avoid overwriting muxed outputs by disambiguating on collision (append codec suffix when needed, then a numeric suffix).
2026-02-07 20:24:32 -07:00
Andy
425b3764f4 fix(titles): avoid None/double spaces in HDR tokens
Ensure dynamic-range tokens use safe fallback when not in DYNAMIC_RANGE_MAP and append exactly one space-separated token without trailing/double spaces.
2026-02-07 19:55:45 -07:00
Andy
44ea9a90a7 fix(titles): remove trailing space from HDR dynamic range label 2026-02-07 19:46:35 -07:00
Andy
96411e5d7d fix(hls): keep range offset numeric and align MonaLisa licensing
- Parse init section byterange offset as int to avoid string arithmetic bugs

- Wrap MonaLisa licensing in the same progress + error handling flow as Widevine/PlayReady
2026-02-07 19:44:23 -07:00
Andy
6c83790834 fix(monalisa): avoid leaking secrets and add worker safety
- Pass ML-Worker key via env/stdin instead of argv to reduce exposure in process listings/logs.

- Add a hard timeout to the ML-Worker subprocess call and convert timeouts into DecryptionFailed errors.

- Make ticket bytes decoding defensive: try UTF-8, fall back to ASCII (base64), otherwise raise a descriptive ValueError.
2026-02-07 19:24:15 -07:00
Andy
a04f1ad4db fix(gluetun): stop leaking proxy/vpn secrets to process list
- Switch docker run to use a temporary --env-file instead of per-var -e flags\n- Ensure temp env file is always removed (best-effort overwrite + unlink)\n- Tighten _is_container_running to exact-name matching via anchored docker filter\n- Close requests.Session used for IP verification to release connections\n- Redact more secret-like env keys in debug logs\n
2026-02-07 19:22:13 -07:00
Andy
c7d4a68cbf fix(aria2c): warn on config mismatch and wait for RPC ready
When ensure_started() is called while aria2c is already running, it now compares the requested proxy/max_workers against the values the process was started with and logs a warning if they differ (since the running process cannot be reconfigured in-place). Startup no longer uses a fixed sleep; instead it probes the JSON-RPC endpoint with a bounded retry loop (aria2.getVersion) and only proceeds once RPC is responsive, terminating the subprocess and raising on timeout.
2026-02-07 19:04:39 -07:00
Andy
62aa85c666 chore(release): bump version to 2.4.0 2026-02-07 14:52:54 -07:00
Andy
03c309303c fix(downloader): restore requests progress for single-url downloads 2026-02-06 23:34:15 -07:00
Andy
ace89760e7 fix(hls): finalize n_m3u8dl_re outputs
- Add a small helper to move N_m3u8DL-RE final outputs into the expected temp path (preserve actual suffix) and keep subtitle codec consistent with the produced file.
- Skip generic HLS segment merging when N_m3u8DL-RE is in use to avoid mixing in sidecar files and reduce Windows file-lock issues.
- Harden segmented WebVTT merging to avoid IndexError when caption segment indexes exceed the provided duration list.
2026-02-06 16:17:06 -07:00
Andy
2308644374 chore(api): remove remote services 2026-02-06 10:46:39 -07:00