mirror of
https://github.com/unshackle-dl/unshackle.git
synced 2026-11-14 13:05:09 +00:00
feat(dl): add --all-drm to license Widevine and PlayReady per track
Each DRM system sends one challenge per KID set in a run, also when a vault has the content keys. Needs a CDM for each system in the cdm config.
This commit is contained in:
@@ -444,6 +444,7 @@ Make a download job. It requires `service` and `title_id`. Every other field is
|
||||
| `slow` | boolean/string | `null` | Randomized delay between downloads. |
|
||||
| `split_audio` | boolean | `null` | Separate files per audio codec. |
|
||||
| `skip_dl` | boolean | `false` | Only fetch keys, do not download. |
|
||||
| `all_drm` | boolean | `false` | License each track with both Widevine and PlayReady. Needs a CDM for each DRM system. The server refuses it with `cdm_only: false` and with `cdm`, which selects one device. |
|
||||
| `export` | boolean | `false` | Export manifest/keys/subs to JSON. |
|
||||
| `cdm_only` | boolean | `null` | Force CDM-only (`true`) or vault-only (`false`) key retrieval. |
|
||||
| `proxy` / `no_proxy` / `no_proxy_download` / `proxy_download` | string / bool / bool / string | `null` / `false` / `false` / `null` | Proxy controls. `proxy` and `proxy_download` must be full proxy URIs unless the API key has `server_proxy`. A Control D resolver, `controld://<resolver>@dns.controld.com`, counts as a full proxy URI: the server runs a forwarder for it. |
|
||||
@@ -453,7 +454,7 @@ Make a download job. It requires `service` and `title_id`. Every other field is
|
||||
| `download_processes` | int | `1` | Split a track's segments across this many processes. Only engages for large batches. |
|
||||
| `downloads` | int | `1` | Concurrent tracks. |
|
||||
| `worst` | boolean | `false` | Lowest bitrate within quality. |
|
||||
| `best_available` | boolean | `false` | Fall back to best available. |
|
||||
| `best_available` | boolean | `false` | Fall back to best available. With `all_drm`, a DRM system that does not license is a warning. |
|
||||
| `repack` | boolean | `false` | Add REPACK tag. |
|
||||
| `tag` | string | `null` | Release group tag. |
|
||||
| `tmdb_id` / `imdb_id` / `tvdb_id` / `anilist_id` | - | `null` | External ID overrides. Each resolves its metadata directly instead of by a title search, and is used for tagging. Set `enrich` to also take the title, year and original language. Give at most one of `tmdb_id`, `imdb_id` and `tvdb_id`, since unshackle resolves the others from it. Sending two returns `400`. `anilist_id` still combines with one of them. `tmdb_id` and `tvdb_id` must be positive integers, `imdb_id` must look like `tt1375666`, and `anilist_id` must be a positive integer or a string like `mal:12345`, or the request returns `400`. An ID whose provider is unconfigured, such as `tmdb_id` with no `tmdb_api_key`, fails the job rather than returning `400`. `anilist_id` needs no API key. |
|
||||
|
||||
@@ -83,7 +83,7 @@ unshackle dl [OPTIONS] SERVICE [SERVICE ARGS...]
|
||||
| `-c`, `--channels` | - | Audio channels; matches sub-layouts (5.1 ≈ 6.0). |
|
||||
| `-naa`, `--noatmos` | off | Exclude Dolby Atmos audio tracks. |
|
||||
| `--worst` | off | Pick the lowest bitrate within the requested quality. **Requires `-q`.** |
|
||||
| `--best-available`, `--warn-only` | off | Warn and continue when a requested resolution, range, or language is absent, instead of failing. |
|
||||
| `--best-available`, `--warn-only` | off | Warn and continue when a requested resolution, range, or language is absent, instead of failing. With `--all-drm`, also when one DRM system does not license. |
|
||||
| `-rvb`, `--real-video-bitrate` | off | Probe real media size for true video bitrates, overriding the manifest. |
|
||||
| `-rab`, `--real-audio-bitrate` | off | Same for audio (slower). |
|
||||
|
||||
@@ -194,6 +194,7 @@ order the service used, then renumbers the episodes into the order you asked for
|
||||
| `--cdm-only` / `--vaults-only` | Use only the CDM, or only Key Vaults, for key acquisition. |
|
||||
| `--cdm <name>` | Use the named CDM device from the `cdm` config mapping for this run, ignoring the service/default mapping. Over `--remote`, that device licenses the remote session, not the server CDM. |
|
||||
| `--skip-dl` | Skip the download but still retrieve keys. |
|
||||
| `--all-drm` | License each track with both Widevine and PlayReady. Needs a CDM for each DRM system. Not for use with `--vaults-only` or `--cdm`. |
|
||||
| `--export` | Export track info and keys to a `mediaexport` JSON file in the exports directory. |
|
||||
|
||||
### Network & proxy
|
||||
|
||||
@@ -97,7 +97,7 @@ By default a missing requested resolution is an error. Two flags change that:
|
||||
|
||||
| Flag | Behaviour |
|
||||
| --- | --- |
|
||||
| `--best-available` (`--warn-only`) | If the requested resolution(s) are not present, continue with the best that *is* available instead of failing. Also softens missing video/audio/subtitle languages and hybrid fallbacks. |
|
||||
| `--best-available` (`--warn-only`) | If the requested resolution(s) are not present, continue with the best that *is* available instead of failing. Also softens missing video/audio/subtitle languages and hybrid fallbacks, and with `--all-drm` a DRM system that does not license. |
|
||||
| `--worst` | Within the specified quality, pick the **lowest** bitrate rendition. **Requires `-q/--quality`.** |
|
||||
|
||||
```shell title="Never fail on a missing resolution"
|
||||
@@ -662,6 +662,7 @@ Before committing to a long download, inspect what unshackle *would* do:
|
||||
| `--list` | List the tracks the service exposes for each title, then stop. No selection, no download. |
|
||||
| `--list-titles` | List every title the service returned, then stop. `-w`, `--latest-episode` and `--latest-episodes` are not applied to this listing. |
|
||||
| `--skip-dl` | Skip downloading but still acquire the decryption keys. |
|
||||
| `--all-drm` | License each track with both Widevine and PlayReady. See [Widevine and PlayReady on the same title](drm-and-cdm.md#widevine-and-playready-on-the-same-title). |
|
||||
|
||||
```shell title="See the track selection without downloading"
|
||||
unshackle dl -q 1080 -v H.265 -r HDR10 --list EXAMPLE 81234567
|
||||
@@ -795,6 +796,13 @@ older unshackle `version: 2` files and unidl's own export files.
|
||||
unshackle dl --skip-dl --export EXAMPLE 81234567
|
||||
```
|
||||
|
||||
Add `--all-drm` to send a challenge for each DRM system the title offers. The export then
|
||||
holds the DRM init data of both.
|
||||
|
||||
```shell title="License with Widevine and PlayReady, no download"
|
||||
unshackle dl --skip-dl --all-drm --export EXAMPLE 81234567
|
||||
```
|
||||
|
||||
The file name tells what the file holds, in the form
|
||||
`{title}.{scope}.{resolutions}.{codecs}.{ranges}.{manifests}.{audio}-{SERVICE}.json`:
|
||||
|
||||
|
||||
@@ -482,6 +482,42 @@ Use the `cdm` mapping's [DRM-based selection](#advanced-selection-by-quality-drm
|
||||
to configure a device for each system. unshackle selects the right one per track
|
||||
automatically.
|
||||
|
||||
### License both systems with `--all-drm`
|
||||
|
||||
By default a track licenses with one DRM system. `--all-drm` sends a challenge for
|
||||
Widevine and for PlayReady on each track that offers both. Use it with `--skip-dl` and
|
||||
`--export` to keep the content keys and the DRM init data of both systems. The two
|
||||
systems can return different sets of KIDs, and unshackle keeps the content keys of both.
|
||||
|
||||
```shell
|
||||
unshackle dl --skip-dl --all-drm --export EXAMPLE 81234567
|
||||
```
|
||||
|
||||
- The `cdm` mapping must name a device for each system. A single device name, or `--cdm`,
|
||||
stops the run with an error that names the missing system.
|
||||
- Each DRM system sends one challenge for a set of KIDs in a run. A content key in a
|
||||
Key Vault does not stop the challenge, so `--vaults-only` is refused.
|
||||
- A service with a Widevine licence function only gets the PlayReady challenge through that
|
||||
function. If its licence server refuses the challenge, that DRM system does not license.
|
||||
- If one DRM system does not license, the title fails. With `--best-available` unshackle
|
||||
shows a warning and continues, if the other system gave the content key of the track.
|
||||
unshackle does not send the challenge again for the same KIDs in that run.
|
||||
- A track gets its DRM systems from the manifest. For a DASH track or a direct URL,
|
||||
unshackle also reads the init segment for a system that the manifest does not carry.
|
||||
- The service gets a challenge from each DRM system for each set of KIDs. A licence server
|
||||
that limits the request rate can answer `429`, and unshackle then tries again.
|
||||
|
||||
!!! note "Where `--all-drm` licenses one system only"
|
||||
- A service that gets a different manifest for each DRM system. unshackle shows a
|
||||
warning one time when a track offers one system only.
|
||||
- A service that fetched its playback for one DRM system and refuses the other. That
|
||||
system does not license, so the title fails unless you use `--best-available`.
|
||||
- An HLS playlist that changes its `EXT-X-KEY` entries part-way: only the first set
|
||||
licenses with the second system.
|
||||
- A remote session that the server CDM licenses, and `unshackle import`. unshackle
|
||||
shows a warning and ignores the flag.
|
||||
- A remote CDM that stores content keys can answer without a challenge to the service.
|
||||
|
||||
## Keys, vaults, and caching
|
||||
|
||||
Fetching a license is comparatively slow and, for some services, rate-limited.
|
||||
|
||||
@@ -48,7 +48,7 @@ Common config keys. This is a useful subset, and every `dl` flag works:
|
||||
| `workers` | int | *(downloader default)* | Threads per track. |
|
||||
| `speed_limit` | str | *(unlimited)* | Total download speed cap across all downloads combined, e.g. `500k`, `5M`, `1.5G` or plain bytes/sec. Values are bytes, not bits (`5M` = 5.0 MB/s). |
|
||||
| `slow` | str | *(unset)* | Inter-title delay, e.g. `"20-40"`. |
|
||||
| `best_available` | bool | `false` | Warn instead of failing when a requested resolution, range, or language is missing. The CLI flag is `--best-available`, also spelled `--warn-only`. |
|
||||
| `best_available` | bool | `false` | Warn instead of failing when a requested resolution, range, or language is missing, or when one DRM system does not license under `--all-drm`. The CLI flag is `--best-available`, also spelled `--warn-only`. |
|
||||
| `proxy` | str | *(unset)* | Default proxy URI or 2-letter country. |
|
||||
| `no_folder` | bool | `false` | Do not create a per-title folder. |
|
||||
|
||||
|
||||
@@ -45,6 +45,23 @@ are `widevine` / `playready`. unshackle matches the quality keys first, but only
|
||||
height is known. If the value is still a dict after that, unshackle uses
|
||||
`widevine`/`playready` when present, or else the credential profile name, then `default`.
|
||||
|
||||
A quality key can also hold a dict of `widevine` / `playready` devices, and so can the
|
||||
top-level `default` entry:
|
||||
|
||||
```yaml
|
||||
cdm:
|
||||
default:
|
||||
widevine: chromecdm_l3
|
||||
playready: sl2000
|
||||
EXAMPLE1:
|
||||
">=1080": { widevine: android_l1, playready: sl3000 }
|
||||
"<1080": { widevine: chromecdm_l3, playready: sl2000 }
|
||||
```
|
||||
|
||||
A quality key that holds one device name applies to both DRM systems. When a track needs the
|
||||
other system, unshackle uses the `widevine` / `playready` config key of the entry. `dl --all-drm`
|
||||
needs a device for each system from one of these shapes.
|
||||
|
||||
unshackle finds the resolved name in [`remote_cdm`](#remote_cdm) by `name` first. If no entry
|
||||
matches, unshackle loads it as a local device file, in this order: `<name>.prd` in
|
||||
`directories.prds`, `<name>.prd` in `directories.wvds`, then `<name>.wvd` in
|
||||
|
||||
Reference in New Issue
Block a user