Commit Graph
78 Commits
Author SHA1 Message Date
imSp4rky c071a00ba6 fix(remote): report a missing title list and a refused track URI clearly
A service returning no titles now fails with a service error instead of an unsupported "other" title, and the init segment read names the HTTP status.
2026-09-25 14:37:18 -06:00
imSp4rky 1883386539 test(serve): remove reader-thread races in prompt relay tests 2026-09-25 13:18:13 -06:00
imSp4rky 69360d1b4c feat(remote): let a remote client license with its own device identity
Relay the service's CDM calls to the client, accept the service's allowed identity config (for example ESN/Kpe/Kph), add the server_vault grant and a lent server-device mode that reads keys only from vaults and returns no login cache. Also fixes the proxied certificate fetch, Base64 Widevine licences, an answered call that stayed pending and a missing default quality.
2026-09-25 12:32:49 -06:00
imSp4rky 174192882f feat(serve): relay service prompts from download jobs to the REST client
A job's input_prompt carries a service's request_input() prompt; the client answers it with POST /api/download/jobs/{job_id}/input.
2026-09-25 09:32:35 -06:00
imSp4rky 0e4e6f2ec6 feat(remote): list only configured services on the dashboard
/api/dashboard/services and the /status count now use serve.services, else the union of serve.users services lists; ?all=1 lists every installed service.
2026-09-24 17:14:18 -06:00
imSp4rky 7d31153c7f feat(remote): cap server CDM licensing by height per API key and service
A session above the cap licenses with the client's own device, and a track above it in an uncapped -q run is handed back to the client. Also names the fallback in the ccextractor crash warning.
2026-09-24 16:50:26 -06:00
imSp4rky 91db1fa0b1 feat(remote): keep slow remote session requests alive with a heartbeat
Titles, tracks and licence stream a newline every 30s until the body is ready, so a slow service outlasts the client timeout and proxy idle limits; add a per-server timeout.
2026-09-24 10:18:03 -06:00
imSp4rky db771a13c6 fix(remote): forward dl track selection and profile to remote sessions
Remote sessions now carry -l/-vl/-al/-a/-fs under a nested dl_params, so services fetch the requested audio versions. Server-account tokens for non-default accounts move from default to the account name, so each account logs in once after upgrade.
2026-09-22 12:52:05 -06:00
imSp4rky 4639d9d496 fix(remote): let the server's CDM mapping decide the DRM system under server_cdm
A client with a local PlayReady device asked the server for a PlayReady licence on a service the server maps to a Widevine device. Both server_cdm routes now share one candidate list from one config lookup, report the system that licensed in drm_type, and the client adopts it.
2026-09-22 10:54:31 -06:00
imSp4rky d239964f0b fix(serve): apply staged service reloads when sessions end, with a max staging age
A staged tag was only retried on the refresh tick or a job completion, so a service with steady remote sessions never swapped in. Session end, expiry and eviction now trigger a single-flight apply, the tick applies after the pull, and serve.services_staged_max_age swaps an overdue tag in even while busy.
2026-09-22 10:40:49 -06:00
imSp4rky b8f00f6b95 fix(remote): keep the server's own CDM when the tier licenses with server_cdm 2026-09-20 01:19:48 -06:00
imSp4rky 025499efa7 test(vaults): fix the vault-write fakes is_flagged and log.error 2026-09-19 22:42:26 -06:00
imSp4rky cd6a38aec8 fix(remote): stop warning about missing keys for tracks that carry no DRM
The server names the clear tracks in the licence response and the client skips them instead of warning for every requested track without keys.
2026-09-19 22:05:30 -06:00
imSp4rky 9c9e059e2d fix(remote): forward nested service cache files to and from the server
Cache keys are now the path relative to the service cache dir without .json, so Cacher keys like session_web/<sha1> reach the remote session. The credential filter runs on every path segment, the suffix is appended rather than substituted, and both sides cap the map at 64 keys.
2026-09-19 21:42:01 -06:00
imSp4rky cf2906f120 fix(cli): make the click param types the one source of codec spellings
--acodec now lists its codecs in --help, --vcodec drops the duplicate entries, and the REST API derives its allowlists from the same types, so AC-4, DDP, VORB and sub_format "original" stop being rejected and H264 stops being silently dropped. Adds shell completion for --acodec and repairs MultipleChoice completion. Raises the click floor to 8.2.
2026-09-17 19:22:19 -06:00
imSp4rky dfaeb83076 fix(remote): honor proxy client cdm_type for DRM system selection 2026-09-16 22:39:03 -06:00
imSp4rky ffda836442 fix(remote): return session cache for device-code and cache-only logins
Answered login prompts and uploaded cache now count as client auth; the client closes on exit and keeps the remote session alive during long downloads.
2026-09-16 19:36:31 -06:00
imSp4rky aec45e30cc feat(service): add GEOBLOCK negative geofence
Regions in GEOBLOCK refuse the service and everything else is allowed. A hit stops the run with a region error instead of auto-proxying; the check also covers proxy exits and the remote-dl client region.
2026-09-16 15:06:43 -06:00
imSp4rky aa36d4c225 feat(vaults): report bad keys to the vault that served them 2026-09-13 20:46:38 -06:00
imSp4rky e40421a855 fix(serve): defer service hot reload while a remote session uses it
Remote-only serve no longer builds the download queue manager just to read busy services.
2026-09-13 12:21:31 -06:00
imSp4rky a7d6791136 feat(remote): verify server-CDM vault keys on the client and report bad pairs
The licence response lists KIDs a server vault supplied, the client proves them with the decode check, and a bad pair goes to the new session keys/bad route so the server flags its own row. Client vault keys go first over --remote, and the dashboard health warns when no SQLite vault can store flags.
2026-09-12 15:13:08 -06:00
imSp4rky 7c82282813 feat(vaults): flag and skip wrong content keys from poisoned vaults
Verify a vault-sourced key with an FFmpeg decode after decryption. On failure flag the KID:KEY locally with its source, restore the ciphertext, and retry through the remaining vaults and then the CDM.
2026-09-12 13:11:44 -06:00
imSp4rky 1939ebaf79 test(api): expect a str challenge on the playready proxy licence path 2026-09-10 17:14:20 -06:00
imSp4rky d860eb9e01 fix(proxy): check the proxy exit IP before any service request
A dead proxy, or one that exits from this machine's IP, now fails with INVALID_PROXY instead of retrying every request; remote session create also builds the service off the event loop so a stuck check cannot block the server.
2026-09-10 17:08:04 -06:00
imSp4rky 76d82df25b fix(api): keep error URLs readable and mask host paths in dashboard logs 2026-09-08 17:37:32 -06:00
imSp4rky 84b0a92c41 feat(api): report the live title and the client's command line to the dashboard 2026-09-07 17:03:36 -06:00
imSp4rky b8c78c1a82 fix(api): tell the service that the client sent a cookie jar
A service that picks its auth path in init could only check the server's cookies directory, so a client-sent jar was invisible and the service fell back to the wrong path. The ctx now carries cookies_supplied, and a malformed cookie blob answers 400 instead of 500.
2026-09-07 13:20:55 -06:00
imSp4rky bbd26a2dc3 fix(api): let the server CDM see service-supplied keys and HLS track DRM 2026-09-07 12:30:50 -06:00
imSp4rky b91d7bfa5b fix(api): reach every PlayReady header on all server CDM routes
The rebuild raised KIDNotFound for a header whose KID lives only in the manifest, the single-track route stripped the track's other headers, and the batch cache keyed on the first PSSH alone. Licensing failures now reach the client instead of only the server log.
2026-09-07 11:54:35 -06:00
imSp4rky 8e261ae238 fix(api): license every PlayReady header in the server CDM path
extract_pssh_from_track returns the first PSSH only, so a track carrying one PlayReady object per header licensed fewer keys than the local path, which absorbs its siblings first. Relay batch licensing failures to the client too.
2026-09-07 10:59:33 -06:00
imSp4rky 7065cbf911 fix(drm): license every PlayReady header until all KIDs are covered
Only the first WRM header was read and licensed, so a manifest carrying several headers silently lost content keys. Collect KIDs from every header and license each distinct one until coverage is complete.
2026-09-07 10:05:09 -06:00
imSp4rky 627f1fa81c fix(dl): cache server-CDM keys to the local vaults
Batch and per-track remote licences read the vaults but never wrote back, so a --remote or import run kept nothing. Vault hits now replicate to the other vaults, and the server branch resolves keys under drm_lock like the local path.
2026-09-06 23:10:04 -06:00
imSp4rky 22cc739e83 fix(downloader): correct truncation, ranged sizing, and session carry
Check a sequential download against the complete length whenever one is known, and settle the unknown-total case on the 416. An empty body of unknown length, a 206 with no complete length, and a 206 starting past the resume offset all passed the size checks before and were renamed into place. Four restart paths spent no attempt, so a host that always answered the same way cycled forever.
2026-09-06 20:03:08 -06:00
imSp4rky dffb8b27e3 fix(serve): lock shared session state and throttle progress writes
Handlers share one service instance, so a per-session lock keeps two requests out of it at once. Track threads merge and write job state under one lock, and the progress sink coalesces ticks that say the same thing.
2026-09-06 20:01:38 -06:00
imSp4rky adea7583f0 test(services): use placeholder tags instead of real service names 2026-09-05 22:16:22 -06:00
imSp4rky 0f9997be4c refactor(drm): drop the hardcoded service branch in the license flow
One service needed session_id in its license call, which a near-duplicate of get_content_keys supplied behind a service-tag test. service_licence now passes each service only the arguments its own license function declares, so the duplicate and the branch are gone. The REST API license paths and the base PlayReady delegate get the same filtering, replacing their fixed argument set.

