mirror of
https://github.com/unshackle-dl/unshackle.git
synced 2026-11-12 20:15:10 +00:00
docs: cleanup and correct documentation
This commit is contained in:
@@ -36,18 +36,18 @@ unshackle --help
|
|||||||
|
|
||||||
### Requirements
|
### Requirements
|
||||||
|
|
||||||
External tools on your `PATH` (recommended versions):
|
External tools. (recommended versions):
|
||||||
|
|
||||||
- [Python](https://www.python.org/) - 3.11 - 3.14
|
- [Python](https://www.python.org/) - 3.11 - 3.14
|
||||||
- [uv](https://docs.astral.sh/uv/) - ≥ 0.5
|
- [uv](https://docs.astral.sh/uv/) - ≥ 0.5
|
||||||
- [FFmpeg](https://ffmpeg.org/) - ≥ 6.0
|
- [FFmpeg](https://ffmpeg.org/) - ≥ 6.0
|
||||||
- [MKVToolNix](https://mkvtoolnix.download/) - ≥ 80
|
- [MKVToolNix](https://mkvtoolnix.download/) - ≥ 80
|
||||||
- [shaka-packager](https://github.com/shaka-project/shaka-packager/releases/tag/v2.6.1) - 2.6.1
|
- [shaka-packager](https://github.com/shaka-project/shaka-packager/releases/tag/v2.6.1) - 2.6.1
|
||||||
- [Bento4](https://github.com/axiomatic-systems/Bento4) - ≥ 1.6.0-639
|
|
||||||
- [dovi_tool](https://github.com/quietvoid/dovi_tool) - ≥ 2.1
|
|
||||||
|
|
||||||
Optional:
|
Optional:
|
||||||
|
|
||||||
|
- [Bento4](https://github.com/axiomatic-systems/Bento4) - ≥ 1.6.0-639
|
||||||
|
- [dovi_tool](https://github.com/quietvoid/dovi_tool) - ≥ 2.1
|
||||||
- [SubtitleEdit](https://github.com/SubtitleEdit/subtitleedit/releases) - ≥ 5.0 (`SeConv` CLI)
|
- [SubtitleEdit](https://github.com/SubtitleEdit/subtitleedit/releases) - ≥ 5.0 (`SeConv` CLI)
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|||||||
@@ -105,7 +105,7 @@ turned into underscores (`--best-available` → `best_available`).
|
|||||||
dl:
|
dl:
|
||||||
lang: [en] # -l en
|
lang: [en] # -l en
|
||||||
quality: [1080] # -q 1080
|
quality: [1080] # -q 1080
|
||||||
vcodec: [H265] # -v H265
|
vcodec: [H.265] # -v H.265
|
||||||
sub_format: srt # convert subtitles to SRT
|
sub_format: srt # convert subtitles to SRT
|
||||||
downloads: 2 # two tracks at once
|
downloads: 2 # two tracks at once
|
||||||
```
|
```
|
||||||
@@ -159,7 +159,7 @@ The directories unshackle uses:
|
|||||||
| `fonts` | Bundled fonts | Yes |
|
| `fonts` | Bundled fonts | Yes |
|
||||||
|
|
||||||
!!! note "Some directories cannot be moved"
|
!!! note "Some directories cannot be moved"
|
||||||
A handful of internal locations are protected: the package root, the core directory, the user-config directory, and the data base. If you list them under `directories`, unshackle silently ignores the override. This is intentional; those paths are tied to where the package is installed.
|
unshackle protects five internal entries: `app_dirs`, `core_dir`, `namespace_dir`, `user_configs`, and `data`. If you list any of them under `directories`, unshackle ignores the override. This is intentional; those paths are tied to where the package is installed.
|
||||||
|
|
||||||
### The `services` directory is special
|
### The `services` directory is special
|
||||||
|
|
||||||
@@ -168,12 +168,12 @@ Unlike the other entries, `services` is a **list**, and each entry can be either
|
|||||||
```yaml title="unshackle.yaml"
|
```yaml title="unshackle.yaml"
|
||||||
directories:
|
directories:
|
||||||
services:
|
services:
|
||||||
- unshackle-dl/services # a GitHub owner/repo shorthand
|
- you/your-services # a GitHub owner/repo shorthand
|
||||||
- https://github.com/me/my-services.git
|
- https://example.com/private-services.git
|
||||||
- ~/code/local-services # a local folder
|
- ~/code/local-services # a local folder
|
||||||
```
|
```
|
||||||
|
|
||||||
Entries are searched in the order listed, and **the first source to define a given service tag wins**, so put local folders last if you want them to act as fallbacks rather than overrides. Remote repositories are cloned and periodically updated for you. See [Services](../dev/creating-a-service.md) for the full details on how service discovery and repositories work.
|
unshackle searches entries in the order listed, and **the first source to define a given service tag wins**, so put local folders last if you want them to act as fallbacks rather than overrides. unshackle clones remote repositories on first use and refreshes them at most once a day. See [Creating a Service](../dev/creating-a-service.md) for how service discovery and repositories work.
|
||||||
|
|
||||||
## The `filenames` key
|
## The `filenames` key
|
||||||
|
|
||||||
@@ -197,10 +197,10 @@ $ unshackle cfg tag MYGRP
|
|||||||
$ unshackle cfg cdm.default my_device_l3
|
$ unshackle cfg cdm.default my_device_l3
|
||||||
```
|
```
|
||||||
|
|
||||||
Values are parsed as Python literals where possible, so numbers, booleans, and lists work naturally, while bare text is treated as a string:
|
unshackle parses the value as a Python literal, so write booleans as `True`/`False` and quote the strings inside a list (`"['en']"`). Anything that is not valid Python literal syntax is stored as a plain string:
|
||||||
|
|
||||||
```console
|
```console
|
||||||
$ unshackle cfg update_checks false
|
$ unshackle cfg update_checks False
|
||||||
$ unshackle cfg vault_timeout 30
|
$ unshackle cfg vault_timeout 30
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -216,7 +216,7 @@ $ unshackle cfg cdm.default --unset
|
|||||||
$ unshackle cfg --list
|
$ unshackle cfg --list
|
||||||
```
|
```
|
||||||
|
|
||||||
When it writes, `unshackle cfg` targets the config file that was loaded. If none exists yet, it creates `unshackle.yaml` in your OS user-config directory.
|
When it writes, `unshackle cfg` targets the config file that was loaded. If none exists yet, it creates `unshackle.yaml` inside the `unshackle` package folder (search location 1), not your OS user-config directory. To keep the config outside the package, create the file at the user-config path yourself first, then `unshackle cfg` writes to it.
|
||||||
|
|
||||||
!!! warning "Editing with `cfg` strips comments"
|
!!! warning "Editing with `cfg` strips comments"
|
||||||
Because `unshackle cfg` rewrites the whole file when it saves, any comments in `unshackle.yaml` are removed by a write. If you keep important notes as comments, edit the file by hand instead, or keep those notes elsewhere.
|
Because `unshackle cfg` rewrites the whole file when it saves, any comments in `unshackle.yaml` are removed by a write. If you keep important notes as comments, edit the file by hand instead, or keep those notes elsewhere.
|
||||||
@@ -225,4 +225,4 @@ When it writes, `unshackle cfg` targets the config file that was loaded. If none
|
|||||||
|
|
||||||
- Browse the [Configuration Reference](../reference/configuration.md) for every key and default.
|
- Browse the [Configuration Reference](../reference/configuration.md) for every key and default.
|
||||||
- Set up your first download in [Downloading](../guide/downloading.md).
|
- Set up your first download in [Downloading](../guide/downloading.md).
|
||||||
- Learn how services are discovered and updated in [Services](../dev/creating-a-service.md).
|
- Learn how services are discovered and updated in [Creating a Service](../dev/creating-a-service.md).
|
||||||
|
|||||||
@@ -88,8 +88,8 @@ uv run unshackle env check
|
|||||||
## External tools on your PATH
|
## External tools on your PATH
|
||||||
|
|
||||||
unshackle shells out to a number of external command-line programs for media
|
unshackle shells out to a number of external command-line programs for media
|
||||||
processing and DRM work. It looks for each one first in a `binaries/` folder
|
processing and DRM work. It looks for each one first in the `binaries/` folder
|
||||||
next to the installed package, and then falls back to your system `PATH`, so
|
inside the installed package, and then falls back to your system `PATH`, so
|
||||||
installing these tools system-wide (or dropping them into that folder) both
|
installing these tools system-wide (or dropping them into that folder) both
|
||||||
work.
|
work.
|
||||||
|
|
||||||
@@ -108,7 +108,7 @@ These must be present for core downloading, decryption, and muxing to work:
|
|||||||
!!! warning "shaka-packager is the default decryptor"
|
!!! warning "shaka-packager is the default decryptor"
|
||||||
unshackle decrypts with shaka-packager unless you explicitly configure a
|
unshackle decrypts with shaka-packager unless you explicitly configure a
|
||||||
different decryptor. If it is missing, protected downloads will fail at the
|
different decryptor. If it is missing, protected downloads will fail at the
|
||||||
decryption step. See the [configuration reference](configuration-file.md) for the
|
decryption step. See the [configuration reference](../reference/configuration.md#decryption) for the
|
||||||
`decryption` key if you want to switch to `mp4decrypt`.
|
`decryption` key if you want to switch to `mp4decrypt`.
|
||||||
|
|
||||||
### Recommended and optional tools
|
### Recommended and optional tools
|
||||||
@@ -147,7 +147,7 @@ it depends on.
|
|||||||
unshackle --help
|
unshackle --help
|
||||||
```
|
```
|
||||||
|
|
||||||
This prints the banner and the list of available commands (`dl`, `env`, `kv`,
|
This prints the list of available commands (`dl`, `env`, `kv`,
|
||||||
`serve`, `wvd`, `prd`, `search`, `util`, `cfg`, `import`). If your shell reports
|
`serve`, `wvd`, `prd`, `search`, `util`, `cfg`, `import`). If your shell reports
|
||||||
that `unshackle` is not found, the `uv tool` bin directory is probably not on
|
that `unshackle` is not found, the `uv tool` bin directory is probably not on
|
||||||
your `PATH`. Run `uv tool update-shell` and open a new terminal.
|
your `PATH`. Run `uv tool update-shell` and open a new terminal.
|
||||||
|
|||||||
@@ -1,15 +1,21 @@
|
|||||||
# Quick Start
|
# Quick Start
|
||||||
|
|
||||||
This page takes you from a fresh install to your first downloaded file. You will
|
This page takes you from a fresh install to your first downloaded file. You will
|
||||||
create the one piece of configuration unshackle insists on, add a streaming
|
create the one piece of configuration unshackle insists on, supply the service
|
||||||
service and a CDM so it can actually fetch and decrypt media, run a basic
|
module and CDM it needs to fetch and decrypt media, run a basic `unshackle dl`
|
||||||
`unshackle dl` command, and learn where the finished file lands.
|
command, and learn where the finished file lands.
|
||||||
|
|
||||||
!!! note "Before you start"
|
!!! note "Before you start"
|
||||||
This guide assumes unshackle is already installed and on your `PATH`. If
|
This guide assumes unshackle is already installed and on your `PATH`. If
|
||||||
`unshackle --help` does not print a help screen, work through
|
`unshackle --help` does not print a help screen, work through
|
||||||
[Installation](installation.md) first.
|
[Installation](installation.md) first.
|
||||||
|
|
||||||
|
!!! warning "unshackle includes no services"
|
||||||
|
unshackle handles manifests, DRM, downloading, and muxing. It does not include a
|
||||||
|
module for any streaming platform, so you write that part yourself
|
||||||
|
([step 3](#3-write-a-service)). `EXAMPLE` in this guide stands in for the tag you
|
||||||
|
give yours.
|
||||||
|
|
||||||
## 1. Check your environment
|
## 1. Check your environment
|
||||||
|
|
||||||
unshackle drives several external tools (FFmpeg, MKVToolNix, shaka-packager, and
|
unshackle drives several external tools (FFmpeg, MKVToolNix, shaka-packager, and
|
||||||
@@ -58,12 +64,12 @@ Everything else has a sensible default. A minimal, working config looks like thi
|
|||||||
```yaml title="unshackle.yaml"
|
```yaml title="unshackle.yaml"
|
||||||
output_template:
|
output_template:
|
||||||
movies: "{title} ({year}) {quality} {source}"
|
movies: "{title} ({year}) {quality} {source}"
|
||||||
series: "{title} S{season}E{episode} {episode_name} {quality} {source}"
|
series: "{title} {season_episode} {episode_name?} {quality} {source}"
|
||||||
```
|
```
|
||||||
|
|
||||||
Each `{variable}` is filled in from the title and the tracks you downloaded. The
|
Each `{variable}` is filled in from the title and the tracks you downloaded. The
|
||||||
full set of valid variables, including `resolution`, `video`, `audio`, `hdr`,
|
full set of valid variables, including `resolution`, `video`, `audio`, `hdr`,
|
||||||
`edition`, `tag`, and more, is documented in [Configuration](configuration-file.md).
|
`edition`, `tag`, and more, is documented in [Output and Naming](../guide/output-and-naming.md).
|
||||||
|
|
||||||
!!! note "Spaces or dots?"
|
!!! note "Spaces or dots?"
|
||||||
unshackle auto-detects your naming style from the template: if the separators
|
unshackle auto-detects your naming style from the template: if the separators
|
||||||
@@ -77,51 +83,15 @@ full set of valid variables, including `resolution`, `video`, `audio`, `hdr`,
|
|||||||
rewrites the file and **removes any comments** it contained. If you keep notes
|
rewrites the file and **removes any comments** it contained. If you keep notes
|
||||||
in your config, edit the file by hand instead.
|
in your config, edit the file by hand instead.
|
||||||
|
|
||||||
## 3. Add a service
|
## 3. Write a service
|
||||||
|
|
||||||
The service tag you pass to `dl` (like `EXAMPLE`) maps to a **service module**, a small
|
The service tag you pass to `dl` (like `EXAMPLE`) maps to a **service module**, the
|
||||||
plugin that knows how to talk to one streaming platform. unshackle ships without
|
plugin that talks to one streaming platform. unshackle includes none, so you write
|
||||||
any bundled services, so you add the one(s) you want.
|
the one you need. [Creating a Service](../dev/creating-a-service.md) covers how.
|
||||||
|
|
||||||
Services live under the `directories.services` path (run `unshackle env info` to
|
Put the finished module in your `directories.services` folder (`unshackle env info`
|
||||||
see where that is). unshackle discovers them by looking for `*/__init__.py`: the
|
shows the path). The tag then works with `dl`, `search`, and the other service
|
||||||
folder name becomes the **service tag**, and the folder must contain a class with
|
commands.
|
||||||
that exact same name.
|
|
||||||
|
|
||||||
=== "Local folder"
|
|
||||||
|
|
||||||
Drop a service folder into your services directory. A service tagged `EXAMPLE`
|
|
||||||
lives at:
|
|
||||||
|
|
||||||
```
|
|
||||||
<services>/EXAMPLE/__init__.py # defines a class named EXAMPLE
|
|
||||||
```
|
|
||||||
|
|
||||||
Once the folder is in place, the tag `EXAMPLE` is immediately available to `dl`,
|
|
||||||
`search`, and the other service-aware commands.
|
|
||||||
|
|
||||||
=== "Git repository"
|
|
||||||
|
|
||||||
`directories.services` may also list git repositories. unshackle clones them
|
|
||||||
on first use and keeps them up to date:
|
|
||||||
|
|
||||||
```yaml title="unshackle.yaml"
|
|
||||||
directories:
|
|
||||||
services:
|
|
||||||
- owner/unshackle-services # a GitHub owner/repo shorthand
|
|
||||||
- /path/to/local/services # local folders still work too
|
|
||||||
```
|
|
||||||
|
|
||||||
Force a refresh of every configured service repo at any time with:
|
|
||||||
|
|
||||||
```shell
|
|
||||||
unshackle util refresh-services
|
|
||||||
```
|
|
||||||
|
|
||||||
!!! info "Where to get services"
|
|
||||||
Service modules are kept separate from the core project. Ask in the community
|
|
||||||
[Discord](https://discord.gg/mHYyPaCbFK) for where to find the service you
|
|
||||||
need. The core repository deliberately does not host them.
|
|
||||||
|
|
||||||
## 4. Add a CDM for DRM
|
## 4. Add a CDM for DRM
|
||||||
|
|
||||||
@@ -144,7 +114,7 @@ cdm:
|
|||||||
```
|
```
|
||||||
|
|
||||||
PlayReady works the same way with `.prd` files created and managed by the
|
PlayReady works the same way with `.prd` files created and managed by the
|
||||||
[`prd`](configuration-file.md) command. If a title is DRM-free, no CDM is needed.
|
[`prd`](../guide/cli-reference.md#prd) command. If a title is DRM-free, no CDM is needed.
|
||||||
|
|
||||||
!!! tip
|
!!! tip
|
||||||
Run `unshackle wvd parse my_device` to inspect a device's security level and
|
Run `unshackle wvd parse my_device` to inspect a device's security level and
|
||||||
@@ -199,7 +169,7 @@ unshackle dl <FLAGS> <SERVICE-TAG> <TITLE>
|
|||||||
- **`<SERVICE-TAG>`** picks which service to talk to (e.g. `EXAMPLE`).
|
- **`<SERVICE-TAG>`** picks which service to talk to (e.g. `EXAMPLE`).
|
||||||
- **`<TITLE>`** is the URL, ID, or slug the service understands.
|
- **`<TITLE>`** is the URL, ID, or slug the service understands.
|
||||||
|
|
||||||
A good first command asks for 1080p with English audio and subtitles:
|
A good first command asks for 1080p with English audio:
|
||||||
|
|
||||||
```shell title="Your first download"
|
```shell title="Your first download"
|
||||||
unshackle dl -q 1080 -l en EXAMPLE 81234567
|
unshackle dl -q 1080 -l en EXAMPLE 81234567
|
||||||
@@ -213,7 +183,7 @@ keys through your CDM (and any key vaults), then decrypt, mux, and tag the resul
|
|||||||
| Flag | Meaning |
|
| Flag | Meaning |
|
||||||
|---|---|
|
|---|---|
|
||||||
| `-q`, `--quality` | Target resolution(s), e.g. `-q 1080` or `-q 1080,720`. Defaults to best available. |
|
| `-q`, `--quality` | Target resolution(s), e.g. `-q 1080` or `-q 1080,720`. Defaults to best available. |
|
||||||
| `-l`, `--lang` | Language(s) for video and audio, e.g. `-l en` or `-l orig,en`. `orig` = the title's original language. |
|
| `-l`, `--lang` | Language(s) for video and audio, e.g. `-l en` or `-l orig,en`. `orig` = the title's original language. Defaults to `orig`. |
|
||||||
| `-sl`, `--s-lang` | Subtitle language(s); defaults to `all`. |
|
| `-sl`, `--s-lang` | Subtitle language(s); defaults to `all`. |
|
||||||
| `-v`, `--vcodec` | Video codec, e.g. `-v H.265`. Defaults to any. |
|
| `-v`, `--vcodec` | Video codec, e.g. `-v H.265`. Defaults to any. |
|
||||||
| `-r`, `--range` | Dynamic range, e.g. `-r HDR10` or `-r DV`. Defaults to `SDR`. |
|
| `-r`, `--range` | Dynamic range, e.g. `-r HDR10` or `-r DV`. Defaults to `SDR`. |
|
||||||
@@ -238,18 +208,18 @@ codec, bitrate, channel-layout, and track-type selection.
|
|||||||
|
|
||||||
## 8. Where the output lands
|
## 8. Where the output lands
|
||||||
|
|
||||||
By default, finished files are written to the `downloads` directory
|
By default, unshackle writes finished files to the `downloads` directory
|
||||||
(`unshackle env info` shows its exact path; the built-in default is a `downloads`
|
(`unshackle env info` shows its exact path; the built-in default is a `downloads`
|
||||||
folder alongside the project). Override it per run with `-o`:
|
folder one level above the installed `unshackle` package). Override it per run with `-o`:
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
unshackle dl -q 1080 -o /mnt/media/incoming EXAMPLE 81234567
|
unshackle dl -q 1080 -o /mnt/media/incoming EXAMPLE 81234567
|
||||||
```
|
```
|
||||||
|
|
||||||
- **Movies** are written as a single `.mkv` file named from your `movies` template.
|
- unshackle writes **movies** as a single `.mkv` file named from your `movies` template.
|
||||||
- **TV episodes** are grouped into a per-show / per-season folder (from your
|
- **TV episodes** are grouped into a per-show / per-season folder (from your
|
||||||
`series` template) unless you pass `--no-folder`.
|
`series` template) unless you pass `--no-folder`.
|
||||||
- The filename is built from your `output_template`, and IMDb/TMDB IDs are added to
|
- unshackle builds the filename from your `output_template` and adds IMDb/TMDB IDs to
|
||||||
the file's metadata tags when available.
|
the file's metadata tags when available.
|
||||||
|
|
||||||
To change the default output location permanently, set it in your config:
|
To change the default output location permanently, set it in your config:
|
||||||
@@ -270,5 +240,5 @@ directories:
|
|||||||
|
|
||||||
!!! tip "You are never far from help"
|
!!! tip "You are never far from help"
|
||||||
`unshackle --help`, `unshackle dl --help`, and `unshackle <command> --help`
|
`unshackle --help`, `unshackle dl --help`, and `unshackle <command> --help`
|
||||||
list every option with its default. When in doubt, add `--list` to a `dl`
|
list every option. When in doubt, add `--list` to a `dl`
|
||||||
command to preview what it would do before it downloads anything.
|
command to preview what it would do before it downloads anything.
|
||||||
|
|||||||
+22
-18
@@ -4,7 +4,7 @@
|
|||||||
streaming service, selects exactly the tracks you asked for, acquires and applies
|
streaming service, selects exactly the tracks you asked for, acquires and applies
|
||||||
decryption keys, and muxes everything into a finished Matroska file. The flags below
|
decryption keys, and muxes everything into a finished Matroska file. The flags below
|
||||||
cover quality and codec selection, language and subtitle handling, episode ranges, and
|
cover quality and codec selection, language and subtitle handling, episode ranges, and
|
||||||
the download flow itself, with examples throughout.
|
the download flow itself.
|
||||||
|
|
||||||
!!! note "Where the full flag list lives"
|
!!! note "Where the full flag list lives"
|
||||||
This page covers the flags you will use most and explains how they interact. It is
|
This page covers the flags you will use most and explains how they interact. It is
|
||||||
@@ -64,8 +64,9 @@ helps explain why, for example, `--list` stops early and why keys are fetched ev
|
|||||||
9. **Post-process**: extract closed captions, convert subtitles, repack, mux with
|
9. **Post-process**: extract closed captions, convert subtitles, repack, mux with
|
||||||
`mkvmerge`, and move the finished file to your downloads directory.
|
`mkvmerge`, and move the finished file to your downloads directory.
|
||||||
|
|
||||||
`--list` and `--list-titles` stop after selection/filtering and print what *would* be
|
`--list` prints the tracks a title exposes and stops before selection. `--list-titles`
|
||||||
downloaded. `--skip-dl` runs the license step but skips the actual segment download.
|
prints every title the service returned and stops before `--wanted`/`--latest-episode`
|
||||||
|
filtering. `--skip-dl` runs the license step but skips the actual segment download.
|
||||||
|
|
||||||
## Choosing quality
|
## Choosing quality
|
||||||
|
|
||||||
@@ -141,9 +142,11 @@ unshackle dl -q 2160 -r HDR10,DV EXAMPLE '...'
|
|||||||
|
|
||||||
!!! warning "HYBRID requires dovi_tool"
|
!!! warning "HYBRID requires dovi_tool"
|
||||||
`-r HYBRID` produces a single hybrid stream by injecting the Dolby Vision RPU
|
`-r HYBRID` produces a single hybrid stream by injecting the Dolby Vision RPU
|
||||||
metadata onto an HDR10/HDR10+ base layer using **dovi_tool**. It requires the
|
metadata onto an HDR10/HDR10+ base layer using **dovi_tool**.
|
||||||
`dovi_tool` binary on your PATH and needs both an HDR10(+) *and* a DV track to be
|
It requires the `dovi_tool` binary, resolved from unshackle's `binaries/` folder or
|
||||||
available, otherwise the title fails (unless `--best-available` lets it fall back).
|
your `PATH`. The normal case is a DV track plus an HDR10 or HDR10+ base. With HDR10+
|
||||||
|
and no DV, unshackle converts the HDR10+ metadata to DV instead, which also needs
|
||||||
|
`hdr10plus_tool`. With no DV and no HDR10+, the title fails.
|
||||||
When HDR10+ is present it is preferred over HDR10 as the base layer.
|
When HDR10+ is present it is preferred over HDR10 as the base layer.
|
||||||
|
|
||||||
To keep an HDR10+ deliverable *alongside* the hybrid, request both ranges:
|
To keep an HDR10+ deliverable *alongside* the hybrid, request both ranges:
|
||||||
@@ -171,8 +174,8 @@ Manifest-declared bitrates are sometimes rounded or wrong. Services often advert
|
|||||||
**peak** or **nominal** bandwidth that is far from the stream's real average. This matters
|
**peak** or **nominal** bandwidth that is far from the stream's real average. This matters
|
||||||
because a track's bitrate drives the track listing, the sort order, *and* the
|
because a track's bitrate drives the track listing, the sort order, *and* the
|
||||||
`--vbitrate`/`--vbitrate-range` selection above. A bogus declared value therefore makes
|
`--vbitrate`/`--vbitrate-range` selection above. A bogus declared value therefore makes
|
||||||
unshackle pick the wrong track. These flags remove that risk by probing the actual media
|
unshackle pick the wrong track. These flags probe the actual media size to compute a true
|
||||||
size to compute a true bitrate for the top renditions, overriding the manifest value:
|
bitrate for the top renditions, overriding the manifest value:
|
||||||
|
|
||||||
- `-rvb` / `--real-video-bitrate`: probe real video bitrates (per codec/range).
|
- `-rvb` / `--real-video-bitrate`: probe real video bitrates (per codec/range).
|
||||||
- `-rab` / `--real-audio-bitrate`: probe real audio bitrates (per codec/channels/
|
- `-rab` / `--real-audio-bitrate`: probe real audio bitrates (per codec/channels/
|
||||||
@@ -186,12 +189,13 @@ size to compute a true bitrate for the top renditions, overriding the manifest v
|
|||||||
That is the real *delivered* size, not an over-report or a bug.
|
That is the real *delivered* size, not an over-report or a bug.
|
||||||
|
|
||||||
!!! tip "Why not every rendition is probed"
|
!!! tip "Why not every rendition is probed"
|
||||||
Probing does not touch every rendition. Only the top rendition of each quality tier is
|
Probing does not touch every rendition. Only the five highest declared-bitrate
|
||||||
probed in parallel (video grouped by codec+range, audio by codec+channels+language),
|
renditions of each quality tier are probed in parallel (video grouped by codec and
|
||||||
and the pass then reaches downward only as far as it must to keep the ranking correct.
|
range, audio by codec, channels, language, and descriptive flag), and unshackle
|
||||||
This keeps probing fast even when a service exposes dozens of renditions. Tracks whose
|
extends a group downward while a lower unprobed rendition could still outrank a
|
||||||
duration can't be determined fall back to `ffprobe`, and a probe failure is non-fatal:
|
probed one. This keeps probing fast even when a service exposes dozens of renditions.
|
||||||
the manifest value is simply left in place.
|
Tracks whose duration can't be determined fall back to `ffprobe`, and a probe failure
|
||||||
|
is non-fatal: the manifest value is simply left in place.
|
||||||
|
|
||||||
## Audio codec, channels, and Atmos
|
## Audio codec, channels, and Atmos
|
||||||
|
|
||||||
@@ -347,7 +351,7 @@ with `-` to exclude it.
|
|||||||
| --- | --- |
|
| --- | --- |
|
||||||
| `--select-titles` | Interactively pick episodes from a list (Series only). **Cannot combine with `-w`.** |
|
| `--select-titles` | Interactively pick episodes from a list (Series only). **Cannot combine with `-w`.** |
|
||||||
| `--latest-episode` | Download only the single most recent episode. |
|
| `--latest-episode` | Download only the single most recent episode. |
|
||||||
| `--list-titles` | List the titles that would be downloaded, then stop. |
|
| `--list-titles` | List every title the service returned, then stop. `-w`/`--latest-episode` are not applied to this listing. |
|
||||||
|
|
||||||
```shell title="Grab just the newest episode"
|
```shell title="Grab just the newest episode"
|
||||||
unshackle dl --latest-episode EXAMPLE 81234567
|
unshackle dl --latest-episode EXAMPLE 81234567
|
||||||
@@ -398,8 +402,8 @@ Before committing to a long download, inspect what unshackle *would* do:
|
|||||||
|
|
||||||
| Flag | Effect |
|
| Flag | Effect |
|
||||||
| --- | --- |
|
| --- | --- |
|
||||||
| `--list` | List the available tracks and which would be selected, then stop. No download. |
|
| `--list` | List the tracks the service exposes for each title, then stop. No selection, no download. |
|
||||||
| `--list-titles` | List the titles (episodes) that would be downloaded, then stop. |
|
| `--list-titles` | List every title the service returned, then stop. `-w`/`--latest-episode` are not applied to this listing. |
|
||||||
| `--skip-dl` | Skip downloading but still acquire the decryption keys. |
|
| `--skip-dl` | Skip downloading but still acquire the decryption keys. |
|
||||||
|
|
||||||
```shell title="See the track selection without downloading"
|
```shell title="See the track selection without downloading"
|
||||||
@@ -428,7 +432,7 @@ flags change how the output is assembled:
|
|||||||
| --- | --- | --- |
|
| --- | --- | --- |
|
||||||
| `--no-mux` | Do not mux; keep the individual track files. | - |
|
| `--no-mux` | Do not mux; keep the individual track files. | - |
|
||||||
| `--split-audio` | Write a separate output file per audio codec instead of merging all audio. | config `muxing.merge_audio` (on) |
|
| `--split-audio` | Write a separate output file per audio codec instead of merging all audio. | config `muxing.merge_audio` (on) |
|
||||||
| `--merge-video` | Mux all selected video tracks into one file. | config `muxing.merge_video` (off) |
|
| `--merge-video` | Mux video tracks that share a height, range, and codec into one file, so only language varies inside a file. | config `muxing.merge_video` (off) |
|
||||||
|
|
||||||
### Naming tags
|
### Naming tags
|
||||||
|
|
||||||
|
|||||||
+10
-8
@@ -5,18 +5,20 @@ media from streaming manifests, handles the DRM, and muxes everything into clean
|
|||||||
well-tagged files, all driven from a single command-line tool, or served over a
|
well-tagged files, all driven from a single command-line tool, or served over a
|
||||||
REST API for automation.
|
REST API for automation.
|
||||||
|
|
||||||
It is a fork of [Devine](https://github.com/devine-dl/devine) with first-class
|
It is a fork of [Devine](https://github.com/devine-dl/devine) with DASH, HLS, and
|
||||||
DASH, HLS, and Smooth Streaming (ISM) parsing, both **Widevine** and **PlayReady**
|
Smooth Streaming (ISM) parsing, both **Widevine** and **PlayReady** DRM support,
|
||||||
DRM support, and a built-in HTTP server.
|
and a built-in HTTP server.
|
||||||
|
|
||||||
!!! warning "Use responsibly"
|
!!! warning "Use responsibly"
|
||||||
unshackle is licensed under [GPL-3.0](https://github.com/unshackle-dl/unshackle/blob/master/LICENSE).
|
unshackle is licensed under [GPL-3.0](https://github.com/unshackle-dl/unshackle/blob/main/LICENSE).
|
||||||
Do not use it for content you do not have the rights to. Keep the core free and
|
Do not use it for content you do not have the rights to. Keep the core free and
|
||||||
open, keep service code private, and be kind.
|
open, keep service code private, and be kind.
|
||||||
|
|
||||||
## What it does
|
## What it does
|
||||||
|
|
||||||
Point unshackle at a title on a streaming service and it will:
|
unshackle does everything except talk to the streaming platform. You write that part
|
||||||
|
as a service module ([Creating a Service](dev/creating-a-service.md)). Point unshackle
|
||||||
|
at a title and it will:
|
||||||
|
|
||||||
- Fetch the title metadata (movies, full series, seasons, episodes, albums, tracks).
|
- Fetch the title metadata (movies, full series, seasons, episodes, albums, tracks).
|
||||||
- Parse the streaming manifest: **DASH**, **HLS**, or **Smooth Streaming (ISM)**.
|
- Parse the streaming manifest: **DASH**, **HLS**, or **Smooth Streaming (ISM)**.
|
||||||
@@ -40,7 +42,7 @@ Point unshackle at a title on a streaming service and it will:
|
|||||||
| Subtitles | SRT, WebVTT, ASS/SSA, TTML and more, with optional SDH stripping and format conversion |
|
| Subtitles | SRT, WebVTT, ASS/SSA, TTML and more, with optional SDH stripping and format conversion |
|
||||||
| Key vaults | SQLite, MySQL, and HTTP/API vaults to store and share content keys |
|
| Key vaults | SQLite, MySQL, and HTTP/API vaults to store and share content keys |
|
||||||
| Proxies | Basic proxies plus NordVPN, ProtonVPN, Surfshark, Windscribe, ExpressVPN, Gluetun, and Hola providers |
|
| Proxies | Basic proxies plus NordVPN, ProtonVPN, Surfshark, Windscribe, ExpressVPN, Gluetun, and Hola providers |
|
||||||
| Services | Pluggable service modules, loadable from local folders or git repositories |
|
| Services | A plugin API for the service modules you write. unshackle includes none |
|
||||||
| Automation | A REST API with a job queue, live progress, history, and remote-download sessions |
|
| Automation | A REST API with a job queue, live progress, history, and remote-download sessions |
|
||||||
|
|
||||||
## Installation at a glance
|
## Installation at a glance
|
||||||
@@ -70,7 +72,7 @@ Point unshackle at a title on a streaming service and it will:
|
|||||||
Every download is three parts: the `dl` command, a **service tag**, and the
|
Every download is three parts: the `dl` command, a **service tag**, and the
|
||||||
service's title argument (a URL, ID, or slug).
|
service's title argument (a URL, ID, or slug).
|
||||||
|
|
||||||
```shell title="Download a 1080p title with English audio and subtitles"
|
```shell title="Download a 1080p title with English audio"
|
||||||
unshackle dl -q 1080 -l en EXAMPLE 81234567
|
unshackle dl -q 1080 -l en EXAMPLE 81234567
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -84,7 +86,7 @@ install to your first file.
|
|||||||
- **[Installation](getting-started/installation.md)**. Install unshackle and the external tools it depends on.
|
- **[Installation](getting-started/installation.md)**. Install unshackle and the external tools it depends on.
|
||||||
- **[Quickstart](getting-started/quickstart.md)**. Configure `unshackle.yaml` and run your first download.
|
- **[Quickstart](getting-started/quickstart.md)**. Configure `unshackle.yaml` and run your first download.
|
||||||
- **[Downloading](guide/downloading.md)**. The full `dl` command guide: quality, codecs, languages, track selection, and output.
|
- **[Downloading](guide/downloading.md)**. The full `dl` command guide: quality, codecs, languages, track selection, and output.
|
||||||
- **[Configuration](getting-started/configuration-file.md)**. Every `unshackle.yaml` key, directories, vaults, proxies, and naming templates.
|
- **[Configuration](getting-started/configuration-file.md)**. Where `unshackle.yaml` lives, the directory layout, and how to edit values. Full key list in the [Configuration Reference](reference/configuration.md).
|
||||||
- **[REST API](dev/rest-api/index.md)**. Run the `serve` HTTP server and drive downloads programmatically.
|
- **[REST API](dev/rest-api/index.md)**. Run the `serve` HTTP server and drive downloads programmatically.
|
||||||
|
|
||||||
!!! tip "Getting help"
|
!!! tip "Getting help"
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
# Configuration Reference
|
# Configuration Reference
|
||||||
|
|
||||||
This page is the exhaustive, authoritative reference for **every** key you can set in
|
This page documents every key you can set in
|
||||||
`unshackle.yaml`. For each key you will find its name, expected type, default value, and
|
`unshackle.yaml`. For each key you will find its name, expected type, default value, and
|
||||||
what it does. Keys are grouped by area so you can jump straight to the part of unshackle
|
what it does. Keys are grouped by area so you can jump straight to the part of unshackle
|
||||||
you are configuring.
|
you are configuring.
|
||||||
@@ -10,10 +10,12 @@ edit it), start with [The Configuration File](../getting-started/configuration-f
|
|||||||
This page assumes you already know the basics and want precise details.
|
This page assumes you already know the basics and want precise details.
|
||||||
|
|
||||||
!!! info "How defaults work"
|
!!! info "How defaults work"
|
||||||
Every key is optional. If you omit a key, unshackle uses the built-in default listed
|
Every key is optional except [`output_template`](#output-naming), which `dl` requires.
|
||||||
here. There is **no schema validation**: unknown keys are silently ignored (they never
|
Without it, `dl` aborts with an error. If you omit any other key, unshackle uses
|
||||||
become settings), and the file is parsed with `yaml.safe_load`. An empty or missing
|
the built-in default listed here. There is **no schema validation**: unknown keys are
|
||||||
file means *all* defaults apply.
|
silently ignored (they never become settings), and the file is parsed with
|
||||||
|
`yaml.safe_load`. An empty or missing file means every other key falls back to its
|
||||||
|
default.
|
||||||
|
|
||||||
!!! warning "Two keys behave specially on load"
|
!!! warning "Two keys behave specially on load"
|
||||||
- `curl_impersonate` is a **deprecated** alias of [`network`](#network-proxy) and emits a
|
- `curl_impersonate` is a **deprecated** alias of [`network`](#network-proxy) and emits a
|
||||||
@@ -32,7 +34,7 @@ This page assumes you already know the basics and want precise details.
|
|||||||
|------|------|
|
|------|------|
|
||||||
| [Directories](#directories) | `directories`, `filenames` |
|
| [Directories](#directories) | `directories`, `filenames` |
|
||||||
| [Services & authentication](#services-auth) | `services`, `credentials`, `firefox_cookies`, `remote_services`, `serve` |
|
| [Services & authentication](#services-auth) | `services`, `credentials`, `firefox_cookies`, `remote_services`, `serve` |
|
||||||
| [Download & processing](#download-processing) | `dl`, `subtitle`, `audio`, `muxing`, `language_tags` |
|
| [Download & processing](#download-processing) | `dl`, `subtitle`, `audio`, `muxing`, `language_tags`, `dual_multi_mode` |
|
||||||
| [Output & naming](#output-naming) | `output_template`, `tag`, `tag_group_name`, `tag_imdb_tmdb`, `chapter_fallback_name`, `unicode_filenames` |
|
| [Output & naming](#output-naming) | `output_template`, `tag`, `tag_group_name`, `tag_imdb_tmdb`, `chapter_fallback_name`, `unicode_filenames` |
|
||||||
| [DRM & CDM](#drm-cdm) | `cdm`, `remote_cdm`, `decryption` |
|
| [DRM & CDM](#drm-cdm) | `cdm`, `remote_cdm`, `decryption` |
|
||||||
| [Network & proxy](#network-proxy) | `network`, `headers`, `proxy_providers` |
|
| [Network & proxy](#network-proxy) | `network`, `headers`, `proxy_providers` |
|
||||||
@@ -91,7 +93,7 @@ directories:
|
|||||||
```yaml
|
```yaml
|
||||||
directories:
|
directories:
|
||||||
services:
|
services:
|
||||||
- unshackle-dl/community-services # cloned from GitHub
|
- you/your-services # cloned from GitHub
|
||||||
- https://example.com/private.git@stable
|
- https://example.com/private.git@stable
|
||||||
- ~/my-services # local, lowest priority
|
- ~/my-services # local, lowest priority
|
||||||
```
|
```
|
||||||
@@ -238,7 +240,7 @@ is the [REST API](../dev/rest-api/index.md) section; these are the config keys.
|
|||||||
| `api_secret` | str | *(unset)* | Master secret accepted in the `X-Secret-Key` header. |
|
| `api_secret` | str | *(unset)* | Master secret accepted in the `X-Secret-Key` header. |
|
||||||
| `users` | dict | `{}` | Per-user API keys and their allowlists (see below). |
|
| `users` | dict | `{}` | Per-user API keys and their allowlists (see below). |
|
||||||
| `services` | list | *(unset)* | Global service allowlist. Omit to allow all. |
|
| `services` | list | *(unset)* | Global service allowlist. Omit to allow all. |
|
||||||
| `remote_only` | bool | `false` | Run without a local `output_template` (CORS/Cloudflare-friendly). |
|
| `remote_only` | bool | `false` | Expose only the remote service session endpoints (health, services, search, session) and disable the rest of the REST API. |
|
||||||
| `session_ttl` | int (s) | `300` | Lifetime of an interactive auth session. |
|
| `session_ttl` | int (s) | `300` | Lifetime of an interactive auth session. |
|
||||||
| `max_sessions` | int | `100` | Maximum concurrent sessions. |
|
| `max_sessions` | int | `100` | Maximum concurrent sessions. |
|
||||||
| `history_limit` | int | `100` | How many finished jobs to retain in history. |
|
| `history_limit` | int | `100` | How many finished jobs to retain in history. |
|
||||||
@@ -247,7 +249,6 @@ is the [REST API](../dev/rest-api/index.md) section; these are the config keys.
|
|||||||
| `allow_job_credentials` | bool | `false` | Permit clients to supply credentials per job. |
|
| `allow_job_credentials` | bool | `false` | Permit clients to supply credentials per job. |
|
||||||
| `devices` | list | *(auto)* | Widevine devices offered; auto-filled from `directories.wvds`. |
|
| `devices` | list | *(auto)* | Widevine devices offered; auto-filled from `directories.wvds`. |
|
||||||
| `playready_devices` | list | *(auto)* | PlayReady devices; auto-filled from `directories.prds`. |
|
| `playready_devices` | list | *(auto)* | PlayReady devices; auto-filled from `directories.prds`. |
|
||||||
| `country` / `locations` | str / dict | *(unset)* | Advertised region metadata. |
|
|
||||||
|
|
||||||
Each entry under `users` is keyed by that user's API key and may set its own `services`,
|
Each entry under `users` is keyed by that user's API key and may set its own `services`,
|
||||||
`devices`, and `playready_devices` allowlists, narrowing the global ones.
|
`devices`, and `playready_devices` allowlists, narrowing the global ones.
|
||||||
@@ -266,9 +267,10 @@ serve:
|
|||||||
```
|
```
|
||||||
|
|
||||||
!!! tip "Declaring `dl` defaults under `serve`"
|
!!! tip "Declaring `dl` defaults under `serve`"
|
||||||
You can set any [`dl`](#dl) flag key (`downloads`, `workers`, `best_available`, and so on)
|
You can set most [`dl`](#dl) flag keys (`downloads`, `workers`, `best_available`, and so on)
|
||||||
directly inside `serve`. The point is to raise concurrency and behaviour defaults
|
directly inside `serve`; the server recognises a fixed subset of download parameters, so a
|
||||||
**server-wide** (every request the server handles picks them up) without having to change
|
few CLI-only flags are ignored here. This raises concurrency and behaviour defaults
|
||||||
|
**server-wide** (every request the server handles picks them up) without changing
|
||||||
each client call individually.
|
each client call individually.
|
||||||
|
|
||||||
---
|
---
|
||||||
@@ -299,7 +301,7 @@ after the flag's internal destination rather than its visible name; set these ex
|
|||||||
| `-o` / `--output` | `output_dir` |
|
| `-o` / `--output` | `output_dir` |
|
||||||
| `--cdm-only` / `--vaults-only` | `cdm_only` |
|
| `--cdm-only` / `--vaults-only` | `cdm_only` |
|
||||||
|
|
||||||
**Precedence** (highest first): an explicit CLI flag or environment variable → a per-service
|
**Precedence** (highest first): an explicit CLI flag → a per-service
|
||||||
[`services.<TAG>.dl`](#services-auth) override → this global `dl:` block → the built-in
|
[`services.<TAG>.dl`](#services-auth) override → this global `dl:` block → the built-in
|
||||||
default. In other words, config only fills in options you did not set on the command line.
|
default. In other words, config only fills in options you did not set on the command line.
|
||||||
|
|
||||||
@@ -369,7 +371,7 @@ written as sidecar files. See [Subtitles](../guide/subtitles.md) for the full gu
|
|||||||
| `convert_before_strip` | bool | `true` | Convert to the working format before stripping SDH. |
|
| `convert_before_strip` | bool | `true` | Convert to the working format before stripping SDH. |
|
||||||
| `conversion_method` | str | `"auto"` | Subtitle conversion backend. |
|
| `conversion_method` | str | `"auto"` | Subtitle conversion backend. |
|
||||||
| `preferred_conversion_method` | str | *(unset)* | Preferred converter when several are available. |
|
| `preferred_conversion_method` | str | *(unset)* | Preferred converter when several are available. |
|
||||||
| `output_mode` | str | `"mux"` | `mux` embeds subtitles in the MKV; `sidecar` writes separate files. |
|
| `output_mode` | str | `"mux"` | `mux` embeds subtitles in the MKV; `sidecar` writes separate files; `both` writes sidecars and still muxes. |
|
||||||
| `sidecar_format` | str | `"srt"` | Format for sidecar files when `output_mode: sidecar`. |
|
| `sidecar_format` | str | `"srt"` | Format for sidecar files when `output_mode: sidecar`. |
|
||||||
| `type_priority` | list | *(unset)* | Ordered ranking of subtitle types (`forced`, `normal`, `sdh`; CC counts as SDH) that sorts the variants within each language. Types you leave out fall to the end. |
|
| `type_priority` | list | *(unset)* | Ordered ranking of subtitle types (`forced`, `normal`, `sdh`; CC counts as SDH) that sorts the variants within each language. Types you leave out fall to the end. |
|
||||||
|
|
||||||
@@ -406,9 +408,9 @@ audio:
|
|||||||
```
|
```
|
||||||
|
|
||||||
!!! note "`codec_priority` is a soft priority: nothing is dropped"
|
!!! note "`codec_priority` is a soft priority: nothing is dropped"
|
||||||
`codec_priority` only breaks ties **among tracks that share the same bitrate and language**.
|
`codec_priority` outranks bitrate: any listed codec sorts above every unlisted one, and among
|
||||||
Codecs not in the list keep their normal bitrate-based ordering and are simply placed after
|
listed codecs the list order decides. Bitrate order survives only within a single codec rank.
|
||||||
all listed codecs, and none are ever removed. Two higher-level rules still override it: **Atmos
|
Nothing is ever removed. Two higher-level rules still override it: **Atmos
|
||||||
tracks always take precedence over `codec_priority`**, and **audio-description tracks are
|
tracks always take precedence over `codec_priority`**, and **audio-description tracks are
|
||||||
always forced to the end** regardless of it. When `codec_priority` is unset, tracks sort by
|
always forced to the end** regardless of it. When `codec_priority` is unset, tracks sort by
|
||||||
bitrate alone, with those same Atmos/descriptive rules still applied.
|
bitrate alone, with those same Atmos/descriptive rules still applied.
|
||||||
@@ -424,7 +426,7 @@ Matroska (MKV) muxing options.
|
|||||||
| `set_title` | bool | `true` | Write a human-readable title into the MKV container. |
|
| `set_title` | bool | `true` | Write a human-readable title into the MKV container. |
|
||||||
| `default_language` | dict | `{}` | Force which language is flagged *default* per track type, e.g. `{audio: en, subtitle: en}`. |
|
| `default_language` | dict | `{}` | Force which language is flagged *default* per track type, e.g. `{audio: en, subtitle: en}`. |
|
||||||
| `merge_audio` | bool | `true` | Merge all audio into one file. `--split-audio` on the CLI flips this off. |
|
| `merge_audio` | bool | `true` | Merge all audio into one file. `--split-audio` on the CLI flips this off. |
|
||||||
| `merge_video` | bool | `false` | Merge all video tracks into one file. `--merge-video` on the CLI flips this on. |
|
| `merge_video` | bool | `false` | Merge video tracks that share height, range, and codec into one file, so only language varies inside a file. `--merge-video` on the CLI flips this on. |
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
muxing:
|
muxing:
|
||||||
@@ -451,9 +453,6 @@ A rule may test:
|
|||||||
```yaml
|
```yaml
|
||||||
language_tags:
|
language_tags:
|
||||||
rules:
|
rules:
|
||||||
- audio: [en]
|
|
||||||
subs_contain_all: [en]
|
|
||||||
tag: "" # native English release, no tag
|
|
||||||
- audio: [ja]
|
- audio: [ja]
|
||||||
subs_contain: [en]
|
subs_contain: [en]
|
||||||
tag: "SUBBED"
|
tag: "SUBBED"
|
||||||
@@ -498,7 +497,7 @@ For the full picture of how templates render, see
|
|||||||
|
|
||||||
### `output_template`
|
### `output_template`
|
||||||
|
|
||||||
- **Type:** `dict` · **Default:** `{}`
|
- **Type:** `dict` · **Required** (no usable default; `dl` exits with an error if this is missing)
|
||||||
|
|
||||||
Filename templates keyed by media kind, using `{variable}` placeholders. Recognised kinds are
|
Filename templates keyed by media kind, using `{variable}` placeholders. Recognised kinds are
|
||||||
`movies`, `series`, and `songs` (and `albums` for folder templates). A trailing `?` on a
|
`movies`, `series`, and `songs` (and `albums` for folder templates). A trailing `?` on a
|
||||||
@@ -627,7 +626,7 @@ case-insensitively; `"mp4decrypt"` selects Bento4's mp4decrypt, and **anything e
|
|||||||
```yaml
|
```yaml
|
||||||
decryption:
|
decryption:
|
||||||
default: shaka
|
default: shaka
|
||||||
SOMESERVICE: mp4decrypt
|
EXAMPLE1: mp4decrypt
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
@@ -758,8 +757,9 @@ key_vaults:
|
|||||||
|
|
||||||
!!! tip "Common per-entry options"
|
!!! tip "Common per-entry options"
|
||||||
- `no_push: true` makes a vault read-only (keys are fetched but never written to it).
|
- `no_push: true` makes a vault read-only (keys are fetched but never written to it).
|
||||||
- A vault of `type: api` whose `name` contains `decrypt_labs` auto-fills its `token` from
|
- A vault of `type: API` whose `name` contains `decrypt_labs` auto-fills its `token` from
|
||||||
[`decrypt_labs_api_key`](#external-api-keys) when not set inline.
|
[`decrypt_labs_api_key`](#external-api-keys) when not set inline. Vault `type` values are
|
||||||
|
case-sensitive module names.
|
||||||
- An all-zero content key (32 zeros) is treated as "no key" everywhere and is never
|
- An all-zero content key (32 zeros) is treated as "no key" everywhere and is never
|
||||||
stored.
|
stored.
|
||||||
|
|
||||||
@@ -786,9 +786,9 @@ All default to an empty string and enable optional metadata/geolocation features
|
|||||||
| `ipinfo_api_key` | str | `""` | ipinfo.io API key for IP/region lookups. |
|
| `ipinfo_api_key` | str | `""` | ipinfo.io API key for IP/region lookups. |
|
||||||
|
|
||||||
!!! tip "SIMKL is a fallback for TMDB"
|
!!! tip "SIMKL is a fallback for TMDB"
|
||||||
SIMKL is positioned as an alternative metadata source, and it is most valuable precisely
|
SIMKL is an alternative metadata source. Use it when you have no `tmdb_api_key`
|
||||||
**when no `tmdb_api_key` is configured**. It improves title-matching and tagging
|
configured; it improves title matching and tagging in that case rather than replacing
|
||||||
reliability in that case rather than replacing TMDB where TMDB is available.
|
TMDB.
|
||||||
|
|
||||||
!!! note "`ipinfo_api_key` never touches your service sessions"
|
!!! note "`ipinfo_api_key` never touches your service sessions"
|
||||||
The token is only ever sent to `api.ipinfo.io` as a per-request `Authorization` header; it
|
The token is only ever sent to `api.ipinfo.io` as a per-request `Authorization` header; it
|
||||||
|
|||||||
Reference in New Issue
Block a user