mirror of
https://github.com/unshackle-dl/unshackle.git
synced 2026-11-12 20:15:10 +00:00
Deployed 40ae213 with MkDocs version: 1.6.1
This commit is contained in:
@@ -2025,7 +2025,7 @@ turned into underscores (<code>--best-available</code> → <code>best_available<
|
||||
<div class="language-yaml highlight"><span class="filename">unshackle.yaml</span><pre><span></span><code><span id="__span-4-1"><a id="__codelineno-4-1" name="__codelineno-4-1" href="#__codelineno-4-1"></a><span class="nt">dl</span><span class="p">:</span>
|
||||
</span><span id="__span-4-2"><a id="__codelineno-4-2" name="__codelineno-4-2" href="#__codelineno-4-2"></a><span class="w"> </span><span class="nt">lang</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="c1"># -l en</span>
|
||||
</span><span id="__span-4-3"><a id="__codelineno-4-3" name="__codelineno-4-3" href="#__codelineno-4-3"></a><span class="w"> </span><span class="nt">quality</span><span class="p">:</span><span class="w"> </span><span class="p p-Indicator">[</span><span class="nv">1080</span><span class="p p-Indicator">]</span><span class="w"> </span><span class="c1"># -q 1080</span>
|
||||
</span><span id="__span-4-4"><a id="__codelineno-4-4" name="__codelineno-4-4" href="#__codelineno-4-4"></a><span class="w"> </span><span class="nt">vcodec</span><span class="p">:</span><span class="w"> </span><span class="p p-Indicator">[</span><span class="nv">H265</span><span class="p p-Indicator">]</span><span class="w"> </span><span class="c1"># -v H265</span>
|
||||
</span><span id="__span-4-4"><a id="__codelineno-4-4" name="__codelineno-4-4" href="#__codelineno-4-4"></a><span class="w"> </span><span class="nt">vcodec</span><span class="p">:</span><span class="w"> </span><span class="p p-Indicator">[</span><span class="nv">H.265</span><span class="p p-Indicator">]</span><span class="w"> </span><span class="c1"># -v H.265</span>
|
||||
</span><span id="__span-4-5"><a id="__codelineno-4-5" name="__codelineno-4-5" href="#__codelineno-4-5"></a><span class="w"> </span><span class="nt">sub_format</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">srt</span><span class="w"> </span><span class="c1"># convert subtitles to SRT</span>
|
||||
</span><span id="__span-4-6"><a id="__codelineno-4-6" name="__codelineno-4-6" href="#__codelineno-4-6"></a><span class="w"> </span><span class="nt">downloads</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">2</span><span class="w"> </span><span class="c1"># two tracks at once</span>
|
||||
</span></code></pre></div>
|
||||
@@ -2132,17 +2132,17 @@ and every available key.</p>
|
||||
</table>
|
||||
<div class="admonition note">
|
||||
<p class="admonition-title">Some directories cannot be moved</p>
|
||||
<p>A handful of internal locations are protected: the package root, the core directory, the user-config directory, and the data base. If you list them under <code>directories</code>, unshackle silently ignores the override. This is intentional; those paths are tied to where the package is installed.</p>
|
||||
<p>unshackle protects five internal entries: <code>app_dirs</code>, <code>core_dir</code>, <code>namespace_dir</code>, <code>user_configs</code>, and <code>data</code>. If you list any of them under <code>directories</code>, unshackle ignores the override. This is intentional; those paths are tied to where the package is installed.</p>
|
||||
</div>
|
||||
<h3 id="the-services-directory-is-special">The <code>services</code> directory is special<a class="headerlink" href="#the-services-directory-is-special" title="Permanent link">¶</a></h3>
|
||||
<p>Unlike the other entries, <code>services</code> is a <strong>list</strong>, and each entry can be either a local folder or a remote repository. This lets you mix your own local service code with services pulled from Git:</p>
|
||||
<div class="language-yaml highlight"><span class="filename">unshackle.yaml</span><pre><span></span><code><span id="__span-7-1"><a id="__codelineno-7-1" name="__codelineno-7-1" href="#__codelineno-7-1"></a><span class="nt">directories</span><span class="p">:</span>
|
||||
</span><span id="__span-7-2"><a id="__codelineno-7-2" name="__codelineno-7-2" href="#__codelineno-7-2"></a><span class="w"> </span><span class="nt">services</span><span class="p">:</span>
|
||||
</span><span id="__span-7-3"><a id="__codelineno-7-3" name="__codelineno-7-3" href="#__codelineno-7-3"></a><span class="w"> </span><span class="p p-Indicator">-</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">unshackle-dl/services</span><span class="w"> </span><span class="c1"># a GitHub owner/repo shorthand</span>
|
||||
</span><span id="__span-7-4"><a id="__codelineno-7-4" name="__codelineno-7-4" href="#__codelineno-7-4"></a><span class="w"> </span><span class="p p-Indicator">-</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">https://github.com/me/my-services.git</span>
|
||||
</span><span id="__span-7-3"><a id="__codelineno-7-3" name="__codelineno-7-3" href="#__codelineno-7-3"></a><span class="w"> </span><span class="p p-Indicator">-</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">you/your-services</span><span class="w"> </span><span class="c1"># a GitHub owner/repo shorthand</span>
|
||||
</span><span id="__span-7-4"><a id="__codelineno-7-4" name="__codelineno-7-4" href="#__codelineno-7-4"></a><span class="w"> </span><span class="p p-Indicator">-</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">https://example.com/private-services.git</span>
|
||||
</span><span id="__span-7-5"><a id="__codelineno-7-5" name="__codelineno-7-5" href="#__codelineno-7-5"></a><span class="w"> </span><span class="p p-Indicator">-</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">~/code/local-services</span><span class="w"> </span><span class="c1"># a local folder</span>
|
||||
</span></code></pre></div>
|
||||
<p>Entries are searched in the order listed, and <strong>the first source to define a given service tag wins</strong>, so put local folders last if you want them to act as fallbacks rather than overrides. Remote repositories are cloned and periodically updated for you. See <a href="../../dev/creating-a-service/">Services</a> for the full details on how service discovery and repositories work.</p>
|
||||
<p>unshackle searches entries in the order listed, and <strong>the first source to define a given service tag wins</strong>, so put local folders last if you want them to act as fallbacks rather than overrides. unshackle clones remote repositories on first use and refreshes them at most once a day. See <a href="../../dev/creating-a-service/">Creating a Service</a> for how service discovery and repositories work.</p>
|
||||
<h2 id="the-filenames-key">The <code>filenames</code> key<a class="headerlink" href="#the-filenames-key" title="Permanent link">¶</a></h2>
|
||||
<p>Alongside <code>directories</code>, the <code>filenames</code> key lets you override the templates unshackle uses when naming its own working and log files (for example the log filename or the temporary chapters file). Most users never need to touch this. The available names and their default templates are listed in the <a href="../../reference/configuration/#filenames">Configuration Reference</a>.</p>
|
||||
<h2 id="editing-the-config-with-unshackle-cfg">Editing the config with <code>unshackle cfg</code><a class="headerlink" href="#editing-the-config-with-unshackle-cfg" title="Permanent link">¶</a></h2>
|
||||
@@ -2155,8 +2155,8 @@ and every available key.</p>
|
||||
<div class="language-console highlight"><pre><span></span><code><span id="__span-9-1"><a id="__codelineno-9-1" name="__codelineno-9-1" href="#__codelineno-9-1"></a><span class="gp">$ </span>unshackle<span class="w"> </span>cfg<span class="w"> </span>tag<span class="w"> </span>MYGRP
|
||||
</span><span id="__span-9-2"><a id="__codelineno-9-2" name="__codelineno-9-2" href="#__codelineno-9-2"></a><span class="gp">$ </span>unshackle<span class="w"> </span>cfg<span class="w"> </span>cdm.default<span class="w"> </span>my_device_l3
|
||||
</span></code></pre></div>
|
||||
<p>Values are parsed as Python literals where possible, so numbers, booleans, and lists work naturally, while bare text is treated as a string:</p>
|
||||
<div class="language-console highlight"><pre><span></span><code><span id="__span-10-1"><a id="__codelineno-10-1" name="__codelineno-10-1" href="#__codelineno-10-1"></a><span class="gp">$ </span>unshackle<span class="w"> </span>cfg<span class="w"> </span>update_checks<span class="w"> </span><span class="nb">false</span>
|
||||
<p>unshackle parses the value as a Python literal, so write booleans as <code>True</code>/<code>False</code> and quote the strings inside a list (<code>"['en']"</code>). Anything that is not valid Python literal syntax is stored as a plain string:</p>
|
||||
<div class="language-console highlight"><pre><span></span><code><span id="__span-10-1"><a id="__codelineno-10-1" name="__codelineno-10-1" href="#__codelineno-10-1"></a><span class="gp">$ </span>unshackle<span class="w"> </span>cfg<span class="w"> </span>update_checks<span class="w"> </span>False
|
||||
</span><span id="__span-10-2"><a id="__codelineno-10-2" name="__codelineno-10-2" href="#__codelineno-10-2"></a><span class="gp">$ </span>unshackle<span class="w"> </span>cfg<span class="w"> </span>vault_timeout<span class="w"> </span><span class="m">30</span>
|
||||
</span></code></pre></div>
|
||||
<p><strong>Remove a value</strong> with <code>--unset</code>:</p>
|
||||
@@ -2165,7 +2165,7 @@ and every available key.</p>
|
||||
<p><strong>List everything</strong> currently set with <code>--list</code>:</p>
|
||||
<div class="language-console 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="gp">$ </span>unshackle<span class="w"> </span>cfg<span class="w"> </span>--list
|
||||
</span></code></pre></div>
|
||||
<p>When it writes, <code>unshackle cfg</code> targets the config file that was loaded. If none exists yet, it creates <code>unshackle.yaml</code> in your OS user-config directory.</p>
|
||||
<p>When it writes, <code>unshackle cfg</code> targets the config file that was loaded. If none exists yet, it creates <code>unshackle.yaml</code> inside the <code>unshackle</code> package folder (search location 1), not your OS user-config directory. To keep the config outside the package, create the file at the user-config path yourself first, then <code>unshackle cfg</code> writes to it.</p>
|
||||
<div class="admonition warning">
|
||||
<p class="admonition-title">Editing with <code>cfg</code> strips comments</p>
|
||||
<p>Because <code>unshackle cfg</code> rewrites the whole file when it saves, any comments in <code>unshackle.yaml</code> are removed by a write. If you keep important notes as comments, edit the file by hand instead, or keep those notes elsewhere.</p>
|
||||
@@ -2174,7 +2174,7 @@ and every available key.</p>
|
||||
<ul>
|
||||
<li>Browse the <a href="../../reference/configuration/">Configuration Reference</a> for every key and default.</li>
|
||||
<li>Set up your first download in <a href="../../guide/downloading/">Downloading</a>.</li>
|
||||
<li>Learn how services are discovered and updated in <a href="../../dev/creating-a-service/">Services</a>.</li>
|
||||
<li>Learn how services are discovered and updated in <a href="../../dev/creating-a-service/">Creating a Service</a>.</li>
|
||||
</ul>
|
||||
|
||||
|
||||
|
||||
@@ -2080,8 +2080,8 @@ these entirely.</p>
|
||||
</div>
|
||||
<h2 id="external-tools-on-your-path">External tools on your PATH<a class="headerlink" href="#external-tools-on-your-path" title="Permanent link">¶</a></h2>
|
||||
<p>unshackle shells out to a number of external command-line programs for media
|
||||
processing and DRM work. It looks for each one first in a <code>binaries/</code> folder
|
||||
next to the installed package, and then falls back to your system <code>PATH</code>, so
|
||||
processing and DRM work. It looks for each one first in the <code>binaries/</code> folder
|
||||
inside the installed package, and then falls back to your system <code>PATH</code>, so
|
||||
installing these tools system-wide (or dropping them into that folder) both
|
||||
work.</p>
|
||||
<h3 id="required-tools">Required tools<a class="headerlink" href="#required-tools" title="Permanent link">¶</a></h3>
|
||||
@@ -2126,7 +2126,7 @@ work.</p>
|
||||
<p class="admonition-title">shaka-packager is the default decryptor</p>
|
||||
<p>unshackle decrypts with shaka-packager unless you explicitly configure a
|
||||
different decryptor. If it is missing, protected downloads will fail at the
|
||||
decryption step. See the <a href="../configuration-file/">configuration reference</a> for the
|
||||
decryption step. See the <a href="../../reference/configuration/#decryption">configuration reference</a> for the
|
||||
<code>decryption</code> key if you want to switch to <code>mp4decrypt</code>.</p>
|
||||
</div>
|
||||
<h3 id="recommended-and-optional-tools">Recommended and optional tools<a class="headerlink" href="#recommended-and-optional-tools" title="Permanent link">¶</a></h3>
|
||||
@@ -2211,7 +2211,7 @@ it depends on.</p>
|
||||
<h3 id="confirm-the-command-is-available">Confirm the command is available<a class="headerlink" href="#confirm-the-command-is-available" title="Permanent link">¶</a></h3>
|
||||
<div class="language-shell highlight"><pre><span></span><code><span id="__span-4-1"><a id="__codelineno-4-1" name="__codelineno-4-1" href="#__codelineno-4-1"></a>unshackle<span class="w"> </span>--help
|
||||
</span></code></pre></div>
|
||||
<p>This prints the banner and the list of available commands (<code>dl</code>, <code>env</code>, <code>kv</code>,
|
||||
<p>This prints the list of available commands (<code>dl</code>, <code>env</code>, <code>kv</code>,
|
||||
<code>serve</code>, <code>wvd</code>, <code>prd</code>, <code>search</code>, <code>util</code>, <code>cfg</code>, <code>import</code>). If your shell reports
|
||||
that <code>unshackle</code> is not found, the <code>uv tool</code> bin directory is probably not on
|
||||
your <code>PATH</code>. Run <code>uv tool update-shell</code> and open a new terminal.</p>
|
||||
|
||||
@@ -638,10 +638,10 @@
|
||||
</li>
|
||||
|
||||
<li class="md-nav__item">
|
||||
<a href="#3-add-a-service" class="md-nav__link">
|
||||
<a href="#3-write-a-service" class="md-nav__link">
|
||||
<span class="md-ellipsis">
|
||||
|
||||
3. Add a service
|
||||
3. Write a service
|
||||
|
||||
</span>
|
||||
</a>
|
||||
@@ -1822,10 +1822,10 @@
|
||||
</li>
|
||||
|
||||
<li class="md-nav__item">
|
||||
<a href="#3-add-a-service" class="md-nav__link">
|
||||
<a href="#3-write-a-service" class="md-nav__link">
|
||||
<span class="md-ellipsis">
|
||||
|
||||
3. Add a service
|
||||
3. Write a service
|
||||
|
||||
</span>
|
||||
</a>
|
||||
@@ -1937,15 +1937,22 @@
|
||||
|
||||
<h1 id="quick-start">Quick Start<a class="headerlink" href="#quick-start" title="Permanent link">¶</a></h1>
|
||||
<p>This page takes you from a fresh install to your first downloaded file. You will
|
||||
create the one piece of configuration unshackle insists on, add a streaming
|
||||
service and a CDM so it can actually fetch and decrypt media, run a basic
|
||||
<code>unshackle dl</code> command, and learn where the finished file lands.</p>
|
||||
create the one piece of configuration unshackle insists on, supply the service
|
||||
module and CDM it needs to fetch and decrypt media, run a basic <code>unshackle dl</code>
|
||||
command, and learn where the finished file lands.</p>
|
||||
<div class="admonition note">
|
||||
<p class="admonition-title">Before you start</p>
|
||||
<p>This guide assumes unshackle is already installed and on your <code>PATH</code>. If
|
||||
<code>unshackle --help</code> does not print a help screen, work through
|
||||
<a href="../installation/">Installation</a> first.</p>
|
||||
</div>
|
||||
<div class="admonition warning">
|
||||
<p class="admonition-title">unshackle includes no services</p>
|
||||
<p>unshackle handles manifests, DRM, downloading, and muxing. It does not include a
|
||||
module for any streaming platform, so you write that part yourself
|
||||
(<a href="#3-write-a-service">step 3</a>). <code>EXAMPLE</code> in this guide stands in for the tag you
|
||||
give yours.</p>
|
||||
</div>
|
||||
<h2 id="1-check-your-environment">1. Check your environment<a class="headerlink" href="#1-check-your-environment" title="Permanent link">¶</a></h2>
|
||||
<p>unshackle drives several external tools (FFmpeg, MKVToolNix, shaka-packager, and
|
||||
others) to decrypt, repack, and mux media. Confirm they are visible before you
|
||||
@@ -1982,11 +1989,11 @@ That means <code>output_template</code> is the one setting a first run genuinely
|
||||
Everything else has a sensible default. A minimal, working config looks like this:</p>
|
||||
<div class="language-yaml highlight"><span class="filename">unshackle.yaml</span><pre><span></span><code><span id="__span-2-1"><a id="__codelineno-2-1" name="__codelineno-2-1" href="#__codelineno-2-1"></a><span class="nt">output_template</span><span class="p">:</span>
|
||||
</span><span id="__span-2-2"><a id="__codelineno-2-2" name="__codelineno-2-2" href="#__codelineno-2-2"></a><span class="w"> </span><span class="nt">movies</span><span class="p">:</span><span class="w"> </span><span class="s">"{title}</span><span class="nv"> </span><span class="s">({year})</span><span class="nv"> </span><span class="s">{quality}</span><span class="nv"> </span><span class="s">{source}"</span>
|
||||
</span><span id="__span-2-3"><a id="__codelineno-2-3" name="__codelineno-2-3" href="#__codelineno-2-3"></a><span class="w"> </span><span class="nt">series</span><span class="p">:</span><span class="w"> </span><span class="s">"{title}</span><span class="nv"> </span><span class="s">S{season}E{episode}</span><span class="nv"> </span><span class="s">{episode_name}</span><span class="nv"> </span><span class="s">{quality}</span><span class="nv"> </span><span class="s">{source}"</span>
|
||||
</span><span id="__span-2-3"><a id="__codelineno-2-3" name="__codelineno-2-3" href="#__codelineno-2-3"></a><span class="w"> </span><span class="nt">series</span><span class="p">:</span><span class="w"> </span><span class="s">"{title}</span><span class="nv"> </span><span class="s">{season_episode}</span><span class="nv"> </span><span class="s">{episode_name?}</span><span class="nv"> </span><span class="s">{quality}</span><span class="nv"> </span><span class="s">{source}"</span>
|
||||
</span></code></pre></div>
|
||||
<p>Each <code>{variable}</code> is filled in from the title and the tracks you downloaded. The
|
||||
full set of valid variables, including <code>resolution</code>, <code>video</code>, <code>audio</code>, <code>hdr</code>,
|
||||
<code>edition</code>, <code>tag</code>, and more, is documented in <a href="../configuration-file/">Configuration</a>.</p>
|
||||
<code>edition</code>, <code>tag</code>, and more, is documented in <a href="../../guide/output-and-naming/">Output and Naming</a>.</p>
|
||||
<div class="admonition note">
|
||||
<p class="admonition-title">Spaces or dots?</p>
|
||||
<p>unshackle auto-detects your naming style from the template: if the separators
|
||||
@@ -2001,59 +2008,28 @@ style you want the filenames to look.</p>
|
||||
rewrites the file and <strong>removes any comments</strong> it contained. If you keep notes
|
||||
in your config, edit the file by hand instead.</p>
|
||||
</div>
|
||||
<h2 id="3-add-a-service">3. Add a service<a class="headerlink" href="#3-add-a-service" title="Permanent link">¶</a></h2>
|
||||
<p>The service tag you pass to <code>dl</code> (like <code>EXAMPLE</code>) maps to a <strong>service module</strong>, a small
|
||||
plugin that knows how to talk to one streaming platform. unshackle ships without
|
||||
any bundled services, so you add the one(s) you want.</p>
|
||||
<p>Services live under the <code>directories.services</code> path (run <code>unshackle env info</code> to
|
||||
see where that is). unshackle discovers them by looking for <code>*/__init__.py</code>: the
|
||||
folder name becomes the <strong>service tag</strong>, and the folder must contain a class with
|
||||
that exact same name.</p>
|
||||
<div class="tabbed-set tabbed-alternate" data-tabs="1:2"><input checked="checked" id="__tabbed_1_1" name="__tabbed_1" type="radio" /><input id="__tabbed_1_2" name="__tabbed_1" type="radio" /><div class="tabbed-labels"><label for="__tabbed_1_1">Local folder</label><label for="__tabbed_1_2">Git repository</label></div>
|
||||
<div class="tabbed-content">
|
||||
<div class="tabbed-block">
|
||||
<p>Drop a service folder into your services directory. A service tagged <code>EXAMPLE</code>
|
||||
lives at:</p>
|
||||
<div class="language-text highlight"><pre><span></span><code><span id="__span-3-1"><a id="__codelineno-3-1" name="__codelineno-3-1" href="#__codelineno-3-1"></a><services>/EXAMPLE/__init__.py # defines a class named EXAMPLE
|
||||
</span></code></pre></div>
|
||||
<p>Once the folder is in place, the tag <code>EXAMPLE</code> is immediately available to <code>dl</code>,
|
||||
<code>search</code>, and the other service-aware commands.</p>
|
||||
</div>
|
||||
<div class="tabbed-block">
|
||||
<p><code>directories.services</code> may also list git repositories. unshackle clones them
|
||||
on first use and keeps them up to date:</p>
|
||||
<div class="language-yaml highlight"><span class="filename">unshackle.yaml</span><pre><span></span><code><span id="__span-4-1"><a id="__codelineno-4-1" name="__codelineno-4-1" href="#__codelineno-4-1"></a><span class="nt">directories</span><span class="p">:</span>
|
||||
</span><span id="__span-4-2"><a id="__codelineno-4-2" name="__codelineno-4-2" href="#__codelineno-4-2"></a><span class="w"> </span><span class="nt">services</span><span class="p">:</span>
|
||||
</span><span id="__span-4-3"><a id="__codelineno-4-3" name="__codelineno-4-3" href="#__codelineno-4-3"></a><span class="w"> </span><span class="p p-Indicator">-</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">owner/unshackle-services</span><span class="w"> </span><span class="c1"># a GitHub owner/repo shorthand</span>
|
||||
</span><span id="__span-4-4"><a id="__codelineno-4-4" name="__codelineno-4-4" href="#__codelineno-4-4"></a><span class="w"> </span><span class="p p-Indicator">-</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">/path/to/local/services</span><span class="w"> </span><span class="c1"># local folders still work too</span>
|
||||
</span></code></pre></div>
|
||||
<p>Force a refresh of every configured service repo at any time with:</p>
|
||||
<div class="language-shell highlight"><pre><span></span><code><span id="__span-5-1"><a id="__codelineno-5-1" name="__codelineno-5-1" href="#__codelineno-5-1"></a>unshackle<span class="w"> </span>util<span class="w"> </span>refresh-services
|
||||
</span></code></pre></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="admonition info">
|
||||
<p class="admonition-title">Where to get services</p>
|
||||
<p>Service modules are kept separate from the core project. Ask in the community
|
||||
<a href="https://discord.gg/mHYyPaCbFK">Discord</a> for where to find the service you
|
||||
need. The core repository deliberately does not host them.</p>
|
||||
</div>
|
||||
<h2 id="3-write-a-service">3. Write a service<a class="headerlink" href="#3-write-a-service" title="Permanent link">¶</a></h2>
|
||||
<p>The service tag you pass to <code>dl</code> (like <code>EXAMPLE</code>) maps to a <strong>service module</strong>, the
|
||||
plugin that talks to one streaming platform. unshackle includes none, so you write
|
||||
the one you need. <a href="../../dev/creating-a-service/">Creating a Service</a> covers how.</p>
|
||||
<p>Put the finished module in your <code>directories.services</code> folder (<code>unshackle env info</code>
|
||||
shows the path). The tag then works with <code>dl</code>, <code>search</code>, and the other service
|
||||
commands.</p>
|
||||
<h2 id="4-add-a-cdm-for-drm">4. Add a CDM for DRM<a class="headerlink" href="#4-add-a-cdm-for-drm" title="Permanent link">¶</a></h2>
|
||||
<p>Most streaming content is encrypted. To fetch decryption keys, unshackle needs a
|
||||
<strong>CDM</strong>, a Widevine device (<code>.wvd</code>) or a PlayReady device (<code>.prd</code>). Register a
|
||||
Widevine device you already have with:</p>
|
||||
<div class="language-shell highlight"><pre><span></span><code><span id="__span-6-1"><a id="__codelineno-6-1" name="__codelineno-6-1" href="#__codelineno-6-1"></a>unshackle<span class="w"> </span>wvd<span class="w"> </span>add<span class="w"> </span>/path/to/device.wvd
|
||||
<div class="language-shell highlight"><pre><span></span><code><span id="__span-3-1"><a id="__codelineno-3-1" name="__codelineno-3-1" href="#__codelineno-3-1"></a>unshackle<span class="w"> </span>wvd<span class="w"> </span>add<span class="w"> </span>/path/to/device.wvd
|
||||
</span></code></pre></div>
|
||||
<p>This validates the file and moves it into your WVDs directory. Then point services
|
||||
at it in your config. The <code>cdm</code> map is keyed by service tag, with a <code>default</code> that
|
||||
covers everything else:</p>
|
||||
<div class="language-yaml highlight"><span class="filename">unshackle.yaml</span><pre><span></span><code><span id="__span-7-1"><a id="__codelineno-7-1" name="__codelineno-7-1" href="#__codelineno-7-1"></a><span class="nt">cdm</span><span class="p">:</span>
|
||||
</span><span id="__span-7-2"><a id="__codelineno-7-2" name="__codelineno-7-2" href="#__codelineno-7-2"></a><span class="w"> </span><span class="nt">default</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">my_device</span><span class="w"> </span><span class="c1"># the .wvd file's name, without the extension</span>
|
||||
</span><span id="__span-7-3"><a id="__codelineno-7-3" name="__codelineno-7-3" href="#__codelineno-7-3"></a><span class="w"> </span><span class="nt">EXAMPLE</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">my_other_device</span><span class="w"> </span><span class="c1"># override for a specific service</span>
|
||||
<div class="language-yaml highlight"><span class="filename">unshackle.yaml</span><pre><span></span><code><span id="__span-4-1"><a id="__codelineno-4-1" name="__codelineno-4-1" href="#__codelineno-4-1"></a><span class="nt">cdm</span><span class="p">:</span>
|
||||
</span><span id="__span-4-2"><a id="__codelineno-4-2" name="__codelineno-4-2" href="#__codelineno-4-2"></a><span class="w"> </span><span class="nt">default</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">my_device</span><span class="w"> </span><span class="c1"># the .wvd file's name, without the extension</span>
|
||||
</span><span id="__span-4-3"><a id="__codelineno-4-3" name="__codelineno-4-3" href="#__codelineno-4-3"></a><span class="w"> </span><span class="nt">EXAMPLE</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">my_other_device</span><span class="w"> </span><span class="c1"># override for a specific service</span>
|
||||
</span></code></pre></div>
|
||||
<p>PlayReady works the same way with <code>.prd</code> files created and managed by the
|
||||
<a href="../configuration-file/"><code>prd</code></a> command. If a title is DRM-free, no CDM is needed.</p>
|
||||
<a href="../../guide/cli-reference/#prd"><code>prd</code></a> command. If a title is DRM-free, no CDM is needed.</p>
|
||||
<div class="admonition tip">
|
||||
<p class="admonition-title">Tip</p>
|
||||
<p>Run <code>unshackle wvd parse my_device</code> to inspect a device's security level and
|
||||
@@ -2071,8 +2047,8 @@ contents, and <code>unshackle env info</code> to confirm where WVDs and PRDs are
|
||||
</li>
|
||||
<li>
|
||||
<p><strong>Credentials</strong>: store a username and password per service in your config:</p>
|
||||
<div class="language-yaml highlight"><span class="filename">unshackle.yaml</span><pre><span></span><code><span id="__span-8-1"><a id="__codelineno-8-1" name="__codelineno-8-1" href="#__codelineno-8-1"></a><span class="nt">credentials</span><span class="p">:</span>
|
||||
</span><span id="__span-8-2"><a id="__codelineno-8-2" name="__codelineno-8-2" href="#__codelineno-8-2"></a><span class="w"> </span><span class="nt">EXAMPLE</span><span class="p">:</span><span class="w"> </span><span class="s">"email@example.com:your-password"</span>
|
||||
<div class="language-yaml highlight"><span class="filename">unshackle.yaml</span><pre><span></span><code><span id="__span-5-1"><a id="__codelineno-5-1" name="__codelineno-5-1" href="#__codelineno-5-1"></a><span class="nt">credentials</span><span class="p">:</span>
|
||||
</span><span id="__span-5-2"><a id="__codelineno-5-2" name="__codelineno-5-2" href="#__codelineno-5-2"></a><span class="w"> </span><span class="nt">EXAMPLE</span><span class="p">:</span><span class="w"> </span><span class="s">"email@example.com:your-password"</span>
|
||||
</span></code></pre></div>
|
||||
</li>
|
||||
</ul>
|
||||
@@ -2082,23 +2058,23 @@ depends on the service module.</p>
|
||||
<h2 id="6-find-a-title-optional">6. Find a title (optional)<a class="headerlink" href="#6-find-a-title-optional" title="Permanent link">¶</a></h2>
|
||||
<p>If you have a URL or ID already, skip this. Otherwise, search the service for a
|
||||
title and note the <code>id</code> it prints, since that is what you feed to <code>dl</code>:</p>
|
||||
<div class="language-shell highlight"><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>search<span class="w"> </span>EXAMPLE<span class="w"> </span><span class="s2">"My Show"</span>
|
||||
<div class="language-shell highlight"><pre><span></span><code><span id="__span-6-1"><a id="__codelineno-6-1" name="__codelineno-6-1" href="#__codelineno-6-1"></a>unshackle<span class="w"> </span>search<span class="w"> </span>EXAMPLE<span class="w"> </span><span class="s2">"My Show"</span>
|
||||
</span></code></pre></div>
|
||||
<p>You can also list what a service exposes for a given title without downloading:</p>
|
||||
<div class="language-shell highlight"><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>--list-titles<span class="w"> </span>EXAMPLE<span class="w"> </span><span class="m">81234567</span><span class="w"> </span><span class="c1"># show seasons/episodes</span>
|
||||
</span><span id="__span-10-2"><a id="__codelineno-10-2" name="__codelineno-10-2" href="#__codelineno-10-2"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>--list<span class="w"> </span>EXAMPLE<span class="w"> </span><span class="m">81234567</span><span class="w"> </span><span class="c1"># show available tracks</span>
|
||||
<div class="language-shell highlight"><pre><span></span><code><span id="__span-7-1"><a id="__codelineno-7-1" name="__codelineno-7-1" href="#__codelineno-7-1"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>--list-titles<span class="w"> </span>EXAMPLE<span class="w"> </span><span class="m">81234567</span><span class="w"> </span><span class="c1"># show seasons/episodes</span>
|
||||
</span><span id="__span-7-2"><a id="__codelineno-7-2" name="__codelineno-7-2" href="#__codelineno-7-2"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>--list<span class="w"> </span>EXAMPLE<span class="w"> </span><span class="m">81234567</span><span class="w"> </span><span class="c1"># show available tracks</span>
|
||||
</span></code></pre></div>
|
||||
<h2 id="7-run-your-first-download">7. Run your first download<a class="headerlink" href="#7-run-your-first-download" title="Permanent link">¶</a></h2>
|
||||
<p>A download always has three parts:</p>
|
||||
<div class="language-text highlight"><pre><span></span><code><span id="__span-11-1"><a id="__codelineno-11-1" name="__codelineno-11-1" href="#__codelineno-11-1"></a>unshackle dl <FLAGS> <SERVICE-TAG> <TITLE>
|
||||
<div class="language-text highlight"><pre><span></span><code><span id="__span-8-1"><a id="__codelineno-8-1" name="__codelineno-8-1" href="#__codelineno-8-1"></a>unshackle dl <FLAGS> <SERVICE-TAG> <TITLE>
|
||||
</span></code></pre></div>
|
||||
<ul>
|
||||
<li><strong><code>dl</code></strong> carries every quality, language, track, and output flag.</li>
|
||||
<li><strong><code><SERVICE-TAG></code></strong> picks which service to talk to (e.g. <code>EXAMPLE</code>).</li>
|
||||
<li><strong><code><TITLE></code></strong> is the URL, ID, or slug the service understands.</li>
|
||||
</ul>
|
||||
<p>A good first command asks for 1080p with English audio and subtitles:</p>
|
||||
<div class="language-shell highlight"><span class="filename">Your first download</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>-q<span class="w"> </span><span class="m">1080</span><span class="w"> </span>-l<span class="w"> </span>en<span class="w"> </span>EXAMPLE<span class="w"> </span><span class="m">81234567</span>
|
||||
<p>A good first command asks for 1080p with English audio:</p>
|
||||
<div class="language-shell highlight"><span class="filename">Your first download</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>-q<span class="w"> </span><span class="m">1080</span><span class="w"> </span>-l<span class="w"> </span>en<span class="w"> </span>EXAMPLE<span class="w"> </span><span class="m">81234567</span>
|
||||
</span></code></pre></div>
|
||||
<p>unshackle will fetch the title, select the tracks matching your flags, acquire
|
||||
keys through your CDM (and any key vaults), then decrypt, mux, and tag the result.</p>
|
||||
@@ -2117,7 +2093,7 @@ keys through your CDM (and any key vaults), then decrypt, mux, and tag the resul
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>-l</code>, <code>--lang</code></td>
|
||||
<td>Language(s) for video and audio, e.g. <code>-l en</code> or <code>-l orig,en</code>. <code>orig</code> = the title's original language.</td>
|
||||
<td>Language(s) for video and audio, e.g. <code>-l en</code> or <code>-l orig,en</code>. <code>orig</code> = the title's original language. Defaults to <code>orig</code>.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>-sl</code>, <code>--s-lang</code></td>
|
||||
@@ -2147,34 +2123,34 @@ keys through your CDM (and any key vaults), then decrypt, mux, and tag the resul
|
||||
</table>
|
||||
<div class="admonition example">
|
||||
<p class="admonition-title">A few realistic variations</p>
|
||||
<div class="language-shell highlight"><pre><span></span><code><span id="__span-13-1"><a id="__codelineno-13-1" name="__codelineno-13-1" href="#__codelineno-13-1"></a><span class="c1"># A whole first season in the best available quality</span>
|
||||
</span><span id="__span-13-2"><a id="__codelineno-13-2" name="__codelineno-13-2" href="#__codelineno-13-2"></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-13-3"><a id="__codelineno-13-3" name="__codelineno-13-3" href="#__codelineno-13-3"></a>
|
||||
</span><span id="__span-13-4"><a id="__codelineno-13-4" name="__codelineno-13-4" href="#__codelineno-13-4"></a><span class="c1"># 2160p HDR10 with the original-language audio plus English subtitles</span>
|
||||
</span><span id="__span-13-5"><a id="__codelineno-13-5" name="__codelineno-13-5" href="#__codelineno-13-5"></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>HDR10<span class="w"> </span>-l<span class="w"> </span>orig<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><span id="__span-13-6"><a id="__codelineno-13-6" name="__codelineno-13-6" href="#__codelineno-13-6"></a>
|
||||
</span><span id="__span-13-7"><a id="__codelineno-13-7" name="__codelineno-13-7" href="#__codelineno-13-7"></a><span class="c1"># Just the newest episode of an ongoing show</span>
|
||||
</span><span id="__span-13-8"><a id="__codelineno-13-8" name="__codelineno-13-8" href="#__codelineno-13-8"></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"><pre><span></span><code><span id="__span-10-1"><a id="__codelineno-10-1" name="__codelineno-10-1" href="#__codelineno-10-1"></a><span class="c1"># A whole first season in the best available quality</span>
|
||||
</span><span id="__span-10-2"><a id="__codelineno-10-2" name="__codelineno-10-2" href="#__codelineno-10-2"></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-10-3"><a id="__codelineno-10-3" name="__codelineno-10-3" href="#__codelineno-10-3"></a>
|
||||
</span><span id="__span-10-4"><a id="__codelineno-10-4" name="__codelineno-10-4" href="#__codelineno-10-4"></a><span class="c1"># 2160p HDR10 with the original-language audio plus English subtitles</span>
|
||||
</span><span id="__span-10-5"><a id="__codelineno-10-5" name="__codelineno-10-5" href="#__codelineno-10-5"></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>HDR10<span class="w"> </span>-l<span class="w"> </span>orig<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><span id="__span-10-6"><a id="__codelineno-10-6" name="__codelineno-10-6" href="#__codelineno-10-6"></a>
|
||||
</span><span id="__span-10-7"><a id="__codelineno-10-7" name="__codelineno-10-7" href="#__codelineno-10-7"></a><span class="c1"># Just the newest episode of an ongoing show</span>
|
||||
</span><span id="__span-10-8"><a id="__codelineno-10-8" name="__codelineno-10-8" href="#__codelineno-10-8"></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>
|
||||
<p>See <a href="../../guide/downloading/">Downloading</a> for the complete flag reference, including
|
||||
codec, bitrate, channel-layout, and track-type selection.</p>
|
||||
<h2 id="8-where-the-output-lands">8. Where the output lands<a class="headerlink" href="#8-where-the-output-lands" title="Permanent link">¶</a></h2>
|
||||
<p>By default, finished files are written to the <code>downloads</code> directory
|
||||
<p>By default, unshackle writes finished files to the <code>downloads</code> directory
|
||||
(<code>unshackle env info</code> shows its exact path; the built-in default is a <code>downloads</code>
|
||||
folder alongside the project). Override it per run with <code>-o</code>:</p>
|
||||
<div class="language-shell highlight"><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>-q<span class="w"> </span><span class="m">1080</span><span class="w"> </span>-o<span class="w"> </span>/mnt/media/incoming<span class="w"> </span>EXAMPLE<span class="w"> </span><span class="m">81234567</span>
|
||||
folder one level above the installed <code>unshackle</code> package). Override it per run with <code>-o</code>:</p>
|
||||
<div class="language-shell highlight"><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>-q<span class="w"> </span><span class="m">1080</span><span class="w"> </span>-o<span class="w"> </span>/mnt/media/incoming<span class="w"> </span>EXAMPLE<span class="w"> </span><span class="m">81234567</span>
|
||||
</span></code></pre></div>
|
||||
<ul>
|
||||
<li><strong>Movies</strong> are written as a single <code>.mkv</code> file named from your <code>movies</code> template.</li>
|
||||
<li>unshackle writes <strong>movies</strong> as a single <code>.mkv</code> file named from your <code>movies</code> template.</li>
|
||||
<li><strong>TV episodes</strong> are grouped into a per-show / per-season folder (from your
|
||||
<code>series</code> template) unless you pass <code>--no-folder</code>.</li>
|
||||
<li>The filename is built from your <code>output_template</code>, and IMDb/TMDB IDs are added to
|
||||
<li>unshackle builds the filename from your <code>output_template</code> and adds IMDb/TMDB IDs to
|
||||
the file's metadata tags when available.</li>
|
||||
</ul>
|
||||
<p>To change the default output location permanently, set it in your config:</p>
|
||||
<div class="language-yaml highlight"><span class="filename">unshackle.yaml</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="nt">directories</span><span class="p">:</span>
|
||||
</span><span id="__span-15-2"><a id="__codelineno-15-2" name="__codelineno-15-2" href="#__codelineno-15-2"></a><span class="w"> </span><span class="nt">downloads</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">/mnt/media/incoming</span>
|
||||
<div class="language-yaml highlight"><span class="filename">unshackle.yaml</span><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">directories</span><span class="p">:</span>
|
||||
</span><span id="__span-12-2"><a id="__codelineno-12-2" name="__codelineno-12-2" href="#__codelineno-12-2"></a><span class="w"> </span><span class="nt">downloads</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">/mnt/media/incoming</span>
|
||||
</span></code></pre></div>
|
||||
<h2 id="where-to-go-next">Where to go next<a class="headerlink" href="#where-to-go-next" title="Permanent link">¶</a></h2>
|
||||
<ul>
|
||||
@@ -2188,7 +2164,7 @@ folder alongside the project). Override it per run with <code>-o</code>:</p>
|
||||
<div class="admonition tip">
|
||||
<p class="admonition-title">You are never far from help</p>
|
||||
<p><code>unshackle --help</code>, <code>unshackle dl --help</code>, and <code>unshackle <command> --help</code>
|
||||
list every option with its default. When in doubt, add <code>--list</code> to a <code>dl</code>
|
||||
list every option. When in doubt, add <code>--list</code> to a <code>dl</code>
|
||||
command to preview what it would do before it downloads anything.</p>
|
||||
</div>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user