Two behaviour changes ride along: an empty license challenge now raises EmptyLicense for every service, not just the one, and a service that declares only challenge now receives a working call instead of a TypeError.
2026-09-05 22:14:47 -06:00
imSp4rky bae71c0194 fix(serve): resolve DRM keys for manifests with no ContentProtection PSSH
Read the init segment server-side so server_cdm licenses every track's real KID, and re-license when the manifest PSSH misses it.
2026-09-04 22:19:21 -06:00
imSp4rky c9f178f8f0 test(serve): make the session touch test clock-independent 2026-09-03 00:15:17 -06:00
imSp4rky 8354235d56 feat(serve): add operator dashboard endpoints and per-key rate limits 2026-09-02 23:52:55 -06:00
imSp4rky ac8f71b969 fix(remote): send per-track MPD fragments for service-built AdaptationSets
A service can build an AdaptationSet the served manifest does not contain, so the client's re-parse could never find it and the track downloaded with no manifest data. Those tracks now get a one-AdaptationSet MPD of their own.
2026-09-02 15:13:06 -06:00
imSp4rky f8f58f86ef fix(remote): match re-parsed manifest tracks by ID before attributes
Match once after every server manifest is parsed, and require range and bitrate in the video fallback, so a per-range ISM ladder no longer hands an HDR10 track the SDR quality level. Pass -xerror to the bsf ffmpeg calls so a failed rewrite keeps the original file instead of a near-empty one.
2026-09-01 15:06:29 -06:00
imSp4rky 7310273594 fix(ism): signal Dolby Vision and Atmos from Smooth manifests
Init segments now carry dvcC/dvvC with a profile-keyed sample entry and the dby1 brand; track ids cover the manifest URL so per-range ladders stop colliding, and the remote path carries the Atmos flag without inventing a JOC count.
2026-09-01 12:50:59 -06:00
imSp4rky dae2b37ad6 fix(serve): license multi-key PlayReady through server CDM instead of vault subset
A PlayReady WRMHEADER can advertise fewer KIDs than its multi-key license returns, so a server-vault hit on the PSSH KID alone handed every track the same key subset and failed sibling tracks. Drop the pre-license vault shortcut for PlayReady and reuse the licensed bundle per PSSH.
2026-08-31 14:38:00 -06:00
imSp4rky a01ff594da fix(remote): send only the active profile's cache files to the server
The client withheld nothing before: every profile's tokens went to any remote server. Filter by active-credential digests and profile names, keeping service-global files; worst case for a withheld file is a server-side re-auth.
2026-08-30 21:17:20 -06:00
imSp4rky f7b1446427 feat(serve): forward per-session service logs to remote-dl clients
Mirror each remote session's self.log into a bounded buffer, drained by the client via GET /api/session/{id}/logs and re-emitted locally. Server-account sessions get no relay. Also namespace service CLI options under service_params so a transport key (profile) no longer collides with a service's own option, on both the session and download-job paths.
2026-08-30 20:52:18 -06:00
imSp4rky d9b21229c3 feat(serve)!: add server-held accounts for remote sessions
serve.server_accounts lends region-tagged server credentials to remote sessions (round-robin per region, per-key opt-in, per-account cache). Remote sessions no longer fall back to the server's local credentials when the client sends none.
2026-08-28 16:36:39 -06:00
imSp4rky e3f4e52444 feat(serve): add --quiet mode and developer dashboard API
Headless serve with plain stderr logging; /api/dashboard/* (status, sessions, jobs, logs, SSE/poll events) behind a separate serve.dashboard.key.
2026-08-28 13:18:41 -06:00
imSp4rky c49fccf3b5 fix(remote): resolve service names against the remote server
Remote mode resolved names with the local alias table and built an empty stub for any unknown tag, so an unentitled service showed a blank help page. Resolve against the server's tags and aliases, and reject unknown names with the list the server does offer.
2026-08-28 10:54:21 -06:00
imSp4rky 3cb3613565 feat(remote): forward HLS segment filters to remote clients
Add POST /api/session/{id}/segment_filter: the server runs the service's OnSegmentFilter and returns only the unwanted segment URIs, so ads and bumpers are dropped over --remote-only without exposing service code.
2026-08-27 23:56:16 -06:00
imSp4rky dcc1c8af18 feat(serve)!: gate the server's own proxies behind server_proxy
The server no longer spends its configured proxy providers on a remote client unless the API key sets server_proxy. It places the client by geolocating the connection address and asks for a proxy when that region does not match its own.
2026-08-27 12:43:53 -06:00