mirror of
https://github.com/unshackle-dl/unshackle.git
synced 2026-11-12 03:55:05 +00:00
Converted subtitles get one style on a 1080-line canvas shaped like the video; native SSA/ASS is never restyled.
470 lines
24 KiB
Markdown
470 lines
24 KiB
Markdown
# Download & processing { #download-processing }
|
|
|
|
## `dl`
|
|
|
|
- **Type:** `dict` · **Default:** `{}`
|
|
|
|
Persistent defaults for the `dl` command. unshackle uses the block as Click's `default_map`,
|
|
so you can give any `dl` flag a default here. See [Downloading](../../guide/downloading.md) and the
|
|
[CLI Reference](../../guide/cli-reference.md) for what each flag does.
|
|
|
|
**Config key naming.** A config key is the flag's long name with dashes replaced by
|
|
underscores (`--best-available` → `best_available`, `--sub-format` → `sub_format`). A few
|
|
config keys use the flag's internal destination and not its visible name. Set these exact
|
|
config keys:
|
|
|
|
| Flag | Config key |
|
|
|------|-----------|
|
|
| `-r` / `--range` | `range` |
|
|
| `--list` | `list` |
|
|
| `--tmdb` | `tmdb_id` |
|
|
| `--imdb` | `imdb_id` |
|
|
| `--anilist` | `anilist_id` |
|
|
| `-naa` / `--noatmos` | `no_atmos` |
|
|
| `-o` / `--output` | `output_dir` |
|
|
| `--cdm-only` / `--vaults-only` | `cdm_only` |
|
|
|
|
**Precedence** (highest first): an explicit CLI flag → a per-service
|
|
[`services.<TAG>.dl`](services.md) 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.
|
|
|
|
Common config keys. This is a useful subset, and every `dl` flag works:
|
|
|
|
| Key | Type | Default | Sets |
|
|
|-----|------|---------|------|
|
|
| `lang` | list | `["orig"]` | Video/audio language(s); `orig` = original language. A `-` prefix excludes, e.g. `[all, -es]`. |
|
|
| `a_lang` / `v_lang` | list | `[]` | Audio- / video-only language override. A `-` prefix excludes. |
|
|
| `s_lang` | list | `["all"]` | Subtitle language(s). A `-` prefix excludes, e.g. `[all, -es]`. |
|
|
| `quality` | list | `[]` (best) | Resolution(s), e.g. `[1080]`. |
|
|
| `vcodec` | list | `[]` (any) | Video codec(s), e.g. `[H265]`. |
|
|
| `acodec` | list | `[]` (any) | Audio codec(s), e.g. `[EC3]`. |
|
|
| `range` | list | `["SDR"]` | Colour range(s): `SDR`, `HLG`, `HDR10`, `HDR10P`, `DV`, `HYBRID`. |
|
|
| `channels` | float | *(unset)* | Audio channels, e.g. `6` for 5.1. |
|
|
| `sub_format` | str | *(unset)* | Convert subtitles to this format (`srt`, `vtt`, `original`, ...). |
|
|
| `sub_font` | str | *(unset)* | Font for subtitles converted to ASS; implies `sub_format: ass`. Ignored when `sub_format` is another format. |
|
|
| `forced_subs` | bool | `false` | Include forced subtitle tracks. |
|
|
| `forced_s_lang` | list | `[]` | Forced subtitle language(s); implies `forced_subs`. A `-` prefix excludes. |
|
|
| `forced_subs_only` | bool | `false` | Keep only forced subtitle tracks; implies `forced_subs`. |
|
|
| `audio_description` | bool | `false` | Include descriptive (audio-description) tracks. |
|
|
| `audio_description_only` | bool | `false` | Keep only descriptive (audio-description) tracks. |
|
|
| `no_subs` / `no_audio` / `no_chapters` / `no_attachments` | bool | `false` | Skip that track type. `no_attachments` also skips attaching subtitle fonts. |
|
|
| `downloads` | int | `1` | Tracks downloaded concurrently. |
|
|
| `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, video language, or audio language is missing, or when one DRM system does not license under `--all-drm`. The CLI flag is `--best-available`, also spelled `--warn-only`. |
|
|
| `generate_dv` | bool | `false` | With `-r HYBRID`, make Dolby Vision from the HDR10+ metadata or the decoded video when a title has no DV track. With `-r HDR10` or `-r HDR10P`, make it for that base and ignore a DV track. See [Dolby Vision without a DV track](../../guide/downloading.md#dolby-vision-without-a-dv-track). |
|
|
| `proxy` | str | *(unset)* | Default proxy URI or 2-letter country. |
|
|
| `no_folder` | bool | `false` | Do not create a per-title folder. |
|
|
|
|
!!! note "`no` and `yes` are language tags"
|
|
YAML reads a bare `no` as `false` and a bare `yes` as `true`. unshackle puts both back to
|
|
the tags `no` (Norwegian) and `yes` (Nyankpa) in every config key that takes a language: `lang`,
|
|
`v_lang`, `a_lang`, `s_lang`, `forced_s_lang`, `require_audio`, `require_video`,
|
|
`require_subs`, [`language_priority`](#subtitle), [`muxing.default_language`](#muxing) and
|
|
the [`language_tags`](#language_tags) rules. Quotes (`lang: "no"`) work as well.
|
|
|
|
```yaml title="Global download defaults"
|
|
dl:
|
|
lang: [en]
|
|
quality: [1080]
|
|
range: [HDR10]
|
|
vcodec: [H265]
|
|
sub_format: srt
|
|
downloads: 2
|
|
```
|
|
|
|
!!! note "Language exclusions in YAML"
|
|
The language keys accept the same `-` exclusion tokens as the command line. Give them
|
|
as a list or as one comma-separated string.
|
|
|
|
```yaml
|
|
dl:
|
|
s_lang: [all, -es]
|
|
a_lang: "orig,-es"
|
|
```
|
|
|
|
See [Excluding languages](../../guide/downloading.md#excluding-languages) for the rules.
|
|
|
|
!!! note "Per-service overrides"
|
|
A `dl` block nested under a service in [`services`](services.md) takes the same keys and
|
|
applies to that service only.
|
|
|
|
```yaml
|
|
dl:
|
|
lang: [en]
|
|
services:
|
|
EXAMPLE1:
|
|
dl:
|
|
lang: [en, ja]
|
|
range: [DV]
|
|
```
|
|
|
|
!!! note "`serve` uses these same keys"
|
|
The [`serve`](services.md#serve) block accepts most of the same `dl` option keys at its top level
|
|
to set server-wide download defaults for every request it handles. The API ignores the
|
|
config keys it does not know there, `speed_limit` for example. `serve` has its own
|
|
`global_speed_limit`.
|
|
|
|
## `continue_downloads`
|
|
|
|
- **Type:** `bool` · **Default:** `false`
|
|
|
|
Keep a failed download's completed segment files so the next download resumes from where it
|
|
stopped instead of restarting from byte zero.
|
|
|
|
unshackle keeps the segments of a failed track in a `resume` directory inside the temp
|
|
directory, and the next download of the same track takes them back from there. It removes a
|
|
kept entry after 7 days, and `unshackle env clear temp` removes them all. A process that is
|
|
killed, or a job cancelled over the REST API, keeps nothing.
|
|
|
|
unshackle reuses only whole, fully downloaded segments. It always discards partially written
|
|
segments, and no partial-byte (`Range`) resume across runs takes place. Reuse is possible only
|
|
with proof that the segmentation did not change. The manifest URL, segment count, and byte
|
|
ranges must all match the previous download, or the download silently restarts clean.
|
|
|
|
!!! note "What can and cannot resume"
|
|
- Segmented DASH, ISM, and HLS tracks resume.
|
|
- Single-file (non-segmented) downloads and DASH tracks collapsed to a single ranged
|
|
download never make segment files, so this option does not apply to them (the
|
|
downloader has its own in-flight partial-file handling for those).
|
|
- HLS resumes Widevine/PlayReady and unencrypted titles only. An AES-128 title always
|
|
restarts. An HLS failure during the post-download merge step also restarts.
|
|
- A track downloaded with [`merge_segments`](#merge_segments) or
|
|
[`decrypt_segments`](drm.md#decrypt_segments) never resumes. Both options consume
|
|
or rewrite the segment files during the download.
|
|
|
|
For a one-off resume without changing config, pass `dl --continue-downloads` on the
|
|
command line (the flag can only enable resume, never disable it).
|
|
|
|
```yaml title="Resume failed downloads"
|
|
continue_downloads: true
|
|
```
|
|
|
|
## `merge_segments`
|
|
|
|
- **Type:** `bool` · **Default:** `false`
|
|
|
|
Appends each segment to the output file as soon as it and every segment before it have
|
|
arrived, instead of joining all the segment files after the last one lands. The join runs
|
|
during the download, so the "Merging" step after the last segment goes away. The output file
|
|
is the same either way.
|
|
|
|
Segments arrive out of order because the workers run in parallel. unshackle keeps a cursor on
|
|
the next segment it needs and appends every segment that is ready in order, then deletes the
|
|
segment file. With [`decrypt_segments`](drm.md#decrypt_segments) also on, each segment is
|
|
appended after its decryption completes, never before.
|
|
|
|
This option is off by default because it disables resume, and because its cost during the
|
|
download is not measured. The append reads each segment straight after a worker wrote it, so
|
|
the read usually comes from the page cache. On a hard disk, the append to one file while the
|
|
workers write many segment files can still make the head seek. If a download gets slower with
|
|
the option on, turn it off.
|
|
|
|
This applies to video and audio tracks from DASH, ISM, and HLS. An HLS track qualifies
|
|
only when every segment shares one init segment and one `EXT-X-KEY`, with no
|
|
`EXT-X-DISCONTINUITY`, and the DRM is Widevine, PlayReady, or none. AES-128 tracks, tracks
|
|
with content key rotation or discontinuities, and subtitle tracks keep the merge after the download.
|
|
|
|
!!! note "No resume"
|
|
|
|
A track that merges segment by segment always downloads from the start.
|
|
[`continue_downloads`](#continue_downloads) cannot reuse its segments, because unshackle
|
|
deletes each segment after it appends it.
|
|
|
|
```yaml
|
|
merge_segments: true
|
|
```
|
|
|
|
## `subtitle`
|
|
|
|
- **Type:** `dict` · **Default:** `{}`
|
|
|
|
Subtitle handling: SDH stripping, format conversion, and whether unshackle muxes the subtitles
|
|
in or writes them as sidecar files. See [Subtitles](../../guide/subtitles.md) for the full guide.
|
|
|
|
| Sub-key | Type | Default | Description |
|
|
|---------|------|---------|-------------|
|
|
| `strip_sdh` | bool | `true` | Strip SDH/CC cues (hearing-impaired annotations) into a clean track. |
|
|
| `sdh_method` | str | `"auto"` | SDH-stripping backend to use. |
|
|
| `preserve_formatting` | bool | `true` | Pass WebVTT cue text through as written. `false` re-encodes it through pycaption, which merges identical cues but flattens styling. unshackle removes WebVTT-only cue markup either way. |
|
|
| `convert_before_strip` | bool | `true` | Convert to the working format before stripping SDH. |
|
|
| `conversion_method` | str | `"auto"` | Subtitle conversion backend. |
|
|
| `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` is `sidecar` or `both`. |
|
|
| `type_priority` | list | *(unset)* | Ordered ranking of subtitle types (`forced`, `normal`, `sdh`; CC counts as SDH). Types you leave out fall to the end. |
|
|
| `group_by` | str | `"type"` | Which key groups the subtitle tracks. `type` puts all forced tracks together, then all normal, then all SDH. `language` keeps each language next to its own variants. |
|
|
| `language_priority` | list | *(unset)* | Languages to sort to the top, in the order you give. The rest keep the default order: original language first, then alphabetical. Nothing is removed. |
|
|
| `ass_style` | dict | *(unset)* | Style for subtitles converted to ASS, as pysubs2 or ASS style fields (`fontname`, `fontsize`, `primarycolor` or `PrimaryColour`, ...) for a 1080-line picture. Makes ASS the output format when `sub_format` is unset. See [Custom font and style](../../guide/subtitles.md#custom-font-and-style). |
|
|
| `dedupe_codecs` | list | *(unset)* | Subtitle codecs in order of preference, by value or name, for example `[VTT, STPP, WVTT]`. When tracks of the same language, forced/SDH/CC type and name come in several listed codecs, unshackle drops the ones in a later codec. It always keeps codecs you leave out. Unset keeps every track. |
|
|
|
|
```yaml
|
|
subtitle:
|
|
strip_sdh: true
|
|
output_mode: sidecar
|
|
sidecar_format: srt
|
|
```
|
|
|
|
!!! note "`group_by` track order"
|
|
| `group_by` | Result |
|
|
|---|---|
|
|
| `type` | Danish, Finnish, French, … Danish SDH, Finnish SDH, French SDH |
|
|
| `language` | Danish, Danish SDH, Finnish, Finnish SDH, French, French SDH |
|
|
|
|
`type_priority` still sets the order of the variants, so with `group_by: language` it
|
|
controls the order inside each language.
|
|
|
|
!!! note "`language_priority` sorts languages, it does not select them"
|
|
```yaml
|
|
subtitle:
|
|
group_by: language
|
|
language_priority: [en, es, fr]
|
|
```
|
|
|
|
| | Result for an English title |
|
|
|---|---|
|
|
| Default | English, Arabic, Bulgarian, Spanish, French, Japanese |
|
|
| With the list above | English, Spanish, French, Arabic, Bulgarian, Japanese |
|
|
|
|
unshackle removes nothing, unlike `-sl`, which drops every subtitle language it does not name.
|
|
|
|
Use `orig` in the list for the title's original language. A base tag puts the variant it
|
|
means first and its other regional forms after it, so `en` sorts `en-US` and then
|
|
`en-GB`, but `zh` does **not** cover `zh-Hant`, which you must name. A tag with a region sorts only that variant, so
|
|
`[en-US]` puts `en-US` before `en-GB`. The sort ignores entries that match no track, and
|
|
it ignores entries that are not valid language tags.
|
|
|
|
`--exact-lang` applies here too: with it, `en` sorts only the variant it means, and
|
|
`en-GB` falls to the alphabetical tail with the rest. Name each tag you want when you use
|
|
that flag.
|
|
|
|
!!! note "`type_priority` alone does not pick the default subtitle"
|
|
At mux time the `default` flag goes to every forced subtitle whose language matches the
|
|
default audio track, so a full dialogue track never becomes default on its own.
|
|
`type_priority` changes the order of the tracks in the file. It decides the flag only
|
|
between the tracks of one language, when you set `muxing.default_language.subtitle`. Set
|
|
[`muxing.default_subtitle_type`](#muxing) to name the type that gets the flag:
|
|
|
|
```yaml
|
|
muxing:
|
|
default_subtitle_type: [normal, sdh, forced]
|
|
default_language:
|
|
subtitle: en
|
|
```
|
|
|
|
Here the flag goes to the full English track, then to the English SDH track when the
|
|
title has no full one, then to the forced one. Without `default_language.subtitle`, the
|
|
first track of the type in file order gets the flag, in any language. A forced track is
|
|
the exception: it gets the flag only in the language of the default audio track.
|
|
|
|
## `audio`
|
|
|
|
- **Type:** `dict` · **Default:** `{}`
|
|
|
|
Audio handling options. The most notable sub-key is **`codec_priority`**, an ordered list of
|
|
audio codecs used to break ties in track selection. **`language_priority`** is an ordered list
|
|
of languages that sort to the top of the audio tracks.
|
|
|
|
```yaml
|
|
audio:
|
|
codec_priority:
|
|
- EAC3
|
|
- AC3
|
|
language_priority:
|
|
- orig
|
|
- en
|
|
```
|
|
|
|
!!! note "`codec_priority` is a soft priority: nothing is dropped"
|
|
`codec_priority` outranks bitrate: any listed codec sorts above every unlisted one, and among
|
|
listed codecs the list order decides. Bitrate order survives only within a single codec rank.
|
|
Nothing is ever removed. Two higher-level rules still override it: **Atmos
|
|
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
|
|
bitrate alone, with those same Atmos/descriptive rules still applied.
|
|
|
|
## `muxing`
|
|
|
|
- **Type:** `dict` · **Default:** `{}`
|
|
|
|
Matroska (MKV) muxing options.
|
|
|
|
| Sub-key | Type | Default | Description |
|
|
|---------|------|---------|-------------|
|
|
| `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}`. A tag with a region, such as `en-US`, matches only that variant. |
|
|
| `default_subtitle_type` | str or list | unset | The subtitle types that can take the *default* flag, in order: `forced`, `normal`, `sdh` (CC counts as SDH, and `cc` is the same as `sdh`). The first subtitle track of the first type that the title has gets the flag. With `default_language.subtitle`, only the tracks in that language count. unshackle ignores a different word with a warning. `normal` is the value for players that read the forced flag. Read [Muxing](../../guide/output-and-naming.md#muxing-options). |
|
|
| `merge_audio` | bool | `true` | Merge all audio into one file. `--split-audio` on the CLI flips this off. |
|
|
| `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. |
|
|
| `track_names` | str | `english` | The language of the name unshackle gives a track that the service left unnamed: `english` (`Chinese (Traditional)`), `native`, the name in the language itself (`中文(繁體)`), or `none`, which leaves the track unnamed. Read [Track names and language tags](../../guide/output-and-naming.md#track-names-and-language-tags). |
|
|
| `original_label` | str | unset | Text that unshackle adds after the name of an audio or subtitle track in the title's original language, such as `[Original]`. Read [Track names and language tags](../../guide/output-and-naming.md#track-names-and-language-tags). |
|
|
| `concurrency` | int | `4` | How many mkvmerge processes run at the same time when a title muxes more than one output file (one per video variant or audio codec). Each process uses one CPU core, so this shortens the mux step on an SSD. Set it to `1` on a hard disk, where parallel writes are slower. |
|
|
|
|
```yaml
|
|
muxing:
|
|
set_title: true
|
|
concurrency: 4
|
|
default_language:
|
|
audio: en
|
|
subtitle: en
|
|
default_subtitle_type: normal
|
|
```
|
|
|
|
## `language_tags`
|
|
|
|
- **Type:** `dict` · **Default:** `{}`
|
|
|
|
Language-tag remapping and the rule engine behind the `{lang_tag}` filename variable. When a
|
|
`rules` list is present, unshackle evaluates each rule in order and uses the first match's
|
|
`tag`. A rule can examine:
|
|
|
|
| Condition | Meaning |
|
|
|-----------|---------|
|
|
| `audio` | At least one audio language matches. |
|
|
| `audio_contain_all` | Every listed language must be present in the audio. |
|
|
| `subs_contain` | At least one subtitle language matches. |
|
|
| `subs_contain_all` | Every listed language must be present in the subtitles. |
|
|
| `dual` / `multi` / `dubbed` | `true` matches when that filename variable is set, `false` when it is not. |
|
|
|
|
Each language condition takes one language tag or a list of them. A list matches when **any**
|
|
entry matches, except `audio_contain_all` and `subs_contain_all`, which need them all. An empty
|
|
list never matches. An entry that is not a valid language tag (for example `japanese`) never
|
|
matches. A tag with a region matches only that variant, so `audio: es-419` does not match
|
|
`es-ES` audio. `dual`, `multi` and `dubbed` take a bare `true` or `false`, not a quoted string.
|
|
unshackle skips a rule with a condition name it does not know, or with any other value in a
|
|
boolean condition. It logs a warning in each of these cases and tries the next rule.
|
|
|
|
`dual`, `multi` and `dubbed` carry the same meaning as the
|
|
[filename variables of those names](#dual_multi_mode). Pair one with a language to name a
|
|
release yourself, in place of the fixed `DUAL`, `MULTi` and `DUBBED` text. A rule that names
|
|
`dubbed: true` and a language tags a localized dub without tagging a native release the same way.
|
|
|
|
```yaml
|
|
language_tags:
|
|
rules:
|
|
- audio: [ja]
|
|
subs_contain: [en]
|
|
tag: "SUBBED"
|
|
- audio: th
|
|
dubbed: true
|
|
tag: "THAIDUB"
|
|
- audio: th
|
|
dual: true
|
|
tag: "THAIDUAL"
|
|
```
|
|
|
|
unshackle examines the rules in order, so put a rule that needs more languages before a rule that
|
|
needs fewer. Here, a release with both French dubs gets `VF2`, not `VFQ`:
|
|
|
|
```yaml
|
|
language_tags:
|
|
rules:
|
|
- audio_contain_all: [fr-FR, fr-CA]
|
|
tag: "VF2"
|
|
- audio: fr-CA
|
|
tag: "VFQ"
|
|
- audio: fr-FR
|
|
tag: "VFF"
|
|
```
|
|
|
|
!!! tip "Give regional tags in an `_all` list"
|
|
A tag without a region also matches a regional track, so one `fr-CA` track satisfies both
|
|
entries of `[fr, fr-CA]`. Use `[fr-FR, fr-CA]` to require two different tracks.
|
|
|
|
!!! note "Put `{lang_tag}` where you want the name"
|
|
These rules fill `{lang_tag}`. To use your own name in place of the fixed text, keep
|
|
`{lang_tag?}` in the template and leave out `{dual?}`, `{multi?}` and `{dubbed?}`.
|
|
|
|
## `dual_multi_mode`
|
|
|
|
- **Type:** `str` · **Default:** `strict`
|
|
|
|
Rule set for the `{dual}`, `{multi}`, and `{dubbed}` filename variables.
|
|
|
|
=== "`strict` (default)"
|
|
|
|
| Variable | Set when |
|
|
|----------|----------|
|
|
| `{dual}` | Exactly two audio languages **and one is the title's original language**. |
|
|
| `{multi}` | Three or more audio languages, even without the original. |
|
|
| `{dubbed}` | A single audio language that is not the title's original language (requires a known original). |
|
|
|
|
=== "`count` (legacy)"
|
|
|
|
| Variable | Set when |
|
|
|----------|----------|
|
|
| `{dual}` | Exactly two audio languages (original language ignored). |
|
|
| `{multi}` | Three or more audio languages. |
|
|
| `{dubbed}` | Never set. |
|
|
|
|
```yaml
|
|
dual_multi_mode: strict
|
|
```
|
|
|
|
!!! note "Dialects count as one language"
|
|
Regional variants of the same base language (e.g. `en-US` and `en-GB`) collapse to a single
|
|
language in both modes, so they never trigger `{dual}` on their own. An individual language
|
|
counts as its macrolanguage: `cmn` and `zh` are one language, and so are `arb` and `ar`.
|
|
Norwegian `nb` (Bokmål) and `nn` (Nynorsk) count as `no`.
|
|
Cantonese (`yue`) stays separate, so `cmn` and `yue` audio give `{dual}`.
|
|
|
|
## `hdr10plus_probe`
|
|
|
|
- **Type:** `bool` · **Default:** `true`
|
|
|
|
Find the HDR10+ tracks that a service labels as HDR10. Before unshackle lists or selects tracks, it
|
|
reads the first fragment of HEVC HDR10 tracks from DASH, HLS fMP4 and one-file sources. A track
|
|
whose first frame carries HDR10+ (SMPTE ST 2094-40) metadata becomes `HDR10P`. Then `-r HDR10P`,
|
|
`--list` and [`--generate-dv`](../../guide/downloading.md#dolby-vision-without-a-dv-track) use it.
|
|
|
|
unshackle also probes HEVC Dolby Vision tracks. A DV track that carries HDR10+ keeps its `DV`
|
|
range, so `-r DV` selects it, and `--list` shows it as `DV+HDR10P`. `-r HYBRID` uses it as the
|
|
[hybrid](../../guide/downloading.md#colour-range) of its resolution, with no base track. The
|
|
HDR10 tracks and the DV tracks of a title are sampled as two separate sets.
|
|
|
|
When two HDR10 tracks have the same resolution, they can be an HDR10 encode and an HDR10+ encode
|
|
side by side, so unshackle probes every track. When each track has its own resolution, unshackle
|
|
probes the two highest and the two lowest bitrates first:
|
|
|
|
| Result | Action |
|
|
|--------|--------|
|
|
| All four carry HDR10+ | Every HDR10 track of the title becomes `HDR10P`. |
|
|
| Some carry HDR10+ | The title has HDR10 and HDR10+ encodes side by side, so unshackle probes every track. |
|
|
| None carry HDR10+ | Every track stays `HDR10`. |
|
|
|
|
A probe that fails, or a fragment whose metadata is encrypted, keeps the label from the service.
|
|
unshackle does not probe ISM tracks. Each probe makes one to three small requests: the 64 KiB
|
|
fragment, plus the playlist of an HLS track or the header of a one-file track. The probes run in
|
|
parallel, with no more at a time than `--workers` (or `dl.workers`) sets for a track download.
|
|
|
|
```yaml
|
|
hdr10plus_probe: true
|
|
```
|
|
|
|
A remote server probes its tracks before it sends them, so the setting on the server applies to
|
|
remote downloads and to the REST API.
|
|
|
|
## `generate_dv_mode`
|
|
|
|
- **Type:** `str` · **Default:** `v29`
|
|
|
|
How [`--generate-dv`](../../guide/downloading.md#dolby-vision-without-a-dv-track) sets the Level 1 brightness
|
|
values of the Dolby Vision it makes from HDR10+. All modes make one shot per HDR10+ scene and keep the
|
|
same peak and letterbox area. They differ in the scene average, which the TV uses to tone-map.
|
|
|
|
| Mode | Scene average |
|
|
|------|---------------|
|
|
| `v29` (default) | unshackle's average from the HDR10+ brightness distribution, at least about 2.4 nits. Closest to the pixels. |
|
|
| `v40` | The same average, at least about 10 nits, as in studio Dolby Vision (CM v4.0). Dark scenes read brighter than `v29`. |
|
|
| `legacy` | The `dovi_tool generate --hdr10plus-json` average. Most scenes read brighter than the pixels. |
|
|
|
|
```yaml
|
|
generate_dv_mode: v29
|
|
```
|
|
|
|
Dolby Vision that unshackle measures from the decoded video uses its measured average in all modes.
|
|
`v40` raises the lowest average to about 10 nits, and `legacy` is the same as `v29`.
|
|
|
|
The setting applies on the machine that runs the hybrid step: the client for a remote download, the
|
|
server for a REST API job.
|