Deployed 35871f3 with MkDocs version: 1.6.1

This commit is contained in:
2026-10-17 22:40:48 +00:00
parent d3a5b8c695
commit 461292b693
12 changed files with 1170 additions and 946 deletions
+8
View File
@@ -2566,8 +2566,16 @@ fetching tracks:</p>
</span><span id="__span-4-3"><a id="__codelineno-4-3" name="__codelineno-4-3" href="#__codelineno-4-3"></a> <span class="n">codecs</span><span class="p">:</span> <span class="nb">list</span><span class="p">[</span><span class="n">Video</span><span class="o">.</span><span class="n">Codec</span><span class="p">]</span> <span class="o">=</span> <span class="p">[]</span> <span class="c1"># empty == accept any codec</span>
</span><span id="__span-4-4"><a id="__codelineno-4-4" name="__codelineno-4-4" href="#__codelineno-4-4"></a> <span class="n">ranges</span><span class="p">:</span> <span class="nb">list</span><span class="p">[</span><span class="n">Video</span><span class="o">.</span><span class="n">Range</span><span class="p">]</span> <span class="o">=</span> <span class="p">[</span><span class="n">Video</span><span class="o">.</span><span class="n">Range</span><span class="o">.</span><span class="n">SDR</span><span class="p">]</span>
</span><span id="__span-4-5"><a id="__codelineno-4-5" name="__codelineno-4-5" href="#__codelineno-4-5"></a> <span class="n">best_available</span><span class="p">:</span> <span class="nb">bool</span> <span class="o">=</span> <span class="kc">False</span>
</span><span id="__span-4-6"><a id="__codelineno-4-6" name="__codelineno-4-6" href="#__codelineno-4-6"></a> <span class="n">generate_dv</span><span class="p">:</span> <span class="nb">bool</span> <span class="o">=</span> <span class="kc">False</span> <span class="c1"># --generate-dv: make Dolby Vision from HDR10+</span>
</span></code></pre></div>
<div class="admonition note">
<p class="admonition-title"><code>generate_dv</code> and a hand-made HYBRID</p>
<p>A service that fetches the HYBRID variants itself (HDR10 and DV) must also fetch
HDR10P when <code>track_request.generate_dv</code> is set and the title has no DV track.
The conversion needs an HEVC HDR10+ track as its base.
<code>get_tracks_for_variants</code> does this for you.</p>
</div>
<div class="admonition note">
<p class="admonition-title">Read the request, don't second-guess the user</p>
<p>Services may narrow <code>track_request</code> for hard technical constraints (e.g.
<em>"this service delivers HDR only as HEVC"</em>), but must <strong>not</strong> filter
+6
View File
@@ -4066,6 +4066,12 @@ ignore it safely. See <a href="../../creating-a-service/#split-episodes">Split e
<td>Fall back to best available. With <code>all_drm</code>, a DRM system that does not license is a warning.</td>
</tr>
<tr>
<td><code>generate_dv</code></td>
<td>boolean</td>
<td><code>false</code></td>
<td>With <code>HYBRID</code> in <code>range</code>, make Dolby Vision from the HDR10+ metadata when a title has no DV track. Needs <code>hdr10plus_tool</code> on the server. Without <code>HYBRID</code> in <code>range</code>, the request returns <code>400</code>.</td>
</tr>
<tr>
<td><code>repack</code></td>
<td>boolean</td>
<td><code>false</code></td>
+3 -3
View File
@@ -2536,8 +2536,8 @@ server does not have to prompt:</p>
The client also downloads playlists and segments through the same proxy,
as a local run does. <code>--no-proxy-download</code> and <code>--proxy-download</code> change
that for downloads only.</li>
<li>Track-selection hints (<code>range_</code>, <code>vcodec</code>, <code>quality</code>, <code>best_available</code>) so
the server fetches the right manifests</li>
<li>Track-selection hints (<code>range_</code>, <code>vcodec</code>, <code>quality</code>, <code>best_available</code>,
<code>generate_dv</code>) so the server fetches the right manifests</li>
<li>Your language and audio codec selection (<code>-l</code>, <code>-vl</code>, <code>-al</code>, <code>-a</code>, <code>-fs</code>)
in a <code>dl_params</code> object. Some services fetch one manifest
for each audio language, and pick the languages from these values</li>
@@ -2901,7 +2901,7 @@ from a browser origin, not when you want only the local HTTP API.</p>
answers CDM calls), <code>cdm_system_id</code> and <code>cdm_device_type</code> (Widevine only), <code>service_config</code>
(the identity config keys the service lists in <code>client_config</code>), <code>client</code> (a freeform identity
object the dashboard shows as sent), and the track-selection hints <code>range_</code>, <code>vcodec</code>,
<code>quality</code>, <code>best_available</code>, plus arbitrary service CLI options
<code>quality</code>, <code>best_available</code>, <code>generate_dv</code>, plus arbitrary service CLI options
(<code>additionalProperties: true</code>).</p>
<p><code>dl_params</code> holds the <code>dl</code> track selection: <code>lang</code>, <code>v_lang</code> and <code>a_lang</code>
(arrays of language strings), <code>acodec</code> (an array of audio codec names, such as
+4 -2
View File
@@ -2835,8 +2835,10 @@ See <a href="../../guide/proxies-and-vpn/">Proxies and VPN</a>.</p>
<p class="admonition-title"><code>TrackRequest</code></p>
<p><code>self.track_request</code> is a small dataclass built from the CLI: <code>codecs</code>
(from <code>--vcodec</code>, empty means "accept any"), <code>ranges</code> (from <code>--range</code>, default
<code>[Video.Range.SDR]</code>), and <code>best_available</code>. Use it in <code>get_tracks</code> to decide which
variants to fetch.</p>
<code>[Video.Range.SDR]</code>), <code>best_available</code>, and <code>generate_dv</code> (from <code>--generate-dv</code>).
Use it in <code>get_tracks</code> to decide which variants to fetch. A service that fetches
the HYBRID variants itself must also fetch HDR10P when <code>generate_dv</code> is set and
the title has no DV track, because the conversion needs an HEVC HDR10+ base.</p>
</div>
<h2 id="titles-and-the-title-hierarchy">Titles and the <code>Title</code> hierarchy<a class="headerlink" href="#titles-and-the-title-hierarchy" title="Permanent link">&para;</a></h2>
<p><code>get_titles()</code> returns a <strong>title collection</strong>, one of the <code>Titles_T</code> types. Each
+5
View File
@@ -3048,6 +3048,11 @@
<td>Colour range(s): <code>SDR</code>, <code>HLG</code>, <code>HDR10</code>, <code>HDR10P</code> (HDR10+), <code>DV</code>, <code>HYBRID</code>.</td>
</tr>
<tr>
<td><code>--generate-dv</code></td>
<td>off</td>
<td>With <code>-r HYBRID</code>, make Dolby Vision from the HDR10+ metadata when a title has no Dolby Vision track. Needs <code>hdr10plus_tool</code>. See <a href="../downloading/#dolby-vision-from-hdr10">Dolby Vision from HDR10+</a>.</td>
</tr>
<tr>
<td><code>-c</code>, <code>--channels</code></td>
<td>-</td>
<td>Audio channels; matches sub-layouts (5.1 ≈ 6.0).</td>
+172 -102
View File
@@ -826,6 +826,23 @@
</span>
</a>
<nav class="md-nav" aria-label="Colour range">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#dolby-vision-from-hdr10" class="md-nav__link">
<span class="md-ellipsis">
Dolby Vision from HDR10+
</span>
</a>
</li>
</ul>
</nav>
</li>
</ul>
@@ -2606,6 +2623,23 @@
</span>
</a>
<nav class="md-nav" aria-label="Colour range">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#dolby-vision-from-hdr10" class="md-nav__link">
<span class="md-ellipsis">
Dolby Vision from HDR10+
</span>
</a>
</li>
</ul>
</nav>
</li>
</ul>
@@ -3268,13 +3302,49 @@ either enum <strong>names</strong> or their <strong>values</strong>, comma-separ
<p><code>-r HYBRID</code> makes a single hybrid track by injecting the Dolby Vision RPU
metadata onto an HDR10/HDR10+ base layer with <strong>dovi_tool</strong>.
It requires the <code>dovi_tool</code> binary, resolved from unshackle's <code>binaries/</code> folder,
the <code>binaries</code> folder of your user data directory, or your <code>PATH</code>. 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
<code>hdr10plus_tool</code>. With no DV and no HDR10+, the title fails.
When HDR10+ is present, unshackle prefers it over HDR10 as the base layer.</p>
the <code>binaries</code> folder of your user data directory, or your <code>PATH</code>. A hybrid needs a DV track plus an HDR10 or
HDR10+ base. With no DV track, the title fails, unless you add <code>--generate-dv</code> (see below).
When HDR10+ is present, unshackle prefers it over HDR10 as the base layer. The base must be
HEVC; a title whose HDR10/HDR10+ tracks are all in another codec fails before it downloads.
If the hybrid step fails for one resolution, unshackle logs an error, skips that resolution
and goes on with the other resolutions of the title. When no hybrid file at all was made,
the title fails.</p>
<p>To keep an HDR10+ deliverable <em>alongside</em> the hybrid, request both ranges:
<code>-r HYBRID,HDR10P</code>. <code>-r HYBRID</code> on its own muxes only the merged hybrid.</p>
</div>
<h4 id="dolby-vision-from-hdr10">Dolby Vision from HDR10+<a class="headerlink" href="#dolby-vision-from-hdr10" title="Permanent link">&para;</a></h4>
<p>When a title has HDR10+ but no DV track, <code>-r HYBRID --generate-dv</code> makes a Dolby Vision
Profile 8.1 track from the HDR10+ metadata. It needs <code>hdr10plus_tool</code> as well as <code>dovi_tool</code>.
When a title has a DV track, unshackle uses that track and ignores the flag. When it has none,
the flag also makes unshackle ask the service for its HDR10+ tracks.</p>
<div class="language-shell highlight"><span class="filename">Generate Dolby Vision from HDR10+, and keep the HDR10+ file too</span><pre><span></span><code><span id="__span-8-1"><a id="__codelineno-8-1" name="__codelineno-8-1" href="#__codelineno-8-1"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>-q<span class="w"> </span><span class="m">2160</span><span class="w"> </span>-r<span class="w"> </span>HYBRID,HDR10P<span class="w"> </span>--generate-dv<span class="w"> </span>EXAMPLE<span class="w"> </span><span class="s1">'...'</span>
</span></code></pre></div>
<p>Each HDR10+ scene becomes one Dolby Vision shot, with its own scene cut and its own Level 1
brightness values (peak and average). unshackle calculates the average itself, as a PQ mean of
the HDR10+ brightness distribution without the letterbox bars. A scene with no black pixels keeps
its whole frame, so a title that changes aspect ratio is also correct. The <code>dovi_tool generate
--hdr10plus-json</code> average makes most scenes too bright.</p>
<p>The <a href="../../reference/configuration/download/#generate_dv_mode"><code>generate_dv_mode</code></a> setting in
<code>unshackle.yaml</code> changes how the average is set: <code>v29</code> (default), <code>v40</code> for the 10-nit floor of studio
Dolby Vision, or <code>legacy</code> for the <code>dovi_tool</code> average.</p>
<div class="admonition warning">
<p class="admonition-title">Generated Dolby Vision is not studio Dolby Vision</p>
<ul>
<li>There are no colourist trims (Level 2 and Level 8). The TV does all the tone mapping
from the Level 1 values.</li>
<li>Dolby Vision does not let the average go below about 2.4 nits (10 nits with
<code>generate_dv_mode: v40</code>), so a very dark scene reads a little brighter than its pixels.</li>
<li>The HDR10+ tone-mapping curve (Profile B) has no Dolby Vision equivalent. The HDR10+
metadata stays in the file, so an HDR10+ TV still reads it.</li>
<li>The result can be no better than the HDR10+ metadata. Profile A metadata is often less
reliable than Profile B, and unshackle shows a warning for Profile A.</li>
<li>A TV or player that supports both formats almost always picks Dolby Vision. On such a
TV, the generated Dolby Vision replaces the original HDR10+. To keep the original, also
request <code>HDR10P</code>, as in the example above.</li>
</ul>
<p>An HDR10 track that a service labels HDR10 but that carries HDR10+ metadata does not
convert. Only a track with the <code>HDR10P</code> range does.</p>
</div>
<h2 id="bitrate-selection">Bitrate selection<a class="headerlink" href="#bitrate-selection" title="Permanent link">&para;</a></h2>
<p>By default unshackle keeps the highest-bitrate rendition for each selected
resolution/codec/range/language combination. You can constrain this.</p>
@@ -3405,7 +3475,7 @@ non-fatal: the manifest value stays in place.</p>
</table>
<p>unshackle accepts names, values, and a few aliases: <code>eac3</code> and <code>ddp</code> both give <code>EC3</code>,
and <code>vorbis</code> gives <code>OGG</code>.</p>
<div class="language-shell highlight"><span class="filename">Prefer Dolby Digital Plus, fall back to AAC</span><pre><span></span><code><span id="__span-8-1"><a id="__codelineno-8-1" name="__codelineno-8-1" href="#__codelineno-8-1"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>-a<span class="w"> </span>EC3,AAC<span class="w"> </span>EXAMPLE<span class="w"> </span><span class="m">81234567</span>
<div class="language-shell highlight"><span class="filename">Prefer Dolby Digital Plus, fall back to AAC</span><pre><span></span><code><span id="__span-9-1"><a id="__codelineno-9-1" name="__codelineno-9-1" href="#__codelineno-9-1"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>-a<span class="w"> </span>EC3,AAC<span class="w"> </span>EXAMPLE<span class="w"> </span><span class="m">81234567</span>
</span></code></pre></div>
<h3 id="channels-and-atmos">Channels and Atmos<a class="headerlink" href="#channels-and-atmos" title="Permanent link">&para;</a></h3>
<ul>
@@ -3414,16 +3484,16 @@ and <code>vorbis</code> gives <code>OGG</code>.</p>
<code>5.1.4</code> matches on its total number of channels, so <code>-c 10</code> selects it.</li>
<li><code>-naa</code> / <code>--noatmos</code>: exclude Atmos audio tracks from selection.</li>
</ul>
<div class="language-shell highlight"><span class="filename">5.1 audio, no Atmos</span><pre><span></span><code><span id="__span-9-1"><a id="__codelineno-9-1" name="__codelineno-9-1" href="#__codelineno-9-1"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>-c<span class="w"> </span><span class="m">5</span>.1<span class="w"> </span>--noatmos<span class="w"> </span>EXAMPLE<span class="w"> </span>0ABC123
<div class="language-shell highlight"><span class="filename">5.1 audio, no Atmos</span><pre><span></span><code><span id="__span-10-1"><a id="__codelineno-10-1" name="__codelineno-10-1" href="#__codelineno-10-1"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>-c<span class="w"> </span><span class="m">5</span>.1<span class="w"> </span>--noatmos<span class="w"> </span>EXAMPLE<span class="w"> </span>0ABC123
</span></code></pre></div>
<h3 id="music-quality">Music quality<a class="headerlink" href="#music-quality" title="Permanent link">&para;</a></h3>
<p>A music service gives one <code>Audio</code> track for each codec and bitrate it offers for a song.
The audio options above choose between them: <code>-a</code> picks the codec and <code>-ab</code> or <code>-ab-range</code>
picks the bitrate. If you set neither, unshackle takes the best track.</p>
<p><code>-q</code> / <code>--quality</code> is a video height. It has no effect on a music download.</p>
<div class="language-shell highlight"><span class="filename">Take the lossless track</span><pre><span></span><code><span id="__span-10-1"><a id="__codelineno-10-1" name="__codelineno-10-1" href="#__codelineno-10-1"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>-a<span class="w"> </span>FLAC<span class="w"> </span>EXAMPLE<span class="w"> </span><span class="m">81234567</span>
<div class="language-shell highlight"><span class="filename">Take the lossless track</span><pre><span></span><code><span id="__span-11-1"><a id="__codelineno-11-1" name="__codelineno-11-1" href="#__codelineno-11-1"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>-a<span class="w"> </span>FLAC<span class="w"> </span>EXAMPLE<span class="w"> </span><span class="m">81234567</span>
</span></code></pre></div>
<div class="language-shell highlight"><span class="filename">Take the lossy track at 320 kb/s</span><pre><span></span><code><span id="__span-11-1"><a id="__codelineno-11-1" name="__codelineno-11-1" href="#__codelineno-11-1"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>-a<span class="w"> </span>AAC<span class="w"> </span>-ab<span class="w"> </span><span class="m">320</span><span class="w"> </span>EXAMPLE<span class="w"> </span><span class="m">81234567</span>
<div class="language-shell highlight"><span class="filename">Take the lossy track at 320 kb/s</span><pre><span></span><code><span id="__span-12-1"><a id="__codelineno-12-1" name="__codelineno-12-1" href="#__codelineno-12-1"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>-a<span class="w"> </span>AAC<span class="w"> </span>-ab<span class="w"> </span><span class="m">320</span><span class="w"> </span>EXAMPLE<span class="w"> </span><span class="m">81234567</span>
</span></code></pre></div>
<div class="admonition tip">
<p class="admonition-title">Two FLAC tracks in one release</p>
@@ -3435,7 +3505,7 @@ the one you want.</p>
<h3 id="video-and-audio-language">Video and audio language<a class="headerlink" href="#video-and-audio-language" title="Permanent link">&para;</a></h3>
<p><code>-l</code> / <code>--lang</code> sets the wanted language(s) for <strong>both video and audio</strong>. The default is
<code>orig</code>, the title's original language.</p>
<div class="language-shell highlight"><span class="filename">Original language plus English</span><pre><span></span><code><span id="__span-12-1"><a id="__codelineno-12-1" name="__codelineno-12-1" href="#__codelineno-12-1"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>-l<span class="w"> </span>orig,en<span class="w"> </span>EXAMPLE<span class="w"> </span><span class="m">81234567</span>
<div class="language-shell highlight"><span class="filename">Original language plus English</span><pre><span></span><code><span id="__span-13-1"><a id="__codelineno-13-1" name="__codelineno-13-1" href="#__codelineno-13-1"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>-l<span class="w"> </span>orig,en<span class="w"> </span>EXAMPLE<span class="w"> </span><span class="m">81234567</span>
</span></code></pre></div>
<p>unshackle changes the special token <code>orig</code> to the title's own original language
everywhere you use it. You can override each track type independently:</p>
@@ -3444,27 +3514,27 @@ everywhere you use it. You can override each track type independently:</p>
when the burned-in video language differs from the audio you want.</li>
<li><code>-al</code> / <code>--a-lang</code>: language for <strong>audio only</strong> (overrides <code>-l</code> for audio).</li>
</ul>
<div class="language-shell highlight"><span class="filename">English audio over the original video</span><pre><span></span><code><span id="__span-13-1"><a id="__codelineno-13-1" name="__codelineno-13-1" href="#__codelineno-13-1"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>-al<span class="w"> </span>en<span class="w"> </span>EXAMPLE<span class="w"> </span><span class="m">81234567</span>
<div class="language-shell highlight"><span class="filename">English audio over the original video</span><pre><span></span><code><span id="__span-14-1"><a id="__codelineno-14-1" name="__codelineno-14-1" href="#__codelineno-14-1"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>-al<span class="w"> </span>en<span class="w"> </span>EXAMPLE<span class="w"> </span><span class="m">81234567</span>
</span></code></pre></div>
<h3 id="excluding-languages">Excluding languages<a class="headerlink" href="#excluding-languages" title="Permanent link">&para;</a></h3>
<p>Put a <code>-</code> in front of a language to remove it from the selection. This works on <code>-l</code>,
<code>-vl</code>, <code>-al</code>, <code>-sl</code>, and <code>-fsl</code>, in the same way as it works on <code>-w</code> / <code>--wanted</code>.</p>
<div class="language-shell highlight"><span class="filename">Every subtitle language except Spanish</span><pre><span></span><code><span id="__span-14-1"><a id="__codelineno-14-1" name="__codelineno-14-1" href="#__codelineno-14-1"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>-sl<span class="w"> </span>all,-es<span class="w"> </span>EXAMPLE<span class="w"> </span><span class="m">81234567</span>
<div class="language-shell highlight"><span class="filename">Every subtitle language except Spanish</span><pre><span></span><code><span id="__span-15-1"><a id="__codelineno-15-1" name="__codelineno-15-1" href="#__codelineno-15-1"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>-sl<span class="w"> </span>all,-es<span class="w"> </span>EXAMPLE<span class="w"> </span><span class="m">81234567</span>
</span></code></pre></div>
<p>unshackle subtracts the exclusions from the languages the flag would otherwise select,
and the order of the values does not matter. If you give only exclusions, the flag keeps its own
default: <code>-sl -es</code> is the same as <code>-sl all,-es</code>, and <code>-l -es</code> is the same as <code>-l orig,-es</code>.</p>
<div class="language-shell highlight"><span class="filename">Only exclusions</span><pre><span></span><code><span id="__span-15-1"><a id="__codelineno-15-1" name="__codelineno-15-1" href="#__codelineno-15-1"></a><span class="c1"># every subtitle language except Spanish and French</span>
</span><span id="__span-15-2"><a id="__codelineno-15-2" name="__codelineno-15-2" href="#__codelineno-15-2"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>-sl<span class="w"> </span>-es,-fr<span class="w"> </span>EXAMPLE<span class="w"> </span><span class="m">81234567</span>
</span><span id="__span-15-3"><a id="__codelineno-15-3" name="__codelineno-15-3" href="#__codelineno-15-3"></a>
</span><span id="__span-15-4"><a id="__codelineno-15-4" name="__codelineno-15-4" href="#__codelineno-15-4"></a><span class="c1"># the original audio language, unless it is Spanish</span>
</span><span id="__span-15-5"><a id="__codelineno-15-5" name="__codelineno-15-5" href="#__codelineno-15-5"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>-l<span class="w"> </span>-es<span class="w"> </span>EXAMPLE<span class="w"> </span><span class="m">81234567</span>
<div class="language-shell highlight"><span class="filename">Only exclusions</span><pre><span></span><code><span id="__span-16-1"><a id="__codelineno-16-1" name="__codelineno-16-1" href="#__codelineno-16-1"></a><span class="c1"># every subtitle language except Spanish and French</span>
</span><span id="__span-16-2"><a id="__codelineno-16-2" name="__codelineno-16-2" href="#__codelineno-16-2"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>-sl<span class="w"> </span>-es,-fr<span class="w"> </span>EXAMPLE<span class="w"> </span><span class="m">81234567</span>
</span><span id="__span-16-3"><a id="__codelineno-16-3" name="__codelineno-16-3" href="#__codelineno-16-3"></a>
</span><span id="__span-16-4"><a id="__codelineno-16-4" name="__codelineno-16-4" href="#__codelineno-16-4"></a><span class="c1"># the original audio language, unless it is Spanish</span>
</span><span id="__span-16-5"><a id="__codelineno-16-5" name="__codelineno-16-5" href="#__codelineno-16-5"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>-l<span class="w"> </span>-es<span class="w"> </span>EXAMPLE<span class="w"> </span><span class="m">81234567</span>
</span></code></pre></div>
<p><code>-vl</code> and <code>-al</code> have no default of their own: they cascade to <code>-l</code>. An override that names
a language replaces <code>-l</code> for that track type, exclusions included. An override that gives
only exclusions adds them to the ones from <code>-l</code>.</p>
<div class="language-shell highlight"><span class="filename">Cascade</span><pre><span></span><code><span id="__span-16-1"><a id="__codelineno-16-1" name="__codelineno-16-1" href="#__codelineno-16-1"></a><span class="c1"># video keeps the Japanese track; only the audio drops Spanish</span>
</span><span id="__span-16-2"><a id="__codelineno-16-2" name="__codelineno-16-2" href="#__codelineno-16-2"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>-l<span class="w"> </span>en,-es<span class="w"> </span>-vl<span class="w"> </span>ja<span class="w"> </span>EXAMPLE<span class="w"> </span><span class="m">81234567</span>
<div class="language-shell highlight"><span class="filename">Cascade</span><pre><span></span><code><span id="__span-17-1"><a id="__codelineno-17-1" name="__codelineno-17-1" href="#__codelineno-17-1"></a><span class="c1"># video keeps the Japanese track; only the audio drops Spanish</span>
</span><span id="__span-17-2"><a id="__codelineno-17-2" name="__codelineno-17-2" href="#__codelineno-17-2"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>-l<span class="w"> </span>en,-es<span class="w"> </span>-vl<span class="w"> </span>ja<span class="w"> </span>EXAMPLE<span class="w"> </span><span class="m">81234567</span>
</span></code></pre></div>
<div class="admonition note">
<p class="admonition-title">Rules for exclusion tokens</p>
@@ -3483,11 +3553,11 @@ only exclusions adds them to the ones from <code>-l</code>.</p>
<h3 id="sort-order">Sort order<a class="headerlink" href="#sort-order" title="Permanent link">&para;</a></h3>
<p><code>-l</code> and <code>-sl</code> <strong>select</strong> languages: naming some removes the rest. To keep every language
but decide which ones come first, set a priority list in your configuration file:</p>
<div class="language-yaml highlight"><span class="filename">unshackle.yaml</span><pre><span></span><code><span id="__span-17-1"><a id="__codelineno-17-1" name="__codelineno-17-1" href="#__codelineno-17-1"></a><span class="nt">audio</span><span class="p">:</span>
</span><span id="__span-17-2"><a id="__codelineno-17-2" name="__codelineno-17-2" href="#__codelineno-17-2"></a><span class="w"> </span><span class="nt">language_priority</span><span class="p">:</span><span class="w"> </span><span class="p p-Indicator">[</span><span class="nv">orig</span><span class="p p-Indicator">,</span><span class="w"> </span><span class="nv">en</span><span class="p p-Indicator">]</span>
</span><span id="__span-17-3"><a id="__codelineno-17-3" name="__codelineno-17-3" href="#__codelineno-17-3"></a><span class="nt">subtitle</span><span class="p">:</span>
</span><span id="__span-17-4"><a id="__codelineno-17-4" name="__codelineno-17-4" href="#__codelineno-17-4"></a><span class="w"> </span><span class="nt">group_by</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">language</span>
</span><span id="__span-17-5"><a id="__codelineno-17-5" name="__codelineno-17-5" href="#__codelineno-17-5"></a><span class="w"> </span><span class="nt">language_priority</span><span class="p">:</span><span class="w"> </span><span class="p p-Indicator">[</span><span class="nv">en</span><span class="p p-Indicator">,</span><span class="w"> </span><span class="nv">es</span><span class="p p-Indicator">,</span><span class="w"> </span><span class="nv">fr</span><span class="p p-Indicator">]</span>
<div class="language-yaml highlight"><span class="filename">unshackle.yaml</span><pre><span></span><code><span id="__span-18-1"><a id="__codelineno-18-1" name="__codelineno-18-1" href="#__codelineno-18-1"></a><span class="nt">audio</span><span class="p">:</span>
</span><span id="__span-18-2"><a id="__codelineno-18-2" name="__codelineno-18-2" href="#__codelineno-18-2"></a><span class="w"> </span><span class="nt">language_priority</span><span class="p">:</span><span class="w"> </span><span class="p p-Indicator">[</span><span class="nv">orig</span><span class="p p-Indicator">,</span><span class="w"> </span><span class="nv">en</span><span class="p p-Indicator">]</span>
</span><span id="__span-18-3"><a id="__codelineno-18-3" name="__codelineno-18-3" href="#__codelineno-18-3"></a><span class="nt">subtitle</span><span class="p">:</span>
</span><span id="__span-18-4"><a id="__codelineno-18-4" name="__codelineno-18-4" href="#__codelineno-18-4"></a><span class="w"> </span><span class="nt">group_by</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">language</span>
</span><span id="__span-18-5"><a id="__codelineno-18-5" name="__codelineno-18-5" href="#__codelineno-18-5"></a><span class="w"> </span><span class="nt">language_priority</span><span class="p">:</span><span class="w"> </span><span class="p p-Indicator">[</span><span class="nv">en</span><span class="p p-Indicator">,</span><span class="w"> </span><span class="nv">es</span><span class="p p-Indicator">,</span><span class="w"> </span><span class="nv">fr</span><span class="p p-Indicator">]</span>
</span></code></pre></div>
<p>Subtitles then start with English, Spanish, and French. The languages you leave out follow
alphabetically, after the title's original language. unshackle removes nothing. Audio
@@ -3522,7 +3592,7 @@ keeps every subtitle language.</p>
<h3 id="selecting-subtitle-languages">Selecting subtitle languages<a class="headerlink" href="#selecting-subtitle-languages" title="Permanent link">&para;</a></h3>
<p><code>-sl</code> / <code>--s-lang</code> sets the wanted subtitle language(s). The default is <code>all</code>, so
unshackle downloads every available subtitle language.</p>
<div class="language-shell highlight"><span class="filename">Only English and Spanish subtitles</span><pre><span></span><code><span id="__span-18-1"><a id="__codelineno-18-1" name="__codelineno-18-1" href="#__codelineno-18-1"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>-sl<span class="w"> </span>en,es<span class="w"> </span>EXAMPLE<span class="w"> </span><span class="m">81234567</span>
<div class="language-shell highlight"><span class="filename">Only English and Spanish subtitles</span><pre><span></span><code><span id="__span-19-1"><a id="__codelineno-19-1" name="__codelineno-19-1" href="#__codelineno-19-1"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>-sl<span class="w"> </span>en,es<span class="w"> </span>EXAMPLE<span class="w"> </span><span class="m">81234567</span>
</span></code></pre></div>
<p>To keep the default and drop one language, use the <code>-</code> prefix described in
<a href="#excluding-languages">Excluding languages</a>. <code>-sl all,-es</code> keeps every subtitle language
@@ -3533,11 +3603,11 @@ title fails, even under <code>--best-available</code> / <code>--warn-only</code>
worth keeping if a specific subtitle track is present.</p>
<p>It gates the title. It does not select tracks: <code>--s-lang</code> still decides what to keep, and
it defaults to <code>all</code>:</p>
<div class="language-bash highlight"><pre><span></span><code><span id="__span-19-1"><a id="__codelineno-19-1" name="__codelineno-19-1" href="#__codelineno-19-1"></a><span class="c1"># every subtitle language, but only if English is one of them</span>
</span><span id="__span-19-2"><a id="__codelineno-19-2" name="__codelineno-19-2" href="#__codelineno-19-2"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>--require-subs<span class="w"> </span>en<span class="w"> </span>EXAMPLE<span class="w"> </span>0ABC123
</span><span id="__span-19-3"><a id="__codelineno-19-3" name="__codelineno-19-3" href="#__codelineno-19-3"></a>
</span><span id="__span-19-4"><a id="__codelineno-19-4" name="__codelineno-19-4" href="#__codelineno-19-4"></a><span class="c1"># English, Korean and Japanese only, and only if English is present</span>
</span><span id="__span-19-5"><a id="__codelineno-19-5" name="__codelineno-19-5" href="#__codelineno-19-5"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>-sl<span class="w"> </span>en,ko,ja<span class="w"> </span>--require-subs<span class="w"> </span>en<span class="w"> </span>EXAMPLE<span class="w"> </span>0ABC123
<div class="language-bash highlight"><pre><span></span><code><span id="__span-20-1"><a id="__codelineno-20-1" name="__codelineno-20-1" href="#__codelineno-20-1"></a><span class="c1"># every subtitle language, but only if English is one of them</span>
</span><span id="__span-20-2"><a id="__codelineno-20-2" name="__codelineno-20-2" href="#__codelineno-20-2"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>--require-subs<span class="w"> </span>en<span class="w"> </span>EXAMPLE<span class="w"> </span>0ABC123
</span><span id="__span-20-3"><a id="__codelineno-20-3" name="__codelineno-20-3" href="#__codelineno-20-3"></a>
</span><span id="__span-20-4"><a id="__codelineno-20-4" name="__codelineno-20-4" href="#__codelineno-20-4"></a><span class="c1"># English, Korean and Japanese only, and only if English is present</span>
</span><span id="__span-20-5"><a id="__codelineno-20-5" name="__codelineno-20-5" href="#__codelineno-20-5"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>-sl<span class="w"> </span>en,ko,ja<span class="w"> </span>--require-subs<span class="w"> </span>en<span class="w"> </span>EXAMPLE<span class="w"> </span>0ABC123
</span></code></pre></div>
<h3 id="requiring-audio-and-video-languages">Requiring audio and video languages<a class="headerlink" href="#requiring-audio-and-video-languages" title="Permanent link">&para;</a></h3>
<p><code>--require-audio</code> and <code>--require-video</code> take a list of languages that <strong>must</strong> exist. If
@@ -3546,11 +3616,11 @@ one is missing, the title fails, even under <code>--best-available</code> / <cod
decide what unshackle downloads.</p>
<p>This matters most with <code>-l best</code> or <code>-l all</code>, which accept whatever the service offers and
so never report a missing language on their own:</p>
<div class="language-bash highlight"><pre><span></span><code><span id="__span-20-1"><a id="__codelineno-20-1" name="__codelineno-20-1" href="#__codelineno-20-1"></a><span class="c1"># every audio language except French, but only if English is one of them</span>
</span><span id="__span-20-2"><a id="__codelineno-20-2" name="__codelineno-20-2" href="#__codelineno-20-2"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>-l<span class="w"> </span>best,-fr<span class="w"> </span>--require-audio<span class="w"> </span>en<span class="w"> </span>EXAMPLE<span class="w"> </span>0ABC123
</span><span id="__span-20-3"><a id="__codelineno-20-3" name="__codelineno-20-3" href="#__codelineno-20-3"></a>
</span><span id="__span-20-4"><a id="__codelineno-20-4" name="__codelineno-20-4" href="#__codelineno-20-4"></a><span class="c1"># English is required, French is optional</span>
</span><span id="__span-20-5"><a id="__codelineno-20-5" name="__codelineno-20-5" href="#__codelineno-20-5"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>-l<span class="w"> </span>en,fr<span class="w"> </span>--require-audio<span class="w"> </span>en<span class="w"> </span>--warn-only<span class="w"> </span>EXAMPLE<span class="w"> </span>0ABC123
<div class="language-bash highlight"><pre><span></span><code><span id="__span-21-1"><a id="__codelineno-21-1" name="__codelineno-21-1" href="#__codelineno-21-1"></a><span class="c1"># every audio language except French, but only if English is one of them</span>
</span><span id="__span-21-2"><a id="__codelineno-21-2" name="__codelineno-21-2" href="#__codelineno-21-2"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>-l<span class="w"> </span>best,-fr<span class="w"> </span>--require-audio<span class="w"> </span>en<span class="w"> </span>EXAMPLE<span class="w"> </span>0ABC123
</span><span id="__span-21-3"><a id="__codelineno-21-3" name="__codelineno-21-3" href="#__codelineno-21-3"></a>
</span><span id="__span-21-4"><a id="__codelineno-21-4" name="__codelineno-21-4" href="#__codelineno-21-4"></a><span class="c1"># English is required, French is optional</span>
</span><span id="__span-21-5"><a id="__codelineno-21-5" name="__codelineno-21-5" href="#__codelineno-21-5"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>-l<span class="w"> </span>en,fr<span class="w"> </span>--require-audio<span class="w"> </span>en<span class="w"> </span>--warn-only<span class="w"> </span>EXAMPLE<span class="w"> </span>0ABC123
</span></code></pre></div>
<p>The check runs against the full track list, before any language selection or exclusion.
<code>orig</code> resolves to the title language, and <code>--exact-lang</code> applies. Audio carried inside the
@@ -3603,7 +3673,7 @@ video track counts. <code>--no-audio</code> and <code>--no-video</code> drop the
</tr>
</tbody>
</table>
<div class="language-shell highlight"><span class="filename">Convert subtitles to SRT</span><pre><span></span><code><span id="__span-21-1"><a id="__codelineno-21-1" name="__codelineno-21-1" href="#__codelineno-21-1"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>--sub-format<span class="w"> </span>srt<span class="w"> </span>EXAMPLE<span class="w"> </span><span class="m">81234567</span>
<div class="language-shell highlight"><span class="filename">Convert subtitles to SRT</span><pre><span></span><code><span id="__span-22-1"><a id="__codelineno-22-1" name="__codelineno-22-1" href="#__codelineno-22-1"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>--sub-format<span class="w"> </span>srt<span class="w"> </span>EXAMPLE<span class="w"> </span><span class="m">81234567</span>
</span></code></pre></div>
<div class="admonition note">
<p class="admonition-title">SDH stripping happens by default</p>
@@ -3623,42 +3693,42 @@ with <code>-</code> to exclude it. For a music release, the same option takes tr
<div class="tabbed-set tabbed-alternate" data-tabs="1:5"><input checked="checked" id="__tabbed_1_1" name="__tabbed_1" type="radio" /><input id="__tabbed_1_2" name="__tabbed_1" type="radio" /><input id="__tabbed_1_3" name="__tabbed_1" type="radio" /><input id="__tabbed_1_4" name="__tabbed_1" type="radio" /><input id="__tabbed_1_5" name="__tabbed_1" type="radio" /><div class="tabbed-labels"><label for="__tabbed_1_1">Whole seasons</label><label for="__tabbed_1_2">Specific episodes</label><label for="__tabbed_1_3">Exclusions</label><label for="__tabbed_1_4">Split episodes</label><label for="__tabbed_1_5">Air dates</label></div>
<div class="tabbed-content">
<div class="tabbed-block">
<div class="language-shell highlight"><pre><span></span><code><span id="__span-22-1"><a id="__codelineno-22-1" name="__codelineno-22-1" href="#__codelineno-22-1"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>-w<span class="w"> </span>S01<span class="w"> </span>EXAMPLE<span class="w"> </span><span class="m">81234567</span>
</span><span id="__span-22-2"><a id="__codelineno-22-2" name="__codelineno-22-2" href="#__codelineno-22-2"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>-w<span class="w"> </span>S01-S03<span class="w"> </span>EXAMPLE<span class="w"> </span><span class="m">81234567</span>
</span><span id="__span-22-3"><a id="__codelineno-22-3" name="__codelineno-22-3" href="#__codelineno-22-3"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>-w<span class="w"> </span>S01,S03,S05<span class="w"> </span>EXAMPLE<span class="w"> </span><span class="m">81234567</span>
<div class="language-shell highlight"><pre><span></span><code><span id="__span-23-1"><a id="__codelineno-23-1" name="__codelineno-23-1" href="#__codelineno-23-1"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>-w<span class="w"> </span>S01<span class="w"> </span>EXAMPLE<span class="w"> </span><span class="m">81234567</span>
</span><span id="__span-23-2"><a id="__codelineno-23-2" name="__codelineno-23-2" href="#__codelineno-23-2"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>-w<span class="w"> </span>S01-S03<span class="w"> </span>EXAMPLE<span class="w"> </span><span class="m">81234567</span>
</span><span id="__span-23-3"><a id="__codelineno-23-3" name="__codelineno-23-3" href="#__codelineno-23-3"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>-w<span class="w"> </span>S01,S03,S05<span class="w"> </span>EXAMPLE<span class="w"> </span><span class="m">81234567</span>
</span></code></pre></div>
</div>
<div class="tabbed-block">
<div class="language-shell highlight"><pre><span></span><code><span id="__span-23-1"><a id="__codelineno-23-1" name="__codelineno-23-1" href="#__codelineno-23-1"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>-w<span class="w"> </span>S01E01<span class="w"> </span>EXAMPLE<span class="w"> </span><span class="m">81234567</span>
</span><span id="__span-23-2"><a id="__codelineno-23-2" name="__codelineno-23-2" href="#__codelineno-23-2"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>-w<span class="w"> </span>S01E01-S01E05<span class="w"> </span>EXAMPLE<span class="w"> </span><span class="m">81234567</span>
</span><span id="__span-23-3"><a id="__codelineno-23-3" name="__codelineno-23-3" href="#__codelineno-23-3"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>-w<span class="w"> </span>S01E01-S02E03<span class="w"> </span>EXAMPLE<span class="w"> </span><span class="m">81234567</span>
<div class="language-shell highlight"><pre><span></span><code><span id="__span-24-1"><a id="__codelineno-24-1" name="__codelineno-24-1" href="#__codelineno-24-1"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>-w<span class="w"> </span>S01E01<span class="w"> </span>EXAMPLE<span class="w"> </span><span class="m">81234567</span>
</span><span id="__span-24-2"><a id="__codelineno-24-2" name="__codelineno-24-2" href="#__codelineno-24-2"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>-w<span class="w"> </span>S01E01-S01E05<span class="w"> </span>EXAMPLE<span class="w"> </span><span class="m">81234567</span>
</span><span id="__span-24-3"><a id="__codelineno-24-3" name="__codelineno-24-3" href="#__codelineno-24-3"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>-w<span class="w"> </span>S01E01-S02E03<span class="w"> </span>EXAMPLE<span class="w"> </span><span class="m">81234567</span>
</span></code></pre></div>
</div>
<div class="tabbed-block">
<div class="language-shell highlight"><pre><span></span><code><span id="__span-24-1"><a id="__codelineno-24-1" name="__codelineno-24-1" href="#__codelineno-24-1"></a><span class="c1"># Seasons 1 through 5, but not season 3</span>
</span><span id="__span-24-2"><a id="__codelineno-24-2" name="__codelineno-24-2" href="#__codelineno-24-2"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>-w<span class="w"> </span>S01-S05,-S03<span class="w"> </span>EXAMPLE<span class="w"> </span><span class="m">81234567</span>
<div class="language-shell highlight"><pre><span></span><code><span id="__span-25-1"><a id="__codelineno-25-1" name="__codelineno-25-1" href="#__codelineno-25-1"></a><span class="c1"># Seasons 1 through 5, but not season 3</span>
</span><span id="__span-25-2"><a id="__codelineno-25-2" name="__codelineno-25-2" href="#__codelineno-25-2"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>-w<span class="w"> </span>S01-S05,-S03<span class="w"> </span>EXAMPLE<span class="w"> </span><span class="m">81234567</span>
</span></code></pre></div>
</div>
<div class="tabbed-block">
<div class="language-shell highlight"><pre><span></span><code><span id="__span-25-1"><a id="__codelineno-25-1" name="__codelineno-25-1" href="#__codelineno-25-1"></a><span class="c1"># Part 2 of episode 1 only</span>
</span><span id="__span-25-2"><a id="__codelineno-25-2" name="__codelineno-25-2" href="#__codelineno-25-2"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>-w<span class="w"> </span>S01E01.2<span class="w"> </span>EXAMPLE<span class="w"> </span><span class="m">81234567</span>
</span><span id="__span-25-3"><a id="__codelineno-25-3" name="__codelineno-25-3" href="#__codelineno-25-3"></a>
</span><span id="__span-25-4"><a id="__codelineno-25-4" name="__codelineno-25-4" href="#__codelineno-25-4"></a><span class="c1"># Parts 1 through 3 of episode 1</span>
</span><span id="__span-25-5"><a id="__codelineno-25-5" name="__codelineno-25-5" href="#__codelineno-25-5"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>-w<span class="w"> </span>S01E01.1-S01E01.3<span class="w"> </span>EXAMPLE<span class="w"> </span><span class="m">81234567</span>
</span><span id="__span-25-6"><a id="__codelineno-25-6" name="__codelineno-25-6" href="#__codelineno-25-6"></a>
</span><span id="__span-25-7"><a id="__codelineno-25-7" name="__codelineno-25-7" href="#__codelineno-25-7"></a><span class="c1"># All of season 1 except episode 1 part 2</span>
</span><span id="__span-25-8"><a id="__codelineno-25-8" name="__codelineno-25-8" href="#__codelineno-25-8"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>-w<span class="w"> </span>S01,-S01E01.2<span class="w"> </span>EXAMPLE<span class="w"> </span><span class="m">81234567</span>
</span></code></pre></div>
</div>
<div class="tabbed-block">
<div class="language-shell highlight"><pre><span></span><code><span id="__span-26-1"><a id="__codelineno-26-1" name="__codelineno-26-1" href="#__codelineno-26-1"></a><span class="c1"># One day</span>
</span><span id="__span-26-2"><a id="__codelineno-26-2" name="__codelineno-26-2" href="#__codelineno-26-2"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>-w<span class="w"> </span><span class="m">2026</span>-08-11<span class="w"> </span>EXAMPLE<span class="w"> </span><span class="m">81234567</span>
<div class="language-shell highlight"><pre><span></span><code><span id="__span-26-1"><a id="__codelineno-26-1" name="__codelineno-26-1" href="#__codelineno-26-1"></a><span class="c1"># Part 2 of episode 1 only</span>
</span><span id="__span-26-2"><a id="__codelineno-26-2" name="__codelineno-26-2" href="#__codelineno-26-2"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>-w<span class="w"> </span>S01E01.2<span class="w"> </span>EXAMPLE<span class="w"> </span><span class="m">81234567</span>
</span><span id="__span-26-3"><a id="__codelineno-26-3" name="__codelineno-26-3" href="#__codelineno-26-3"></a>
</span><span id="__span-26-4"><a id="__codelineno-26-4" name="__codelineno-26-4" href="#__codelineno-26-4"></a><span class="c1"># A range of days, colon separated</span>
</span><span id="__span-26-5"><a id="__codelineno-26-5" name="__codelineno-26-5" href="#__codelineno-26-5"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>-w<span class="w"> </span><span class="m">2026</span>-08-01:2026-08-31<span class="w"> </span>EXAMPLE<span class="w"> </span><span class="m">81234567</span>
</span><span id="__span-26-4"><a id="__codelineno-26-4" name="__codelineno-26-4" href="#__codelineno-26-4"></a><span class="c1"># Parts 1 through 3 of episode 1</span>
</span><span id="__span-26-5"><a id="__codelineno-26-5" name="__codelineno-26-5" href="#__codelineno-26-5"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>-w<span class="w"> </span>S01E01.1-S01E01.3<span class="w"> </span>EXAMPLE<span class="w"> </span><span class="m">81234567</span>
</span><span id="__span-26-6"><a id="__codelineno-26-6" name="__codelineno-26-6" href="#__codelineno-26-6"></a>
</span><span id="__span-26-7"><a id="__codelineno-26-7" name="__codelineno-26-7" href="#__codelineno-26-7"></a><span class="c1"># August, but not the 15th</span>
</span><span id="__span-26-8"><a id="__codelineno-26-8" name="__codelineno-26-8" href="#__codelineno-26-8"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>-w<span class="w"> </span><span class="m">2026</span>-08-01:2026-08-31,-2026-08-15<span class="w"> </span>EXAMPLE<span class="w"> </span><span class="m">81234567</span>
</span><span id="__span-26-7"><a id="__codelineno-26-7" name="__codelineno-26-7" href="#__codelineno-26-7"></a><span class="c1"># All of season 1 except episode 1 part 2</span>
</span><span id="__span-26-8"><a id="__codelineno-26-8" name="__codelineno-26-8" href="#__codelineno-26-8"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>-w<span class="w"> </span>S01,-S01E01.2<span class="w"> </span>EXAMPLE<span class="w"> </span><span class="m">81234567</span>
</span></code></pre></div>
</div>
<div class="tabbed-block">
<div class="language-shell highlight"><pre><span></span><code><span id="__span-27-1"><a id="__codelineno-27-1" name="__codelineno-27-1" href="#__codelineno-27-1"></a><span class="c1"># One day</span>
</span><span id="__span-27-2"><a id="__codelineno-27-2" name="__codelineno-27-2" href="#__codelineno-27-2"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>-w<span class="w"> </span><span class="m">2026</span>-08-11<span class="w"> </span>EXAMPLE<span class="w"> </span><span class="m">81234567</span>
</span><span id="__span-27-3"><a id="__codelineno-27-3" name="__codelineno-27-3" href="#__codelineno-27-3"></a>
</span><span id="__span-27-4"><a id="__codelineno-27-4" name="__codelineno-27-4" href="#__codelineno-27-4"></a><span class="c1"># A range of days, colon separated</span>
</span><span id="__span-27-5"><a id="__codelineno-27-5" name="__codelineno-27-5" href="#__codelineno-27-5"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>-w<span class="w"> </span><span class="m">2026</span>-08-01:2026-08-31<span class="w"> </span>EXAMPLE<span class="w"> </span><span class="m">81234567</span>
</span><span id="__span-27-6"><a id="__codelineno-27-6" name="__codelineno-27-6" href="#__codelineno-27-6"></a>
</span><span id="__span-27-7"><a id="__codelineno-27-7" name="__codelineno-27-7" href="#__codelineno-27-7"></a><span class="c1"># August, but not the 15th</span>
</span><span id="__span-27-8"><a id="__codelineno-27-8" name="__codelineno-27-8" href="#__codelineno-27-8"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>-w<span class="w"> </span><span class="m">2026</span>-08-01:2026-08-31,-2026-08-15<span class="w"> </span>EXAMPLE<span class="w"> </span><span class="m">81234567</span>
</span></code></pre></div>
</div>
</div>
@@ -3670,30 +3740,30 @@ track on disc 1, which is the number the track list shows for a single-disc rele
<div class="tabbed-set tabbed-alternate" data-tabs="2:3"><input checked="checked" id="__tabbed_2_1" name="__tabbed_2" type="radio" /><input id="__tabbed_2_2" name="__tabbed_2" type="radio" /><input id="__tabbed_2_3" name="__tabbed_2" type="radio" /><div class="tabbed-labels"><label for="__tabbed_2_1">Tracks</label><label for="__tabbed_2_2">More than one disc</label><label for="__tabbed_2_3">Exclusions</label></div>
<div class="tabbed-content">
<div class="tabbed-block">
<div class="language-shell highlight"><pre><span></span><code><span id="__span-27-1"><a id="__codelineno-27-1" name="__codelineno-27-1" href="#__codelineno-27-1"></a><span class="c1"># Track 3</span>
</span><span id="__span-27-2"><a id="__codelineno-27-2" name="__codelineno-27-2" href="#__codelineno-27-2"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>-w<span class="w"> </span><span class="m">3</span><span class="w"> </span>EXAMPLE<span class="w"> </span><span class="m">81234567</span>
</span><span id="__span-27-3"><a id="__codelineno-27-3" name="__codelineno-27-3" href="#__codelineno-27-3"></a>
</span><span id="__span-27-4"><a id="__codelineno-27-4" name="__codelineno-27-4" href="#__codelineno-27-4"></a><span class="c1"># Tracks 1 through 5</span>
</span><span id="__span-27-5"><a id="__codelineno-27-5" name="__codelineno-27-5" href="#__codelineno-27-5"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>-w<span class="w"> </span><span class="m">1</span>-5<span class="w"> </span>EXAMPLE<span class="w"> </span><span class="m">81234567</span>
</span><span id="__span-27-6"><a id="__codelineno-27-6" name="__codelineno-27-6" href="#__codelineno-27-6"></a>
</span><span id="__span-27-7"><a id="__codelineno-27-7" name="__codelineno-27-7" href="#__codelineno-27-7"></a><span class="c1"># Tracks 1, 3 and 7</span>
</span><span id="__span-27-8"><a id="__codelineno-27-8" name="__codelineno-27-8" href="#__codelineno-27-8"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>-w<span class="w"> </span><span class="m">1</span>,3,7<span class="w"> </span>EXAMPLE<span class="w"> </span><span class="m">81234567</span>
</span></code></pre></div>
</div>
<div class="tabbed-block">
<div class="language-shell highlight"><pre><span></span><code><span id="__span-28-1"><a id="__codelineno-28-1" name="__codelineno-28-1" href="#__codelineno-28-1"></a><span class="c1"># Disc 2, track 3</span>
</span><span id="__span-28-2"><a id="__codelineno-28-2" name="__codelineno-28-2" href="#__codelineno-28-2"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>-w<span class="w"> </span>2x3<span class="w"> </span>EXAMPLE<span class="w"> </span><span class="m">81234567</span>
<div class="language-shell highlight"><pre><span></span><code><span id="__span-28-1"><a id="__codelineno-28-1" name="__codelineno-28-1" href="#__codelineno-28-1"></a><span class="c1"># Track 3</span>
</span><span id="__span-28-2"><a id="__codelineno-28-2" name="__codelineno-28-2" href="#__codelineno-28-2"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>-w<span class="w"> </span><span class="m">3</span><span class="w"> </span>EXAMPLE<span class="w"> </span><span class="m">81234567</span>
</span><span id="__span-28-3"><a id="__codelineno-28-3" name="__codelineno-28-3" href="#__codelineno-28-3"></a>
</span><span id="__span-28-4"><a id="__codelineno-28-4" name="__codelineno-28-4" href="#__codelineno-28-4"></a><span class="c1"># Disc 2, tracks 1 through 4</span>
</span><span id="__span-28-5"><a id="__codelineno-28-5" name="__codelineno-28-5" href="#__codelineno-28-5"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>-w<span class="w"> </span>2x1-2x4<span class="w"> </span>EXAMPLE<span class="w"> </span><span class="m">81234567</span>
</span><span id="__span-28-4"><a id="__codelineno-28-4" name="__codelineno-28-4" href="#__codelineno-28-4"></a><span class="c1"># Tracks 1 through 5</span>
</span><span id="__span-28-5"><a id="__codelineno-28-5" name="__codelineno-28-5" href="#__codelineno-28-5"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>-w<span class="w"> </span><span class="m">1</span>-5<span class="w"> </span>EXAMPLE<span class="w"> </span><span class="m">81234567</span>
</span><span id="__span-28-6"><a id="__codelineno-28-6" name="__codelineno-28-6" href="#__codelineno-28-6"></a>
</span><span id="__span-28-7"><a id="__codelineno-28-7" name="__codelineno-28-7" href="#__codelineno-28-7"></a><span class="c1"># Disc 1 track 3, through disc 2 track 2</span>
</span><span id="__span-28-8"><a id="__codelineno-28-8" name="__codelineno-28-8" href="#__codelineno-28-8"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>-w<span class="w"> </span>1x3-2x2<span class="w"> </span>EXAMPLE<span class="w"> </span><span class="m">81234567</span>
</span><span id="__span-28-7"><a id="__codelineno-28-7" name="__codelineno-28-7" href="#__codelineno-28-7"></a><span class="c1"># Tracks 1, 3 and 7</span>
</span><span id="__span-28-8"><a id="__codelineno-28-8" name="__codelineno-28-8" href="#__codelineno-28-8"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>-w<span class="w"> </span><span class="m">1</span>,3,7<span class="w"> </span>EXAMPLE<span class="w"> </span><span class="m">81234567</span>
</span></code></pre></div>
</div>
<div class="tabbed-block">
<div class="language-shell highlight"><pre><span></span><code><span id="__span-29-1"><a id="__codelineno-29-1" name="__codelineno-29-1" href="#__codelineno-29-1"></a><span class="c1"># Tracks 1 through 8, but not track 4</span>
</span><span id="__span-29-2"><a id="__codelineno-29-2" name="__codelineno-29-2" href="#__codelineno-29-2"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>-w<span class="w"> </span><span class="m">1</span>-8,-4<span class="w"> </span>EXAMPLE<span class="w"> </span><span class="m">81234567</span>
<div class="language-shell highlight"><pre><span></span><code><span id="__span-29-1"><a id="__codelineno-29-1" name="__codelineno-29-1" href="#__codelineno-29-1"></a><span class="c1"># Disc 2, track 3</span>
</span><span id="__span-29-2"><a id="__codelineno-29-2" name="__codelineno-29-2" href="#__codelineno-29-2"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>-w<span class="w"> </span>2x3<span class="w"> </span>EXAMPLE<span class="w"> </span><span class="m">81234567</span>
</span><span id="__span-29-3"><a id="__codelineno-29-3" name="__codelineno-29-3" href="#__codelineno-29-3"></a>
</span><span id="__span-29-4"><a id="__codelineno-29-4" name="__codelineno-29-4" href="#__codelineno-29-4"></a><span class="c1"># Disc 2, tracks 1 through 4</span>
</span><span id="__span-29-5"><a id="__codelineno-29-5" name="__codelineno-29-5" href="#__codelineno-29-5"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>-w<span class="w"> </span>2x1-2x4<span class="w"> </span>EXAMPLE<span class="w"> </span><span class="m">81234567</span>
</span><span id="__span-29-6"><a id="__codelineno-29-6" name="__codelineno-29-6" href="#__codelineno-29-6"></a>
</span><span id="__span-29-7"><a id="__codelineno-29-7" name="__codelineno-29-7" href="#__codelineno-29-7"></a><span class="c1"># Disc 1 track 3, through disc 2 track 2</span>
</span><span id="__span-29-8"><a id="__codelineno-29-8" name="__codelineno-29-8" href="#__codelineno-29-8"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>-w<span class="w"> </span>1x3-2x2<span class="w"> </span>EXAMPLE<span class="w"> </span><span class="m">81234567</span>
</span></code></pre></div>
</div>
<div class="tabbed-block">
<div class="language-shell highlight"><pre><span></span><code><span id="__span-30-1"><a id="__codelineno-30-1" name="__codelineno-30-1" href="#__codelineno-30-1"></a><span class="c1"># Tracks 1 through 8, but not track 4</span>
</span><span id="__span-30-2"><a id="__codelineno-30-2" name="__codelineno-30-2" href="#__codelineno-30-2"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>-w<span class="w"> </span><span class="m">1</span>-8,-4<span class="w"> </span>EXAMPLE<span class="w"> </span><span class="m">81234567</span>
</span></code></pre></div>
</div>
</div>
@@ -3711,7 +3781,7 @@ the year.</p>
<p>A service that only carries this kind of title sets <code>DAILY = True</code> on its class, and a
service can set <code>air_date</code> on each episode itself. Add <code>--daily</code> to mark any other title
as date-based:</p>
<div class="language-shell highlight"><pre><span></span><code><span id="__span-30-1"><a id="__codelineno-30-1" name="__codelineno-30-1" href="#__codelineno-30-1"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>--daily<span class="w"> </span>--tvdb<span class="w"> </span><span class="m">73871</span><span class="w"> </span>--enrich<span class="w"> </span>EXAMPLE<span class="w"> </span><span class="m">81234567</span>
<div class="language-shell highlight"><pre><span></span><code><span id="__span-31-1"><a id="__codelineno-31-1" name="__codelineno-31-1" href="#__codelineno-31-1"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>--daily<span class="w"> </span>--tvdb<span class="w"> </span><span class="m">73871</span><span class="w"> </span>--enrich<span class="w"> </span>EXAMPLE<span class="w"> </span><span class="m">81234567</span>
</span></code></pre></div>
<p>With <code>--enrich</code> and a TVDB ID, <code>--daily</code> fills in the air date of every episode that has
none. An air date the service already set is kept. unshackle skips dates before 1970 and
@@ -3793,9 +3863,9 @@ the episode has no parts, rather than quietly handing you the whole episode. Use
</tbody>
</table>
<p>When <code>--latest-episode</code> or <code>--latest-episodes</code> is set, <code>-w</code> has no effect.</p>
<div class="language-shell highlight"><span class="filename">Grab just the newest episode</span><pre><span></span><code><span id="__span-31-1"><a id="__codelineno-31-1" name="__codelineno-31-1" href="#__codelineno-31-1"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>--latest-episode<span class="w"> </span>EXAMPLE<span class="w"> </span><span class="m">81234567</span>
<div class="language-shell highlight"><span class="filename">Grab just the newest episode</span><pre><span></span><code><span id="__span-32-1"><a id="__codelineno-32-1" name="__codelineno-32-1" href="#__codelineno-32-1"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>--latest-episode<span class="w"> </span>EXAMPLE<span class="w"> </span><span class="m">81234567</span>
</span></code></pre></div>
<div class="language-shell highlight"><span class="filename">Grab the three newest episodes</span><pre><span></span><code><span id="__span-32-1"><a id="__codelineno-32-1" name="__codelineno-32-1" href="#__codelineno-32-1"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>--latest-episodes<span class="w"> </span><span class="m">3</span><span class="w"> </span>EXAMPLE<span class="w"> </span><span class="m">81234567</span>
<div class="language-shell highlight"><span class="filename">Grab the three newest episodes</span><pre><span></span><code><span id="__span-33-1"><a id="__codelineno-33-1" name="__codelineno-33-1" href="#__codelineno-33-1"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>--latest-episodes<span class="w"> </span><span class="m">3</span><span class="w"> </span>EXAMPLE<span class="w"> </span><span class="m">81234567</span>
</span></code></pre></div>
<h2 id="including-and-excluding-track-types">Including and excluding track types<a class="headerlink" href="#including-and-excluding-track-types" title="Permanent link">&para;</a></h2>
<p>You can restrict a download to certain track categories, either positively (only these)
@@ -3840,11 +3910,11 @@ video and audio. Add <code>-A</code> or <code>-S</code> for that.</p>
neither of them marks as descriptive or forced does not match.</li>
</ul>
</div>
<div class="language-shell highlight"><span class="filename">Audio description only, in English</span><pre><span></span><code><span id="__span-33-1"><a id="__codelineno-33-1" name="__codelineno-33-1" href="#__codelineno-33-1"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>-A<span class="w"> </span>-ado<span class="w"> </span>-al<span class="w"> </span>en<span class="w"> </span>EXAMPLE<span class="w"> </span><span class="m">81234567</span>
<div class="language-shell highlight"><span class="filename">Audio description only, in English</span><pre><span></span><code><span id="__span-34-1"><a id="__codelineno-34-1" name="__codelineno-34-1" href="#__codelineno-34-1"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>-A<span class="w"> </span>-ado<span class="w"> </span>-al<span class="w"> </span>en<span class="w"> </span>EXAMPLE<span class="w"> </span><span class="m">81234567</span>
</span></code></pre></div>
<div class="language-shell highlight"><span class="filename">Subtitles only</span><pre><span></span><code><span id="__span-34-1"><a id="__codelineno-34-1" name="__codelineno-34-1" href="#__codelineno-34-1"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>-S<span class="w"> </span>-sl<span class="w"> </span>en<span class="w"> </span>EXAMPLE<span class="w"> </span><span class="m">81234567</span>
<div class="language-shell highlight"><span class="filename">Subtitles only</span><pre><span></span><code><span id="__span-35-1"><a id="__codelineno-35-1" name="__codelineno-35-1" href="#__codelineno-35-1"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>-S<span class="w"> </span>-sl<span class="w"> </span>en<span class="w"> </span>EXAMPLE<span class="w"> </span><span class="m">81234567</span>
</span></code></pre></div>
<div class="language-shell highlight"><span class="filename">Everything except chapters</span><pre><span></span><code><span id="__span-35-1"><a id="__codelineno-35-1" name="__codelineno-35-1" href="#__codelineno-35-1"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>-nc<span class="w"> </span>EXAMPLE<span class="w"> </span><span class="m">81234567</span>
<div class="language-shell highlight"><span class="filename">Everything except chapters</span><pre><span></span><code><span id="__span-36-1"><a id="__codelineno-36-1" name="__codelineno-36-1" href="#__codelineno-36-1"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>-nc<span class="w"> </span>EXAMPLE<span class="w"> </span><span class="m">81234567</span>
</span></code></pre></div>
<div class="admonition note">
<p class="admonition-title">Note</p>
@@ -3880,7 +3950,7 @@ are always kept.</p>
</tr>
</tbody>
</table>
<div class="language-shell highlight"><span class="filename">See the track selection without downloading</span><pre><span></span><code><span id="__span-36-1"><a id="__codelineno-36-1" name="__codelineno-36-1" href="#__codelineno-36-1"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>-q<span class="w"> </span><span class="m">1080</span><span class="w"> </span>-v<span class="w"> </span>H.265<span class="w"> </span>-r<span class="w"> </span>HDR10<span class="w"> </span>--list<span class="w"> </span>EXAMPLE<span class="w"> </span><span class="m">81234567</span>
<div class="language-shell highlight"><span class="filename">See the track selection without downloading</span><pre><span></span><code><span id="__span-37-1"><a id="__codelineno-37-1" name="__codelineno-37-1" href="#__codelineno-37-1"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>-q<span class="w"> </span><span class="m">1080</span><span class="w"> </span>-v<span class="w"> </span>H.265<span class="w"> </span>-r<span class="w"> </span>HDR10<span class="w"> </span>--list<span class="w"> </span>EXAMPLE<span class="w"> </span><span class="m">81234567</span>
</span></code></pre></div>
<h2 id="output-and-muxing">Output and muxing<a class="headerlink" href="#output-and-muxing" title="Permanent link">&para;</a></h2>
<h3 id="output-location-and-folders">Output location and folders<a class="headerlink" href="#output-location-and-folders" title="Permanent link">&para;</a></h3>
@@ -3890,7 +3960,7 @@ are always kept.</p>
<li><code>--no-folder</code>: do not make a per-show folder for TV downloads.</li>
<li><code>--no-source</code>: remove the service source tag from the filename and path.</li>
</ul>
<div class="language-shell highlight"><span class="filename">Send this download somewhere specific</span><pre><span></span><code><span id="__span-37-1"><a id="__codelineno-37-1" name="__codelineno-37-1" href="#__codelineno-37-1"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>-o<span class="w"> </span>~/Videos/incoming<span class="w"> </span>EXAMPLE<span class="w"> </span><span class="m">81234567</span>
<div class="language-shell highlight"><span class="filename">Send this download somewhere specific</span><pre><span></span><code><span id="__span-38-1"><a id="__codelineno-38-1" name="__codelineno-38-1" href="#__codelineno-38-1"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>-o<span class="w"> </span>~/Videos/incoming<span class="w"> </span>EXAMPLE<span class="w"> </span><span class="m">81234567</span>
</span></code></pre></div>
<h3 id="muxing-behaviour">Muxing behaviour<a class="headerlink" href="#muxing-behaviour" title="Permanent link">&para;</a></h3>
<p>By default, <code>mkvmerge</code> muxes the tracks of a movie or an episode into a single Matroska
@@ -3954,11 +4024,11 @@ Read <a href="../output-and-naming/#music-output-files">Music output files</a>.<
metadata substituted into <code>{variable}</code> placeholders. It is repeatable, and it replaces the
<code>post_scripts</code> config for that run. No <code>success</code> post-script operates under <code>--no-mux</code>, because
that run writes no muxed output. A <code>failure</code> post-script still operates if the download fails.</p>
<div class="language-shell highlight"><span class="filename">Hand each finished file to an uploader</span><pre><span></span><code><span id="__span-38-1"><a id="__codelineno-38-1" name="__codelineno-38-1" href="#__codelineno-38-1"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>--postscript<span class="w"> </span><span class="s2">"python /opt/upload.py {filepath} --service={service}"</span><span class="w"> </span>EXAMPLE<span class="w"> </span><span class="m">81234567</span>
<div class="language-shell highlight"><span class="filename">Hand each finished file to an uploader</span><pre><span></span><code><span id="__span-39-1"><a id="__codelineno-39-1" name="__codelineno-39-1" href="#__codelineno-39-1"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>--postscript<span class="w"> </span><span class="s2">"python /opt/upload.py {filepath} --service={service}"</span><span class="w"> </span>EXAMPLE<span class="w"> </span><span class="m">81234567</span>
</span></code></pre></div>
<p><code>--no-postscript</code> operates the run with no post-script at all. It silences the <code>post_scripts</code>
config and <code>--postscript</code> together, for every event and mode.</p>
<div class="language-shell highlight"><span class="filename">Skip the uploader for one run</span><pre><span></span><code><span id="__span-39-1"><a id="__codelineno-39-1" name="__codelineno-39-1" href="#__codelineno-39-1"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>--no-postscript<span class="w"> </span>EXAMPLE<span class="w"> </span><span class="m">81234567</span>
<div class="language-shell highlight"><span class="filename">Skip the uploader for one run</span><pre><span></span><code><span id="__span-40-1"><a id="__codelineno-40-1" name="__codelineno-40-1" href="#__codelineno-40-1"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>--no-postscript<span class="w"> </span>EXAMPLE<span class="w"> </span><span class="m">81234567</span>
</span></code></pre></div>
<p>For post-scripts that continue across runs, for the <code>season</code> and <code>run</code> modes, for <code>failure</code>
post-scripts and for the full variable list, see
@@ -3968,16 +4038,16 @@ post-scripts and for the full variable list, see
<li><code>--tag</code>: set the release group tag (overrides the configured tag).</li>
<li><code>--repack</code>: add a <code>REPACK</code> tag to the output filename.</li>
</ul>
<div class="language-shell highlight"><span class="filename">Custom group tag and a REPACK label</span><pre><span></span><code><span id="__span-40-1"><a id="__codelineno-40-1" name="__codelineno-40-1" href="#__codelineno-40-1"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>--tag<span class="w"> </span>MYGRP<span class="w"> </span>--repack<span class="w"> </span>EXAMPLE<span class="w"> </span><span class="m">81234567</span>
<div class="language-shell highlight"><span class="filename">Custom group tag and a REPACK label</span><pre><span></span><code><span id="__span-41-1"><a id="__codelineno-41-1" name="__codelineno-41-1" href="#__codelineno-41-1"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>--tag<span class="w"> </span>MYGRP<span class="w"> </span>--repack<span class="w"> </span>EXAMPLE<span class="w"> </span><span class="m">81234567</span>
</span></code></pre></div>
<h2 id="proxies">Proxies<a class="headerlink" href="#proxies" title="Permanent link">&para;</a></h2>
<p><code>--proxy</code> accepts a full proxy URI, a country or location code (resolved through your
configured proxy providers), or a <code>provider:region</code> form. See
<a href="../proxies-and-vpn/#how-proxy-resolution-works">Proxies &amp; VPN</a> for the exact grammar.</p>
<div class="language-shell highlight"><span class="filename">Proxy forms</span><pre><span></span><code><span id="__span-41-1"><a id="__codelineno-41-1" name="__codelineno-41-1" href="#__codelineno-41-1"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>--proxy<span class="w"> </span>us<span class="w"> </span>EXAMPLE<span class="w"> </span><span class="m">81234567</span>
</span><span id="__span-41-2"><a id="__codelineno-41-2" name="__codelineno-41-2" href="#__codelineno-41-2"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>--proxy<span class="w"> </span>nordvpn:ca<span class="w"> </span>EXAMPLE<span class="w"> </span><span class="m">81234567</span>
</span><span id="__span-41-3"><a id="__codelineno-41-3" name="__codelineno-41-3" href="#__codelineno-41-3"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>--proxy<span class="w"> </span>controld:yul<span class="w"> </span>EXAMPLE<span class="w"> </span><span class="m">81234567</span>
</span><span id="__span-41-4"><a id="__codelineno-41-4" name="__codelineno-41-4" href="#__codelineno-41-4"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>--proxy<span class="w"> </span><span class="s1">'http://user:pass@host:8080'</span><span class="w"> </span>EXAMPLE<span class="w"> </span><span class="m">81234567</span>
<div class="language-shell highlight"><span class="filename">Proxy forms</span><pre><span></span><code><span id="__span-42-1"><a id="__codelineno-42-1" name="__codelineno-42-1" href="#__codelineno-42-1"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>--proxy<span class="w"> </span>us<span class="w"> </span>EXAMPLE<span class="w"> </span><span class="m">81234567</span>
</span><span id="__span-42-2"><a id="__codelineno-42-2" name="__codelineno-42-2" href="#__codelineno-42-2"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>--proxy<span class="w"> </span>nordvpn:ca<span class="w"> </span>EXAMPLE<span class="w"> </span><span class="m">81234567</span>
</span><span id="__span-42-3"><a id="__codelineno-42-3" name="__codelineno-42-3" href="#__codelineno-42-3"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>--proxy<span class="w"> </span>controld:yul<span class="w"> </span>EXAMPLE<span class="w"> </span><span class="m">81234567</span>
</span><span id="__span-42-4"><a id="__codelineno-42-4" name="__codelineno-42-4" href="#__codelineno-42-4"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>--proxy<span class="w"> </span><span class="s1">'http://user:pass@host:8080'</span><span class="w"> </span>EXAMPLE<span class="w"> </span><span class="m">81234567</span>
</span></code></pre></div>
<p>Three related flags:</p>
<ul>
@@ -4032,9 +4102,9 @@ configured proxy providers), or a <code>provider:region</code> form. See
</tr>
</tbody>
</table>
<div class="language-shell highlight"><span class="filename">Two tracks at a time, eight threads each</span><pre><span></span><code><span id="__span-42-1"><a id="__codelineno-42-1" name="__codelineno-42-1" href="#__codelineno-42-1"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>--downloads<span class="w"> </span><span class="m">2</span><span class="w"> </span>--workers<span class="w"> </span><span class="m">8</span><span class="w"> </span>EXAMPLE<span class="w"> </span><span class="m">81234567</span>
<div class="language-shell highlight"><span class="filename">Two tracks at a time, eight threads each</span><pre><span></span><code><span id="__span-43-1"><a id="__codelineno-43-1" name="__codelineno-43-1" href="#__codelineno-43-1"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>--downloads<span class="w"> </span><span class="m">2</span><span class="w"> </span>--workers<span class="w"> </span><span class="m">8</span><span class="w"> </span>EXAMPLE<span class="w"> </span><span class="m">81234567</span>
</span></code></pre></div>
<div class="language-shell highlight"><span class="filename">Space out a season download</span><pre><span></span><code><span id="__span-43-1"><a id="__codelineno-43-1" name="__codelineno-43-1" href="#__codelineno-43-1"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>-w<span class="w"> </span>S01<span class="w"> </span>--slow<span class="w"> </span><span class="m">30</span>-60<span class="w"> </span>EXAMPLE<span class="w"> </span><span class="m">81234567</span>
<div class="language-shell highlight"><span class="filename">Space out a season download</span><pre><span></span><code><span id="__span-44-1"><a id="__codelineno-44-1" name="__codelineno-44-1" href="#__codelineno-44-1"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>-w<span class="w"> </span>S01<span class="w"> </span>--slow<span class="w"> </span><span class="m">30</span>-60<span class="w"> </span>EXAMPLE<span class="w"> </span><span class="m">81234567</span>
</span></code></pre></div>
<h2 id="keys-vaults-and-export">Keys, vaults, and export<a class="headerlink" href="#keys-vaults-and-export" title="Permanent link">&para;</a></h2>
<p>By default, unshackle checks your <strong>key vaults</strong> first and only asks a <strong>CDM</strong> to license
@@ -4045,19 +4115,19 @@ a content key when the vault misses. You can force one side or the other:</p>
<li><code>--vaults-only</code>: only use key vaults and never license through the CDM. A missing
content key fails.</li>
</ul>
<div class="language-shell highlight"><span class="filename">Fetch keys only, no download</span><pre><span></span><code><span id="__span-44-1"><a id="__codelineno-44-1" name="__codelineno-44-1" href="#__codelineno-44-1"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>--skip-dl<span class="w"> </span>EXAMPLE<span class="w"> </span><span class="m">81234567</span>
<div class="language-shell highlight"><span class="filename">Fetch keys only, no download</span><pre><span></span><code><span id="__span-45-1"><a id="__codelineno-45-1" name="__codelineno-45-1" href="#__codelineno-45-1"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>--skip-dl<span class="w"> </span>EXAMPLE<span class="w"> </span><span class="m">81234567</span>
</span></code></pre></div>
<p><code>--export</code> writes a <code>mediaexport</code> JSON file into the configured exports directory. It holds
the manifest, the DRM init data, the content keys, the KIDs of each track and the title
metadata for each title. <code>unshackle import</code> reads it to reconstruct a download later, and gives
each track only the content keys for its KIDs. The importer also reads the
older unshackle <code>version: 2</code> files and unidl's own export files.</p>
<div class="language-shell highlight"><span class="filename">Export track info and keys</span><pre><span></span><code><span id="__span-45-1"><a id="__codelineno-45-1" name="__codelineno-45-1" href="#__codelineno-45-1"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>--skip-dl<span class="w"> </span>--export<span class="w"> </span>EXAMPLE<span class="w"> </span><span class="m">81234567</span>
<div class="language-shell highlight"><span class="filename">Export track info and keys</span><pre><span></span><code><span id="__span-46-1"><a id="__codelineno-46-1" name="__codelineno-46-1" href="#__codelineno-46-1"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>--skip-dl<span class="w"> </span>--export<span class="w"> </span>EXAMPLE<span class="w"> </span><span class="m">81234567</span>
</span></code></pre></div>
<p>Add <code>--all-drm</code> to get the content keys of each DRM system the title offers. The export then
holds the DRM init data of both. A Key Vault that has a content key stops the challenge for
its KID; add <code>--cdm-only</code> to send a challenge for each DRM system.</p>
<div class="language-shell highlight"><span class="filename">License with Widevine and PlayReady, no download</span><pre><span></span><code><span id="__span-46-1"><a id="__codelineno-46-1" name="__codelineno-46-1" href="#__codelineno-46-1"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>--skip-dl<span class="w"> </span>--all-drm<span class="w"> </span>--export<span class="w"> </span>EXAMPLE<span class="w"> </span><span class="m">81234567</span>
<div class="language-shell highlight"><span class="filename">License with Widevine and PlayReady, no download</span><pre><span></span><code><span id="__span-47-1"><a id="__codelineno-47-1" name="__codelineno-47-1" href="#__codelineno-47-1"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>--skip-dl<span class="w"> </span>--all-drm<span class="w"> </span>--export<span class="w"> </span>EXAMPLE<span class="w"> </span><span class="m">81234567</span>
</span></code></pre></div>
<p>The file name tells what the file holds, in the form
<code>{title}.{scope}.{resolutions}.{codecs}.{ranges}.{manifests}.{audio}-{SERVICE}.json</code>:</p>
@@ -4181,9 +4251,9 @@ lookups but keep the IDs you give, set
</tr>
</tbody>
</table>
<div class="language-shell highlight"><span class="filename">Force the right IMDb match, and keep the service&#x27;s own naming</span><pre><span></span><code><span id="__span-47-1"><a id="__codelineno-47-1" name="__codelineno-47-1" href="#__codelineno-47-1"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>--imdb<span class="w"> </span>tt1375666<span class="w"> </span>EXAMPLE<span class="w"> </span><span class="m">81234567</span>
<div class="language-shell highlight"><span class="filename">Force the right IMDb match, and keep the service&#x27;s own naming</span><pre><span></span><code><span id="__span-48-1"><a id="__codelineno-48-1" name="__codelineno-48-1" href="#__codelineno-48-1"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>--imdb<span class="w"> </span>tt1375666<span class="w"> </span>EXAMPLE<span class="w"> </span><span class="m">81234567</span>
</span></code></pre></div>
<div class="language-shell highlight"><span class="filename">Force the match and take IMDb&#x27;s title, year and language too</span><pre><span></span><code><span id="__span-48-1"><a id="__codelineno-48-1" name="__codelineno-48-1" href="#__codelineno-48-1"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>--imdb<span class="w"> </span>tt1375666<span class="w"> </span>--enrich<span class="w"> </span>EXAMPLE<span class="w"> </span><span class="m">81234567</span>
<div class="language-shell highlight"><span class="filename">Force the match and take IMDb&#x27;s title, year and language too</span><pre><span></span><code><span id="__span-49-1"><a id="__codelineno-49-1" name="__codelineno-49-1" href="#__codelineno-49-1"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>--imdb<span class="w"> </span>tt1375666<span class="w"> </span>--enrich<span class="w"> </span>EXAMPLE<span class="w"> </span><span class="m">81234567</span>
</span></code></pre></div>
<h3 id="what-each-metadata-provider-supplies">What each metadata provider supplies<a class="headerlink" href="#what-each-metadata-provider-supplies" title="Permanent link">&para;</a></h3>
<p>Metadata providers differ in what they answer with, so the fields <code>--enrich</code> can replace
@@ -4301,7 +4371,7 @@ selection.</p>
TVDB's <code>alternate</code> (Streaming) order for Futurama, for example, while TVDB's <code>official</code> order
holds back four season-one episodes to the start of season two. <code>--tvdb-order</code> works out which
order the service used, then renumbers the episodes into the order you asked for:</p>
<div class="language-shell highlight"><span class="filename">Download Futurama in DVD order</span><pre><span></span><code><span id="__span-49-1"><a id="__codelineno-49-1" name="__codelineno-49-1" href="#__codelineno-49-1"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>--tvdb-order<span class="w"> </span>dvd<span class="w"> </span>EXAMPLE<span class="w"> </span><span class="m">81234567</span>
<div class="language-shell highlight"><span class="filename">Download Futurama in DVD order</span><pre><span></span><code><span id="__span-50-1"><a id="__codelineno-50-1" name="__codelineno-50-1" href="#__codelineno-50-1"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>--tvdb-order<span class="w"> </span>dvd<span class="w"> </span>EXAMPLE<span class="w"> </span><span class="m">81234567</span>
</span></code></pre></div>
<p>Available orders are <code>official</code> (aired), <code>dvd</code>, <code>absolute</code>, <code>alternate</code>, and <code>regional</code>. Set
<code>tvdb_order</code> in your config to apply one by default.</p>
BIN
View File
Binary file not shown.
File diff suppressed because it is too large Load Diff
+52 -4
View File
@@ -2164,6 +2164,17 @@
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#unshackle.core.tracks.Hybrid.detect_active_area" class="md-nav__link">
<span class="md-ellipsis">
<code class="doc-symbol doc-symbol-toc doc-symbol-method"></code>&nbsp;detect_active_area
</span>
</a>
</li>
<li class="md-nav__item">
@@ -3384,6 +3395,17 @@
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#unshackle.core.tracks.Hybrid.detect_active_area" class="md-nav__link">
<span class="md-ellipsis">
<code class="doc-symbol doc-symbol-toc doc-symbol-method"></code>&nbsp;detect_active_area
</span>
</a>
</li>
<li class="md-nav__item">
@@ -5360,12 +5382,12 @@ If no DV track is available but HDR10+ is present, it will convert HDR10+ to DV.
<a href="#unshackle.core.tracks.Hybrid.level_5" class="headerlink" title="Permanent link">&para;</a></h3>
<div class="language-python doc-signature highlight"><pre><span></span><code><span id="__span-0-1"><a id="__codelineno-0-1" name="__codelineno-0-1" href="#__codelineno-0-1"></a><span class="nf">level_5</span><span class="p">(</span><span class="n">input_video</span><span class="p">)</span>
<div class="language-python doc-signature highlight"><pre><span></span><code><span id="__span-0-1"><a id="__codelineno-0-1" name="__codelineno-0-1" href="#__codelineno-0-1"></a><span class="nf">level_5</span><span class="p">(</span><span class="n">crop</span><span class="p">)</span>
</span></code></pre></div>
<div class="doc doc-contents ">
<p>Make Level 5 active area metadata through crop detection on the HDR10 track.</p>
<p>Write the active area of the HDR10 track, as (left, top, right, bottom), to Level 5.</p>
<p>This resolves mismatches where DV has no black bars but HDR10 does (or vice versa)
by telling the display the correct active area.</p>
@@ -5377,6 +5399,28 @@ by telling the display the correct active area.</p>
<div class="doc doc-object doc-function">
<h3 id="unshackle.core.tracks.Hybrid.detect_active_area" class="doc doc-heading">
<code class="doc-symbol doc-symbol-heading doc-symbol-method"></code> <span class="doc doc-object-name doc-function-name">detect_active_area</span>
<a href="#unshackle.core.tracks.Hybrid.detect_active_area" class="headerlink" title="Permanent link">&para;</a></h3>
<div class="language-python doc-signature highlight"><pre><span></span><code><span id="__span-0-1"><a id="__codelineno-0-1" name="__codelineno-0-1" href="#__codelineno-0-1"></a><span class="nf">detect_active_area</span><span class="p">(</span><span class="n">input_video</span><span class="p">)</span>
</span></code></pre></div>
<div class="doc doc-contents ">
<p>The picture's crop as (left, top, right, bottom) and its share of the frame, or None.</p>
<p>None also when the picture is under 40% of the frame: cropdetect on dark samples can report a tiny
picture, which would be wrong in L5 and would divide the HDR10+ conversion's mean by a tiny share.</p>
</div>
</div>
<div class="doc doc-object doc-function">
<h3 id="unshackle.core.tracks.Hybrid.sanitize_l6" class="doc doc-heading">
<code class="doc-symbol doc-symbol-heading doc-symbol-method"></code> <span class="doc doc-object-name doc-function-name">sanitize_l6</span>
@@ -5473,12 +5517,16 @@ MaxCLL. A value of 0 means "unknown", and this method keeps it as-is.</p>
<a href="#unshackle.core.tracks.Hybrid.convert_hdr10plus_to_dv" class="headerlink" title="Permanent link">&para;</a></h3>
<div class="language-python doc-signature highlight"><pre><span></span><code><span id="__span-0-1"><a id="__codelineno-0-1" name="__codelineno-0-1" href="#__codelineno-0-1"></a><span class="nf">convert_hdr10plus_to_dv</span><span class="p">()</span>
<div class="language-python doc-signature highlight"><pre><span></span><code><span id="__span-0-1"><a id="__codelineno-0-1" name="__codelineno-0-1" href="#__codelineno-0-1"></a><span class="nf">convert_hdr10plus_to_dv</span><span class="p">(</span><span class="n">active_fraction</span><span class="o">=</span><span class="mf">1.0</span><span class="p">)</span>
</span></code></pre></div>
<div class="doc doc-contents ">
<p>Convert HDR10+ metadata to Dolby Vision RPU</p>
<p>Generate a Dolby Vision RPU with one shot per HDR10+ scene.</p>
<p>By default unshackle builds the L1 of each shot itself (see hdr10plus_shots), because dovi_tool's
--hdr10plus-json sets L1 avg from the linear AverageMaxRGB and so makes most scenes too bright.
config.generate_dv_mode picks the L1 avg floor: v29 (about 2.4 nits, closest to the pixels) or v40
(about 10 nits, as in studio CM v4.0 RPUs). legacy hands the HDR10+ JSON to dovi_tool instead.</p>
</div>
@@ -1193,6 +1193,17 @@
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#generate_dv_mode" class="md-nav__link">
<span class="md-ellipsis">
generate_dv_mode
</span>
</a>
</li>
</ul>
@@ -2138,6 +2149,17 @@
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#generate_dv_mode" class="md-nav__link">
<span class="md-ellipsis">
generate_dv_mode
</span>
</a>
</li>
</ul>
@@ -2349,6 +2371,12 @@ default. In other words, config only fills in options you did not set on the com
<td>Warn instead of failing when a requested resolution, range, or language is missing, or when one DRM system does not license under <code>--all-drm</code>. The CLI flag is <code>--best-available</code>, also spelled <code>--warn-only</code>.</td>
</tr>
<tr>
<td><code>generate_dv</code></td>
<td>bool</td>
<td><code>false</code></td>
<td>With <code>-r HYBRID</code>, make Dolby Vision from the HDR10+ metadata when a title has no DV track. Needs <code>hdr10plus_tool</code>. See <a href="../../../guide/downloading/#dolby-vision-from-hdr10">Dolby Vision from HDR10+</a>.</td>
</tr>
<tr>
<td><code>proxy</code></td>
<td>str</td>
<td><em>(unset)</em></td>
@@ -2822,6 +2850,39 @@ release yourself, in place of the fixed <code>DUAL</code>, <code>MULTi</code> an
<p>Regional variants of the same base language (e.g. <code>en-US</code> and <code>en-GB</code>) collapse to a single
language in both modes, so they never trigger <code>{dual}</code> on their own.</p>
</div>
<h2 id="generate_dv_mode"><code>generate_dv_mode</code><a class="headerlink" href="#generate_dv_mode" title="Permanent link">&para;</a></h2>
<ul>
<li><strong>Type:</strong> <code>str</code> &nbsp;·&nbsp; <strong>Default:</strong> <code>v29</code></li>
</ul>
<p>How <a href="../../../guide/downloading/#dolby-vision-from-hdr10"><code>--generate-dv</code></a> 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.</p>
<table>
<thead>
<tr>
<th>Mode</th>
<th>Scene average</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>v29</code> (default)</td>
<td>unshackle's average from the HDR10+ brightness distribution, at least about 2.4 nits. Closest to the pixels.</td>
</tr>
<tr>
<td><code>v40</code></td>
<td>The same average, at least about 10 nits, as in studio Dolby Vision (CM v4.0). Dark scenes read brighter than <code>v29</code>.</td>
</tr>
<tr>
<td><code>legacy</code></td>
<td>The <code>dovi_tool generate --hdr10plus-json</code> average. Most scenes read brighter than the pixels.</td>
</tr>
</tbody>
</table>
<div class="language-yaml highlight"><pre><span></span><code><span id="__span-12-1"><a id="__codelineno-12-1" name="__codelineno-12-1" href="#__codelineno-12-1"></a><span class="nt">generate_dv_mode</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">v29</span>
</span></code></pre></div>
<p>The setting applies on the machine that runs the hybrid step: the client for a remote download, the
server for a REST API job.</p>
+1 -1
View File
@@ -1993,7 +1993,7 @@ default.</p>
</tr>
<tr>
<td><a href="download/">Download &amp; processing</a></td>
<td><code>dl</code>, <code>continue_downloads</code>, <code>merge_segments</code>, <code>subtitle</code>, <code>audio</code>, <code>muxing</code>, <code>language_tags</code>, <code>dual_multi_mode</code></td>
<td><code>dl</code>, <code>continue_downloads</code>, <code>merge_segments</code>, <code>subtitle</code>, <code>audio</code>, <code>muxing</code>, <code>language_tags</code>, <code>dual_multi_mode</code>, <code>generate_dv_mode</code></td>
</tr>
<tr>
<td><a href="output/">Output &amp; naming</a></td>
File diff suppressed because one or more lines are too long