Deployed 8b10b79 with MkDocs version: 1.6.1

This commit is contained in:
2026-08-20 03:01:15 +00:00
parent 01248725da
commit 94f2b09ef6
40 changed files with 1967 additions and 1920 deletions
+4 -4
View File
@@ -2142,7 +2142,7 @@
<h1 id="config-api">Config API<a class="headerlink" href="#config-api" title="Permanent link">&para;</a></h1>
<p>Auto-generated reference for the <a class="autorefs autorefs-internal" title="&lt;code class=&quot;doc-symbol doc-symbol-heading doc-symbol-class&quot;&gt;&lt;/code&gt; &lt;span class=&quot;doc doc-object-name doc-class-name&quot;&gt;Config&lt;/span&gt;" href="#unshackle.core.config.Config"><code>Config</code></a> object that models the
<code>unshackle</code> configuration file. For a human-friendly walkthrough of every key, see the
<code>unshackle</code> configuration file. For a human-friendly walkthrough of every config key, see the
<a href="../../configuration/">Configuration Reference</a>.</p>
@@ -2242,7 +2242,7 @@
<div class="doc doc-contents ">
<p>Resolve the folder template for the given title kind.</p>
<p>Find the folder template for the given title kind.</p>
<p>kind: one of "movies", "series", "songs", "albums".
Falls back to the legacy single-string folder template, then "".</p>
@@ -2326,7 +2326,7 @@ between variables. Falls back to dot separator (scene-style) by default.</p>
<div class="doc doc-contents ">
<p>Pick the decryption tool for a service (case-insensitive), falling back to default.</p>
<p>Pick the decryption backend for a service (case-insensitive), falling back to default.</p>
</div>
@@ -2346,7 +2346,7 @@ between variables. Falls back to dot separator (scene-style) by default.</p>
<div class="doc doc-contents ">
<p>Resolve a service's top-level CDM entry (case-insensitive), with default fallback.</p>
<p>Find a service's top-level CDM entry (case-insensitive), with default fallback.</p>
</div>
+56 -53
View File
@@ -3369,10 +3369,10 @@ For configuring DRM as a user, see <a href="../../../guide/drm-and-cdm/">DRM &am
<p>AES Clear Key DRM System.</p>
<p>AES-128 ClearKey (HLS) DRM system.</p>
<p>Generally IV should be provided where possible. If not provided, it will be
set to of the same bit-size of the key.</p>
<p>Give the IV where possible. If you do not give an IV, unshackle sets it to
of the same bit-size as the content key.</p>
@@ -3408,7 +3408,7 @@ set to of the same bit-size of the key.</p>
<div class="doc doc-contents ">
<p>Warn once per track that a segment was passed through undecrypted.</p>
<p>Warn once per track that unshackle passed a segment through undecrypted.</p>
</div>
@@ -3428,7 +3428,7 @@ set to of the same bit-size of the key.</p>
<div class="doc doc-contents ">
<p>Decrypt a Track with AES Clear Key DRM.</p>
<p>Decrypt a Track with AES-128 ClearKey (HLS) DRM.</p>
</div>
@@ -3475,7 +3475,7 @@ set to of the same bit-size of the key.</p>
</td>
<td>
<div class="doc-md-description">
<p>A Key object parsed from a m3u(8) playlist using
<p>A <code>Key</code> object parsed from a m3u(8) playlist using
the <code>m3u8</code> library.</p>
</div>
</td>
@@ -3492,7 +3492,7 @@ the <code>m3u8</code> library.</p>
</td>
<td>
<div class="doc-md-description">
<p>Optional session used to request external URIs with.
<p>Optional HTTP session used to request external URIs with.
Useful to set headers, proxies, cookies, and so forth.</p>
</div>
</td>
@@ -3532,9 +3532,9 @@ Useful to set headers, proxies, cookies, and so forth.</p>
<p>W3C EME ClearKey (org.w3.clearkey) DRM System over MPEG-CENC content.</p>
<p>Distinct from the HLS AES-128 <code>ClearKey</code> class: keys here are delivered by a
license server as a JWK Set keyed by KID, and content is standard CENC
<p>W3C EME ClearKey (org.w3.clearkey) DRM System over MPEG-CENC tracks.</p>
<p>Distinct from the HLS AES-128 <code>ClearKey</code> class: a license server gives the keys
here as a JWK Set keyed by KID, and the media is standard CENC
(decrypted with shaka-packager/mp4decrypt KID:KEY pairs, same as Widevine).</p>
@@ -3733,7 +3733,8 @@ license server as a JWK Set keyed by KID, and content is standard CENC
<div class="doc doc-contents ">
<p>Serialise this DRM instance for export/import (KIDs + license URL).</p>
<p>Content keys are stored once at the export's track level, not duplicated here.</p>
<p>unshackle stores the content keys once at the export's track level, and does not
duplicate them here.</p>
</div>
@@ -3753,7 +3754,7 @@ license server as a JWK Set keyed by KID, and content is standard CENC
<div class="doc doc-contents ">
<p>Build the W3C EME ClearKey JSON license request for the unkeyed KIDs.</p>
<p>Assemble the W3C EME ClearKey JSON license request for the unkeyed KIDs.</p>
</div>
@@ -3773,11 +3774,11 @@ license server as a JWK Set keyed by KID, and content is standard CENC
<div class="doc doc-contents ">
<p>Obtain Content Keys for this DRM Instance from a ClearKey license server.</p>
<p>The licence param is expected to be a function and will be provided with the
W3C JSON license request as <code>challenge</code>. It may return the JWK Set license as
a dict, JSON str, or bytes. If it returns None and the manifest provided a
Laurl, the challenge is POSTed there directly instead.</p>
<p>Get Content Keys for this DRM Instance from a ClearKey license server.</p>
<p>The licence param is a function. unshackle gives it the W3C JSON license
request as <code>challenge</code>. It may return the JWK Set license as a dict, JSON str,
or bytes. If it returns None and the manifest gave a Laurl, unshackle POSTs the
challenge there directly instead.</p>
</div>
@@ -3802,7 +3803,7 @@ Args:
path: Path to the encrypted file to decrypt
Raises:
EnvironmentError if the required decryption executable could not be found.
ValueError if the track has not yet been downloaded.
ValueError if unshackle has not yet downloaded the track.
SubprocessError if the decryption process returned a non-zero exit code.</p>
@@ -3843,7 +3844,7 @@ Raises:
<div class="doc doc-contents ">
<p>Decrypt using Shaka Packager</p>
<p>Decrypt with shaka-packager</p>
</div>
@@ -3876,13 +3877,13 @@ Raises:
<p>MonaLisa DRM System.</p>
<p>Unlike Widevine/PlayReady, MonaLisa does not use a challenge/response flow
with a license server. Instead, the PSSH value (ticket) is provided directly
by the service API, and keys are extracted locally via a WASM module.</p>
<p>Decryption is performed in two stages:
with a license server. Instead, the service API gives the PSSH value (ticket)
directly, and a WASM module extracts the content keys locally.</p>
<p>Decryption has two stages:
1. ML-Worker binary: Removes MonaLisa encryption layer (bbts -&gt; ents)
2. AES-ECB decryption: Final decryption with service-provided key</p>
2. AES-ECB decryption: Final decryption with the service-supplied content key</p>
<p>Initialize MonaLisa DRM.</p>
<p>Initialise MonaLisa DRM.</p>
<p><span class="doc-section-title">Parameters:</span></p>
@@ -3921,7 +3922,7 @@ by the service API, and keys are extracted locally via a WASM module.</p>
</td>
<td>
<div class="doc-md-description">
<p>AES-ECB key for second-stage decryption (hex string or bytes).</p>
<p>AES-ECB content key for second-stage decryption (hex string or bytes).</p>
</div>
</td>
<td>
@@ -3989,7 +3990,7 @@ by the service API, and keys are extracted locally via a WASM module.</p>
</td>
<td>
<div class="doc-md-description">
<p>If key extraction fails.</p>
<p>If content key extraction fails.</p>
</div>
</td>
</tr>
@@ -4194,7 +4195,7 @@ H5DCID-V3-P1-YYYYMMDD-HHMMSS-MEDIAID-TIMESTAMP-SUFFIX</p>
</td>
<td>
<div class="doc-md-description">
<p>Dictionary mapping KID to key hex string.</p>
<p>Dictionary mapping KID to the content key hex string.</p>
</div>
</td>
</tr>
@@ -4259,7 +4260,7 @@ H5DCID-V3-P1-YYYYMMDD-HHMMSS-MEDIAID-TIMESTAMP-SUFFIX</p>
<p>Raised when no PSSH/ticket data is provided.</p>
<p>Raised when the caller gives no PSSH/ticket data.</p>
@@ -4290,7 +4291,7 @@ H5DCID-V3-P1-YYYYMMDD-HHMMSS-MEDIAID-TIMESTAMP-SUFFIX</p>
<p>Raised when key extraction from the ticket fails.</p>
<p>Raised when content key extraction from the ticket fails.</p>
@@ -4413,7 +4414,7 @@ H5DCID-V3-P1-YYYYMMDD-HHMMSS-MEDIAID-TIMESTAMP-SUFFIX</p>
<div class="doc doc-contents ">
<p>Create a MonaLisa DRM instance from a PSSH/ticket.</p>
<p>Make a MonaLisa DRM instance from a PSSH/ticket.</p>
<p><span class="doc-section-title">Parameters:</span></p>
@@ -4452,7 +4453,7 @@ H5DCID-V3-P1-YYYYMMDD-HHMMSS-MEDIAID-TIMESTAMP-SUFFIX</p>
</td>
<td>
<div class="doc-md-description">
<p>AES-ECB key for second-stage decryption.</p>
<p>AES-ECB content key for second-stage decryption.</p>
</div>
</td>
<td>
@@ -4605,9 +4606,9 @@ Stage 2: AES-ECB decryption (ents -&gt; ts)</p>
<div class="doc doc-contents ">
<p>MonaLisa uses per-segment decryption during download via the
on_segment_downloaded callback. By the time this method is called,
the content has already been decrypted and muxed into a container.</p>
<p>MonaLisa uses per-segment decryption during download, through the
on_segment_downloaded callback. When the caller calls this method,
unshackle has already decrypted the media and muxed it into a container.</p>
<p><span class="doc-section-title">Parameters:</span></p>
@@ -4726,7 +4727,8 @@ the content has already been decrypted and muxed into a container.</p>
<div class="doc doc-contents ">
<p>Serialise this DRM instance for export/import (PSSH + KIDs).</p>
<p>Content keys are stored once at the export's track level, not duplicated here.</p>
<p>unshackle stores the content keys once at the export's track level, and does not
duplicate them here.</p>
</div>
@@ -4842,7 +4844,7 @@ the content has already been decrypted and muxed into a container.</p>
<p>Return the decoded error string if a revocation HRESULT is present, else None.</p>
<p>Reads the code from the raw SOAP body (<StatusCode>0x8004C065</StatusCode>)
or from an exception message that carries it, so any service is covered.</p>
or from an exception message that carries it, so this method covers any service.</p>
</div>
@@ -4867,7 +4869,7 @@ Args:
path: Path to the encrypted file to decrypt
Raises:
EnvironmentError if the required decryption executable could not be found.
ValueError if the track has not yet been downloaded.
ValueError if unshackle has not yet downloaded the track.
SubprocessError if the decryption process returned a non-zero exit code.</p>
@@ -4908,7 +4910,7 @@ Raises:
<div class="doc doc-contents ">
<p>Decrypt using Shaka Packager (original method)</p>
<p>Decrypt with shaka-packager (original method)</p>
</div>
@@ -5221,12 +5223,12 @@ Raises:
<p>Get PSSH and KID from within the Initiation Segment of the Track Data.
It also tries to get PSSH and KID from other track data like M3U8 data
as well as through ffprobe.</p>
<p>Create a Widevine DRM System object from a track's information.
This should only be used if a PSSH could not be provided directly.
as well as through FFprobe.</p>
<p>Make a Widevine DRM System object from a track's information.
Use this method only when a PSSH cannot be given directly.
It is <em>rare</em> to need to use this.</p>
<p>You may provide your own requests session to be able to use custom
headers and more.</p>
<p>You can give your own <code>requests.Session</code> to use custom headers
and more.</p>
<p><span class="doc-section-title">Raises:</span></p>
@@ -5284,7 +5286,7 @@ headers and more.</p>
<div class="doc doc-contents ">
<p>Get PSSH and KID from within Initialization Segment Data.</p>
<p>This should only be used if a PSSH could not be provided directly.
<p>Use this method only when a PSSH cannot be given directly.
It is <em>rare</em> to need to use this.</p>
@@ -5339,7 +5341,8 @@ It is <em>rare</em> to need to use this.</p>
<div class="doc doc-contents ">
<p>Serialise this DRM instance for export/import (PSSH + KIDs).</p>
<p>Content keys are stored once at the export's track level, not duplicated here.</p>
<p>unshackle stores the content keys once at the export's track level, and does not
duplicate them here.</p>
</div>
@@ -5359,9 +5362,9 @@ It is <em>rare</em> to need to use this.</p>
<div class="doc doc-contents ">
<p>Create a CDM Session and obtain Content Keys for this DRM Instance.
The certificate and license params are expected to be a function and will
be provided with the challenge and session ID.</p>
<p>Make a CDM Session and get Content Keys for this DRM Instance.
The certificate and license params are functions. unshackle gives them
the challenge and the session ID.</p>
</div>
@@ -5381,9 +5384,9 @@ be provided with the challenge and session ID.</p>
<div class="doc doc-contents ">
<p>Create a CDM Session and obtain Content Keys for this DRM Instance.
The certificate and license params are expected to be a function and will
be provided with the challenge and session ID.</p>
<p>Make a CDM Session and get Content Keys for this DRM Instance.
The certificate and license params are functions. unshackle gives them
the challenge and the session ID.</p>
</div>
@@ -5408,7 +5411,7 @@ Args:
path: Path to the encrypted file to decrypt
Raises:
EnvironmentError if the required decryption executable could not be found.
ValueError if the track has not yet been downloaded.
ValueError if unshackle has not yet downloaded the track.
SubprocessError if the decryption process returned a non-zero exit code.</p>
@@ -5449,7 +5452,7 @@ Raises:
<div class="doc doc-contents ">
<p>Decrypt using Shaka Packager (original method)</p>
<p>Decrypt with shaka-packager (original method)</p>
</div>
+132 -132
View File
@@ -2564,13 +2564,13 @@ walkthrough and <a href="../../../dev/service-architecture/">Service Architectur
<p>requests.Session applying DEFAULT_TIMEOUT when the caller passes none.</p>
<p>requests has no native default timeout; without one a stalled connect or
read hangs forever. RnetSession bounds every request via its client's
<p>requests has no native default timeout. Without one, a stalled connect or
read hangs forever. RnetSession bounds every request through its client's
connect_timeout/read_timeout, so this mirrors that on the requests path.
A per-request non-None <code>timeout=</code> wins; an explicit <code>timeout=None</code> is
still replaced with the default by :class:<code>TimeoutHTTPAdapter</code> on the
mounted adapters, so there is no unbounded read, matching RnetSession where
the client-level timeouts always apply. Pass a large timeout instead.</p>
A per-request non-None <code>timeout=</code> wins. :class:<code>TimeoutHTTPAdapter</code> on the
mounted adapters still replaces an explicit <code>timeout=None</code> with the default,
so there is no unbounded read, as with RnetSession where the client-level
timeouts always apply. Pass a large timeout instead.</p>
@@ -2623,8 +2623,8 @@ the client-level timeouts always apply. Pass a large timeout instead.</p>
<p>HTTPAdapter applying DEFAULT_TIMEOUT when the caller passes none.</p>
<p>Backstops :class:<code>TimeoutSession</code> for the <code>session.send(prepared)</code> path,
which bypasses <code>Session.request</code>; RnetSession bounds those too via its
client, so this keeps parity. A per-request non-None <code>timeout=</code> wins;
which bypasses <code>Session.request</code>. RnetSession bounds those too through its
client, so this keeps parity. A per-request non-None <code>timeout=</code> wins.
<code>None</code> (unset, or explicitly passed) gets the default, because the adapter
cannot distinguish the two, and rnet has no unbounded mode either.</p>
@@ -2775,10 +2775,10 @@ cannot distinguish the two, and rnet has no unbounded mode either.</p>
<p>The Service Base Class.</p>
<p>A Service must implement the abstract methods; the rest are optional overrides that fall back to the base
implementation when a Service does not define them. The main flow runs the session and authentication
methods first, then titles, then tracks and chapters. The license callbacks run later still, during track
download.</p>
<p>A Service must define the abstract methods. The rest are optional overrides that fall back to the base
implementation when a Service does not define them. The main flow operates the HTTP session and
authentication methods first, then titles, then tracks and chapters. The license callbacks operate later
still, during track download.</p>
@@ -3081,8 +3081,8 @@ download.</p>
<p>Services that need separate API calls per codec/range combo can use this
helper from their get_tracks() implementation.</p>
<p>The fetch_fn signature should be: (title, codec, range_) -&gt; Tracks</p>
<p>For HYBRID range, fetch_fn is called with HDR10 and DV separately and
the DV video tracks are merged into the HDR10 result.</p>
<p>For HYBRID range, this helper calls fetch_fn with HDR10 and DV separately,
then merges the DV video tracks into the HDR10 result.</p>
<p><span class="doc-section-title">Parameters:</span></p>
@@ -3105,7 +3105,7 @@ the DV video tracks are merged into the HDR10 result.</p>
</td>
<td>
<div class="doc-md-description">
<p>The title being processed.</p>
<p>The title to process.</p>
</div>
</td>
<td>
@@ -3216,11 +3216,11 @@ the DV video tracks are merged into the HDR10 result.</p>
</span><span id="__span-0-299"><a id="__codelineno-0-299" name="__codelineno-0-299"></a>
</span><span id="__span-0-300"><a id="__codelineno-0-300" name="__codelineno-0-300"></a><span class="sd"> The fetch_fn signature should be: (title, codec, range_) -&gt; Tracks</span>
</span><span id="__span-0-301"><a id="__codelineno-0-301" name="__codelineno-0-301"></a>
</span><span id="__span-0-302"><a id="__codelineno-0-302" name="__codelineno-0-302"></a><span class="sd"> For HYBRID range, fetch_fn is called with HDR10 and DV separately and</span>
</span><span id="__span-0-303"><a id="__codelineno-0-303" name="__codelineno-0-303"></a><span class="sd"> the DV video tracks are merged into the HDR10 result.</span>
</span><span id="__span-0-302"><a id="__codelineno-0-302" name="__codelineno-0-302"></a><span class="sd"> For HYBRID range, this helper calls fetch_fn with HDR10 and DV separately,</span>
</span><span id="__span-0-303"><a id="__codelineno-0-303" name="__codelineno-0-303"></a><span class="sd"> then merges the DV video tracks into the HDR10 result.</span>
</span><span id="__span-0-304"><a id="__codelineno-0-304" name="__codelineno-0-304"></a>
</span><span id="__span-0-305"><a id="__codelineno-0-305" name="__codelineno-0-305"></a><span class="sd"> Args:</span>
</span><span id="__span-0-306"><a id="__codelineno-0-306" name="__codelineno-0-306"></a><span class="sd"> title: The title being processed.</span>
</span><span id="__span-0-306"><a id="__codelineno-0-306" name="__codelineno-0-306"></a><span class="sd"> title: The title to process.</span>
</span><span id="__span-0-307"><a id="__codelineno-0-307" name="__codelineno-0-307"></a><span class="sd"> fetch_fn: A callable that fetches tracks for a specific codec/range.</span>
</span><span id="__span-0-308"><a id="__codelineno-0-308" name="__codelineno-0-308"></a><span class="sd"> """</span>
</span><span id="__span-0-309"><a id="__codelineno-0-309" name="__codelineno-0-309"></a> <span class="n">all_tracks</span> <span class="o">=</span> <span class="n">Tracks</span><span class="p">()</span>
@@ -3298,9 +3298,9 @@ the DV video tracks are merged into the HDR10 result.</p>
<div class="doc doc-contents ">
<p>Creates a Python-requests Session, adds common headers
<p>Creates a Python-requests HTTP session, adds common headers
from config, cookies, retry handler, and a proxy if available.
:returns: Prepared Python-requests Session</p>
:returns: Prepared Python-requests HTTP session</p>
<details class="mkdocstrings-source">
@@ -3340,9 +3340,9 @@ from config, cookies, retry handler, and a proxy if available.
<span class="normal"><a href="#__codelineno-0-397">397</a></span></pre></div></td><td class="code"><div><pre><span></span><code><span id="__span-0-365"><a id="__codelineno-0-365" name="__codelineno-0-365"></a><span class="nd">@staticmethod</span>
</span><span id="__span-0-366"><a id="__codelineno-0-366" name="__codelineno-0-366"></a><span class="k">def</span><span class="w"> </span><span class="nf">get_session</span><span class="p">()</span> <span class="o">-&gt;</span> <span class="n">requests</span><span class="o">.</span><span class="n">Session</span><span class="p">:</span>
</span><span id="__span-0-367"><a id="__codelineno-0-367" name="__codelineno-0-367"></a><span class="w"> </span><span class="sd">"""</span>
</span><span id="__span-0-368"><a id="__codelineno-0-368" name="__codelineno-0-368"></a><span class="sd"> Creates a Python-requests Session, adds common headers</span>
</span><span id="__span-0-368"><a id="__codelineno-0-368" name="__codelineno-0-368"></a><span class="sd"> Creates a Python-requests HTTP session, adds common headers</span>
</span><span id="__span-0-369"><a id="__codelineno-0-369" name="__codelineno-0-369"></a><span class="sd"> from config, cookies, retry handler, and a proxy if available.</span>
</span><span id="__span-0-370"><a id="__codelineno-0-370" name="__codelineno-0-370"></a><span class="sd"> :returns: Prepared Python-requests Session</span>
</span><span id="__span-0-370"><a id="__codelineno-0-370" name="__codelineno-0-370"></a><span class="sd"> :returns: Prepared Python-requests HTTP session</span>
</span><span id="__span-0-371"><a id="__codelineno-0-371" name="__codelineno-0-371"></a><span class="sd"> """</span>
</span><span id="__span-0-372"><a id="__codelineno-0-372" name="__codelineno-0-372"></a> <span class="n">session</span> <span class="o">=</span> <span class="n">TimeoutSession</span><span class="p">()</span>
</span><span id="__span-0-373"><a id="__codelineno-0-373" name="__codelineno-0-373"></a> <span class="n">session</span><span class="o">.</span><span class="n">headers</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="n">config</span><span class="o">.</span><span class="n">headers</span><span class="p">)</span>
@@ -3391,12 +3391,12 @@ from config, cookies, retry handler, and a proxy if available.
<p>Authenticate the Service with Cookies and/or Credentials (Email/Username and Password).</p>
<p>This is effectively a login() function. Any API calls or object initializations
needing to be made, should be made here. This will be run before any of the
following abstract functions.</p>
needing to be made, should be made here. unshackle operates this method before
any of the following abstract functions.</p>
<p>You should avoid storing or using the Credential outside this function.
Make any calls you need for any Cookies, Tokens, or such, then use those.</p>
<p>The Cookie jar should also not be stored outside this function. However, you may load
the Cookie jar into the service session.</p>
<p>Do not store the cookies outside this function either. However, you can load
the cookies into the service HTTP session.</p>
<details class="mkdocstrings-source">
@@ -3426,14 +3426,14 @@ the Cookie jar into the service session.</p>
</span><span id="__span-0-401"><a id="__codelineno-0-401" name="__codelineno-0-401"></a><span class="sd"> Authenticate the Service with Cookies and/or Credentials (Email/Username and Password).</span>
</span><span id="__span-0-402"><a id="__codelineno-0-402" name="__codelineno-0-402"></a>
</span><span id="__span-0-403"><a id="__codelineno-0-403" name="__codelineno-0-403"></a><span class="sd"> This is effectively a login() function. Any API calls or object initializations</span>
</span><span id="__span-0-404"><a id="__codelineno-0-404" name="__codelineno-0-404"></a><span class="sd"> needing to be made, should be made here. This will be run before any of the</span>
</span><span id="__span-0-405"><a id="__codelineno-0-405" name="__codelineno-0-405"></a><span class="sd"> following abstract functions.</span>
</span><span id="__span-0-404"><a id="__codelineno-0-404" name="__codelineno-0-404"></a><span class="sd"> needing to be made, should be made here. unshackle operates this method before</span>
</span><span id="__span-0-405"><a id="__codelineno-0-405" name="__codelineno-0-405"></a><span class="sd"> any of the following abstract functions.</span>
</span><span id="__span-0-406"><a id="__codelineno-0-406" name="__codelineno-0-406"></a>
</span><span id="__span-0-407"><a id="__codelineno-0-407" name="__codelineno-0-407"></a><span class="sd"> You should avoid storing or using the Credential outside this function.</span>
</span><span id="__span-0-408"><a id="__codelineno-0-408" name="__codelineno-0-408"></a><span class="sd"> Make any calls you need for any Cookies, Tokens, or such, then use those.</span>
</span><span id="__span-0-409"><a id="__codelineno-0-409" name="__codelineno-0-409"></a>
</span><span id="__span-0-410"><a id="__codelineno-0-410" name="__codelineno-0-410"></a><span class="sd"> The Cookie jar should also not be stored outside this function. However, you may load</span>
</span><span id="__span-0-411"><a id="__codelineno-0-411" name="__codelineno-0-411"></a><span class="sd"> the Cookie jar into the service session.</span>
</span><span id="__span-0-410"><a id="__codelineno-0-410" name="__codelineno-0-410"></a><span class="sd"> Do not store the cookies outside this function either. However, you can load</span>
</span><span id="__span-0-411"><a id="__codelineno-0-411" name="__codelineno-0-411"></a><span class="sd"> the cookies into the service HTTP session.</span>
</span><span id="__span-0-412"><a id="__codelineno-0-412" name="__codelineno-0-412"></a><span class="sd"> """</span>
</span><span id="__span-0-413"><a id="__codelineno-0-413" name="__codelineno-0-413"></a> <span class="k">if</span> <span class="n">cookies</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
</span><span id="__span-0-414"><a id="__codelineno-0-414" name="__codelineno-0-414"></a> <span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">cookies</span><span class="p">,</span> <span class="n">CookieJar</span><span class="p">):</span>
@@ -3462,7 +3462,7 @@ the Cookie jar into the service session.</p>
<div class="doc doc-contents ">
<p>Request interactive input from the user.</p>
<p>When running locally (CLI), prompts via the shared rich console so the
<p>When running locally (CLI), prompts through the shared rich console so the
prompt renders correctly alongside Live progress / log handlers.
When running in serve mode with an :class:<code>InputBridge</code> attached,
delegates to the bridge which relays the prompt to the remote client.</p>
@@ -3483,7 +3483,7 @@ delegates to the bridge which relays the prompt to the remote client.</p>
<span class="normal"><a href="#__codelineno-0-431">431</a></span></pre></div></td><td class="code"><div><pre><span></span><code><span id="__span-0-421"><a id="__codelineno-0-421" name="__codelineno-0-421"></a><span class="k">def</span><span class="w"> </span><span class="nf">request_input</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">prompt</span><span class="p">:</span> <span class="nb">str</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">str</span><span class="p">:</span>
</span><span id="__span-0-422"><a id="__codelineno-0-422" name="__codelineno-0-422"></a><span class="w"> </span><span class="sd">"""Request interactive input from the user.</span>
</span><span id="__span-0-423"><a id="__codelineno-0-423" name="__codelineno-0-423"></a>
</span><span id="__span-0-424"><a id="__codelineno-0-424" name="__codelineno-0-424"></a><span class="sd"> When running locally (CLI), prompts via the shared rich console so the</span>
</span><span id="__span-0-424"><a id="__codelineno-0-424" name="__codelineno-0-424"></a><span class="sd"> When running locally (CLI), prompts through the shared rich console so the</span>
</span><span id="__span-0-425"><a id="__codelineno-0-425" name="__codelineno-0-425"></a><span class="sd"> prompt renders correctly alongside Live progress / log handlers.</span>
</span><span id="__span-0-426"><a id="__codelineno-0-426" name="__codelineno-0-426"></a><span class="sd"> When running in serve mode with an :class:`InputBridge` attached,</span>
</span><span id="__span-0-427"><a id="__codelineno-0-427" name="__codelineno-0-427"></a><span class="sd"> delegates to the bridge which relays the prompt to the remote client.</span>
@@ -3510,10 +3510,10 @@ delegates to the bridge which relays the prompt to the remote client.</p>
<div class="doc doc-contents ">
<p>Search by query for titles from the Service.</p>
<p>The query must be taken as a CLI argument by the Service class.
Ideally just re-use the title ID argument (i.e. self.title).</p>
<p>Search results will be displayed in the order yielded.</p>
<p>Find titles from the Service by query.</p>
<p>The Service class must take the query as a CLI argument.
Ideally re-use the title ID argument (that is, self.title).</p>
<p>unshackle displays the search results in the order yielded.</p>
<details class="mkdocstrings-source">
@@ -3529,12 +3529,12 @@ Ideally just re-use the title ID argument (i.e. self.title).</p>
<span class="normal"><a href="#__codelineno-0-441">441</a></span>
<span class="normal"><a href="#__codelineno-0-442">442</a></span></pre></div></td><td class="code"><div><pre><span></span><code><span id="__span-0-433"><a id="__codelineno-0-433" name="__codelineno-0-433"></a><span class="k">def</span><span class="w"> </span><span class="nf">search</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">Generator</span><span class="p">[</span><span class="n">SearchResult</span><span class="p">,</span> <span class="kc">None</span><span class="p">,</span> <span class="kc">None</span><span class="p">]:</span>
</span><span id="__span-0-434"><a id="__codelineno-0-434" name="__codelineno-0-434"></a><span class="w"> </span><span class="sd">"""</span>
</span><span id="__span-0-435"><a id="__codelineno-0-435" name="__codelineno-0-435"></a><span class="sd"> Search by query for titles from the Service.</span>
</span><span id="__span-0-435"><a id="__codelineno-0-435" name="__codelineno-0-435"></a><span class="sd"> Find titles from the Service by query.</span>
</span><span id="__span-0-436"><a id="__codelineno-0-436" name="__codelineno-0-436"></a>
</span><span id="__span-0-437"><a id="__codelineno-0-437" name="__codelineno-0-437"></a><span class="sd"> The query must be taken as a CLI argument by the Service class.</span>
</span><span id="__span-0-438"><a id="__codelineno-0-438" name="__codelineno-0-438"></a><span class="sd"> Ideally just re-use the title ID argument (i.e. self.title).</span>
</span><span id="__span-0-437"><a id="__codelineno-0-437" name="__codelineno-0-437"></a><span class="sd"> The Service class must take the query as a CLI argument.</span>
</span><span id="__span-0-438"><a id="__codelineno-0-438" name="__codelineno-0-438"></a><span class="sd"> Ideally re-use the title ID argument (that is, self.title).</span>
</span><span id="__span-0-439"><a id="__codelineno-0-439" name="__codelineno-0-439"></a>
</span><span id="__span-0-440"><a id="__codelineno-0-440" name="__codelineno-0-440"></a><span class="sd"> Search results will be displayed in the order yielded.</span>
</span><span id="__span-0-440"><a id="__codelineno-0-440" name="__codelineno-0-440"></a><span class="sd"> unshackle displays the search results in the order yielded.</span>
</span><span id="__span-0-441"><a id="__codelineno-0-441" name="__codelineno-0-441"></a><span class="sd"> """</span>
</span><span id="__span-0-442"><a id="__codelineno-0-442" name="__codelineno-0-442"></a> <span class="k">raise</span> <span class="ne">NotImplementedError</span><span class="p">(</span><span class="sa">f</span><span class="s2">"Search functionality has not been implemented by </span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="vm">__class__</span><span class="o">.</span><span class="vm">__name__</span><span class="si">}</span><span class="s2">"</span><span class="p">)</span>
</span></code></pre></div></td></tr></table></div>
@@ -3561,10 +3561,10 @@ Ideally just re-use the title ID argument (i.e. self.title).</p>
<p>Get the Widevine Service Certificate used for Privacy Mode.</p>
<p>:param challenge: The service challenge, providing this to a License endpoint should return the
privacy certificate that the service uses.
:param title: The current <code>Title</code> from get_titles that is being executed. This is provided in
case it has data needed to be used, e.g. for a HTTP request.
:param title: The current <code>Title</code> from get_titles that unshackle processes now. unshackle
gives this in case it holds data you need, for example for an HTTP request.
:param track: The current <code>Track</code> needing decryption. Provided for same reason as <code>title</code>.
:return: The Service Privacy Certificate as Bytes or a Base64 string. Don't Base64 Encode or
:return: The Service Privacy Certificate as Bytes or a Base64 string. Do not Base64 Encode or
Decode the data, return as is to reduce unnecessary computations.</p>
@@ -3591,10 +3591,10 @@ Ideally just re-use the title ID argument (i.e. self.title).</p>
</span><span id="__span-0-449"><a id="__codelineno-0-449" name="__codelineno-0-449"></a>
</span><span id="__span-0-450"><a id="__codelineno-0-450" name="__codelineno-0-450"></a><span class="sd"> :param challenge: The service challenge, providing this to a License endpoint should return the</span>
</span><span id="__span-0-451"><a id="__codelineno-0-451" name="__codelineno-0-451"></a><span class="sd"> privacy certificate that the service uses.</span>
</span><span id="__span-0-452"><a id="__codelineno-0-452" name="__codelineno-0-452"></a><span class="sd"> :param title: The current `Title` from get_titles that is being executed. This is provided in</span>
</span><span id="__span-0-453"><a id="__codelineno-0-453" name="__codelineno-0-453"></a><span class="sd"> case it has data needed to be used, e.g. for a HTTP request.</span>
</span><span id="__span-0-452"><a id="__codelineno-0-452" name="__codelineno-0-452"></a><span class="sd"> :param title: The current `Title` from get_titles that unshackle processes now. unshackle</span>
</span><span id="__span-0-453"><a id="__codelineno-0-453" name="__codelineno-0-453"></a><span class="sd"> gives this in case it holds data you need, for example for an HTTP request.</span>
</span><span id="__span-0-454"><a id="__codelineno-0-454" name="__codelineno-0-454"></a><span class="sd"> :param track: The current `Track` needing decryption. Provided for same reason as `title`.</span>
</span><span id="__span-0-455"><a id="__codelineno-0-455" name="__codelineno-0-455"></a><span class="sd"> :return: The Service Privacy Certificate as Bytes or a Base64 string. Don't Base64 Encode or</span>
</span><span id="__span-0-455"><a id="__codelineno-0-455" name="__codelineno-0-455"></a><span class="sd"> :return: The Service Privacy Certificate as Bytes or a Base64 string. Do not Base64 Encode or</span>
</span><span id="__span-0-456"><a id="__codelineno-0-456" name="__codelineno-0-456"></a><span class="sd"> Decode the data, return as is to reduce unnecessary computations.</span>
</span><span id="__span-0-457"><a id="__codelineno-0-457" name="__codelineno-0-457"></a><span class="sd"> """</span>
</span></code></pre></div></td></tr></table></div>
@@ -3617,16 +3617,16 @@ Ideally just re-use the title ID argument (i.e. self.title).</p>
<div class="doc doc-contents ">
<p>Get a Widevine License message by sending a License Request (challenge).</p>
<p>This License message contains the encrypted Content Decryption Keys and will be
<p>This License message contains the encrypted content keys and will be
read by the Cdm and decrypted.</p>
<p>This is a very important request to get correct. A bad, unexpected, or missing
value in the request can cause your key to be detected and promptly banned,
revoked, disabled, or downgraded.</p>
value in the request can cause the service to detect your CDM device. The device
can then be banned, revoked, disabled, or downgraded.</p>
<p>:param challenge: The license challenge from the Widevine CDM.
:param title: The current <code>Title</code> from get_titles that is being executed. This is provided in
case it has data needed to be used, e.g. for a HTTP request.
:param title: The current <code>Title</code> from get_titles that unshackle processes now. unshackle
gives this in case it holds data you need, for example for an HTTP request.
:param track: The current <code>Track</code> needing decryption. Provided for same reason as <code>title</code>.
:return: The License response as Bytes or a Base64 string. Don't Base64 Encode or
:return: The License response as Bytes or a Base64 string. Do not Base64 Encode or
Decode the data, return as is to reduce unnecessary computations.</p>
@@ -3653,18 +3653,18 @@ revoked, disabled, or downgraded.</p>
</span><span id="__span-0-460"><a id="__codelineno-0-460" name="__codelineno-0-460"></a><span class="w"> </span><span class="sd">"""</span>
</span><span id="__span-0-461"><a id="__codelineno-0-461" name="__codelineno-0-461"></a><span class="sd"> Get a Widevine License message by sending a License Request (challenge).</span>
</span><span id="__span-0-462"><a id="__codelineno-0-462" name="__codelineno-0-462"></a>
</span><span id="__span-0-463"><a id="__codelineno-0-463" name="__codelineno-0-463"></a><span class="sd"> This License message contains the encrypted Content Decryption Keys and will be</span>
</span><span id="__span-0-463"><a id="__codelineno-0-463" name="__codelineno-0-463"></a><span class="sd"> This License message contains the encrypted content keys and will be</span>
</span><span id="__span-0-464"><a id="__codelineno-0-464" name="__codelineno-0-464"></a><span class="sd"> read by the Cdm and decrypted.</span>
</span><span id="__span-0-465"><a id="__codelineno-0-465" name="__codelineno-0-465"></a>
</span><span id="__span-0-466"><a id="__codelineno-0-466" name="__codelineno-0-466"></a><span class="sd"> This is a very important request to get correct. A bad, unexpected, or missing</span>
</span><span id="__span-0-467"><a id="__codelineno-0-467" name="__codelineno-0-467"></a><span class="sd"> value in the request can cause your key to be detected and promptly banned,</span>
</span><span id="__span-0-468"><a id="__codelineno-0-468" name="__codelineno-0-468"></a><span class="sd"> revoked, disabled, or downgraded.</span>
</span><span id="__span-0-467"><a id="__codelineno-0-467" name="__codelineno-0-467"></a><span class="sd"> value in the request can cause the service to detect your CDM device. The device</span>
</span><span id="__span-0-468"><a id="__codelineno-0-468" name="__codelineno-0-468"></a><span class="sd"> can then be banned, revoked, disabled, or downgraded.</span>
</span><span id="__span-0-469"><a id="__codelineno-0-469" name="__codelineno-0-469"></a>
</span><span id="__span-0-470"><a id="__codelineno-0-470" name="__codelineno-0-470"></a><span class="sd"> :param challenge: The license challenge from the Widevine CDM.</span>
</span><span id="__span-0-471"><a id="__codelineno-0-471" name="__codelineno-0-471"></a><span class="sd"> :param title: The current `Title` from get_titles that is being executed. This is provided in</span>
</span><span id="__span-0-472"><a id="__codelineno-0-472" name="__codelineno-0-472"></a><span class="sd"> case it has data needed to be used, e.g. for a HTTP request.</span>
</span><span id="__span-0-471"><a id="__codelineno-0-471" name="__codelineno-0-471"></a><span class="sd"> :param title: The current `Title` from get_titles that unshackle processes now. unshackle</span>
</span><span id="__span-0-472"><a id="__codelineno-0-472" name="__codelineno-0-472"></a><span class="sd"> gives this in case it holds data you need, for example for an HTTP request.</span>
</span><span id="__span-0-473"><a id="__codelineno-0-473" name="__codelineno-0-473"></a><span class="sd"> :param track: The current `Track` needing decryption. Provided for same reason as `title`.</span>
</span><span id="__span-0-474"><a id="__codelineno-0-474" name="__codelineno-0-474"></a><span class="sd"> :return: The License response as Bytes or a Base64 string. Don't Base64 Encode or</span>
</span><span id="__span-0-474"><a id="__codelineno-0-474" name="__codelineno-0-474"></a><span class="sd"> :return: The License response as Bytes or a Base64 string. Do not Base64 Encode or</span>
</span><span id="__span-0-475"><a id="__codelineno-0-475" name="__codelineno-0-475"></a><span class="sd"> Decode the data, return as is to reduce unnecessary computations.</span>
</span><span id="__span-0-476"><a id="__codelineno-0-476" name="__codelineno-0-476"></a><span class="sd"> """</span>
</span></code></pre></div></td></tr></table></div>
@@ -3687,16 +3687,16 @@ revoked, disabled, or downgraded.</p>
<div class="doc doc-contents ">
<p>Get a PlayReady License message by sending a License Request (challenge).</p>
<p>This License message contains the encrypted Content Decryption Keys and will be
<p>This License message contains the encrypted content keys and will be
read by the CDM and decrypted.</p>
<p>This is a very important request to get correct. A bad, unexpected, or missing
value in the request can cause your key to be detected and promptly banned,
revoked, disabled, or downgraded.</p>
value in the request can cause the service to detect your CDM device. The device
can then be banned, revoked, disabled, or downgraded.</p>
<p>:param challenge: The license challenge from the PlayReady CDM.
:param title: The current <code>Title</code> from get_titles that is being executed. This is provided in
case it has data needed to be used, e.g. for a HTTP request.
:param title: The current <code>Title</code> from get_titles that unshackle processes now. unshackle
gives this in case it holds data you need, for example for an HTTP request.
:param track: The current <code>Track</code> needing decryption. Provided for same reason as <code>title</code>.
:return: The License response as Bytes or a Base64 string. Don't Base64 Encode or
:return: The License response as Bytes or a Base64 string. Do not Base64 Encode or
Decode the data, return as is to reduce unnecessary computations.</p>
@@ -3729,18 +3729,18 @@ revoked, disabled, or downgraded.</p>
</span><span id="__span-0-481"><a id="__codelineno-0-481" name="__codelineno-0-481"></a><span class="w"> </span><span class="sd">"""</span>
</span><span id="__span-0-482"><a id="__codelineno-0-482" name="__codelineno-0-482"></a><span class="sd"> Get a PlayReady License message by sending a License Request (challenge).</span>
</span><span id="__span-0-483"><a id="__codelineno-0-483" name="__codelineno-0-483"></a>
</span><span id="__span-0-484"><a id="__codelineno-0-484" name="__codelineno-0-484"></a><span class="sd"> This License message contains the encrypted Content Decryption Keys and will be</span>
</span><span id="__span-0-484"><a id="__codelineno-0-484" name="__codelineno-0-484"></a><span class="sd"> This License message contains the encrypted content keys and will be</span>
</span><span id="__span-0-485"><a id="__codelineno-0-485" name="__codelineno-0-485"></a><span class="sd"> read by the CDM and decrypted.</span>
</span><span id="__span-0-486"><a id="__codelineno-0-486" name="__codelineno-0-486"></a>
</span><span id="__span-0-487"><a id="__codelineno-0-487" name="__codelineno-0-487"></a><span class="sd"> This is a very important request to get correct. A bad, unexpected, or missing</span>
</span><span id="__span-0-488"><a id="__codelineno-0-488" name="__codelineno-0-488"></a><span class="sd"> value in the request can cause your key to be detected and promptly banned,</span>
</span><span id="__span-0-489"><a id="__codelineno-0-489" name="__codelineno-0-489"></a><span class="sd"> revoked, disabled, or downgraded.</span>
</span><span id="__span-0-488"><a id="__codelineno-0-488" name="__codelineno-0-488"></a><span class="sd"> value in the request can cause the service to detect your CDM device. The device</span>
</span><span id="__span-0-489"><a id="__codelineno-0-489" name="__codelineno-0-489"></a><span class="sd"> can then be banned, revoked, disabled, or downgraded.</span>
</span><span id="__span-0-490"><a id="__codelineno-0-490" name="__codelineno-0-490"></a>
</span><span id="__span-0-491"><a id="__codelineno-0-491" name="__codelineno-0-491"></a><span class="sd"> :param challenge: The license challenge from the PlayReady CDM.</span>
</span><span id="__span-0-492"><a id="__codelineno-0-492" name="__codelineno-0-492"></a><span class="sd"> :param title: The current `Title` from get_titles that is being executed. This is provided in</span>
</span><span id="__span-0-493"><a id="__codelineno-0-493" name="__codelineno-0-493"></a><span class="sd"> case it has data needed to be used, e.g. for a HTTP request.</span>
</span><span id="__span-0-492"><a id="__codelineno-0-492" name="__codelineno-0-492"></a><span class="sd"> :param title: The current `Title` from get_titles that unshackle processes now. unshackle</span>
</span><span id="__span-0-493"><a id="__codelineno-0-493" name="__codelineno-0-493"></a><span class="sd"> gives this in case it holds data you need, for example for an HTTP request.</span>
</span><span id="__span-0-494"><a id="__codelineno-0-494" name="__codelineno-0-494"></a><span class="sd"> :param track: The current `Track` needing decryption. Provided for same reason as `title`.</span>
</span><span id="__span-0-495"><a id="__codelineno-0-495" name="__codelineno-0-495"></a><span class="sd"> :return: The License response as Bytes or a Base64 string. Don't Base64 Encode or</span>
</span><span id="__span-0-495"><a id="__codelineno-0-495" name="__codelineno-0-495"></a><span class="sd"> :return: The License response as Bytes or a Base64 string. Do not Base64 Encode or</span>
</span><span id="__span-0-496"><a id="__codelineno-0-496" name="__codelineno-0-496"></a><span class="sd"> Decode the data, return as is to reduce unnecessary computations.</span>
</span><span id="__span-0-497"><a id="__codelineno-0-497" name="__codelineno-0-497"></a><span class="sd"> """</span>
</span><span id="__span-0-498"><a id="__codelineno-0-498" name="__codelineno-0-498"></a> <span class="c1"># Delegates license handling to the Widevine license method by default if a service-specific PlayReady implementation is not provided.</span>
@@ -3765,12 +3765,12 @@ revoked, disabled, or downgraded.</p>
<div class="doc doc-contents ">
<p>Get a W3C ClearKey License (JWK Set) by sending a License Request (challenge).</p>
<p>Used for DASH <code>org.w3.clearkey</code> content. No CDM is involved: the challenge is
<p>Used for DASH <code>org.w3.clearkey</code> tracks. unshackle uses no CDM here: the challenge is
the W3C EME JSON license request, e.g. <code>{"kids": ["&lt;base64url&gt;"], "type": "temporary"}</code>,
and the license is a JWK Set, e.g. <code>{"keys": [{"kty": "oct", "k": "...", "kid": "..."}]}</code>.</p>
<p>:param challenge: The JSON license request bytes to POST to the license server.
:param title: The current <code>Title</code> from get_titles that is being executed. This is provided in
case it has data needed to be used, e.g. for a HTTP request.
:param title: The current <code>Title</code> from get_titles that unshackle processes now. unshackle
gives this in case it holds data you need, for example for an HTTP request.
:param track: The current <code>Track</code> needing decryption. Provided for same reason as <code>title</code>.
:return: The JWK Set license as a dict, JSON str, or raw bytes. Return None (the default)
to let the framework POST the challenge to the manifest-provided Laurl, if any.
@@ -3805,13 +3805,13 @@ and the license is a JWK Set, e.g. <code>{"keys": [{"kty": "oct", "k": "...", "k
</span><span id="__span-0-504"><a id="__codelineno-0-504" name="__codelineno-0-504"></a><span class="w"> </span><span class="sd">"""</span>
</span><span id="__span-0-505"><a id="__codelineno-0-505" name="__codelineno-0-505"></a><span class="sd"> Get a W3C ClearKey License (JWK Set) by sending a License Request (challenge).</span>
</span><span id="__span-0-506"><a id="__codelineno-0-506" name="__codelineno-0-506"></a>
</span><span id="__span-0-507"><a id="__codelineno-0-507" name="__codelineno-0-507"></a><span class="sd"> Used for DASH `org.w3.clearkey` content. No CDM is involved: the challenge is</span>
</span><span id="__span-0-507"><a id="__codelineno-0-507" name="__codelineno-0-507"></a><span class="sd"> Used for DASH `org.w3.clearkey` tracks. unshackle uses no CDM here: the challenge is</span>
</span><span id="__span-0-508"><a id="__codelineno-0-508" name="__codelineno-0-508"></a><span class="sd"> the W3C EME JSON license request, e.g. ``{"kids": ["&lt;base64url&gt;"], "type": "temporary"}``,</span>
</span><span id="__span-0-509"><a id="__codelineno-0-509" name="__codelineno-0-509"></a><span class="sd"> and the license is a JWK Set, e.g. ``{"keys": [{"kty": "oct", "k": "...", "kid": "..."}]}``.</span>
</span><span id="__span-0-510"><a id="__codelineno-0-510" name="__codelineno-0-510"></a>
</span><span id="__span-0-511"><a id="__codelineno-0-511" name="__codelineno-0-511"></a><span class="sd"> :param challenge: The JSON license request bytes to POST to the license server.</span>
</span><span id="__span-0-512"><a id="__codelineno-0-512" name="__codelineno-0-512"></a><span class="sd"> :param title: The current `Title` from get_titles that is being executed. This is provided in</span>
</span><span id="__span-0-513"><a id="__codelineno-0-513" name="__codelineno-0-513"></a><span class="sd"> case it has data needed to be used, e.g. for a HTTP request.</span>
</span><span id="__span-0-512"><a id="__codelineno-0-512" name="__codelineno-0-512"></a><span class="sd"> :param title: The current `Title` from get_titles that unshackle processes now. unshackle</span>
</span><span id="__span-0-513"><a id="__codelineno-0-513" name="__codelineno-0-513"></a><span class="sd"> gives this in case it holds data you need, for example for an HTTP request.</span>
</span><span id="__span-0-514"><a id="__codelineno-0-514" name="__codelineno-0-514"></a><span class="sd"> :param track: The current `Track` needing decryption. Provided for same reason as `title`.</span>
</span><span id="__span-0-515"><a id="__codelineno-0-515" name="__codelineno-0-515"></a><span class="sd"> :return: The JWK Set license as a dict, JSON str, or raw bytes. Return None (the default)</span>
</span><span id="__span-0-516"><a id="__codelineno-0-516" name="__codelineno-0-516"></a><span class="sd"> to let the framework POST the challenge to the manifest-provided Laurl, if any.</span>
@@ -3845,10 +3845,10 @@ and the license is a JWK Set, e.g. <code>{"keys": [{"kty": "oct", "k": "...", "k
<p>Get Titles for the provided title ID.</p>
<p>Return a Movies, Series, or Album objects containing Movie, Episode, or Song title objects respectively.
The returned data must be for the given title ID, or a spawn of the title ID.</p>
<p>At least one object is expected to be returned, or it will presume an invalid Title ID was
provided.</p>
<p>You must return at least one object. If you do not, unshackle presumes an invalid
Title ID.</p>
<p>You can use the <code>data</code> dictionary class instance attribute of each Title to store data you may need later on.
This can be useful to store information on each title that will be required like any sub-asset IDs, or such.</p>
This can be useful to store information on each title that you need later, like any sub-asset IDs, or such.</p>
<details class="mkdocstrings-source">
@@ -3874,11 +3874,11 @@ This can be useful to store information on each title that will be required like
</span><span id="__span-0-527"><a id="__codelineno-0-527" name="__codelineno-0-527"></a><span class="sd"> Return a Movies, Series, or Album objects containing Movie, Episode, or Song title objects respectively.</span>
</span><span id="__span-0-528"><a id="__codelineno-0-528" name="__codelineno-0-528"></a><span class="sd"> The returned data must be for the given title ID, or a spawn of the title ID.</span>
</span><span id="__span-0-529"><a id="__codelineno-0-529" name="__codelineno-0-529"></a>
</span><span id="__span-0-530"><a id="__codelineno-0-530" name="__codelineno-0-530"></a><span class="sd"> At least one object is expected to be returned, or it will presume an invalid Title ID was</span>
</span><span id="__span-0-531"><a id="__codelineno-0-531" name="__codelineno-0-531"></a><span class="sd"> provided.</span>
</span><span id="__span-0-530"><a id="__codelineno-0-530" name="__codelineno-0-530"></a><span class="sd"> You must return at least one object. If you do not, unshackle presumes an invalid</span>
</span><span id="__span-0-531"><a id="__codelineno-0-531" name="__codelineno-0-531"></a><span class="sd"> Title ID.</span>
</span><span id="__span-0-532"><a id="__codelineno-0-532" name="__codelineno-0-532"></a>
</span><span id="__span-0-533"><a id="__codelineno-0-533" name="__codelineno-0-533"></a><span class="sd"> You can use the `data` dictionary class instance attribute of each Title to store data you may need later on.</span>
</span><span id="__span-0-534"><a id="__codelineno-0-534" name="__codelineno-0-534"></a><span class="sd"> This can be useful to store information on each title that will be required like any sub-asset IDs, or such.</span>
</span><span id="__span-0-534"><a id="__codelineno-0-534" name="__codelineno-0-534"></a><span class="sd"> This can be useful to store information on each title that you need later, like any sub-asset IDs, or such.</span>
</span><span id="__span-0-535"><a id="__codelineno-0-535" name="__codelineno-0-535"></a><span class="sd"> """</span>
</span></code></pre></div></td></tr></table></div>
</details>
@@ -4116,21 +4116,21 @@ title cache so config edits take effect without a cache reset, and before any
<p>Get Track objects of the Title.</p>
<p>Return a Tracks object, which itself can contain Video, Audio, Subtitle or even Chapters.
Tracks.videos, Tracks.audio, Tracks.subtitles, and Track.chapters should be a List of Track objects.</p>
<p>Each Track in the Tracks should represent a Video/Audio Stream/Representation/Adaptation or
a Subtitle file.</p>
<p>While one Track should only hold information for one stream/downloadable, try to get as many
unique Track objects per stream type so Stream selection by the root code can give you more
options in terms of Resolution, Bitrate, Codecs, Language, e.t.c.</p>
<p>Each Track in the Tracks should represent a Video/Audio track, Representation, or
Adaptation, or a Subtitle file.</p>
<p>While one Track should only hold information for one downloadable track, try to get as many
unique Track objects per track type so track selection by the root code can give you more
options in terms of Resolution, Bitrate, Codecs, Language, and such.</p>
<p>No decision making or filtering of which Tracks get returned should happen here. It can be
considered an error to filter for e.g. resolution, codec, and such. All filtering based on
arguments will be done by the root code automatically when needed.</p>
<p>Make sure you correctly mark which Tracks are encrypted or not, and by which DRM System
via its <code>drm</code> property.</p>
<p>If you are able to obtain the Track's KID (Key ID) as a 32 char (16 bit) HEX string, provide
it to the Track's <code>kid</code> variable as it will speed up the decryption process later on. It may
or may not be needed, that depends on the service. Generally if you can provide it, without
downloading any of the Track's stream data, then do.</p>
<p>:param title: The current <code>Title</code> from get_titles that is being executed.
<p>Make sure you correctly mark which Tracks have encryption, and which DRM System they
use, with the <code>drm</code> property.</p>
<p>If you can get the Track's KID (Key ID) as a 32 char (16 bit) HEX string, give it to the
Track's <code>kid</code> variable, as it will speed up the decryption process later on. The service
decides whether it is necessary. Generally if you can give it, without downloading any of
the Track's media data, then do.</p>
<p>:param title: The current <code>Title</code> from get_titles that unshackle processes now.
:return: Tracks object containing Video, Audio, Subtitles, and Chapters, if available.</p>
@@ -4173,26 +4173,26 @@ downloading any of the Track's stream data, then do.</p>
</span><span id="__span-0-596"><a id="__codelineno-0-596" name="__codelineno-0-596"></a><span class="sd"> Return a Tracks object, which itself can contain Video, Audio, Subtitle or even Chapters.</span>
</span><span id="__span-0-597"><a id="__codelineno-0-597" name="__codelineno-0-597"></a><span class="sd"> Tracks.videos, Tracks.audio, Tracks.subtitles, and Track.chapters should be a List of Track objects.</span>
</span><span id="__span-0-598"><a id="__codelineno-0-598" name="__codelineno-0-598"></a>
</span><span id="__span-0-599"><a id="__codelineno-0-599" name="__codelineno-0-599"></a><span class="sd"> Each Track in the Tracks should represent a Video/Audio Stream/Representation/Adaptation or</span>
</span><span id="__span-0-600"><a id="__codelineno-0-600" name="__codelineno-0-600"></a><span class="sd"> a Subtitle file.</span>
</span><span id="__span-0-599"><a id="__codelineno-0-599" name="__codelineno-0-599"></a><span class="sd"> Each Track in the Tracks should represent a Video/Audio track, Representation, or</span>
</span><span id="__span-0-600"><a id="__codelineno-0-600" name="__codelineno-0-600"></a><span class="sd"> Adaptation, or a Subtitle file.</span>
</span><span id="__span-0-601"><a id="__codelineno-0-601" name="__codelineno-0-601"></a>
</span><span id="__span-0-602"><a id="__codelineno-0-602" name="__codelineno-0-602"></a><span class="sd"> While one Track should only hold information for one stream/downloadable, try to get as many</span>
</span><span id="__span-0-603"><a id="__codelineno-0-603" name="__codelineno-0-603"></a><span class="sd"> unique Track objects per stream type so Stream selection by the root code can give you more</span>
</span><span id="__span-0-604"><a id="__codelineno-0-604" name="__codelineno-0-604"></a><span class="sd"> options in terms of Resolution, Bitrate, Codecs, Language, e.t.c.</span>
</span><span id="__span-0-602"><a id="__codelineno-0-602" name="__codelineno-0-602"></a><span class="sd"> While one Track should only hold information for one downloadable track, try to get as many</span>
</span><span id="__span-0-603"><a id="__codelineno-0-603" name="__codelineno-0-603"></a><span class="sd"> unique Track objects per track type so track selection by the root code can give you more</span>
</span><span id="__span-0-604"><a id="__codelineno-0-604" name="__codelineno-0-604"></a><span class="sd"> options in terms of Resolution, Bitrate, Codecs, Language, and such.</span>
</span><span id="__span-0-605"><a id="__codelineno-0-605" name="__codelineno-0-605"></a>
</span><span id="__span-0-606"><a id="__codelineno-0-606" name="__codelineno-0-606"></a><span class="sd"> No decision making or filtering of which Tracks get returned should happen here. It can be</span>
</span><span id="__span-0-607"><a id="__codelineno-0-607" name="__codelineno-0-607"></a><span class="sd"> considered an error to filter for e.g. resolution, codec, and such. All filtering based on</span>
</span><span id="__span-0-608"><a id="__codelineno-0-608" name="__codelineno-0-608"></a><span class="sd"> arguments will be done by the root code automatically when needed.</span>
</span><span id="__span-0-609"><a id="__codelineno-0-609" name="__codelineno-0-609"></a>
</span><span id="__span-0-610"><a id="__codelineno-0-610" name="__codelineno-0-610"></a><span class="sd"> Make sure you correctly mark which Tracks are encrypted or not, and by which DRM System</span>
</span><span id="__span-0-611"><a id="__codelineno-0-611" name="__codelineno-0-611"></a><span class="sd"> via its `drm` property.</span>
</span><span id="__span-0-610"><a id="__codelineno-0-610" name="__codelineno-0-610"></a><span class="sd"> Make sure you correctly mark which Tracks have encryption, and which DRM System they</span>
</span><span id="__span-0-611"><a id="__codelineno-0-611" name="__codelineno-0-611"></a><span class="sd"> use, with the `drm` property.</span>
</span><span id="__span-0-612"><a id="__codelineno-0-612" name="__codelineno-0-612"></a>
</span><span id="__span-0-613"><a id="__codelineno-0-613" name="__codelineno-0-613"></a><span class="sd"> If you are able to obtain the Track's KID (Key ID) as a 32 char (16 bit) HEX string, provide</span>
</span><span id="__span-0-614"><a id="__codelineno-0-614" name="__codelineno-0-614"></a><span class="sd"> it to the Track's `kid` variable as it will speed up the decryption process later on. It may</span>
</span><span id="__span-0-615"><a id="__codelineno-0-615" name="__codelineno-0-615"></a><span class="sd"> or may not be needed, that depends on the service. Generally if you can provide it, without</span>
</span><span id="__span-0-616"><a id="__codelineno-0-616" name="__codelineno-0-616"></a><span class="sd"> downloading any of the Track's stream data, then do.</span>
</span><span id="__span-0-613"><a id="__codelineno-0-613" name="__codelineno-0-613"></a><span class="sd"> If you can get the Track's KID (Key ID) as a 32 char (16 bit) HEX string, give it to the</span>
</span><span id="__span-0-614"><a id="__codelineno-0-614" name="__codelineno-0-614"></a><span class="sd"> Track's `kid` variable, as it will speed up the decryption process later on. The service</span>
</span><span id="__span-0-615"><a id="__codelineno-0-615" name="__codelineno-0-615"></a><span class="sd"> decides whether it is necessary. Generally if you can give it, without downloading any of</span>
</span><span id="__span-0-616"><a id="__codelineno-0-616" name="__codelineno-0-616"></a><span class="sd"> the Track's media data, then do.</span>
</span><span id="__span-0-617"><a id="__codelineno-0-617" name="__codelineno-0-617"></a>
</span><span id="__span-0-618"><a id="__codelineno-0-618" name="__codelineno-0-618"></a><span class="sd"> :param title: The current `Title` from get_titles that is being executed.</span>
</span><span id="__span-0-618"><a id="__codelineno-0-618" name="__codelineno-0-618"></a><span class="sd"> :param title: The current `Title` from get_titles that unshackle processes now.</span>
</span><span id="__span-0-619"><a id="__codelineno-0-619" name="__codelineno-0-619"></a><span class="sd"> :return: Tracks object containing Video, Audio, Subtitles, and Chapters, if available.</span>
</span><span id="__span-0-620"><a id="__codelineno-0-620" name="__codelineno-0-620"></a><span class="sd"> """</span>
</span></code></pre></div></td></tr></table></div>
@@ -4241,7 +4241,7 @@ downloading any of the Track's stream data, then do.</p>
</td>
<td>
<div class="doc-md-description">
<p>The current Title from <code>get_titles</code> that is being processed.</p>
<p>The current Title from <code>get_titles</code> that unshackle processes now.</p>
</div>
</td>
<td>
@@ -4252,7 +4252,7 @@ downloading any of the Track's stream data, then do.</p>
</table>
<p>You must return a Chapters object containing 0 or more Chapter objects.</p>
<p>You do not need to set a Chapter number or sort/order the chapters in any way as
the Chapters class automatically handles all of that for you. If there's no
the Chapters class automatically handles all of that for you. If there is no
descriptive name for a Chapter then do not set a name at all.</p>
<p>You must not set Chapter names to "Chapter {n}" or such. If you (or the user)
wants "Chapter {n}" style Chapter names (or similar) then they can use the config
@@ -4284,12 +4284,12 @@ option <code>chapter_fallback_name</code>. For example, <code>"Chapter {i:02}"</
</span><span id="__span-0-625"><a id="__codelineno-0-625" name="__codelineno-0-625"></a><span class="sd"> Get Chapters for the Title.</span>
</span><span id="__span-0-626"><a id="__codelineno-0-626" name="__codelineno-0-626"></a>
</span><span id="__span-0-627"><a id="__codelineno-0-627" name="__codelineno-0-627"></a><span class="sd"> Parameters:</span>
</span><span id="__span-0-628"><a id="__codelineno-0-628" name="__codelineno-0-628"></a><span class="sd"> title: The current Title from `get_titles` that is being processed.</span>
</span><span id="__span-0-628"><a id="__codelineno-0-628" name="__codelineno-0-628"></a><span class="sd"> title: The current Title from `get_titles` that unshackle processes now.</span>
</span><span id="__span-0-629"><a id="__codelineno-0-629" name="__codelineno-0-629"></a>
</span><span id="__span-0-630"><a id="__codelineno-0-630" name="__codelineno-0-630"></a><span class="sd"> You must return a Chapters object containing 0 or more Chapter objects.</span>
</span><span id="__span-0-631"><a id="__codelineno-0-631" name="__codelineno-0-631"></a>
</span><span id="__span-0-632"><a id="__codelineno-0-632" name="__codelineno-0-632"></a><span class="sd"> You do not need to set a Chapter number or sort/order the chapters in any way as</span>
</span><span id="__span-0-633"><a id="__codelineno-0-633" name="__codelineno-0-633"></a><span class="sd"> the Chapters class automatically handles all of that for you. If there's no</span>
</span><span id="__span-0-633"><a id="__codelineno-0-633" name="__codelineno-0-633"></a><span class="sd"> the Chapters class automatically handles all of that for you. If there is no</span>
</span><span id="__span-0-634"><a id="__codelineno-0-634" name="__codelineno-0-634"></a><span class="sd"> descriptive name for a Chapter then do not set a name at all.</span>
</span><span id="__span-0-635"><a id="__codelineno-0-635" name="__codelineno-0-635"></a>
</span><span id="__span-0-636"><a id="__codelineno-0-636" name="__codelineno-0-636"></a><span class="sd"> You must not set Chapter names to "Chapter {n}" or such. If you (or the user)</span>
@@ -4354,7 +4354,7 @@ option <code>chapter_fallback_name</code>. For example, <code>"Chapter {i:02}"</
</td>
<td>
<div class="doc-md-description">
<p>The Path to the Segment that was downloaded.</p>
<p>The Path to the downloaded Segment.</p>
</div>
</td>
<td>
@@ -4380,7 +4380,7 @@ option <code>chapter_fallback_name</code>. For example, <code>"Chapter {i:02}"</
</span><span id="__span-0-646"><a id="__codelineno-0-646" name="__codelineno-0-646"></a>
</span><span id="__span-0-647"><a id="__codelineno-0-647" name="__codelineno-0-647"></a><span class="sd"> Parameters:</span>
</span><span id="__span-0-648"><a id="__codelineno-0-648" name="__codelineno-0-648"></a><span class="sd"> track: The Track object that had a Segment downloaded.</span>
</span><span id="__span-0-649"><a id="__codelineno-0-649" name="__codelineno-0-649"></a><span class="sd"> segment: The Path to the Segment that was downloaded.</span>
</span><span id="__span-0-649"><a id="__codelineno-0-649" name="__codelineno-0-649"></a><span class="sd"> segment: The Path to the downloaded Segment.</span>
</span><span id="__span-0-650"><a id="__codelineno-0-650" name="__codelineno-0-650"></a><span class="sd"> """</span>
</span></code></pre></div></td></tr></table></div>
</details>
@@ -4424,7 +4424,7 @@ option <code>chapter_fallback_name</code>. For example, <code>"Chapter {i:02}"</
</td>
<td>
<div class="doc-md-description">
<p>The Track object that was downloaded.</p>
<p>The downloaded Track object.</p>
</div>
</td>
<td>
@@ -4448,7 +4448,7 @@ option <code>chapter_fallback_name</code>. For example, <code>"Chapter {i:02}"</
</span><span id="__span-0-654"><a id="__codelineno-0-654" name="__codelineno-0-654"></a><span class="sd"> Called when a Track has finished downloading.</span>
</span><span id="__span-0-655"><a id="__codelineno-0-655" name="__codelineno-0-655"></a>
</span><span id="__span-0-656"><a id="__codelineno-0-656" name="__codelineno-0-656"></a><span class="sd"> Parameters:</span>
</span><span id="__span-0-657"><a id="__codelineno-0-657" name="__codelineno-0-657"></a><span class="sd"> track: The Track object that was downloaded.</span>
</span><span id="__span-0-657"><a id="__codelineno-0-657" name="__codelineno-0-657"></a><span class="sd"> track: The downloaded Track object.</span>
</span><span id="__span-0-658"><a id="__codelineno-0-658" name="__codelineno-0-658"></a><span class="sd"> """</span>
</span></code></pre></div></td></tr></table></div>
</details>
@@ -4492,7 +4492,7 @@ option <code>chapter_fallback_name</code>. For example, <code>"Chapter {i:02}"</
</td>
<td>
<div class="doc-md-description">
<p>The Track object that was decrypted.</p>
<p>The decrypted Track object.</p>
</div>
</td>
<td>
@@ -4524,7 +4524,7 @@ option <code>chapter_fallback_name</code>. For example, <code>"Chapter {i:02}"</
</td>
<td>
<div class="doc-md-description">
<p>The HLS segment information that was decrypted.</p>
<p>The decrypted HLS segment information.</p>
</div>
</td>
<td>
@@ -4550,9 +4550,9 @@ option <code>chapter_fallback_name</code>. For example, <code>"Chapter {i:02}"</
</span><span id="__span-0-662"><a id="__codelineno-0-662" name="__codelineno-0-662"></a><span class="sd"> Called when a Track has finished decrypting.</span>
</span><span id="__span-0-663"><a id="__codelineno-0-663" name="__codelineno-0-663"></a>
</span><span id="__span-0-664"><a id="__codelineno-0-664" name="__codelineno-0-664"></a><span class="sd"> Parameters:</span>
</span><span id="__span-0-665"><a id="__codelineno-0-665" name="__codelineno-0-665"></a><span class="sd"> track: The Track object that was decrypted.</span>
</span><span id="__span-0-665"><a id="__codelineno-0-665" name="__codelineno-0-665"></a><span class="sd"> track: The decrypted Track object.</span>
</span><span id="__span-0-666"><a id="__codelineno-0-666" name="__codelineno-0-666"></a><span class="sd"> drm: The DRM object it decrypted with.</span>
</span><span id="__span-0-667"><a id="__codelineno-0-667" name="__codelineno-0-667"></a><span class="sd"> segment: The HLS segment information that was decrypted.</span>
</span><span id="__span-0-667"><a id="__codelineno-0-667" name="__codelineno-0-667"></a><span class="sd"> segment: The decrypted HLS segment information.</span>
</span><span id="__span-0-668"><a id="__codelineno-0-668" name="__codelineno-0-668"></a><span class="sd"> """</span>
</span></code></pre></div></td></tr></table></div>
</details>
@@ -4596,7 +4596,7 @@ option <code>chapter_fallback_name</code>. For example, <code>"Chapter {i:02}"</
</td>
<td>
<div class="doc-md-description">
<p>The Track object that was repacked.</p>
<p>The repacked Track object.</p>
</div>
</td>
<td>
@@ -4620,7 +4620,7 @@ option <code>chapter_fallback_name</code>. For example, <code>"Chapter {i:02}"</
</span><span id="__span-0-672"><a id="__codelineno-0-672" name="__codelineno-0-672"></a><span class="sd"> Called when a Track has finished repacking.</span>
</span><span id="__span-0-673"><a id="__codelineno-0-673" name="__codelineno-0-673"></a>
</span><span id="__span-0-674"><a id="__codelineno-0-674" name="__codelineno-0-674"></a><span class="sd"> Parameters:</span>
</span><span id="__span-0-675"><a id="__codelineno-0-675" name="__codelineno-0-675"></a><span class="sd"> track: The Track object that was repacked.</span>
</span><span id="__span-0-675"><a id="__codelineno-0-675" name="__codelineno-0-675"></a><span class="sd"> track: The repacked Track object.</span>
</span><span id="__span-0-676"><a id="__codelineno-0-676" name="__codelineno-0-676"></a><span class="sd"> """</span>
</span></code></pre></div></td></tr></table></div>
</details>
@@ -4641,10 +4641,10 @@ option <code>chapter_fallback_name</code>. For example, <code>"Chapter {i:02}"</
<div class="doc doc-contents ">
<p>Called when a Track is about to be Multiplexed into a Container.</p>
<p>Note: Right now only MKV containers are multiplexed but in the future
this may also be called when multiplexing to other containers like
MP4 via ffmpeg/mp4box.</p>
<p>Called immediately before unshackle multiplexes a Track into a Container.</p>
<p>Note: Right now unshackle multiplexes only MKV containers. In the future
unshackle can also call this when it multiplexes to other containers like
MP4 with FFmpeg/mp4box.</p>
<p><span class="doc-section-title">Parameters:</span></p>
@@ -4667,7 +4667,7 @@ MP4 via ffmpeg/mp4box.</p>
</td>
<td>
<div class="doc-md-description">
<p>The Track object that was repacked.</p>
<p>The repacked Track object.</p>
</div>
</td>
<td>
@@ -4692,14 +4692,14 @@ MP4 via ffmpeg/mp4box.</p>
<span class="normal"><a href="#__codelineno-0-687">687</a></span>
<span class="normal"><a href="#__codelineno-0-688">688</a></span></pre></div></td><td class="code"><div><pre><span></span><code><span id="__span-0-678"><a id="__codelineno-0-678" name="__codelineno-0-678"></a><span class="k">def</span><span class="w"> </span><span class="nf">on_track_multiplex</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">track</span><span class="p">:</span> <span class="n">AnyTrack</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kc">None</span><span class="p">:</span>
</span><span id="__span-0-679"><a id="__codelineno-0-679" name="__codelineno-0-679"></a><span class="w"> </span><span class="sd">"""</span>
</span><span id="__span-0-680"><a id="__codelineno-0-680" name="__codelineno-0-680"></a><span class="sd"> Called when a Track is about to be Multiplexed into a Container.</span>
</span><span id="__span-0-680"><a id="__codelineno-0-680" name="__codelineno-0-680"></a><span class="sd"> Called immediately before unshackle multiplexes a Track into a Container.</span>
</span><span id="__span-0-681"><a id="__codelineno-0-681" name="__codelineno-0-681"></a>
</span><span id="__span-0-682"><a id="__codelineno-0-682" name="__codelineno-0-682"></a><span class="sd"> Note: Right now only MKV containers are multiplexed but in the future</span>
</span><span id="__span-0-683"><a id="__codelineno-0-683" name="__codelineno-0-683"></a><span class="sd"> this may also be called when multiplexing to other containers like</span>
</span><span id="__span-0-684"><a id="__codelineno-0-684" name="__codelineno-0-684"></a><span class="sd"> MP4 via ffmpeg/mp4box.</span>
</span><span id="__span-0-682"><a id="__codelineno-0-682" name="__codelineno-0-682"></a><span class="sd"> Note: Right now unshackle multiplexes only MKV containers. In the future</span>
</span><span id="__span-0-683"><a id="__codelineno-0-683" name="__codelineno-0-683"></a><span class="sd"> unshackle can also call this when it multiplexes to other containers like</span>
</span><span id="__span-0-684"><a id="__codelineno-0-684" name="__codelineno-0-684"></a><span class="sd"> MP4 with FFmpeg/mp4box.</span>
</span><span id="__span-0-685"><a id="__codelineno-0-685" name="__codelineno-0-685"></a>
</span><span id="__span-0-686"><a id="__codelineno-0-686" name="__codelineno-0-686"></a><span class="sd"> Parameters:</span>
</span><span id="__span-0-687"><a id="__codelineno-0-687" name="__codelineno-0-687"></a><span class="sd"> track: The Track object that was repacked.</span>
</span><span id="__span-0-687"><a id="__codelineno-0-687" name="__codelineno-0-687"></a><span class="sd"> track: The repacked Track object.</span>
</span><span id="__span-0-688"><a id="__codelineno-0-688" name="__codelineno-0-688"></a><span class="sd"> """</span>
</span></code></pre></div></td></tr></table></div>
</details>
@@ -4729,7 +4729,7 @@ MP4 via ffmpeg/mp4box.</p>
<div class="doc doc-contents ">
<p>Sanitize a proxy URI for logs by redacting any embedded userinfo (username/password).</p>
<p>Sanitise a proxy URI for logs by redacting any embedded userinfo (username/password).</p>
<p><span class="doc-section-title">Examples:</span></p>
@@ -4779,7 +4779,7 @@ MP4 via ffmpeg/mp4box.</p>
<span class="normal"><a href="#__codelineno-0-136">136</a></span>
<span class="normal"><a href="#__codelineno-0-137">137</a></span></pre></div></td><td class="code"><div><pre><span></span><code><span id="__span-0-101"><a id="__codelineno-0-101" name="__codelineno-0-101"></a><span class="k">def</span><span class="w"> </span><span class="nf">sanitize_proxy_for_log</span><span class="p">(</span><span class="n">uri</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">str</span><span class="p">])</span> <span class="o">-&gt;</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">str</span><span class="p">]:</span>
</span><span id="__span-0-102"><a id="__codelineno-0-102" name="__codelineno-0-102"></a><span class="w"> </span><span class="sd">"""</span>
</span><span id="__span-0-103"><a id="__codelineno-0-103" name="__codelineno-0-103"></a><span class="sd"> Sanitize a proxy URI for logs by redacting any embedded userinfo (username/password).</span>
</span><span id="__span-0-103"><a id="__codelineno-0-103" name="__codelineno-0-103"></a><span class="sd"> Sanitise a proxy URI for logs by redacting any embedded userinfo (username/password).</span>
</span><span id="__span-0-104"><a id="__codelineno-0-104" name="__codelineno-0-104"></a>
</span><span id="__span-0-105"><a id="__codelineno-0-105" name="__codelineno-0-105"></a><span class="sd"> Examples:</span>
</span><span id="__span-0-106"><a id="__codelineno-0-106" name="__codelineno-0-106"></a><span class="sd"> - http://user:pass@host:8080 -&gt; http://REDACTED@host:8080</span>
+2 -2
View File
@@ -2523,7 +2523,7 @@ takes every part. A dated episode also answers to its ISO air date.
<div class="doc doc-contents ">
<p>Season folder label: air year for dated content, else SxxExx-style season.</p>
<p>Season folder label: air year when the air date parsed to a date, else SxxExx-style season.</p>
</div>
@@ -2833,7 +2833,7 @@ takes every part. A dated episode also answers to its ISO air date.
<p>Whether a parsed <code>-w</code> key set selects this song.</p>
<p>A song shares the episode key space, its disc reading as the season and its track
as the episode, so <code>-w 1-5</code> takes tracks 1 to 5 and <code>-w 2x3</code> takes disc 2
track 3. A song has no parts and no air date, so it answers to one key only.</p>
track 3. A song has no parts and no air date, so it answers to its disc-and-track key only.</p>
</div>
+176 -171
View File
@@ -3943,10 +3943,10 @@
<p>Create a new Attachment.</p>
<p>Make a new Attachment.</p>
<p>If providing a path, the file must already exist.
If providing a URL, download() fetches the file during the download phase.
Either path or url must be provided.</p>
You must give either path or url.</p>
<p>If name is not provided it will use the file name (without extension).
If mime_type is not provided, it will try to guess it.</p>
@@ -4051,7 +4051,7 @@ If mime_type is not provided, it will try to guess it.</p>
</td>
<td>
<div class="doc-md-description">
<p>Optional requests session to use for downloading.</p>
<p>Optional requests HTTP session to download the file with.</p>
</div>
</td>
<td>
@@ -4169,7 +4169,7 @@ If mime_type is not provided, it will try to guess it.</p>
<div class="doc doc-contents ">
<p>Create an attachment from a URL.</p>
<p>Make an attachment from a URL.</p>
<p><span class="doc-section-title">Parameters:</span></p>
@@ -4256,7 +4256,7 @@ If mime_type is not provided, it will try to guess it.</p>
</td>
<td>
<div class="doc-md-description">
<p>Optional requests session to use for downloading.</p>
<p>Optional requests HTTP session to download the file with.</p>
</div>
</td>
<td>
@@ -4328,7 +4328,7 @@ If mime_type is not provided, it will try to guess it.</p>
<p>Create a new Audio track object.</p>
<p>Make a new Audio track object.</p>
<p><span class="doc-section-title">Parameters:</span></p>
@@ -4352,8 +4352,8 @@ If mime_type is not provided, it will try to guess it.</p>
<td>
<div class="doc-md-description">
<p>An Audio.Codec enum representing the audio codec.
If not specified, MediaInfo will be used to retrieve the codec
once the track has been downloaded.</p>
If not specified, unshackle uses MediaInfo to get the codec
after it downloads the track.</p>
</div>
</td>
<td>
@@ -4370,7 +4370,7 @@ once the track has been downloaded.</p>
<td>
<div class="doc-md-description">
<p>A number or float representing the average bandwidth in bits/s.
Float values are rounded up to the nearest integer.</p>
unshackle rounds float values up to the nearest integer.</p>
</div>
</td>
<td>
@@ -4404,7 +4404,7 @@ not supported. All numbers and strings will be cast to float.</p>
</td>
<td>
<div class="doc-md-description">
<p>The number of Joint-Object-Coding Channels/Objects in the audio stream.</p>
<p>The number of Joint-Object-Coding Channels/Objects in the audio track.</p>
</div>
</td>
<td>
@@ -4469,7 +4469,7 @@ recommended.</p>
<div class="doc doc-contents ">
<p>Return True if the audio track contains Dolby Atmos.</p>
<p>Return True if the audio track contains Atmos.</p>
</div>
@@ -4495,11 +4495,11 @@ recommended.</p>
<div class="doc doc-contents ">
<p>Converts a Channel string to a float representing audio channel count and layout.
<p>Converts a Channel string to a float representing the audio channel layout.
E.g. "3" -&gt; "3.0", "2.1" -&gt; "2.1", ".1" -&gt; "0.1".</p>
<p>This does not validate channel strings as genuine channel counts or valid layouts.
It does not convert the value to assume a sub speaker channel layout, e.g. 5.1-&gt;6.0.
It also does not support expanded surround sound channel layout strings like 7.1.2.</p>
It also cannot read expanded surround sound channel layout strings like 7.1.2.</p>
</div>
@@ -4550,14 +4550,14 @@ It also does not support expanded surround sound channel layout strings like 7.1
<p>Create a new Chapter with a Timestamp and optional name.</p>
<p>Make a new Chapter with a Timestamp and optional name.</p>
<p>The timestamp may be in the following formats:
- "HH:MM:SS" string, e.g., <code>25:05:23</code>.
- "HH:MM:SS.mss" string, e.g., <code>25:05:23.120</code>.
- a timecode integer in milliseconds, e.g., <code>90323120</code> is <code>25:05:23.120</code>.
- a timecode float in seconds, e.g., <code>90323.12</code> is <code>25:05:23.120</code>.</p>
<p>If you have a timecode integer in seconds, just multiply it by 1000.
If you have a timecode float in milliseconds (no decimal value), just convert
<p>If you have a timecode integer in seconds, multiply it by 1000.
If you have a timecode float in milliseconds (no decimal value), convert
it to an integer.</p>
@@ -4620,7 +4620,7 @@ it to an integer.</p>
<div class="doc doc-contents ">
<p>Check if Chapter is named.</p>
<p>True if the Chapter has a name.</p>
</div>
@@ -4801,7 +4801,7 @@ https://mkvtoolnix.download/doc/mkvmerge.html#mkvmerge.chapters.simple</p>
<li>{j}: A number starting at 1 that increments any time a Chapter has no name.
E.g., <code>"Chapter {j}"</code>: "Chapter 1", "Intro", "Chapter 2".</li>
</ul>
<p>These are formatted with f-strings, directives are supported.
<p>unshackle formats these with f-strings, so format directives work.
For example, <code>"Chapter {i:02}"</code> will result in <code>"Chapter 01"</code>.</p>
@@ -4946,7 +4946,7 @@ If no DV track is available but HDR10+ is present, it will convert HDR10+ to DV.
<div class="doc doc-contents ">
<p>Generate Level 5 active area metadata via crop detection on the HDR10 stream.</p>
<p>Make Level 5 active area metadata through crop detection on the HDR10 track.</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>
@@ -4975,7 +4975,7 @@ by telling the display the correct active area.</p>
<p>Clamp static L6 values to a valid relationship.</p>
<p>MaxCLL must not exceed the mastering-display peak (some HDR10+ sources ship
MaxCLL 10000 on a 1000-nit master), and MaxFALL must not exceed
MaxCLL. A value of 0 means "unknown" and is preserved as-is.</p>
MaxCLL. A value of 0 means "unknown", and this method keeps it as-is.</p>
</div>
@@ -5015,7 +5015,7 @@ MaxCLL. A value of 0 means "unknown" and is preserved as-is.</p>
<div class="doc doc-contents ">
<p>Extract HDR10+ metadata from the video stream</p>
<p>Extract HDR10+ metadata from the video track</p>
</div>
@@ -5035,7 +5035,7 @@ MaxCLL. A value of 0 means "unknown" and is preserved as-is.</p>
<div class="doc doc-contents ">
<p>Extract mastering display and content light level metadata from the HDR10 stream via ffprobe.</p>
<p>Extract mastering display and Content Light Level metadata from the HDR10 track with FFprobe.</p>
<p>Returns (max_mdl, min_mdl, max_cll, max_fall) in dovi_tool level6 units:
- max_mdl: nits (integer)
- min_mdl: 0.0001 nit units (integer)
@@ -5099,7 +5099,7 @@ MaxCLL. A value of 0 means "unknown" and is preserved as-is.</p>
<p>Create a new Subtitle track object.</p>
<p>Make a new Subtitle track object.</p>
<p><span class="doc-section-title">Parameters:</span></p>
@@ -5123,8 +5123,8 @@ MaxCLL. A value of 0 means "unknown" and is preserved as-is.</p>
<td>
<div class="doc-md-description">
<p>A Subtitle.Codec enum representing the subtitle format.
If not specified, MediaInfo will be used to retrieve the format
once the track has been downloaded.</p>
If not specified, unshackle uses MediaInfo to get the format
after it downloads the track.</p>
</div>
</td>
<td>
@@ -5141,18 +5141,18 @@ once the track has been downloaded.</p>
<td>
<div class="doc-md-description">
<p>Closed Caption.
- Intended as if you couldn't hear the audio at all.
- Can have Sound as well as Dialogue, but doesn't have to.
- Original source would be from an EIA-CC encoded stream. Typically all
- Intended as if you could not hear the audio at all.
- Can have Sound as well as Dialogue, but does not have to.
- Original source would be from EIA-CC encoded video. Typically all
upper-case characters.
Indicators of it being CC without knowing original source:
- Extracted with CCExtractor, or
- &gt;&gt;&gt; (or similar) being used at the start of some or all lines, or
- &gt;&gt;&gt; (or similar) at the start of some or all lines, or
- All text is uppercase or at least the majority, or
- Subtitles are Scrolling-text style (one line appears, oldest line
then disappears).
Just because you downloaded it as a SRT or VTT or such, doesn't mean it
isn't from an EIA-CC stream. And I wouldn't take the streaming services
- Subtitles use the scrolling-text style (one line appears, oldest
line then disappears).
The fact that you downloaded it as a SRT or VTT or such does not mean it
is not from an EIA-CC stream. And I would not take the streaming services
(CC) as gospel either as they tend to get it wrong too.</p>
</div>
</td>
@@ -5170,15 +5170,16 @@ Just because you downloaded it as a SRT or VTT or such, doesn't mean it
<td>
<div class="doc-md-description">
<p>Deaf or Hard-of-Hearing. Also known as HOH in the UK (EU?).
- Intended as if you couldn't hear the audio at all.
- MUST have Sound as well as Dialogue to be considered SDH.
- It has no "syntax" or "format" but is not transmitted using archaic
forms like EIA-CC streams, would be intended for transmission via
SubRip (SRT), WebVTT (VTT), TTML, etc.
If you can see important audio/sound transcriptions and not just dialogue
and it doesn't have the indicators of CC, then it's most likely SDH.
If it doesn't have important audio/sounds transcriptions it might just be
regular subtitling (you wouldn't mark as CC or SDH). This would be the
- Intended as if you could not hear the audio at all.
- MUST have Sound as well as Dialogue to count as SDH.
- It has no "syntax" or "format", but it is not transmitted in
archaic forms like EIA-CC streams. It is intended for transmission
through SubRip (SRT), WebVTT (VTT), TTML, and the other modern
subtitle formats.
If you can see important audio/sound transcriptions and not only dialogue
and it does not have the indicators of CC, then it is most likely SDH.
If it does not have important audio/sounds transcriptions it might only be
regular subtitling (you would not mark as CC or SDH). This would be the
case for most translation subtitles. Like Anime for example.</p>
</div>
</td>
@@ -5195,15 +5196,15 @@ Just because you downloaded it as a SRT or VTT or such, doesn't mean it
</td>
<td>
<div class="doc-md-description">
<p>Typically used if there's important information at some point in time
like watching Dubbed content and an important Sign or Letter is shown
<p>Typically used if there is important information at some point in time
like watching a Dubbed title and an important Sign or Letter is shown
or someone talking in a different language.
Forced tracks are recommended by the Matroska Spec to be played if
The Matroska Spec recommends that the player plays Forced tracks if
the player's current playback audio language matches a subtitle
marked as "forced".
However, that doesn't mean every player works like this but there is
However, that does not mean every player works like this but there is
no other way to reliably work with Forced subtitles where multiple
forced subtitles may be in the output file. Just know what to expect
forced subtitles may be in the output file. Know what to expect
with "forced" subtitles.</p>
</div>
</td>
@@ -5213,17 +5214,17 @@ Just because you downloaded it as a SRT or VTT or such, doesn't mean it
</tr>
</tbody>
</table>
<p>Note: If codec is not specified some checks may be skipped or assume a value.
Specifying as much information as possible is highly recommended.</p>
<p>Note: If codec is not specified, unshackle can skip some checks or assume a value.
Give as much information as possible.</p>
<details class="information-on-subtitle-types" open>
<summary>Information on Subtitle Types</summary>
<p>https://bit.ly/2Oe4fLC (3PlayMedia Blog on SUB vs CC vs SDH).
However, I wouldn't pay much attention to the claims about SDH needing to
be in the original source language. It's logically not true.</p>
<p>CC == Closed Captions. Source: Basically every site.
SDH = Subtitles for the Deaf or Hard-of-Hearing. Source: Basically every site.
However, I would not pay much attention to the claims about SDH needing to
be in the original language. It is logically not true.</p>
<p>CC == Closed Captions. Source: Every site.
SDH = Subtitles for the Deaf or Hard-of-Hearing. Source: Every site.
HOH = Exact same as SDH. Is a term used in the UK. Source: https://bit.ly/2PGJatz (ICO UK)</p>
<p>More in-depth information, examples, and stuff to look for can be found in the Parameter
explanation list above.</p>
@@ -5335,7 +5336,7 @@ every cue by it during conversion.</p>
</td>
<td>
<div class="doc-md-description">
<p>The WebVTT content as string</p>
<p>The WebVTT text as string</p>
</div>
</td>
<td>
@@ -5361,7 +5362,7 @@ every cue by it during conversion.</p>
</td>
<td>
<div class="doc-md-description">
<p>Sanitized WebVTT content</p>
<p>Sanitized WebVTT text</p>
</div>
</td>
</tr>
@@ -5390,7 +5391,7 @@ every cue by it during conversion.</p>
<div class="doc doc-contents ">
<p>Check if WebVTT content has cue identifiers that need removal.</p>
<p>Examine WebVTT text for cue identifiers that need removal.</p>
<p><span class="doc-section-title">Parameters:</span></p>
@@ -5413,7 +5414,7 @@ every cue by it during conversion.</p>
</td>
<td>
<div class="doc-md-description">
<p>The WebVTT content as string</p>
<p>The WebVTT text as string</p>
</div>
</td>
<td>
@@ -5439,7 +5440,7 @@ every cue by it during conversion.</p>
</td>
<td>
<div class="doc-md-description">
<p>True if cue identifiers are detected, False otherwise</p>
<p>True if the text has cue identifiers, False otherwise</p>
</div>
</td>
</tr>
@@ -5469,9 +5470,9 @@ every cue by it during conversion.</p>
<div class="doc doc-contents ">
<p>Remove WebVTT cue identifiers that can confuse subtitle parsers.</p>
<p>Some services use cue identifiers like "Q0", "Q1", etc.
<p>Some services use cue identifiers such as "Q0" and "Q1"
that appear on their own line before the timing line. These can be
incorrectly parsed as part of the previous cue's text content by
incorrectly parsed as part of the previous cue's text by
some parsers (like pysubs2).</p>
@@ -5495,7 +5496,7 @@ some parsers (like pysubs2).</p>
</td>
<td>
<div class="doc-md-description">
<p>The WebVTT content as string</p>
<p>The WebVTT text as string</p>
</div>
</td>
<td>
@@ -5521,7 +5522,7 @@ some parsers (like pysubs2).</p>
</td>
<td>
<div class="doc-md-description">
<p>Sanitized WebVTT content with cue identifiers removed</p>
<p>Sanitized WebVTT text with cue identifiers removed</p>
</div>
</td>
</tr>
@@ -5574,7 +5575,7 @@ some parsers (like pysubs2).</p>
<div class="doc doc-contents ">
<p>Check if WebVTT content has overlapping cues that need merging.</p>
<p>Examine WebVTT text for overlapping cues that need merging.</p>
<p>Detects cues with start times within 50ms of each other and the same end time,
which indicates multi-line subtitles split into separate cues.</p>
@@ -5599,7 +5600,7 @@ which indicates multi-line subtitles split into separate cues.</p>
</td>
<td>
<div class="doc-md-description">
<p>The WebVTT content as string</p>
<p>The WebVTT text as string</p>
</div>
</td>
<td>
@@ -5625,7 +5626,7 @@ which indicates multi-line subtitles split into separate cues.</p>
</td>
<td>
<div class="doc-md-description">
<p>True if overlapping cues are detected, False otherwise</p>
<p>True if the text has overlapping cues, False otherwise</p>
</div>
</td>
</tr>
@@ -5681,7 +5682,7 @@ line: position (lower percentage = higher on screen = first line).</p>
</td>
<td>
<div class="doc-md-description">
<p>The WebVTT content as string</p>
<p>The WebVTT text as string</p>
</div>
</td>
<td>
@@ -5707,7 +5708,7 @@ line: position (lower percentage = higher on screen = first line).</p>
</td>
<td>
<div class="doc-md-description">
<p>WebVTT content with overlapping cues merged</p>
<p>WebVTT text with overlapping cues merged</p>
</div>
</td>
</tr>
@@ -5736,10 +5737,11 @@ line: position (lower percentage = higher on screen = first line).</p>
<div class="doc doc-contents ">
<p>More thorough sanitization of WebVTT files to handle multiple potential issues.</p>
<p>This is lossy, so use it only as a fallback once normal parsing has failed. Everything before the
WEBVTT header line is discarded and the header itself is reduced to a bare "WEBVTT" line. Negative
timestamps become 00:00:00.000 and timestamps missing the hours field are padded to HH:MM:SS.mmm.</p>
<p>More thorough sanitization of WebVTT files that corrects multiple potential issues.</p>
<p>This is lossy, so use it only as a fallback once normal parsing has failed. This method discards
everything before the WEBVTT header line and reduces the header itself to a bare "WEBVTT" line.
Negative timestamps become 00:00:00.000, and it pads timestamps that have no hours field to
HH:MM:SS.mmm.</p>
<p><span class="doc-section-title">Parameters:</span></p>
@@ -5762,7 +5764,7 @@ timestamps become 00:00:00.000 and timestamps missing the hours field are padded
</td>
<td>
<div class="doc-md-description">
<p>The WebVTT content as string</p>
<p>The WebVTT text as string</p>
</div>
</td>
<td>
@@ -5788,7 +5790,7 @@ timestamps become 00:00:00.000 and timestamps missing the hours field are padded
</td>
<td>
<div class="doc-md-description">
<p>Sanitized WebVTT content</p>
<p>Sanitized WebVTT text</p>
</div>
</td>
</tr>
@@ -5814,14 +5816,14 @@ timestamps become 00:00:00.000 and timestamps missing the hours field are padded
<div class="doc doc-contents ">
<p>Convert this Subtitle to another format.</p>
<p>Backend selection is data-driven (see <code>tracks/subtitle_convert.py</code>): the best
available backend that supports source-&gt;target is used, falling back through the
capability chain on failure. The backend can be pinned via the <code>conversion_method</code>
config key (<code>auto</code> | <code>subby</code> | <code>pysubs2</code> | <code>subtitleedit</code> | <code>pycaption</code>),
or nudged per-service via <code>preferred_conversion_method</code>; an explicit config value
always wins.</p>
<p><code>forced</code> marks an explicit user request (<code>--sub-format</code>). Lossy downconverts of
styled formats (SSA/ASS -&gt; SRT) are skipped unless <code>forced</code> is True.</p>
<p>Backend selection is data-driven (see <code>tracks/subtitle_convert.py</code>): unshackle
uses the best available backend that can convert source-&gt;target, and falls back
through the capability chain on failure. The <code>conversion_method</code> config key
(<code>auto</code> | <code>subby</code> | <code>pysubs2</code> | <code>subtitleedit</code> | <code>pycaption</code>) pins the
backend, and <code>preferred_conversion_method</code> nudges it per-service. An explicit
config value always wins.</p>
<p><code>forced</code> marks an explicit user request (<code>--sub-format</code>). unshackle skips lossy
downconverts of styled formats (SSA/ASS -&gt; SRT) unless <code>forced</code> is True.</p>
</div>
@@ -5850,8 +5852,8 @@ styled formats (SSA/ASS -&gt; SRT) are skipped unless <code>forced</code> is Tru
- the <code>Fontname</code> column of every <code>Style:</code> line in <code>[V4+ Styles]</code>/<code>[V4 Styles]</code>
(column located from the section's <code>Format:</code> line, not assumed by index), and
- inline <code>\fn</code> font overrides inside <code>Dialogue</code> override blocks.</p>
<p>Leading <code>@</code> (vertical-writing prefix) is stripped and names are de-duplicated
case-insensitively, preferring a mixed-case spelling over an all-lowercase one.</p>
<p>This method removes a leading <code>@</code> (vertical-writing prefix), de-duplicates the
names case-insensitively, and prefers a mixed-case spelling over an all-lowercase one.</p>
</div>
@@ -5898,7 +5900,7 @@ case-insensitively, preferring a mixed-case spelling over an all-lowercase one.<
</td>
<td>
<div class="doc-md-description">
<p>The WebVTT content as string</p>
<p>The WebVTT text as string</p>
</div>
</td>
<td>
@@ -5924,7 +5926,7 @@ case-insensitively, preferring a mixed-case spelling over an all-lowercase one.<
</td>
<td>
<div class="doc-md-description">
<p>Sanitized WebVTT content with corrupted lines removed</p>
<p>Sanitized WebVTT text with corrupted lines removed</p>
</div>
</td>
</tr>
@@ -5956,7 +5958,7 @@ case-insensitively, preferring a mixed-case spelling over an all-lowercase one.<
<p>Space out the WEBVTT Headers from Captions.</p>
<p>Segmented VTT when merged may have the WEBVTT headers part of the next caption
as they were not separated far enough from the previous caption and ended up
being considered as caption text rather than the header for the next segment.</p>
as caption text rather than the header for the next segment.</p>
</div>
@@ -6029,9 +6031,9 @@ being considered as caption text rather than the header for the next segment.</p
<div class="doc doc-contents ">
<p>Convert Segmented DASH WebVTT cues into a pycaption Caption List.
Also returns an ISO 639-2 alpha-3 language code if available.</p>
Also returns an ISO 639-2 alpha-3 language tag if available.</p>
<p>Code ported originally by xhlove to Python from shaka-player.
Has since been improved upon by rlaphoenix using pymp4 and
rlaphoenix has since improved it with pymp4 and
pycaption functions.</p>
@@ -6052,8 +6054,8 @@ pycaption functions.</p>
<div class="doc doc-contents ">
<p>Strip captions for hearing impaired (SDH).</p>
<p>The SDH stripping method is determined by the 'sdh_method' setting in config:
<p>Remove the SDH captions.</p>
<p>The 'sdh_method' setting in config gives the SDH stripping method:
- 'auto' (default): Tries subby first, then SubtitleEdit, then filter-subs
- 'subby': Uses subby's SDHStripper
- 'subtitleedit': Uses SubtitleEdit when available
@@ -6078,7 +6080,7 @@ pycaption functions.</p>
<div class="doc doc-contents ">
<p>Reverse RTL (Right to Left) Start/End on Captions.
This can be used to fix the positioning of sentence-ending characters.</p>
Use this to fix the positioning of sentence-ending characters.</p>
</div>
@@ -6160,7 +6162,7 @@ This can be used to fix the positioning of sentence-ending characters.</p>
<div class="doc doc-contents ">
<p>Return the session, or a new <code>Session</code> if none was set.</p>
<p>Return the HTTP session, or a new <code>Session</code> if none was set.</p>
</div>
@@ -6245,7 +6247,7 @@ This can be used to fix the positioning of sentence-ending characters.</p>
<div class="doc doc-contents ">
<p>Arbitrary track data dictionary.</p>
<p>A defaultdict is used with a dict as the factory for easier
<p>This uses a defaultdict with a dict as the factory for easier
nested saving and safer exists-checks.</p>
<p>Reserved keys:</p>
<ul>
@@ -6262,8 +6264,8 @@ nested saving and safer exists-checks.</p>
<li>segment_durations: list[int] - A list of each segment's duration.</li>
</ul>
<p>You should not add, change, or remove any data within reserved keys.
You may use their data but do note that the values of them may change
or be removed at any point.</p>
You may use their data, but note that these values can change or be removed
at any point.</p>
</div>
@@ -6296,8 +6298,8 @@ or be removed at any point.</p>
<div class="doc doc-contents ">
<p>Download and optionally Decrypt this Track.</p>
<p>A URL-descriptor Video or Audio track with no <code>drm</code> set has its DRM probed from the init data of the
stream and stored on the track, so a service need not declare <code>drm</code> itself.</p>
<p>For a URL-descriptor Video or Audio track with no <code>drm</code> set, unshackle probes the DRM from the
track's init data and stores it on the track, so a service need not declare <code>drm</code> itself.</p>
</div>
@@ -6383,7 +6385,7 @@ This will overwrite anything at the target path.</p>
<div class="doc doc-contents ">
<p>Serialise the track for export/import (identity/URL/descriptor/language).</p>
<p>DRM is not serialised here; the export writer attaches the licensed DRM + keys.
<p>DRM is not serialised here. The export writer attaches the licensed DRM + keys.
Subclasses add their own codec/quality fields.</p>
@@ -6408,7 +6410,7 @@ Subclasses add their own codec/quality fields.</p>
<div class="doc doc-contents ">
<p>Build the shared Track constructor kwargs from a <code>to_dict()</code> payload.</p>
<p>Assemble the shared Track constructor kwargs from a <code>to_dict()</code> payload.</p>
<p>DRM is not reconstructed here: <code>to_dict</code> does not serialise it, and the import
flow attaches the licensed DRM + content keys separately.</p>
@@ -6495,15 +6497,15 @@ flow attaches the licensed DRM + content keys separately.</p>
<div class="doc doc-contents ">
<p>Probe the DRM encryption Key ID (KID) for this specific track.</p>
<p>It currently supports finding the Key ID by probing the track's stream
with ffprobe for <code>enc_key_id</code> data, as well as for mp4 <code>tenc</code> (Track
Encryption) boxes.</p>
<p>It can find the Key ID by probing the track with FFprobe for
<code>enc_key_id</code> data, as well as for mp4 <code>tenc</code> (Track Encryption)
boxes.</p>
<p>It explicitly ignores PSSH information like the <code>PSSH</code> box, as the box
is likely to contain multiple Key IDs that may or may not be for this
specific track.</p>
<p>To retrieve the initialization segment, this method calls :meth:<code>get_init_segment</code>
with the positional and keyword arguments. The return value of <code>get_init_segment</code>
is then used to determine the Key ID.</p>
with the positional and keyword arguments. This method then uses the return value
of <code>get_init_segment</code> to find the Key ID.</p>
<p><span class="doc-section-title">Returns:</span></p>
@@ -6521,7 +6523,7 @@ is then used to determine the Key ID.</p>
</td>
<td>
<div class="doc-md-description">
<p>The Key ID as a UUID object, or None if the Key ID could not be determined.</p>
<p>The Key ID as a UUID object, or None if unshackle cannot find the Key ID.</p>
</div>
</td>
</tr>
@@ -6546,7 +6548,7 @@ is then used to determine the Key ID.</p>
<div class="doc doc-contents ">
<p>Load DRM information for this track if it was deferred during parsing.</p>
<p>Load DRM information for this track if the parser deferred it.</p>
<p><span class="doc-section-title">Parameters:</span></p>
@@ -6595,7 +6597,7 @@ is then used to determine the Key ID.</p>
</td>
<td>
<div class="doc-md-description">
<p>True if DRM was loaded or already present, False if failed</p>
<p>True if the DRM loaded or is already present, False if the load failed</p>
</div>
</td>
</tr>
@@ -6645,11 +6647,11 @@ is then used to determine the Key ID.</p>
<div class="doc doc-contents ">
<p>Get the Track's Initial Segment Data Stream.</p>
<p>HLS and DASH tracks must explicitly provide a URL to the init segment or file.
Providing the byte-range for the init segment is recommended where possible.</p>
<p>If <code>byte_range</code> is not set, it will make a HEAD request and check the size of
the file. If the size could not be determined, it will download up to the first
<p>Get the Track's initial segment data.</p>
<p>HLS and DASH tracks must explicitly give a URL to the init segment or file.
Give the byte-range for the init segment where possible.</p>
<p>If <code>byte_range</code> is not set, it will make a HEAD request and examine the size of
the file. If it cannot find the size, it will download up to the first
20KB only, which should contain the entirety of the init segment. You may
override this by changing the <code>maximum_size</code>.</p>
<p>The default maximum_size of 20000 (20KB) is a tried-and-tested value that
@@ -6676,9 +6678,9 @@ seems to work well across the board.</p>
</td>
<td>
<div class="doc-md-description">
<p>Size to assume as the content length if byte-range is not
used, the content size could not be determined, or the content size
is larger than it. A value of 20000 (20KB) or higher is recommended.</p>
<p>Size to assume as the response body length if byte-range is
not used, if unshackle cannot find the body size, or if the body size
is larger than it. Use a value of 20000 (20KB) or higher.</p>
</div>
</td>
<td>
@@ -6726,7 +6728,7 @@ is larger than it. A value of 20000 (20KB) or higher is recommended.</p>
</td>
<td>
<div class="doc-md-description">
<p>Session context, e.g., authorization and headers.</p>
<p>HTTP session context, for example authorization and headers.</p>
</div>
</td>
<td>
@@ -6754,13 +6756,13 @@ is larger than it. A value of 20000 (20KB) or higher is recommended.</p>
<div class="doc doc-contents ">
<p>Remux the track with ffmpeg <code>-c copy</code>.</p>
<p>When <code>bsf_v</code> is given it is folded into the same pass as <code>-bsf:v</code> (used to
normalize video VUI colour metadata without a second full-file remux). Repackaging
is mandatory; the bitstream filter is best-effort. If the combined run fails (and it
isn't the AAC-retry case) it is retried once without <code>bsf_v</code> so the remux still
succeeds. Returns True if the requested <code>bsf_v</code> was applied (always False when
<code>bsf_v</code> is None, since nothing was requested).</p>
<p>Remux the track with FFmpeg <code>-c copy</code>.</p>
<p>A given <code>bsf_v</code> goes into the same pass as <code>-bsf:v</code>, which normalises video VUI
colour metadata without a second full-file remux. Repackaging is mandatory. The
bitstream filter is best-effort: if the combined pass fails, and it is not the
AAC-retry case, unshackle tries it again once without <code>bsf_v</code> so the remux still
succeeds. Returns True if unshackle applied the requested <code>bsf_v</code> (always False
when <code>bsf_v</code> is None, because the caller requested nothing).</p>
</div>
@@ -6828,7 +6830,7 @@ It provides convenience functions for listing, sorting, and selecting tracks.</p
<div class="doc doc-contents ">
<p>Check if a track already exists by various methods.</p>
<p>Examine whether a track already exists, by various methods.</p>
</div>
@@ -6848,7 +6850,9 @@ It provides convenience functions for listing, sorting, and selecting tracks.</p
<div class="doc doc-contents ">
<p>Add a provided track to its appropriate array and ensuring it's not a duplicate.</p>
<p>Add a provided track to its appropriate array.</p>
<p>A track whose ID is already in the collection raises ValueError. With <code>warn_only</code>
set, this method skips such a track and logs how many it skipped.</p>
</div>
@@ -6916,7 +6920,7 @@ It provides convenience functions for listing, sorting, and selecting tracks.</p
<div class="doc doc-contents ">
<p>Sort subtitle tracks by various track attributes to a common P2P standard.
You may optionally provide a sequence of languages to prioritize to the top.</p>
You may optionally give a sequence of languages to prioritise to the top.</p>
<details class="section-order" open>
@@ -6937,8 +6941,8 @@ You may optionally provide a sequence of languages to prioritize to the top.</p>
(Least to most captions expected in the subtitle)</li>
</ul>
</details> <p>type_priority overrides the Type Order with an explicit ranking of "forced",
"normal", and "sdh" (cc counts as sdh); unlisted types fall to the end.</p>
<p>group_by sets the major key. "type" (default) keeps every forced track together,
"normal", and "sdh" (cc counts as sdh). Unlisted types fall to the end.</p>
<p>group_by sets the major sort order. "type" (default) keeps every forced track together,
then every normal, then every SDH, each block ascending by language. "language"
groups by language instead, so Finnish sits next to Finnish SDH, with the Type
Order applied inside each language.</p>
@@ -6988,8 +6992,9 @@ sorts "en-US" and "en-GB".</p>
<div class="doc doc-contents ">
<p>Concatenate video selections, dropping duplicates (by track id, order-preserving).</p>
<p>A DV track can be chosen as both the hybrid ingredient (lowest) and an explicit
deliverable; without dedup the same track would be muxed/downloaded twice.</p>
<p>A caller can choose a DV track as both the hybrid ingredient (lowest) and an
explicit deliverable. Without dedup, unshackle would mux and download the same
track twice.</p>
</div>
@@ -7014,9 +7019,10 @@ deliverable; without dedup the same track would be muxed/downloaded twice.</p>
<div class="doc doc-contents ">
<p>Split videos into hybrid-ingredient candidates and the standalone-deliverable pool.</p>
<p>HDR10/HDR10+/DV tracks are hybrid ingredients; they only enter the standalone
pool when their range was explicitly requested alongside HYBRID, so e.g.
<code>-r HYBRID</code> muxes only the hybrid while <code>-r HYBRID,HDR10P</code> also delivers HDR10+.</p>
<p>HDR10/HDR10+/DV tracks are hybrid ingredients. They only enter the standalone
pool when the user explicitly requested their range alongside HYBRID, so for
example <code>-r HYBRID</code> muxes only the hybrid while <code>-r HYBRID,HDR10P</code> also delivers
HDR10+.</p>
</div>
@@ -7043,8 +7049,8 @@ pool when their range was explicitly requested alongside HYBRID, so e.g.
<div class="doc doc-contents ">
<p>Mark tracks selected only as hybrid ingredients so the standalone mux loop skips them.</p>
<p>A track that was also picked as an explicit deliverable (same track in both
selections) stays unflagged and is muxed standalone alongside the hybrid.</p>
<p>A track that the caller also selected as an explicit deliverable (same track in both
selections) stays unflagged, and the standalone mux loop muxes it alongside the hybrid.</p>
</div>
@@ -7074,7 +7080,7 @@ selections) stays unflagged and is muxed standalone alongside the hybrid.</p>
<p>Multiplex all the Tracks into a Matroska Container file.</p>
<p>A failed mux does not raise. mkvmerge's exit code and error lines come back alongside the
output path, and the caller must check them.</p>
output path, and the caller must examine them.</p>
<p><span class="doc-section-title">Parameters:</span></p>
@@ -7130,8 +7136,8 @@ instead of the filename if set.</p>
</td>
<td>
<div class="doc-md-description">
<p>Update a rich progress bar via <code>completed=...</code>. This must be the
progress object's update() func, pre-set with task id via functools.partial.</p>
<p>Update a rich progress bar with <code>completed=...</code>. This must be the
progress object's update() func, pre-set with task id by functools.partial.</p>
</div>
</td>
<td>
@@ -7147,8 +7153,8 @@ progress object's update() func, pre-set with task id via functools.partial.</p>
</td>
<td>
<div class="doc-md-description">
<p>Whether audio is expected in the output. Used to determine
if embedded audio metadata should be added.</p>
<p>Whether the output must have audio. unshackle uses this to
decide if it adds embedded audio metadata.</p>
</div>
</td>
<td>
@@ -7197,8 +7203,8 @@ for audio metadata when multiple video tracks exist.</p>
</td>
<td>
<div class="doc-md-description">
<p>Explicit destination for the muxed container. When None (default) the
path is derived from the first track, so callers muxing several track groups that
<p>Explicit destination for the muxed container. When None (default)
unshackle derives the path from the first track, so callers muxing several track groups that
share a video list must pass distinct paths to avoid clobbering each other.</p>
</div>
</td>
@@ -7252,7 +7258,7 @@ share a video list must pass distinct paths to avoid clobbering each other.</p>
<p>Create a new Video track object.</p>
<p>Make a new Video track object.</p>
<p><span class="doc-section-title">Parameters:</span></p>
@@ -7276,8 +7282,8 @@ share a video list must pass distinct paths to avoid clobbering each other.</p>
<td>
<div class="doc-md-description">
<p>A Video.Codec enum representing the video codec.
If not specified, MediaInfo will be used to retrieve the codec
once the track has been downloaded.</p>
If not specified, unshackle uses MediaInfo to get the codec
after it downloads the track.</p>
</div>
</td>
<td>
@@ -7293,7 +7299,7 @@ once the track has been downloaded.</p>
</td>
<td>
<div class="doc-md-description">
<p>A Video.Range enum representing the video color range.
<p>A Video.Range enum representing the video colour range.
Defaults to SDR if not specified.</p>
</div>
</td>
@@ -7311,7 +7317,7 @@ Defaults to SDR if not specified.</p>
<td>
<div class="doc-md-description">
<p>A number or float representing the average bandwidth in bytes/s.
Float values are rounded up to the nearest integer.</p>
unshackle rounds float values up to the nearest integer.</p>
</div>
</td>
<td>
@@ -7370,9 +7376,8 @@ All strings will be cast to either a number or float.</p>
</tr>
</tbody>
</table>
<p>Note: If codec, bitrate, width, height, or fps is not specified some checks
may be skipped or assume a value. Specifying as much information as possible
is highly recommended.</p>
<p>Note: If codec, bitrate, width, height, or fps is not specified, unshackle can
skip some checks or assume a value. Give as much information as possible.</p>
@@ -7450,18 +7455,18 @@ is highly recommended.</p>
<div class="doc doc-contents ">
<p>Convert CICP (Coding-Independent Code Points) values to Video Range.</p>
<p>CICP is defined in ITU-T H.273 and ISO/IEC 23091-2 for signaling video
color properties independently of the compression codec. These values are
<p>ITU-T H.273 and ISO/IEC 23091-2 define CICP for signalling video
colour properties independently of the compression codec. These values are
used across AVC (H.264), HEVC (H.265), VVC, AV1, and other modern codecs.</p>
<p>The enum values (Primaries, Transfer, Matrix) match the official specifications:
- ITU-T H.273: Coding-independent code points for video signal type identification
- ISO/IEC 23091-2: Information technology — Coding-independent code points — Part 2: Video
- ISO/IEC 23091-2: Information technology - Coding-independent code points - Part 2: Video
- H.264 Table E-3 (Colour Primaries) and Table E-4 (Transfer Characteristics)
- H.265 Table E.3 and E.4 (identical to H.264)</p>
<p>Note: Value 0 = "Reserved" and Value 2 = "Unspecified" per specification.
While both effectively mean "unknown" in practice, the distinction matters for
spec compliance. Value 2 was added based on user feedback (GitHub issue) and
verified against FFmpeg's AVColorPrimaries/AVColorTransferCharacteristic enums.</p>
spec compliance. Value 2 was added after user feedback (GitHub issue) and matches
FFmpeg's AVColorPrimaries/AVColorTransferCharacteristic enums.</p>
<p>Sources:
- https://www.itu.int/rec/T-REC-H.273
- https://www.itu.int/rec/T-REC-H.Sup19-202104-I
@@ -7494,7 +7499,7 @@ verified against FFmpeg's AVColorPrimaries/AVColorTransferCharacteristic enums.<
<div class="doc doc-contents ">
<p>Change the Video's Color Range to Limited (0) or Full (1).</p>
<p>Change the Video's Colour Range to Limited (0) or Full (1).</p>
</div>
@@ -7515,9 +7520,9 @@ verified against FFmpeg's AVColorPrimaries/AVColorTransferCharacteristic enums.<
<div class="doc doc-contents ">
<p>Return the <code>-bsf:v</code> value that rewrites SPS VUI colour metadata to match <code>self.range</code>.</p>
<p>Returns None when no rewrite is needed: SDR/DV/HYBRID ranges, non-AVC/HEVC codecs, a
<p>Returns None when a rewrite is not necessary: SDR/DV/HYBRID ranges, non-AVC/HEVC codecs, a
missing file, or when the bitstream already ships the correct colour metadata. Otherwise
returns a <code>{h264,hevc}_metadata=...</code> string suitable for ffmpeg <code>-bsf:v</code>.</p>
returns a <code>{h264,hevc}_metadata=...</code> string suitable for FFmpeg <code>-bsf:v</code>.</p>
</div>
@@ -7540,8 +7545,8 @@ returns a <code>{h264,hevc}_metadata=...</code> string suitable for ffmpeg <code
<p>Rewrite SPS VUI colour metadata to match <code>self.range</code>.</p>
<p>Some services ship HDR10/HLG bitstreams with stale BT.709 VUI, which makes
downstream tools mis-classify the file. The manifest-derived range is the
source of truth. Skips SDR, DV, and HYBRID. Returns True if the bitstream
was rewritten.</p>
source of truth. Skips SDR, DV, and HYBRID. Returns True if unshackle rewrote
the bitstream.</p>
</div>
@@ -7581,19 +7586,19 @@ was rewritten.</p>
<div class="doc doc-contents ">
<p>Extract Apple-Style c608 box (CEA-608) subtitle using ccextractor.</p>
<p>This isn't much more than a wrapper to the track.ccextractor function.
All this does, is actually check if a c608 box exists and only if so
does it actually call ccextractor.</p>
<p>Even though there is a possibility of more than one c608 box, only one
can actually be extracted. It is also very possible this
<p>Extract Apple-Style c608 box (CEA-608) subtitle using CCExtractor.</p>
<p>This is not much more than a wrapper to the track.ccextractor function.
All this does is examine if a c608 box exists, and only then
does it call CCExtractor.</p>
<p>Even though there is a possibility of more than one c608 box, unshackle
can extract only one. It is also very possible this
needs to be done before any decryption as the decryption may destroy
some of the metadata.</p>
<details class="todo" open>
<summary>Need a test file with more than one c608 box to add support for</summary>
<p>more than one CEA-608 extraction.</p>
<summary>Need a test file with more than one c608 box, before unshackle can</summary>
<p>extract more than one CEA-608 track.</p>
</details>
</div>
@@ -7615,9 +7620,9 @@ some of the metadata.</p>
<p>Remove EIA-CC data from Bitstream while keeping SEI data.</p>
<p>This works by removing all NAL Unit's with the Type of 6 from the bistream
and then re-adding SEI data (effectively a new NAL Unit with just the SEI data).
Only bitstreams with x264 encoding information is currently supported due to the
obscurity on the MDAT mp4 box structure. Therefore, we need to use hacky regex.</p>
and then re-adding SEI data (effectively a new NAL Unit with only the SEI data).
unshackle can do this only for bitstreams with x264 encoding information, because of
the obscurity on the MDAT mp4 box structure. Therefore, we need to use hacky regex.</p>
</div>