Remove only control characters in unicode mode. A mark after a zero width joiner or a digit was still dropped (#161). In ASCII mode a decomposed title now transliterates like the composed one.
Names change for titles with combining marks, compatibility ideographs or decomposed spellings, so an existing library can get a second folder.
A remote client that passes --cdm, has a cdm entry for the service that named the loaded device, or sets server_cdm: false now declines the server CDM at session create, and warns when the server keeps it. A service option listed in SERVER_DEVICE_OPTIONS keeps the server CDM.
Failed jobs now keep the worker's traceback, error_details and error_code instead of the "Worker exited" wrapper. error_traceback and worker_stderr only reach API clients under --debug-api.
Readers filter a deque copy, publish takes a re-entrant lock, seq moves after the append, and poll endpoints return a cursor that never skips a record.
A bare query skips a failing provider and errors when none answers; an unknown prefix such as us:seattle fails with a hint. The REST path now loads WindscribeVPN.
Basic, NordVPN, Windscribe, Gluetun and Hola no longer raise on a query they cannot serve. Hola parses stdout only and reports a ban; NordVPN cities use the API filter; uk maps to gb.
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.
/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.
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.
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.
Runs a loopback forwarder per region-named profile (unshackle-<region>), so
--proxy and --proxy-download can exit in different countries
Thanks to Orni_ for the original code and the test account.
Co-authored-by: AntCardFr <24798811+AntCardFR@users.noreply.github.com>
A licence that repeats vault keys no longer sends an empty InsertKeys, --cdm-only no longer logs "Cached N Keys to 0/0 Vaults", and a key two tracks both licensed counts once.
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.
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.
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.
RollingMerge takes the segment path and an append hook. ISM synthesises the init from segment 0 and converts PIFF per fragment; HLS qualifies only with one init, one key and no discontinuity. Both parsers check the merge reached every segment, and resume is decided per track.
Opt-in rolling merge for DASH video and audio: each contiguous segment is appended to the output as it lands, so the post-download "Merging" stage goes away. Decrypts the init segment eagerly when decrypt_segments is on, disables resume for the track, and skips subtitle tracks.
Build the failure context through the title's template builder with an empty MediaInfo, and blank season_episode, absolute and date in season mode. Document {part} and add a docs-to-code parity test.
The importer builds subtitle tracks from track rows that carry a url, which the format promised and no reader did. The writer keeps a conflicting KID instead of overwriting it, identifies a manifest by its whole URL, writes subtitle rows as srt or vtt rather than enum names, and survives an export file it cannot read.