mirror of
https://github.com/unshackle-dl/unshackle.git
synced 2026-11-14 13:05:09 +00:00
Deployed 5b0369e with MkDocs version: 1.6.1
This commit is contained in:
+155
-141
@@ -2649,6 +2649,20 @@ client: a remote-dl session gets it through the attached <code>InputBridge</code
|
||||
REST download job shows it as <code>input_prompt</code>. Locally it routes through the
|
||||
shared Rich console (<code>prompt_user</code>) so the prompt renders correctly alongside
|
||||
progress and log output.</p>
|
||||
<p>For a login that the user approves on another device (a pair code, a QR code),
|
||||
use <code>self.wait_for_approval(message, check, timeout)</code>, never a hand-written
|
||||
loop. It shows the message, then calls <code>check</code> at each interval until <code>check</code>
|
||||
returns a value. <code>check</code> returns <code>None</code> while the approval is pending.</p>
|
||||
<div class="language-python highlight"><pre><span></span><code><span id="__span-7-1"><a id="__codelineno-7-1" name="__codelineno-7-1" href="#__codelineno-7-1"></a><span class="n">token</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">wait_for_approval</span><span class="p">(</span>
|
||||
</span><span id="__span-7-2"><a id="__codelineno-7-2" name="__codelineno-7-2" href="#__codelineno-7-2"></a> <span class="sa">f</span><span class="s2">"Open </span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">config</span><span class="p">[</span><span class="s1">'endpoints'</span><span class="p">][</span><span class="s1">'pair'</span><span class="p">]</span><span class="si">}</span><span class="s2"> and enter code </span><span class="si">{</span><span class="n">code</span><span class="si">}</span><span class="s2">"</span><span class="p">,</span>
|
||||
</span><span id="__span-7-3"><a id="__codelineno-7-3" name="__codelineno-7-3" href="#__codelineno-7-3"></a> <span class="n">check</span><span class="o">=</span><span class="k">lambda</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">poll_pair_token</span><span class="p">(</span><span class="n">code</span><span class="p">),</span>
|
||||
</span><span id="__span-7-4"><a id="__codelineno-7-4" name="__codelineno-7-4" href="#__codelineno-7-4"></a> <span class="n">timeout</span><span class="o">=</span><span class="n">expires_in</span><span class="p">,</span>
|
||||
</span><span id="__span-7-5"><a id="__codelineno-7-5" name="__codelineno-7-5" href="#__codelineno-7-5"></a><span class="p">)</span>
|
||||
</span></code></pre></div>
|
||||
<p>It raises <code>TimeoutError</code> after <code>timeout</code> seconds. Under <code>serve</code> mode it also stops
|
||||
when the client deletes the remote session, so the loop does not continue on the
|
||||
server with no client. The message goes out as a log line, so a remote
|
||||
session shows it, but a REST download job does not relay it as <code>input_prompt</code>.</p>
|
||||
<div class="admonition warning">
|
||||
<p class="admonition-title">Make each token cache entry unique</p>
|
||||
<p>The cache above uses <code>tokens_{device}_{profile}</code> on purpose. A token cache
|
||||
@@ -2694,38 +2708,38 @@ identity for you.</p>
|
||||
<p>Every title carries a <code>language</code> (its <strong>original recorded language</strong>) and an
|
||||
arbitrary <code>data</code> dict you can use to stash metadata for later methods. You must
|
||||
return at least one title. If you return none, unshackle treats the ID as invalid.</p>
|
||||
<div class="language-python highlight"><pre><span></span><code><span id="__span-7-1"><a id="__codelineno-7-1" name="__codelineno-7-1" href="#__codelineno-7-1"></a><span class="k">def</span><span class="w"> </span><span class="nf">get_titles</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-></span> <span class="n">Titles_T</span><span class="p">:</span>
|
||||
</span><span id="__span-7-2"><a id="__codelineno-7-2" name="__codelineno-7-2" href="#__codelineno-7-2"></a> <span class="n">match</span> <span class="o">=</span> <span class="n">re</span><span class="o">.</span><span class="n">match</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">TITLE_RE</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">title</span><span class="p">)</span>
|
||||
</span><span id="__span-7-3"><a id="__codelineno-7-3" name="__codelineno-7-3" href="#__codelineno-7-3"></a> <span class="k">if</span> <span class="ow">not</span> <span class="n">match</span><span class="p">:</span>
|
||||
</span><span id="__span-7-4"><a id="__codelineno-7-4" name="__codelineno-7-4" href="#__codelineno-7-4"></a> <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s2">"Could not parse a title ID - is the URL/ID correct?"</span><span class="p">)</span>
|
||||
</span><span id="__span-7-5"><a id="__codelineno-7-5" name="__codelineno-7-5" href="#__codelineno-7-5"></a> <span class="n">metadata</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">session</span><span class="o">.</span><span class="n">get</span><span class="p">(</span>
|
||||
</span><span id="__span-7-6"><a id="__codelineno-7-6" name="__codelineno-7-6" href="#__codelineno-7-6"></a> <span class="bp">self</span><span class="o">.</span><span class="n">config</span><span class="p">[</span><span class="s2">"endpoints"</span><span class="p">][</span><span class="s2">"metadata"</span><span class="p">]</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">title_id</span><span class="o">=</span><span class="n">match</span><span class="o">.</span><span class="n">group</span><span class="p">(</span><span class="s2">"title_id"</span><span class="p">)),</span>
|
||||
</span><span id="__span-7-7"><a id="__codelineno-7-7" name="__codelineno-7-7" href="#__codelineno-7-7"></a> <span class="n">params</span><span class="o">=</span><span class="p">{</span><span class="s2">"token"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">token</span><span class="p">},</span>
|
||||
</span><span id="__span-7-8"><a id="__codelineno-7-8" name="__codelineno-7-8" href="#__codelineno-7-8"></a> <span class="p">)</span><span class="o">.</span><span class="n">json</span><span class="p">()</span>
|
||||
</span><span id="__span-7-9"><a id="__codelineno-7-9" name="__codelineno-7-9" href="#__codelineno-7-9"></a> <span class="n">original_lang</span> <span class="o">=</span> <span class="n">Language</span><span class="o">.</span><span class="n">find</span><span class="p">(</span><span class="n">metadata</span><span class="p">[</span><span class="s2">"languages"</span><span class="p">][</span><span class="mi">0</span><span class="p">])</span>
|
||||
</span><span id="__span-7-10"><a id="__codelineno-7-10" name="__codelineno-7-10" href="#__codelineno-7-10"></a>
|
||||
</span><span id="__span-7-11"><a id="__codelineno-7-11" name="__codelineno-7-11" href="#__codelineno-7-11"></a> <span class="k">return</span> <span class="n">Movies</span><span class="p">([</span>
|
||||
</span><span id="__span-7-12"><a id="__codelineno-7-12" name="__codelineno-7-12" href="#__codelineno-7-12"></a> <span class="n">Movie</span><span class="p">(</span>
|
||||
</span><span id="__span-7-13"><a id="__codelineno-7-13" name="__codelineno-7-13" href="#__codelineno-7-13"></a> <span class="n">id_</span><span class="o">=</span><span class="n">metadata</span><span class="p">[</span><span class="s2">"id"</span><span class="p">],</span>
|
||||
</span><span id="__span-7-14"><a id="__codelineno-7-14" name="__codelineno-7-14" href="#__codelineno-7-14"></a> <span class="n">service</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="vm">__class__</span><span class="p">,</span>
|
||||
</span><span id="__span-7-15"><a id="__codelineno-7-15" name="__codelineno-7-15" href="#__codelineno-7-15"></a> <span class="n">name</span><span class="o">=</span><span class="n">metadata</span><span class="p">[</span><span class="s2">"title"</span><span class="p">],</span>
|
||||
</span><span id="__span-7-16"><a id="__codelineno-7-16" name="__codelineno-7-16" href="#__codelineno-7-16"></a> <span class="n">year</span><span class="o">=</span><span class="n">metadata</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"releaseYear"</span><span class="p">)</span> <span class="ow">or</span> <span class="kc">None</span><span class="p">,</span>
|
||||
</span><span id="__span-7-17"><a id="__codelineno-7-17" name="__codelineno-7-17" href="#__codelineno-7-17"></a> <span class="n">language</span><span class="o">=</span><span class="n">original_lang</span><span class="p">,</span> <span class="c1"># ORIGINAL audio language, not the -l preference</span>
|
||||
</span><span id="__span-7-18"><a id="__codelineno-7-18" name="__codelineno-7-18" href="#__codelineno-7-18"></a> <span class="n">data</span><span class="o">=</span><span class="n">metadata</span><span class="p">,</span> <span class="c1"># read later as title.data</span>
|
||||
</span><span id="__span-7-19"><a id="__codelineno-7-19" name="__codelineno-7-19" href="#__codelineno-7-19"></a> <span class="p">)</span>
|
||||
</span><span id="__span-7-20"><a id="__codelineno-7-20" name="__codelineno-7-20" href="#__codelineno-7-20"></a> <span class="p">])</span>
|
||||
<div class="language-python highlight"><pre><span></span><code><span id="__span-8-1"><a id="__codelineno-8-1" name="__codelineno-8-1" href="#__codelineno-8-1"></a><span class="k">def</span><span class="w"> </span><span class="nf">get_titles</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-></span> <span class="n">Titles_T</span><span class="p">:</span>
|
||||
</span><span id="__span-8-2"><a id="__codelineno-8-2" name="__codelineno-8-2" href="#__codelineno-8-2"></a> <span class="n">match</span> <span class="o">=</span> <span class="n">re</span><span class="o">.</span><span class="n">match</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">TITLE_RE</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">title</span><span class="p">)</span>
|
||||
</span><span id="__span-8-3"><a id="__codelineno-8-3" name="__codelineno-8-3" href="#__codelineno-8-3"></a> <span class="k">if</span> <span class="ow">not</span> <span class="n">match</span><span class="p">:</span>
|
||||
</span><span id="__span-8-4"><a id="__codelineno-8-4" name="__codelineno-8-4" href="#__codelineno-8-4"></a> <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s2">"Could not parse a title ID - is the URL/ID correct?"</span><span class="p">)</span>
|
||||
</span><span id="__span-8-5"><a id="__codelineno-8-5" name="__codelineno-8-5" href="#__codelineno-8-5"></a> <span class="n">metadata</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">session</span><span class="o">.</span><span class="n">get</span><span class="p">(</span>
|
||||
</span><span id="__span-8-6"><a id="__codelineno-8-6" name="__codelineno-8-6" href="#__codelineno-8-6"></a> <span class="bp">self</span><span class="o">.</span><span class="n">config</span><span class="p">[</span><span class="s2">"endpoints"</span><span class="p">][</span><span class="s2">"metadata"</span><span class="p">]</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">title_id</span><span class="o">=</span><span class="n">match</span><span class="o">.</span><span class="n">group</span><span class="p">(</span><span class="s2">"title_id"</span><span class="p">)),</span>
|
||||
</span><span id="__span-8-7"><a id="__codelineno-8-7" name="__codelineno-8-7" href="#__codelineno-8-7"></a> <span class="n">params</span><span class="o">=</span><span class="p">{</span><span class="s2">"token"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">token</span><span class="p">},</span>
|
||||
</span><span id="__span-8-8"><a id="__codelineno-8-8" name="__codelineno-8-8" href="#__codelineno-8-8"></a> <span class="p">)</span><span class="o">.</span><span class="n">json</span><span class="p">()</span>
|
||||
</span><span id="__span-8-9"><a id="__codelineno-8-9" name="__codelineno-8-9" href="#__codelineno-8-9"></a> <span class="n">original_lang</span> <span class="o">=</span> <span class="n">Language</span><span class="o">.</span><span class="n">find</span><span class="p">(</span><span class="n">metadata</span><span class="p">[</span><span class="s2">"languages"</span><span class="p">][</span><span class="mi">0</span><span class="p">])</span>
|
||||
</span><span id="__span-8-10"><a id="__codelineno-8-10" name="__codelineno-8-10" href="#__codelineno-8-10"></a>
|
||||
</span><span id="__span-8-11"><a id="__codelineno-8-11" name="__codelineno-8-11" href="#__codelineno-8-11"></a> <span class="k">return</span> <span class="n">Movies</span><span class="p">([</span>
|
||||
</span><span id="__span-8-12"><a id="__codelineno-8-12" name="__codelineno-8-12" href="#__codelineno-8-12"></a> <span class="n">Movie</span><span class="p">(</span>
|
||||
</span><span id="__span-8-13"><a id="__codelineno-8-13" name="__codelineno-8-13" href="#__codelineno-8-13"></a> <span class="n">id_</span><span class="o">=</span><span class="n">metadata</span><span class="p">[</span><span class="s2">"id"</span><span class="p">],</span>
|
||||
</span><span id="__span-8-14"><a id="__codelineno-8-14" name="__codelineno-8-14" href="#__codelineno-8-14"></a> <span class="n">service</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="vm">__class__</span><span class="p">,</span>
|
||||
</span><span id="__span-8-15"><a id="__codelineno-8-15" name="__codelineno-8-15" href="#__codelineno-8-15"></a> <span class="n">name</span><span class="o">=</span><span class="n">metadata</span><span class="p">[</span><span class="s2">"title"</span><span class="p">],</span>
|
||||
</span><span id="__span-8-16"><a id="__codelineno-8-16" name="__codelineno-8-16" href="#__codelineno-8-16"></a> <span class="n">year</span><span class="o">=</span><span class="n">metadata</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"releaseYear"</span><span class="p">)</span> <span class="ow">or</span> <span class="kc">None</span><span class="p">,</span>
|
||||
</span><span id="__span-8-17"><a id="__codelineno-8-17" name="__codelineno-8-17" href="#__codelineno-8-17"></a> <span class="n">language</span><span class="o">=</span><span class="n">original_lang</span><span class="p">,</span> <span class="c1"># ORIGINAL audio language, not the -l preference</span>
|
||||
</span><span id="__span-8-18"><a id="__codelineno-8-18" name="__codelineno-8-18" href="#__codelineno-8-18"></a> <span class="n">data</span><span class="o">=</span><span class="n">metadata</span><span class="p">,</span> <span class="c1"># read later as title.data</span>
|
||||
</span><span id="__span-8-19"><a id="__codelineno-8-19" name="__codelineno-8-19" href="#__codelineno-8-19"></a> <span class="p">)</span>
|
||||
</span><span id="__span-8-20"><a id="__codelineno-8-20" name="__codelineno-8-20" href="#__codelineno-8-20"></a> <span class="p">])</span>
|
||||
</span></code></pre></div>
|
||||
<p>Common constructor fields:</p>
|
||||
<div class="tabbed-set tabbed-alternate" data-tabs="1:3"><input checked="checked" id="__tabbed_1_1" name="__tabbed_1" type="radio" /><input id="__tabbed_1_2" name="__tabbed_1" type="radio" /><input id="__tabbed_1_3" name="__tabbed_1" type="radio" /><div class="tabbed-labels"><label for="__tabbed_1_1">Movie</label><label for="__tabbed_1_2">Episode</label><label for="__tabbed_1_3">Song</label></div>
|
||||
<div class="tabbed-content">
|
||||
<div class="tabbed-block">
|
||||
<div class="language-python highlight"><pre><span></span><code><span id="__span-8-1"><a id="__codelineno-8-1" name="__codelineno-8-1" href="#__codelineno-8-1"></a><span class="n">Movie</span><span class="p">(</span><span class="n">id_</span><span class="p">,</span> <span class="n">service</span><span class="p">,</span> <span class="n">name</span><span class="p">,</span> <span class="n">year</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">language</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">data</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">description</span><span class="o">=</span><span class="kc">None</span><span class="p">)</span>
|
||||
<div class="language-python highlight"><pre><span></span><code><span id="__span-9-1"><a id="__codelineno-9-1" name="__codelineno-9-1" href="#__codelineno-9-1"></a><span class="n">Movie</span><span class="p">(</span><span class="n">id_</span><span class="p">,</span> <span class="n">service</span><span class="p">,</span> <span class="n">name</span><span class="p">,</span> <span class="n">year</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">language</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">data</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">description</span><span class="o">=</span><span class="kc">None</span><span class="p">)</span>
|
||||
</span></code></pre></div>
|
||||
</div>
|
||||
<div class="tabbed-block">
|
||||
<div class="language-python highlight"><pre><span></span><code><span id="__span-9-1"><a id="__codelineno-9-1" name="__codelineno-9-1" href="#__codelineno-9-1"></a><span class="n">Episode</span><span class="p">(</span><span class="n">id_</span><span class="p">,</span> <span class="n">service</span><span class="p">,</span> <span class="n">title</span><span class="p">,</span> <span class="n">season</span><span class="p">,</span> <span class="n">number</span><span class="p">,</span> <span class="n">name</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">year</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
|
||||
</span><span id="__span-9-2"><a id="__codelineno-9-2" name="__codelineno-9-2" href="#__codelineno-9-2"></a> <span class="n">language</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">data</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">description</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">air_date</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
|
||||
</span><span id="__span-9-3"><a id="__codelineno-9-3" name="__codelineno-9-3" href="#__codelineno-9-3"></a> <span class="n">part</span><span class="o">=</span><span class="kc">None</span><span class="p">)</span>
|
||||
<div class="language-python highlight"><pre><span></span><code><span id="__span-10-1"><a id="__codelineno-10-1" name="__codelineno-10-1" href="#__codelineno-10-1"></a><span class="n">Episode</span><span class="p">(</span><span class="n">id_</span><span class="p">,</span> <span class="n">service</span><span class="p">,</span> <span class="n">title</span><span class="p">,</span> <span class="n">season</span><span class="p">,</span> <span class="n">number</span><span class="p">,</span> <span class="n">name</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">year</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
|
||||
</span><span id="__span-10-2"><a id="__codelineno-10-2" name="__codelineno-10-2" href="#__codelineno-10-2"></a> <span class="n">language</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">data</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">description</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">air_date</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
|
||||
</span><span id="__span-10-3"><a id="__codelineno-10-3" name="__codelineno-10-3" href="#__codelineno-10-3"></a> <span class="n">part</span><span class="o">=</span><span class="kc">None</span><span class="p">)</span>
|
||||
</span></code></pre></div>
|
||||
<p>Pass <code>air_date</code> for daily and sports titles to name by date instead of
|
||||
<code>SxxExx</code>. Return a <code>Series([...])</code> of episodes. Pass <code>part</code> only when the
|
||||
@@ -2733,8 +2747,8 @@ service splits one episode into several videos, see
|
||||
<a href="#split-episodes">Split episodes</a>.</p>
|
||||
</div>
|
||||
<div class="tabbed-block">
|
||||
<div class="language-python highlight"><pre><span></span><code><span id="__span-10-1"><a id="__codelineno-10-1" name="__codelineno-10-1" href="#__codelineno-10-1"></a><span class="n">Song</span><span class="p">(</span><span class="n">id_</span><span class="p">,</span> <span class="n">service</span><span class="p">,</span> <span class="n">name</span><span class="p">,</span> <span class="n">artist</span><span class="p">,</span> <span class="n">album</span><span class="p">,</span> <span class="n">track</span><span class="p">,</span> <span class="n">disc</span><span class="o">=</span><span class="mi">1</span><span class="p">,</span> <span class="n">year</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
|
||||
</span><span id="__span-10-2"><a id="__codelineno-10-2" name="__codelineno-10-2" href="#__codelineno-10-2"></a> <span class="n">language</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">data</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="o">...</span><span class="p">)</span>
|
||||
<div class="language-python highlight"><pre><span></span><code><span id="__span-11-1"><a id="__codelineno-11-1" name="__codelineno-11-1" href="#__codelineno-11-1"></a><span class="n">Song</span><span class="p">(</span><span class="n">id_</span><span class="p">,</span> <span class="n">service</span><span class="p">,</span> <span class="n">name</span><span class="p">,</span> <span class="n">artist</span><span class="p">,</span> <span class="n">album</span><span class="p">,</span> <span class="n">track</span><span class="p">,</span> <span class="n">disc</span><span class="o">=</span><span class="mi">1</span><span class="p">,</span> <span class="n">year</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
|
||||
</span><span id="__span-11-2"><a id="__codelineno-11-2" name="__codelineno-11-2" href="#__codelineno-11-2"></a> <span class="n">language</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">data</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="o">...</span><span class="p">)</span>
|
||||
</span></code></pre></div>
|
||||
<p>Return an <code>Album([...])</code> of songs. <code>disc</code> defaults to 1 and <code>year</code> is optional.
|
||||
Optional metadata keywords such as <code>album_artist</code>, <code>genre</code>, <code>isrc</code>, <code>label</code>,
|
||||
@@ -2763,8 +2777,8 @@ when the API errors. It also applies the per-service <code>title_map</code> conf
|
||||
<p>Some services split one logical episode into several separately playable videos, for
|
||||
example a variety show that ships episode 1 as <em>Episode 1 (Part 1)</em>, <em>(Part 2)</em> and
|
||||
<em>(Part 3)</em>. <code>Episode.number</code> stays an <code>int</code>. The optional <code>part</code> carries the index.</p>
|
||||
<div class="language-python highlight"><pre><span></span><code><span id="__span-11-1"><a id="__codelineno-11-1" name="__codelineno-11-1" href="#__codelineno-11-1"></a><span class="n">Episode</span><span class="p">(</span><span class="o">...</span><span class="p">,</span> <span class="n">season</span><span class="o">=</span><span class="mi">1</span><span class="p">,</span> <span class="n">number</span><span class="o">=</span><span class="mi">1</span><span class="p">,</span> <span class="n">part</span><span class="o">=</span><span class="mi">1</span><span class="p">,</span> <span class="n">name</span><span class="o">=</span><span class="s2">"The Reckoning"</span><span class="p">)</span>
|
||||
</span><span id="__span-11-2"><a id="__codelineno-11-2" name="__codelineno-11-2" href="#__codelineno-11-2"></a><span class="n">Episode</span><span class="p">(</span><span class="o">...</span><span class="p">,</span> <span class="n">season</span><span class="o">=</span><span class="mi">1</span><span class="p">,</span> <span class="n">number</span><span class="o">=</span><span class="mi">1</span><span class="p">,</span> <span class="n">part</span><span class="o">=</span><span class="mi">2</span><span class="p">,</span> <span class="n">name</span><span class="o">=</span><span class="s2">"The Reckoning"</span><span class="p">)</span>
|
||||
<div class="language-python highlight"><pre><span></span><code><span id="__span-12-1"><a id="__codelineno-12-1" name="__codelineno-12-1" href="#__codelineno-12-1"></a><span class="n">Episode</span><span class="p">(</span><span class="o">...</span><span class="p">,</span> <span class="n">season</span><span class="o">=</span><span class="mi">1</span><span class="p">,</span> <span class="n">number</span><span class="o">=</span><span class="mi">1</span><span class="p">,</span> <span class="n">part</span><span class="o">=</span><span class="mi">1</span><span class="p">,</span> <span class="n">name</span><span class="o">=</span><span class="s2">"The Reckoning"</span><span class="p">)</span>
|
||||
</span><span id="__span-12-2"><a id="__codelineno-12-2" name="__codelineno-12-2" href="#__codelineno-12-2"></a><span class="n">Episode</span><span class="p">(</span><span class="o">...</span><span class="p">,</span> <span class="n">season</span><span class="o">=</span><span class="mi">1</span><span class="p">,</span> <span class="n">number</span><span class="o">=</span><span class="mi">1</span><span class="p">,</span> <span class="n">part</span><span class="o">=</span><span class="mi">2</span><span class="p">,</span> <span class="n">name</span><span class="o">=</span><span class="s2">"The Reckoning"</span><span class="p">)</span>
|
||||
</span></code></pre></div>
|
||||
<ol>
|
||||
<li><code>part</code> counts from 1, contiguous. unshackle rejects <code>part=0</code>, and <code>-w</code> can only
|
||||
@@ -2808,29 +2822,29 @@ has nothing to adopt.</p>
|
||||
<code>Subtitle</code> tracks. In almost all cases you assemble these by parsing a manifest,
|
||||
not by hand.</p>
|
||||
<p>The manifest parsers live in <code>unshackle.core.manifests</code>:</p>
|
||||
<div class="language-python highlight"><pre><span></span><code><span id="__span-12-1"><a id="__codelineno-12-1" name="__codelineno-12-1" href="#__codelineno-12-1"></a><span class="kn">from</span><span class="w"> </span><span class="nn">unshackle.core.manifests</span><span class="w"> </span><span class="kn">import</span> <span class="n">DASH</span><span class="p">,</span> <span class="n">HLS</span><span class="p">,</span> <span class="n">ISM</span>
|
||||
<div class="language-python highlight"><pre><span></span><code><span id="__span-13-1"><a id="__codelineno-13-1" name="__codelineno-13-1" href="#__codelineno-13-1"></a><span class="kn">from</span><span class="w"> </span><span class="nn">unshackle.core.manifests</span><span class="w"> </span><span class="kn">import</span> <span class="n">DASH</span><span class="p">,</span> <span class="n">HLS</span><span class="p">,</span> <span class="n">ISM</span>
|
||||
</span></code></pre></div>
|
||||
<p>Each exposes <code>from_url(url, session=...)</code> (or <code>from_text(text, url)</code>) and then
|
||||
<code>.to_tracks(language=...)</code>:</p>
|
||||
<div class="tabbed-set tabbed-alternate" data-tabs="2:3"><input checked="checked" id="__tabbed_2_1" name="__tabbed_2" type="radio" /><input id="__tabbed_2_2" name="__tabbed_2" type="radio" /><input id="__tabbed_2_3" name="__tabbed_2" type="radio" /><div class="tabbed-labels"><label for="__tabbed_2_1">DASH (.mpd)</label><label for="__tabbed_2_2">HLS (.m3u8)</label><label for="__tabbed_2_3">ISM (Smooth Streaming)</label></div>
|
||||
<div class="tabbed-content">
|
||||
<div class="tabbed-block">
|
||||
<div class="language-python highlight"><pre><span></span><code><span id="__span-13-1"><a id="__codelineno-13-1" name="__codelineno-13-1" href="#__codelineno-13-1"></a><span class="k">def</span><span class="w"> </span><span class="nf">get_tracks</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">title</span><span class="p">:</span> <span class="n">Title_T</span><span class="p">)</span> <span class="o">-></span> <span class="n">Tracks</span><span class="p">:</span>
|
||||
</span><span id="__span-13-2"><a id="__codelineno-13-2" name="__codelineno-13-2" href="#__codelineno-13-2"></a> <span class="k">return</span> <span class="n">DASH</span><span class="o">.</span><span class="n">from_url</span><span class="p">(</span><span class="n">manifest_url</span><span class="p">,</span> <span class="n">session</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">session</span><span class="p">)</span> \
|
||||
</span><span id="__span-13-3"><a id="__codelineno-13-3" name="__codelineno-13-3" href="#__codelineno-13-3"></a> <span class="o">.</span><span class="n">to_tracks</span><span class="p">(</span><span class="n">language</span><span class="o">=</span><span class="n">title</span><span class="o">.</span><span class="n">language</span><span class="p">)</span>
|
||||
<div class="language-python highlight"><pre><span></span><code><span id="__span-14-1"><a id="__codelineno-14-1" name="__codelineno-14-1" href="#__codelineno-14-1"></a><span class="k">def</span><span class="w"> </span><span class="nf">get_tracks</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">title</span><span class="p">:</span> <span class="n">Title_T</span><span class="p">)</span> <span class="o">-></span> <span class="n">Tracks</span><span class="p">:</span>
|
||||
</span><span id="__span-14-2"><a id="__codelineno-14-2" name="__codelineno-14-2" href="#__codelineno-14-2"></a> <span class="k">return</span> <span class="n">DASH</span><span class="o">.</span><span class="n">from_url</span><span class="p">(</span><span class="n">manifest_url</span><span class="p">,</span> <span class="n">session</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">session</span><span class="p">)</span> \
|
||||
</span><span id="__span-14-3"><a id="__codelineno-14-3" name="__codelineno-14-3" href="#__codelineno-14-3"></a> <span class="o">.</span><span class="n">to_tracks</span><span class="p">(</span><span class="n">language</span><span class="o">=</span><span class="n">title</span><span class="o">.</span><span class="n">language</span><span class="p">)</span>
|
||||
</span></code></pre></div>
|
||||
</div>
|
||||
<div class="tabbed-block">
|
||||
<div class="language-python highlight"><pre><span></span><code><span id="__span-14-1"><a id="__codelineno-14-1" name="__codelineno-14-1" href="#__codelineno-14-1"></a><span class="k">def</span><span class="w"> </span><span class="nf">get_tracks</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">title</span><span class="p">:</span> <span class="n">Title_T</span><span class="p">)</span> <span class="o">-></span> <span class="n">Tracks</span><span class="p">:</span>
|
||||
</span><span id="__span-14-2"><a id="__codelineno-14-2" name="__codelineno-14-2" href="#__codelineno-14-2"></a> <span class="k">return</span> <span class="n">HLS</span><span class="o">.</span><span class="n">from_url</span><span class="p">(</span><span class="n">manifest_url</span><span class="p">,</span> <span class="n">session</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">session</span><span class="p">)</span> \
|
||||
</span><span id="__span-14-3"><a id="__codelineno-14-3" name="__codelineno-14-3" href="#__codelineno-14-3"></a> <span class="o">.</span><span class="n">to_tracks</span><span class="p">(</span><span class="n">language</span><span class="o">=</span><span class="n">title</span><span class="o">.</span><span class="n">language</span><span class="p">)</span>
|
||||
<div class="language-python highlight"><pre><span></span><code><span id="__span-15-1"><a id="__codelineno-15-1" name="__codelineno-15-1" href="#__codelineno-15-1"></a><span class="k">def</span><span class="w"> </span><span class="nf">get_tracks</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">title</span><span class="p">:</span> <span class="n">Title_T</span><span class="p">)</span> <span class="o">-></span> <span class="n">Tracks</span><span class="p">:</span>
|
||||
</span><span id="__span-15-2"><a id="__codelineno-15-2" name="__codelineno-15-2" href="#__codelineno-15-2"></a> <span class="k">return</span> <span class="n">HLS</span><span class="o">.</span><span class="n">from_url</span><span class="p">(</span><span class="n">manifest_url</span><span class="p">,</span> <span class="n">session</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">session</span><span class="p">)</span> \
|
||||
</span><span id="__span-15-3"><a id="__codelineno-15-3" name="__codelineno-15-3" href="#__codelineno-15-3"></a> <span class="o">.</span><span class="n">to_tracks</span><span class="p">(</span><span class="n">language</span><span class="o">=</span><span class="n">title</span><span class="o">.</span><span class="n">language</span><span class="p">)</span>
|
||||
</span></code></pre></div>
|
||||
<p>The URL must be a <strong>variant (master) playlist</strong>, not a media playlist.</p>
|
||||
</div>
|
||||
<div class="tabbed-block">
|
||||
<div class="language-python highlight"><pre><span></span><code><span id="__span-15-1"><a id="__codelineno-15-1" name="__codelineno-15-1" href="#__codelineno-15-1"></a><span class="k">def</span><span class="w"> </span><span class="nf">get_tracks</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">title</span><span class="p">:</span> <span class="n">Title_T</span><span class="p">)</span> <span class="o">-></span> <span class="n">Tracks</span><span class="p">:</span>
|
||||
</span><span id="__span-15-2"><a id="__codelineno-15-2" name="__codelineno-15-2" href="#__codelineno-15-2"></a> <span class="k">return</span> <span class="n">ISM</span><span class="o">.</span><span class="n">from_url</span><span class="p">(</span><span class="n">manifest_url</span><span class="p">,</span> <span class="n">session</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">session</span><span class="p">)</span> \
|
||||
</span><span id="__span-15-3"><a id="__codelineno-15-3" name="__codelineno-15-3" href="#__codelineno-15-3"></a> <span class="o">.</span><span class="n">to_tracks</span><span class="p">(</span><span class="n">language</span><span class="o">=</span><span class="n">title</span><span class="o">.</span><span class="n">language</span><span class="p">)</span>
|
||||
<div class="language-python highlight"><pre><span></span><code><span id="__span-16-1"><a id="__codelineno-16-1" name="__codelineno-16-1" href="#__codelineno-16-1"></a><span class="k">def</span><span class="w"> </span><span class="nf">get_tracks</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">title</span><span class="p">:</span> <span class="n">Title_T</span><span class="p">)</span> <span class="o">-></span> <span class="n">Tracks</span><span class="p">:</span>
|
||||
</span><span id="__span-16-2"><a id="__codelineno-16-2" name="__codelineno-16-2" href="#__codelineno-16-2"></a> <span class="k">return</span> <span class="n">ISM</span><span class="o">.</span><span class="n">from_url</span><span class="p">(</span><span class="n">manifest_url</span><span class="p">,</span> <span class="n">session</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">session</span><span class="p">)</span> \
|
||||
</span><span id="__span-16-3"><a id="__codelineno-16-3" name="__codelineno-16-3" href="#__codelineno-16-3"></a> <span class="o">.</span><span class="n">to_tracks</span><span class="p">(</span><span class="n">language</span><span class="o">=</span><span class="n">title</span><span class="o">.</span><span class="n">language</span><span class="p">)</span>
|
||||
</span></code></pre></div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -2848,11 +2862,11 @@ language token.</p>
|
||||
provides <code>get_tracks_for_variants(title, fetch_fn)</code> to fan out over every
|
||||
codec×range in the <code>TrackRequest</code>, including <code>HYBRID</code> (fetch HDR10 + DV and
|
||||
merge) and <code>--best-available</code> skip-on-error handling:</p>
|
||||
<div class="language-python highlight"><pre><span></span><code><span id="__span-16-1"><a id="__codelineno-16-1" name="__codelineno-16-1" href="#__codelineno-16-1"></a><span class="k">def</span><span class="w"> </span><span class="nf">get_tracks</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">title</span><span class="p">:</span> <span class="n">Title_T</span><span class="p">)</span> <span class="o">-></span> <span class="n">Tracks</span><span class="p">:</span>
|
||||
</span><span id="__span-16-2"><a id="__codelineno-16-2" name="__codelineno-16-2" href="#__codelineno-16-2"></a> <span class="k">def</span><span class="w"> </span><span class="nf">fetch_variant</span><span class="p">(</span><span class="n">title</span><span class="p">,</span> <span class="n">codec</span><span class="p">,</span> <span class="n">range_</span><span class="p">)</span> <span class="o">-></span> <span class="n">Tracks</span><span class="p">:</span>
|
||||
</span><span id="__span-16-3"><a id="__codelineno-16-3" name="__codelineno-16-3" href="#__codelineno-16-3"></a> <span class="n">vcodec</span> <span class="o">=</span> <span class="s2">"H265"</span> <span class="k">if</span> <span class="n">codec</span> <span class="o">==</span> <span class="n">Video</span><span class="o">.</span><span class="n">Codec</span><span class="o">.</span><span class="n">HEVC</span> <span class="k">else</span> <span class="s2">"H264"</span>
|
||||
</span><span id="__span-16-4"><a id="__codelineno-16-4" name="__codelineno-16-4" href="#__codelineno-16-4"></a> <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">fetch_dash_manifest</span><span class="p">(</span><span class="n">title</span><span class="p">,</span> <span class="n">vcodec</span><span class="o">=</span><span class="n">vcodec</span><span class="p">,</span> <span class="n">range_</span><span class="o">=</span><span class="n">range_</span><span class="p">)</span>
|
||||
</span><span id="__span-16-5"><a id="__codelineno-16-5" name="__codelineno-16-5" href="#__codelineno-16-5"></a> <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">get_tracks_for_variants</span><span class="p">(</span><span class="n">title</span><span class="p">,</span> <span class="n">fetch_variant</span><span class="p">)</span>
|
||||
<div class="language-python highlight"><pre><span></span><code><span id="__span-17-1"><a id="__codelineno-17-1" name="__codelineno-17-1" href="#__codelineno-17-1"></a><span class="k">def</span><span class="w"> </span><span class="nf">get_tracks</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">title</span><span class="p">:</span> <span class="n">Title_T</span><span class="p">)</span> <span class="o">-></span> <span class="n">Tracks</span><span class="p">:</span>
|
||||
</span><span id="__span-17-2"><a id="__codelineno-17-2" name="__codelineno-17-2" href="#__codelineno-17-2"></a> <span class="k">def</span><span class="w"> </span><span class="nf">fetch_variant</span><span class="p">(</span><span class="n">title</span><span class="p">,</span> <span class="n">codec</span><span class="p">,</span> <span class="n">range_</span><span class="p">)</span> <span class="o">-></span> <span class="n">Tracks</span><span class="p">:</span>
|
||||
</span><span id="__span-17-3"><a id="__codelineno-17-3" name="__codelineno-17-3" href="#__codelineno-17-3"></a> <span class="n">vcodec</span> <span class="o">=</span> <span class="s2">"H265"</span> <span class="k">if</span> <span class="n">codec</span> <span class="o">==</span> <span class="n">Video</span><span class="o">.</span><span class="n">Codec</span><span class="o">.</span><span class="n">HEVC</span> <span class="k">else</span> <span class="s2">"H264"</span>
|
||||
</span><span id="__span-17-4"><a id="__codelineno-17-4" name="__codelineno-17-4" href="#__codelineno-17-4"></a> <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">fetch_dash_manifest</span><span class="p">(</span><span class="n">title</span><span class="p">,</span> <span class="n">vcodec</span><span class="o">=</span><span class="n">vcodec</span><span class="p">,</span> <span class="n">range_</span><span class="o">=</span><span class="n">range_</span><span class="p">)</span>
|
||||
</span><span id="__span-17-5"><a id="__codelineno-17-5" name="__codelineno-17-5" href="#__codelineno-17-5"></a> <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">get_tracks_for_variants</span><span class="p">(</span><span class="n">title</span><span class="p">,</span> <span class="n">fetch_variant</span><span class="p">)</span>
|
||||
</span></code></pre></div>
|
||||
<p>After parsing, you may <strong>correct</strong> track metadata the manifest gets wrong:
|
||||
stamp the real <code>video.range</code>, fix odd audio channel counts, mark descriptive
|
||||
@@ -2888,9 +2902,9 @@ sure encrypted tracks carry the correct <code>drm</code> so the core licenses th
|
||||
<p>Return a <code>Chapters</code> object of 0 or more <code>Chapter</code>s. It sorts by timestamp,
|
||||
numbers the chapters at mux time, and adds a <code>00:00:00.000</code> chapter if none
|
||||
exists. Timestamps take <code>"HH:MM:SS[.mmm]"</code>, int milliseconds, or float seconds.</p>
|
||||
<div class="language-python highlight"><pre><span></span><code><span id="__span-17-1"><a id="__codelineno-17-1" name="__codelineno-17-1" href="#__codelineno-17-1"></a><span class="k">def</span><span class="w"> </span><span class="nf">get_chapters</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">title</span><span class="p">:</span> <span class="n">Title_T</span><span class="p">)</span> <span class="o">-></span> <span class="n">Chapters</span><span class="p">:</span>
|
||||
</span><span id="__span-17-2"><a id="__codelineno-17-2" name="__codelineno-17-2" href="#__codelineno-17-2"></a> <span class="n">chapters</span> <span class="o">=</span> <span class="p">[</span><span class="n">Chapter</span><span class="p">(</span><span class="n">name</span><span class="o">=</span><span class="n">c</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"name"</span><span class="p">),</span> <span class="n">timestamp</span><span class="o">=</span><span class="n">c</span><span class="p">[</span><span class="s2">"start"</span><span class="p">])</span> <span class="k">for</span> <span class="n">c</span> <span class="ow">in</span> <span class="n">title</span><span class="o">.</span><span class="n">data</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"chapters"</span><span class="p">,</span> <span class="p">[])]</span>
|
||||
</span><span id="__span-17-3"><a id="__codelineno-17-3" name="__codelineno-17-3" href="#__codelineno-17-3"></a> <span class="k">return</span> <span class="n">Chapters</span><span class="p">(</span><span class="nb">sorted</span><span class="p">(</span><span class="n">chapters</span><span class="p">,</span> <span class="n">key</span><span class="o">=</span><span class="k">lambda</span> <span class="n">c</span><span class="p">:</span> <span class="n">c</span><span class="o">.</span><span class="n">timestamp</span><span class="p">))</span>
|
||||
<div class="language-python highlight"><pre><span></span><code><span id="__span-18-1"><a id="__codelineno-18-1" name="__codelineno-18-1" href="#__codelineno-18-1"></a><span class="k">def</span><span class="w"> </span><span class="nf">get_chapters</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">title</span><span class="p">:</span> <span class="n">Title_T</span><span class="p">)</span> <span class="o">-></span> <span class="n">Chapters</span><span class="p">:</span>
|
||||
</span><span id="__span-18-2"><a id="__codelineno-18-2" name="__codelineno-18-2" href="#__codelineno-18-2"></a> <span class="n">chapters</span> <span class="o">=</span> <span class="p">[</span><span class="n">Chapter</span><span class="p">(</span><span class="n">name</span><span class="o">=</span><span class="n">c</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"name"</span><span class="p">),</span> <span class="n">timestamp</span><span class="o">=</span><span class="n">c</span><span class="p">[</span><span class="s2">"start"</span><span class="p">])</span> <span class="k">for</span> <span class="n">c</span> <span class="ow">in</span> <span class="n">title</span><span class="o">.</span><span class="n">data</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"chapters"</span><span class="p">,</span> <span class="p">[])]</span>
|
||||
</span><span id="__span-18-3"><a id="__codelineno-18-3" name="__codelineno-18-3" href="#__codelineno-18-3"></a> <span class="k">return</span> <span class="n">Chapters</span><span class="p">(</span><span class="nb">sorted</span><span class="p">(</span><span class="n">chapters</span><span class="p">,</span> <span class="n">key</span><span class="o">=</span><span class="k">lambda</span> <span class="n">c</span><span class="p">:</span> <span class="n">c</span><span class="o">.</span><span class="n">timestamp</span><span class="p">))</span>
|
||||
</span></code></pre></div>
|
||||
<div class="admonition warning">
|
||||
<p class="admonition-title">Sort by timestamp before you build the <code>Chapters</code></p>
|
||||
@@ -2948,17 +2962,17 @@ current <code>title</code> and <code>track</code>:</p>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="language-python highlight"><pre><span></span><code><span id="__span-18-1"><a id="__codelineno-18-1" name="__codelineno-18-1" href="#__codelineno-18-1"></a><span class="k">def</span><span class="w"> </span><span class="nf">get_widevine_license</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">*</span><span class="p">,</span> <span class="n">challenge</span><span class="p">:</span> <span class="nb">bytes</span><span class="p">,</span> <span class="n">title</span><span class="p">,</span> <span class="n">track</span><span class="p">):</span>
|
||||
</span><span id="__span-18-2"><a id="__codelineno-18-2" name="__codelineno-18-2" href="#__codelineno-18-2"></a> <span class="n">response</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">session</span><span class="o">.</span><span class="n">post</span><span class="p">(</span>
|
||||
</span><span id="__span-18-3"><a id="__codelineno-18-3" name="__codelineno-18-3" href="#__codelineno-18-3"></a> <span class="bp">self</span><span class="o">.</span><span class="n">license_data</span><span class="p">[</span><span class="s2">"url"</span><span class="p">],</span>
|
||||
</span><span id="__span-18-4"><a id="__codelineno-18-4" name="__codelineno-18-4" href="#__codelineno-18-4"></a> <span class="n">data</span><span class="o">=</span><span class="n">challenge</span><span class="p">,</span> <span class="c1"># POST the challenge as-is</span>
|
||||
</span><span id="__span-18-5"><a id="__codelineno-18-5" name="__codelineno-18-5" href="#__codelineno-18-5"></a> <span class="n">headers</span><span class="o">=</span><span class="p">{</span><span class="s2">"dt-custom-data"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">license_data</span><span class="p">[</span><span class="s2">"data"</span><span class="p">]},</span>
|
||||
</span><span id="__span-18-6"><a id="__codelineno-18-6" name="__codelineno-18-6" href="#__codelineno-18-6"></a> <span class="p">)</span>
|
||||
</span><span id="__span-18-7"><a id="__codelineno-18-7" name="__codelineno-18-7" href="#__codelineno-18-7"></a> <span class="n">response</span><span class="o">.</span><span class="n">raise_for_status</span><span class="p">()</span>
|
||||
</span><span id="__span-18-8"><a id="__codelineno-18-8" name="__codelineno-18-8" href="#__codelineno-18-8"></a> <span class="k">try</span><span class="p">:</span>
|
||||
</span><span id="__span-18-9"><a id="__codelineno-18-9" name="__codelineno-18-9" href="#__codelineno-18-9"></a> <span class="k">return</span> <span class="n">response</span><span class="o">.</span><span class="n">json</span><span class="p">()[</span><span class="s2">"license"</span><span class="p">]</span> <span class="c1"># some services wrap it in JSON</span>
|
||||
</span><span id="__span-18-10"><a id="__codelineno-18-10" name="__codelineno-18-10" href="#__codelineno-18-10"></a> <span class="k">except</span> <span class="p">(</span><span class="ne">ValueError</span><span class="p">,</span> <span class="ne">KeyError</span><span class="p">):</span>
|
||||
</span><span id="__span-18-11"><a id="__codelineno-18-11" name="__codelineno-18-11" href="#__codelineno-18-11"></a> <span class="k">return</span> <span class="n">response</span><span class="o">.</span><span class="n">content</span> <span class="c1"># others return raw bytes</span>
|
||||
<div class="language-python highlight"><pre><span></span><code><span id="__span-19-1"><a id="__codelineno-19-1" name="__codelineno-19-1" href="#__codelineno-19-1"></a><span class="k">def</span><span class="w"> </span><span class="nf">get_widevine_license</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">*</span><span class="p">,</span> <span class="n">challenge</span><span class="p">:</span> <span class="nb">bytes</span><span class="p">,</span> <span class="n">title</span><span class="p">,</span> <span class="n">track</span><span class="p">):</span>
|
||||
</span><span id="__span-19-2"><a id="__codelineno-19-2" name="__codelineno-19-2" href="#__codelineno-19-2"></a> <span class="n">response</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">session</span><span class="o">.</span><span class="n">post</span><span class="p">(</span>
|
||||
</span><span id="__span-19-3"><a id="__codelineno-19-3" name="__codelineno-19-3" href="#__codelineno-19-3"></a> <span class="bp">self</span><span class="o">.</span><span class="n">license_data</span><span class="p">[</span><span class="s2">"url"</span><span class="p">],</span>
|
||||
</span><span id="__span-19-4"><a id="__codelineno-19-4" name="__codelineno-19-4" href="#__codelineno-19-4"></a> <span class="n">data</span><span class="o">=</span><span class="n">challenge</span><span class="p">,</span> <span class="c1"># POST the challenge as-is</span>
|
||||
</span><span id="__span-19-5"><a id="__codelineno-19-5" name="__codelineno-19-5" href="#__codelineno-19-5"></a> <span class="n">headers</span><span class="o">=</span><span class="p">{</span><span class="s2">"dt-custom-data"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">license_data</span><span class="p">[</span><span class="s2">"data"</span><span class="p">]},</span>
|
||||
</span><span id="__span-19-6"><a id="__codelineno-19-6" name="__codelineno-19-6" href="#__codelineno-19-6"></a> <span class="p">)</span>
|
||||
</span><span id="__span-19-7"><a id="__codelineno-19-7" name="__codelineno-19-7" href="#__codelineno-19-7"></a> <span class="n">response</span><span class="o">.</span><span class="n">raise_for_status</span><span class="p">()</span>
|
||||
</span><span id="__span-19-8"><a id="__codelineno-19-8" name="__codelineno-19-8" href="#__codelineno-19-8"></a> <span class="k">try</span><span class="p">:</span>
|
||||
</span><span id="__span-19-9"><a id="__codelineno-19-9" name="__codelineno-19-9" href="#__codelineno-19-9"></a> <span class="k">return</span> <span class="n">response</span><span class="o">.</span><span class="n">json</span><span class="p">()[</span><span class="s2">"license"</span><span class="p">]</span> <span class="c1"># some services wrap it in JSON</span>
|
||||
</span><span id="__span-19-10"><a id="__codelineno-19-10" name="__codelineno-19-10" href="#__codelineno-19-10"></a> <span class="k">except</span> <span class="p">(</span><span class="ne">ValueError</span><span class="p">,</span> <span class="ne">KeyError</span><span class="p">):</span>
|
||||
</span><span id="__span-19-11"><a id="__codelineno-19-11" name="__codelineno-19-11" href="#__codelineno-19-11"></a> <span class="k">return</span> <span class="n">response</span><span class="o">.</span><span class="n">content</span> <span class="c1"># others return raw bytes</span>
|
||||
</span></code></pre></div>
|
||||
<div class="admonition warning">
|
||||
<p class="admonition-title">Return the license untouched</p>
|
||||
@@ -2998,99 +3012,99 @@ flagged, banned, or downgraded.</p>
|
||||
<code>on_segment_downloaded</code>, <code>on_track_downloaded</code>, <code>on_track_decrypted</code>,
|
||||
<code>on_track_repacked</code>, <code>on_track_multiplex</code>. Also override <code>search()</code> to yield
|
||||
<code>SearchResult</code> objects for <code>unshackle search</code>.</p>
|
||||
<div class="language-python highlight"><pre><span></span><code><span id="__span-19-1"><a id="__codelineno-19-1" name="__codelineno-19-1" href="#__codelineno-19-1"></a><span class="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">-></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-19-2"><a id="__codelineno-19-2" name="__codelineno-19-2" href="#__codelineno-19-2"></a> <span class="n">results</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">session</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">config</span><span class="p">[</span><span class="s2">"endpoints"</span><span class="p">][</span><span class="s2">"search"</span><span class="p">],</span>
|
||||
</span><span id="__span-19-3"><a id="__codelineno-19-3" name="__codelineno-19-3" href="#__codelineno-19-3"></a> <span class="n">params</span><span class="o">=</span><span class="p">{</span><span class="s2">"q"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">title</span><span class="p">})</span><span class="o">.</span><span class="n">json</span><span class="p">()</span>
|
||||
</span><span id="__span-19-4"><a id="__codelineno-19-4" name="__codelineno-19-4" href="#__codelineno-19-4"></a> <span class="k">for</span> <span class="n">r</span> <span class="ow">in</span> <span class="n">results</span><span class="p">[</span><span class="s2">"entries"</span><span class="p">]:</span>
|
||||
</span><span id="__span-19-5"><a id="__codelineno-19-5" name="__codelineno-19-5" href="#__codelineno-19-5"></a> <span class="k">yield</span> <span class="n">SearchResult</span><span class="p">(</span><span class="n">id_</span><span class="o">=</span><span class="n">r</span><span class="p">[</span><span class="s2">"id"</span><span class="p">],</span> <span class="n">title</span><span class="o">=</span><span class="n">r</span><span class="p">[</span><span class="s2">"title"</span><span class="p">],</span>
|
||||
</span><span id="__span-19-6"><a id="__codelineno-19-6" name="__codelineno-19-6" href="#__codelineno-19-6"></a> <span class="n">description</span><span class="o">=</span><span class="n">r</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"description"</span><span class="p">),</span> <span class="n">url</span><span class="o">=</span><span class="n">r</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"url"</span><span class="p">))</span>
|
||||
<div class="language-python highlight"><pre><span></span><code><span id="__span-20-1"><a id="__codelineno-20-1" name="__codelineno-20-1" href="#__codelineno-20-1"></a><span class="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">-></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-20-2"><a id="__codelineno-20-2" name="__codelineno-20-2" href="#__codelineno-20-2"></a> <span class="n">results</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">session</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">config</span><span class="p">[</span><span class="s2">"endpoints"</span><span class="p">][</span><span class="s2">"search"</span><span class="p">],</span>
|
||||
</span><span id="__span-20-3"><a id="__codelineno-20-3" name="__codelineno-20-3" href="#__codelineno-20-3"></a> <span class="n">params</span><span class="o">=</span><span class="p">{</span><span class="s2">"q"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">title</span><span class="p">})</span><span class="o">.</span><span class="n">json</span><span class="p">()</span>
|
||||
</span><span id="__span-20-4"><a id="__codelineno-20-4" name="__codelineno-20-4" href="#__codelineno-20-4"></a> <span class="k">for</span> <span class="n">r</span> <span class="ow">in</span> <span class="n">results</span><span class="p">[</span><span class="s2">"entries"</span><span class="p">]:</span>
|
||||
</span><span id="__span-20-5"><a id="__codelineno-20-5" name="__codelineno-20-5" href="#__codelineno-20-5"></a> <span class="k">yield</span> <span class="n">SearchResult</span><span class="p">(</span><span class="n">id_</span><span class="o">=</span><span class="n">r</span><span class="p">[</span><span class="s2">"id"</span><span class="p">],</span> <span class="n">title</span><span class="o">=</span><span class="n">r</span><span class="p">[</span><span class="s2">"title"</span><span class="p">],</span>
|
||||
</span><span id="__span-20-6"><a id="__codelineno-20-6" name="__codelineno-20-6" href="#__codelineno-20-6"></a> <span class="n">description</span><span class="o">=</span><span class="n">r</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"description"</span><span class="p">),</span> <span class="n">url</span><span class="o">=</span><span class="n">r</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"url"</span><span class="p">))</span>
|
||||
</span></code></pre></div>
|
||||
<hr />
|
||||
<h2 id="minimal-service-skeleton">Minimal service skeleton<a class="headerlink" href="#minimal-service-skeleton" title="Permanent link">¶</a></h2>
|
||||
<p>A complete, minimal single-manifest service. Save as
|
||||
<code>services/MYSVC/__init__.py</code> (class name <code>MYSVC</code>), with an optional
|
||||
<code>services/MYSVC/config.yaml</code> beside it.</p>
|
||||
<div class="language-python highlight"><span class="filename">services/MYSVC/__init__.py</span><pre><span></span><code><span id="__span-20-1"><a id="__codelineno-20-1" name="__codelineno-20-1" href="#__codelineno-20-1"></a><span class="kn">from</span><span class="w"> </span><span class="nn">__future__</span><span class="w"> </span><span class="kn">import</span> <span class="n">annotations</span>
|
||||
</span><span id="__span-20-2"><a id="__codelineno-20-2" name="__codelineno-20-2" href="#__codelineno-20-2"></a>
|
||||
</span><span id="__span-20-3"><a id="__codelineno-20-3" name="__codelineno-20-3" href="#__codelineno-20-3"></a><span class="kn">import</span><span class="w"> </span><span class="nn">re</span>
|
||||
</span><span id="__span-20-4"><a id="__codelineno-20-4" name="__codelineno-20-4" href="#__codelineno-20-4"></a><span class="kn">from</span><span class="w"> </span><span class="nn">typing</span><span class="w"> </span><span class="kn">import</span> <span class="n">Any</span><span class="p">,</span> <span class="n">Optional</span>
|
||||
</span><span id="__span-20-5"><a id="__codelineno-20-5" name="__codelineno-20-5" href="#__codelineno-20-5"></a>
|
||||
</span><span id="__span-20-6"><a id="__codelineno-20-6" name="__codelineno-20-6" href="#__codelineno-20-6"></a><span class="kn">import</span><span class="w"> </span><span class="nn">click</span>
|
||||
</span><span id="__span-20-7"><a id="__codelineno-20-7" name="__codelineno-20-7" href="#__codelineno-20-7"></a>
|
||||
</span><span id="__span-20-8"><a id="__codelineno-20-8" name="__codelineno-20-8" href="#__codelineno-20-8"></a><span class="kn">from</span><span class="w"> </span><span class="nn">unshackle.core.manifests</span><span class="w"> </span><span class="kn">import</span> <span class="n">DASH</span>
|
||||
</span><span id="__span-20-9"><a id="__codelineno-20-9" name="__codelineno-20-9" href="#__codelineno-20-9"></a><span class="kn">from</span><span class="w"> </span><span class="nn">unshackle.core.service</span><span class="w"> </span><span class="kn">import</span> <span class="n">Service</span>
|
||||
</span><span id="__span-20-10"><a id="__codelineno-20-10" name="__codelineno-20-10" href="#__codelineno-20-10"></a><span class="kn">from</span><span class="w"> </span><span class="nn">unshackle.core.titles</span><span class="w"> </span><span class="kn">import</span> <span class="n">Movie</span><span class="p">,</span> <span class="n">Movies</span><span class="p">,</span> <span class="n">Title_T</span><span class="p">,</span> <span class="n">Titles_T</span>
|
||||
</span><span id="__span-20-11"><a id="__codelineno-20-11" name="__codelineno-20-11" href="#__codelineno-20-11"></a><span class="kn">from</span><span class="w"> </span><span class="nn">unshackle.core.tracks</span><span class="w"> </span><span class="kn">import</span> <span class="n">Chapters</span><span class="p">,</span> <span class="n">Tracks</span>
|
||||
</span><span id="__span-20-12"><a id="__codelineno-20-12" name="__codelineno-20-12" href="#__codelineno-20-12"></a>
|
||||
</span><span id="__span-20-13"><a id="__codelineno-20-13" name="__codelineno-20-13" href="#__codelineno-20-13"></a>
|
||||
</span><span id="__span-20-14"><a id="__codelineno-20-14" name="__codelineno-20-14" href="#__codelineno-20-14"></a><span class="k">class</span><span class="w"> </span><span class="nc">MYSVC</span><span class="p">(</span><span class="n">Service</span><span class="p">):</span>
|
||||
</span><span id="__span-20-15"><a id="__codelineno-20-15" name="__codelineno-20-15" href="#__codelineno-20-15"></a><span class="w"> </span><span class="sd">"""</span>
|
||||
</span><span id="__span-20-16"><a id="__codelineno-20-16" name="__codelineno-20-16" href="#__codelineno-20-16"></a><span class="sd"> MyService - https://myservice.com</span>
|
||||
</span><span id="__span-20-17"><a id="__codelineno-20-17" name="__codelineno-20-17" href="#__codelineno-20-17"></a>
|
||||
</span><span id="__span-20-18"><a id="__codelineno-20-18" name="__codelineno-20-18" href="#__codelineno-20-18"></a><span class="sd"> \b</span>
|
||||
</span><span id="__span-20-19"><a id="__codelineno-20-19" name="__codelineno-20-19" href="#__codelineno-20-19"></a><span class="sd"> Usage: unshackle dl MYSVC <title-id-or-url></span>
|
||||
</span><span id="__span-20-20"><a id="__codelineno-20-20" name="__codelineno-20-20" href="#__codelineno-20-20"></a><span class="sd"> """</span>
|
||||
</span><span id="__span-20-21"><a id="__codelineno-20-21" name="__codelineno-20-21" href="#__codelineno-20-21"></a>
|
||||
</span><span id="__span-20-22"><a id="__codelineno-20-22" name="__codelineno-20-22" href="#__codelineno-20-22"></a> <span class="n">ALIASES</span> <span class="o">=</span> <span class="p">(</span><span class="s2">"MY"</span><span class="p">,)</span>
|
||||
</span><span id="__span-20-23"><a id="__codelineno-20-23" name="__codelineno-20-23" href="#__codelineno-20-23"></a> <span class="n">GEOFENCE</span> <span class="o">=</span> <span class="p">(</span><span class="s2">"US"</span><span class="p">,)</span>
|
||||
</span><span id="__span-20-24"><a id="__codelineno-20-24" name="__codelineno-20-24" href="#__codelineno-20-24"></a> <span class="n">TITLE_RE</span> <span class="o">=</span> <span class="sa">r</span><span class="s2">"^(?:https?://myservice\.com/watch/)?(?P<id>[\w-]+)"</span>
|
||||
</span><span id="__span-20-25"><a id="__codelineno-20-25" name="__codelineno-20-25" href="#__codelineno-20-25"></a>
|
||||
</span><span id="__span-20-26"><a id="__codelineno-20-26" name="__codelineno-20-26" href="#__codelineno-20-26"></a> <span class="nd">@staticmethod</span>
|
||||
</span><span id="__span-20-27"><a id="__codelineno-20-27" name="__codelineno-20-27" href="#__codelineno-20-27"></a> <span class="nd">@click</span><span class="o">.</span><span class="n">command</span><span class="p">(</span><span class="n">name</span><span class="o">=</span><span class="s2">"MYSVC"</span><span class="p">,</span> <span class="n">short_help</span><span class="o">=</span><span class="s2">"https://myservice.com"</span><span class="p">,</span> <span class="n">help</span><span class="o">=</span><span class="vm">__doc__</span><span class="p">)</span>
|
||||
</span><span id="__span-20-28"><a id="__codelineno-20-28" name="__codelineno-20-28" href="#__codelineno-20-28"></a> <span class="nd">@click</span><span class="o">.</span><span class="n">argument</span><span class="p">(</span><span class="s2">"title"</span><span class="p">,</span> <span class="nb">type</span><span class="o">=</span><span class="nb">str</span><span class="p">)</span>
|
||||
</span><span id="__span-20-29"><a id="__codelineno-20-29" name="__codelineno-20-29" href="#__codelineno-20-29"></a> <span class="nd">@click</span><span class="o">.</span><span class="n">pass_context</span>
|
||||
</span><span id="__span-20-30"><a id="__codelineno-20-30" name="__codelineno-20-30" href="#__codelineno-20-30"></a> <span class="k">def</span><span class="w"> </span><span class="nf">cli</span><span class="p">(</span><span class="n">ctx</span><span class="p">:</span> <span class="n">click</span><span class="o">.</span><span class="n">Context</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">:</span> <span class="n">Any</span><span class="p">)</span> <span class="o">-></span> <span class="s2">"MYSVC"</span><span class="p">:</span>
|
||||
</span><span id="__span-20-31"><a id="__codelineno-20-31" name="__codelineno-20-31" href="#__codelineno-20-31"></a> <span class="k">return</span> <span class="n">MYSVC</span><span class="p">(</span><span class="n">ctx</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span>
|
||||
</span><span id="__span-20-32"><a id="__codelineno-20-32" name="__codelineno-20-32" href="#__codelineno-20-32"></a>
|
||||
</span><span id="__span-20-33"><a id="__codelineno-20-33" name="__codelineno-20-33" href="#__codelineno-20-33"></a> <span class="k">def</span><span class="w"> </span><span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">ctx</span><span class="p">:</span> <span class="n">click</span><span class="o">.</span><span class="n">Context</span><span class="p">,</span> <span class="n">title</span><span class="p">:</span> <span class="nb">str</span><span class="p">):</span>
|
||||
</span><span id="__span-20-34"><a id="__codelineno-20-34" name="__codelineno-20-34" href="#__codelineno-20-34"></a> <span class="bp">self</span><span class="o">.</span><span class="n">title</span> <span class="o">=</span> <span class="n">title</span>
|
||||
</span><span id="__span-20-35"><a id="__codelineno-20-35" name="__codelineno-20-35" href="#__codelineno-20-35"></a> <span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="fm">__init__</span><span class="p">(</span><span class="n">ctx</span><span class="p">)</span>
|
||||
</span><span id="__span-20-36"><a id="__codelineno-20-36" name="__codelineno-20-36" href="#__codelineno-20-36"></a>
|
||||
</span><span id="__span-20-37"><a id="__codelineno-20-37" name="__codelineno-20-37" href="#__codelineno-20-37"></a> <span class="k">def</span><span class="w"> </span><span class="nf">authenticate</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">cookies</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">credential</span><span class="o">=</span><span class="kc">None</span><span class="p">)</span> <span class="o">-></span> <span class="kc">None</span><span class="p">:</span>
|
||||
</span><span id="__span-20-38"><a id="__codelineno-20-38" name="__codelineno-20-38" href="#__codelineno-20-38"></a> <span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="n">authenticate</span><span class="p">(</span><span class="n">cookies</span><span class="p">,</span> <span class="n">credential</span><span class="p">)</span>
|
||||
</span><span id="__span-20-39"><a id="__codelineno-20-39" name="__codelineno-20-39" href="#__codelineno-20-39"></a> <span class="c1"># obtain any tokens here, e.g. self.token = ...</span>
|
||||
</span><span id="__span-20-40"><a id="__codelineno-20-40" name="__codelineno-20-40" href="#__codelineno-20-40"></a>
|
||||
</span><span id="__span-20-41"><a id="__codelineno-20-41" name="__codelineno-20-41" href="#__codelineno-20-41"></a> <span class="k">def</span><span class="w"> </span><span class="nf">get_titles</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-></span> <span class="n">Titles_T</span><span class="p">:</span>
|
||||
</span><span id="__span-20-42"><a id="__codelineno-20-42" name="__codelineno-20-42" href="#__codelineno-20-42"></a> <span class="n">match</span> <span class="o">=</span> <span class="n">re</span><span class="o">.</span><span class="n">match</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">TITLE_RE</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">title</span><span class="p">)</span>
|
||||
</span><span id="__span-20-43"><a id="__codelineno-20-43" name="__codelineno-20-43" href="#__codelineno-20-43"></a> <span class="k">if</span> <span class="ow">not</span> <span class="n">match</span><span class="p">:</span>
|
||||
</span><span id="__span-20-44"><a id="__codelineno-20-44" name="__codelineno-20-44" href="#__codelineno-20-44"></a> <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s2">"Could not parse a title ID."</span><span class="p">)</span>
|
||||
</span><span id="__span-20-45"><a id="__codelineno-20-45" name="__codelineno-20-45" href="#__codelineno-20-45"></a> <span class="n">meta</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">session</span><span class="o">.</span><span class="n">get</span><span class="p">(</span>
|
||||
</span><span id="__span-20-46"><a id="__codelineno-20-46" name="__codelineno-20-46" href="#__codelineno-20-46"></a> <span class="bp">self</span><span class="o">.</span><span class="n">config</span><span class="p">[</span><span class="s2">"endpoints"</span><span class="p">][</span><span class="s2">"metadata"</span><span class="p">]</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="nb">id</span><span class="o">=</span><span class="n">match</span><span class="o">.</span><span class="n">group</span><span class="p">(</span><span class="s2">"id"</span><span class="p">))</span>
|
||||
</span><span id="__span-20-47"><a id="__codelineno-20-47" name="__codelineno-20-47" href="#__codelineno-20-47"></a> <span class="p">)</span><span class="o">.</span><span class="n">json</span><span class="p">()</span>
|
||||
</span><span id="__span-20-48"><a id="__codelineno-20-48" name="__codelineno-20-48" href="#__codelineno-20-48"></a> <span class="k">return</span> <span class="n">Movies</span><span class="p">([</span>
|
||||
</span><span id="__span-20-49"><a id="__codelineno-20-49" name="__codelineno-20-49" href="#__codelineno-20-49"></a> <span class="n">Movie</span><span class="p">(</span>
|
||||
</span><span id="__span-20-50"><a id="__codelineno-20-50" name="__codelineno-20-50" href="#__codelineno-20-50"></a> <span class="n">id_</span><span class="o">=</span><span class="n">meta</span><span class="p">[</span><span class="s2">"id"</span><span class="p">],</span>
|
||||
</span><span id="__span-20-51"><a id="__codelineno-20-51" name="__codelineno-20-51" href="#__codelineno-20-51"></a> <span class="n">service</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="vm">__class__</span><span class="p">,</span>
|
||||
</span><span id="__span-20-52"><a id="__codelineno-20-52" name="__codelineno-20-52" href="#__codelineno-20-52"></a> <span class="n">name</span><span class="o">=</span><span class="n">meta</span><span class="p">[</span><span class="s2">"title"</span><span class="p">],</span>
|
||||
</span><span id="__span-20-53"><a id="__codelineno-20-53" name="__codelineno-20-53" href="#__codelineno-20-53"></a> <span class="n">year</span><span class="o">=</span><span class="n">meta</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"year"</span><span class="p">)</span> <span class="ow">or</span> <span class="kc">None</span><span class="p">,</span>
|
||||
</span><span id="__span-20-54"><a id="__codelineno-20-54" name="__codelineno-20-54" href="#__codelineno-20-54"></a> <span class="n">language</span><span class="o">=</span><span class="n">meta</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"originalLanguage"</span><span class="p">),</span>
|
||||
</span><span id="__span-20-55"><a id="__codelineno-20-55" name="__codelineno-20-55" href="#__codelineno-20-55"></a> <span class="n">data</span><span class="o">=</span><span class="n">meta</span><span class="p">,</span>
|
||||
</span><span id="__span-20-56"><a id="__codelineno-20-56" name="__codelineno-20-56" href="#__codelineno-20-56"></a> <span class="p">)</span>
|
||||
</span><span id="__span-20-57"><a id="__codelineno-20-57" name="__codelineno-20-57" href="#__codelineno-20-57"></a> <span class="p">])</span>
|
||||
</span><span id="__span-20-58"><a id="__codelineno-20-58" name="__codelineno-20-58" href="#__codelineno-20-58"></a>
|
||||
</span><span id="__span-20-59"><a id="__codelineno-20-59" name="__codelineno-20-59" href="#__codelineno-20-59"></a> <span class="k">def</span><span class="w"> </span><span class="nf">get_tracks</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">title</span><span class="p">:</span> <span class="n">Title_T</span><span class="p">)</span> <span class="o">-></span> <span class="n">Tracks</span><span class="p">:</span>
|
||||
</span><span id="__span-20-60"><a id="__codelineno-20-60" name="__codelineno-20-60" href="#__codelineno-20-60"></a> <span class="n">playback</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">session</span><span class="o">.</span><span class="n">get</span><span class="p">(</span>
|
||||
</span><span id="__span-20-61"><a id="__codelineno-20-61" name="__codelineno-20-61" href="#__codelineno-20-61"></a> <span class="bp">self</span><span class="o">.</span><span class="n">config</span><span class="p">[</span><span class="s2">"endpoints"</span><span class="p">][</span><span class="s2">"playback"</span><span class="p">]</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="nb">id</span><span class="o">=</span><span class="n">title</span><span class="o">.</span><span class="n">id</span><span class="p">)</span>
|
||||
</span><span id="__span-20-62"><a id="__codelineno-20-62" name="__codelineno-20-62" href="#__codelineno-20-62"></a> <span class="p">)</span><span class="o">.</span><span class="n">json</span><span class="p">()</span>
|
||||
</span><span id="__span-20-63"><a id="__codelineno-20-63" name="__codelineno-20-63" href="#__codelineno-20-63"></a> <span class="k">return</span> <span class="n">DASH</span><span class="o">.</span><span class="n">from_url</span><span class="p">(</span>
|
||||
</span><span id="__span-20-64"><a id="__codelineno-20-64" name="__codelineno-20-64" href="#__codelineno-20-64"></a> <span class="n">url</span><span class="o">=</span><span class="n">playback</span><span class="p">[</span><span class="s2">"manifest_url"</span><span class="p">],</span> <span class="n">session</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">session</span>
|
||||
</span><span id="__span-20-65"><a id="__codelineno-20-65" name="__codelineno-20-65" href="#__codelineno-20-65"></a> <span class="p">)</span><span class="o">.</span><span class="n">to_tracks</span><span class="p">(</span><span class="n">language</span><span class="o">=</span><span class="n">title</span><span class="o">.</span><span class="n">language</span><span class="p">)</span>
|
||||
</span><span id="__span-20-66"><a id="__codelineno-20-66" name="__codelineno-20-66" href="#__codelineno-20-66"></a>
|
||||
</span><span id="__span-20-67"><a id="__codelineno-20-67" name="__codelineno-20-67" href="#__codelineno-20-67"></a> <span class="k">def</span><span class="w"> </span><span class="nf">get_chapters</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">title</span><span class="p">:</span> <span class="n">Title_T</span><span class="p">)</span> <span class="o">-></span> <span class="n">Chapters</span><span class="p">:</span>
|
||||
</span><span id="__span-20-68"><a id="__codelineno-20-68" name="__codelineno-20-68" href="#__codelineno-20-68"></a> <span class="k">return</span> <span class="n">Chapters</span><span class="p">()</span>
|
||||
</span><span id="__span-20-69"><a id="__codelineno-20-69" name="__codelineno-20-69" href="#__codelineno-20-69"></a>
|
||||
</span><span id="__span-20-70"><a id="__codelineno-20-70" name="__codelineno-20-70" href="#__codelineno-20-70"></a> <span class="k">def</span><span class="w"> </span><span class="nf">get_widevine_license</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">*</span><span class="p">,</span> <span class="n">challenge</span><span class="p">:</span> <span class="nb">bytes</span><span class="p">,</span> <span class="n">title</span><span class="p">,</span> <span class="n">track</span><span class="p">):</span>
|
||||
</span><span id="__span-20-71"><a id="__codelineno-20-71" name="__codelineno-20-71" href="#__codelineno-20-71"></a> <span class="n">res</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">session</span><span class="o">.</span><span class="n">post</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">config</span><span class="p">[</span><span class="s2">"endpoints"</span><span class="p">][</span><span class="s2">"license"</span><span class="p">],</span> <span class="n">data</span><span class="o">=</span><span class="n">challenge</span><span class="p">)</span>
|
||||
</span><span id="__span-20-72"><a id="__codelineno-20-72" name="__codelineno-20-72" href="#__codelineno-20-72"></a> <span class="n">res</span><span class="o">.</span><span class="n">raise_for_status</span><span class="p">()</span>
|
||||
</span><span id="__span-20-73"><a id="__codelineno-20-73" name="__codelineno-20-73" href="#__codelineno-20-73"></a> <span class="k">return</span> <span class="n">res</span><span class="o">.</span><span class="n">content</span>
|
||||
<div class="language-python highlight"><span class="filename">services/MYSVC/__init__.py</span><pre><span></span><code><span id="__span-21-1"><a id="__codelineno-21-1" name="__codelineno-21-1" href="#__codelineno-21-1"></a><span class="kn">from</span><span class="w"> </span><span class="nn">__future__</span><span class="w"> </span><span class="kn">import</span> <span class="n">annotations</span>
|
||||
</span><span id="__span-21-2"><a id="__codelineno-21-2" name="__codelineno-21-2" href="#__codelineno-21-2"></a>
|
||||
</span><span id="__span-21-3"><a id="__codelineno-21-3" name="__codelineno-21-3" href="#__codelineno-21-3"></a><span class="kn">import</span><span class="w"> </span><span class="nn">re</span>
|
||||
</span><span id="__span-21-4"><a id="__codelineno-21-4" name="__codelineno-21-4" href="#__codelineno-21-4"></a><span class="kn">from</span><span class="w"> </span><span class="nn">typing</span><span class="w"> </span><span class="kn">import</span> <span class="n">Any</span><span class="p">,</span> <span class="n">Optional</span>
|
||||
</span><span id="__span-21-5"><a id="__codelineno-21-5" name="__codelineno-21-5" href="#__codelineno-21-5"></a>
|
||||
</span><span id="__span-21-6"><a id="__codelineno-21-6" name="__codelineno-21-6" href="#__codelineno-21-6"></a><span class="kn">import</span><span class="w"> </span><span class="nn">click</span>
|
||||
</span><span id="__span-21-7"><a id="__codelineno-21-7" name="__codelineno-21-7" href="#__codelineno-21-7"></a>
|
||||
</span><span id="__span-21-8"><a id="__codelineno-21-8" name="__codelineno-21-8" href="#__codelineno-21-8"></a><span class="kn">from</span><span class="w"> </span><span class="nn">unshackle.core.manifests</span><span class="w"> </span><span class="kn">import</span> <span class="n">DASH</span>
|
||||
</span><span id="__span-21-9"><a id="__codelineno-21-9" name="__codelineno-21-9" href="#__codelineno-21-9"></a><span class="kn">from</span><span class="w"> </span><span class="nn">unshackle.core.service</span><span class="w"> </span><span class="kn">import</span> <span class="n">Service</span>
|
||||
</span><span id="__span-21-10"><a id="__codelineno-21-10" name="__codelineno-21-10" href="#__codelineno-21-10"></a><span class="kn">from</span><span class="w"> </span><span class="nn">unshackle.core.titles</span><span class="w"> </span><span class="kn">import</span> <span class="n">Movie</span><span class="p">,</span> <span class="n">Movies</span><span class="p">,</span> <span class="n">Title_T</span><span class="p">,</span> <span class="n">Titles_T</span>
|
||||
</span><span id="__span-21-11"><a id="__codelineno-21-11" name="__codelineno-21-11" href="#__codelineno-21-11"></a><span class="kn">from</span><span class="w"> </span><span class="nn">unshackle.core.tracks</span><span class="w"> </span><span class="kn">import</span> <span class="n">Chapters</span><span class="p">,</span> <span class="n">Tracks</span>
|
||||
</span><span id="__span-21-12"><a id="__codelineno-21-12" name="__codelineno-21-12" href="#__codelineno-21-12"></a>
|
||||
</span><span id="__span-21-13"><a id="__codelineno-21-13" name="__codelineno-21-13" href="#__codelineno-21-13"></a>
|
||||
</span><span id="__span-21-14"><a id="__codelineno-21-14" name="__codelineno-21-14" href="#__codelineno-21-14"></a><span class="k">class</span><span class="w"> </span><span class="nc">MYSVC</span><span class="p">(</span><span class="n">Service</span><span class="p">):</span>
|
||||
</span><span id="__span-21-15"><a id="__codelineno-21-15" name="__codelineno-21-15" href="#__codelineno-21-15"></a><span class="w"> </span><span class="sd">"""</span>
|
||||
</span><span id="__span-21-16"><a id="__codelineno-21-16" name="__codelineno-21-16" href="#__codelineno-21-16"></a><span class="sd"> MyService - https://myservice.com</span>
|
||||
</span><span id="__span-21-17"><a id="__codelineno-21-17" name="__codelineno-21-17" href="#__codelineno-21-17"></a>
|
||||
</span><span id="__span-21-18"><a id="__codelineno-21-18" name="__codelineno-21-18" href="#__codelineno-21-18"></a><span class="sd"> \b</span>
|
||||
</span><span id="__span-21-19"><a id="__codelineno-21-19" name="__codelineno-21-19" href="#__codelineno-21-19"></a><span class="sd"> Usage: unshackle dl MYSVC <title-id-or-url></span>
|
||||
</span><span id="__span-21-20"><a id="__codelineno-21-20" name="__codelineno-21-20" href="#__codelineno-21-20"></a><span class="sd"> """</span>
|
||||
</span><span id="__span-21-21"><a id="__codelineno-21-21" name="__codelineno-21-21" href="#__codelineno-21-21"></a>
|
||||
</span><span id="__span-21-22"><a id="__codelineno-21-22" name="__codelineno-21-22" href="#__codelineno-21-22"></a> <span class="n">ALIASES</span> <span class="o">=</span> <span class="p">(</span><span class="s2">"MY"</span><span class="p">,)</span>
|
||||
</span><span id="__span-21-23"><a id="__codelineno-21-23" name="__codelineno-21-23" href="#__codelineno-21-23"></a> <span class="n">GEOFENCE</span> <span class="o">=</span> <span class="p">(</span><span class="s2">"US"</span><span class="p">,)</span>
|
||||
</span><span id="__span-21-24"><a id="__codelineno-21-24" name="__codelineno-21-24" href="#__codelineno-21-24"></a> <span class="n">TITLE_RE</span> <span class="o">=</span> <span class="sa">r</span><span class="s2">"^(?:https?://myservice\.com/watch/)?(?P<id>[\w-]+)"</span>
|
||||
</span><span id="__span-21-25"><a id="__codelineno-21-25" name="__codelineno-21-25" href="#__codelineno-21-25"></a>
|
||||
</span><span id="__span-21-26"><a id="__codelineno-21-26" name="__codelineno-21-26" href="#__codelineno-21-26"></a> <span class="nd">@staticmethod</span>
|
||||
</span><span id="__span-21-27"><a id="__codelineno-21-27" name="__codelineno-21-27" href="#__codelineno-21-27"></a> <span class="nd">@click</span><span class="o">.</span><span class="n">command</span><span class="p">(</span><span class="n">name</span><span class="o">=</span><span class="s2">"MYSVC"</span><span class="p">,</span> <span class="n">short_help</span><span class="o">=</span><span class="s2">"https://myservice.com"</span><span class="p">,</span> <span class="n">help</span><span class="o">=</span><span class="vm">__doc__</span><span class="p">)</span>
|
||||
</span><span id="__span-21-28"><a id="__codelineno-21-28" name="__codelineno-21-28" href="#__codelineno-21-28"></a> <span class="nd">@click</span><span class="o">.</span><span class="n">argument</span><span class="p">(</span><span class="s2">"title"</span><span class="p">,</span> <span class="nb">type</span><span class="o">=</span><span class="nb">str</span><span class="p">)</span>
|
||||
</span><span id="__span-21-29"><a id="__codelineno-21-29" name="__codelineno-21-29" href="#__codelineno-21-29"></a> <span class="nd">@click</span><span class="o">.</span><span class="n">pass_context</span>
|
||||
</span><span id="__span-21-30"><a id="__codelineno-21-30" name="__codelineno-21-30" href="#__codelineno-21-30"></a> <span class="k">def</span><span class="w"> </span><span class="nf">cli</span><span class="p">(</span><span class="n">ctx</span><span class="p">:</span> <span class="n">click</span><span class="o">.</span><span class="n">Context</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">:</span> <span class="n">Any</span><span class="p">)</span> <span class="o">-></span> <span class="s2">"MYSVC"</span><span class="p">:</span>
|
||||
</span><span id="__span-21-31"><a id="__codelineno-21-31" name="__codelineno-21-31" href="#__codelineno-21-31"></a> <span class="k">return</span> <span class="n">MYSVC</span><span class="p">(</span><span class="n">ctx</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span>
|
||||
</span><span id="__span-21-32"><a id="__codelineno-21-32" name="__codelineno-21-32" href="#__codelineno-21-32"></a>
|
||||
</span><span id="__span-21-33"><a id="__codelineno-21-33" name="__codelineno-21-33" href="#__codelineno-21-33"></a> <span class="k">def</span><span class="w"> </span><span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">ctx</span><span class="p">:</span> <span class="n">click</span><span class="o">.</span><span class="n">Context</span><span class="p">,</span> <span class="n">title</span><span class="p">:</span> <span class="nb">str</span><span class="p">):</span>
|
||||
</span><span id="__span-21-34"><a id="__codelineno-21-34" name="__codelineno-21-34" href="#__codelineno-21-34"></a> <span class="bp">self</span><span class="o">.</span><span class="n">title</span> <span class="o">=</span> <span class="n">title</span>
|
||||
</span><span id="__span-21-35"><a id="__codelineno-21-35" name="__codelineno-21-35" href="#__codelineno-21-35"></a> <span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="fm">__init__</span><span class="p">(</span><span class="n">ctx</span><span class="p">)</span>
|
||||
</span><span id="__span-21-36"><a id="__codelineno-21-36" name="__codelineno-21-36" href="#__codelineno-21-36"></a>
|
||||
</span><span id="__span-21-37"><a id="__codelineno-21-37" name="__codelineno-21-37" href="#__codelineno-21-37"></a> <span class="k">def</span><span class="w"> </span><span class="nf">authenticate</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">cookies</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">credential</span><span class="o">=</span><span class="kc">None</span><span class="p">)</span> <span class="o">-></span> <span class="kc">None</span><span class="p">:</span>
|
||||
</span><span id="__span-21-38"><a id="__codelineno-21-38" name="__codelineno-21-38" href="#__codelineno-21-38"></a> <span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="n">authenticate</span><span class="p">(</span><span class="n">cookies</span><span class="p">,</span> <span class="n">credential</span><span class="p">)</span>
|
||||
</span><span id="__span-21-39"><a id="__codelineno-21-39" name="__codelineno-21-39" href="#__codelineno-21-39"></a> <span class="c1"># obtain any tokens here, e.g. self.token = ...</span>
|
||||
</span><span id="__span-21-40"><a id="__codelineno-21-40" name="__codelineno-21-40" href="#__codelineno-21-40"></a>
|
||||
</span><span id="__span-21-41"><a id="__codelineno-21-41" name="__codelineno-21-41" href="#__codelineno-21-41"></a> <span class="k">def</span><span class="w"> </span><span class="nf">get_titles</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-></span> <span class="n">Titles_T</span><span class="p">:</span>
|
||||
</span><span id="__span-21-42"><a id="__codelineno-21-42" name="__codelineno-21-42" href="#__codelineno-21-42"></a> <span class="n">match</span> <span class="o">=</span> <span class="n">re</span><span class="o">.</span><span class="n">match</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">TITLE_RE</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">title</span><span class="p">)</span>
|
||||
</span><span id="__span-21-43"><a id="__codelineno-21-43" name="__codelineno-21-43" href="#__codelineno-21-43"></a> <span class="k">if</span> <span class="ow">not</span> <span class="n">match</span><span class="p">:</span>
|
||||
</span><span id="__span-21-44"><a id="__codelineno-21-44" name="__codelineno-21-44" href="#__codelineno-21-44"></a> <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s2">"Could not parse a title ID."</span><span class="p">)</span>
|
||||
</span><span id="__span-21-45"><a id="__codelineno-21-45" name="__codelineno-21-45" href="#__codelineno-21-45"></a> <span class="n">meta</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">session</span><span class="o">.</span><span class="n">get</span><span class="p">(</span>
|
||||
</span><span id="__span-21-46"><a id="__codelineno-21-46" name="__codelineno-21-46" href="#__codelineno-21-46"></a> <span class="bp">self</span><span class="o">.</span><span class="n">config</span><span class="p">[</span><span class="s2">"endpoints"</span><span class="p">][</span><span class="s2">"metadata"</span><span class="p">]</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="nb">id</span><span class="o">=</span><span class="n">match</span><span class="o">.</span><span class="n">group</span><span class="p">(</span><span class="s2">"id"</span><span class="p">))</span>
|
||||
</span><span id="__span-21-47"><a id="__codelineno-21-47" name="__codelineno-21-47" href="#__codelineno-21-47"></a> <span class="p">)</span><span class="o">.</span><span class="n">json</span><span class="p">()</span>
|
||||
</span><span id="__span-21-48"><a id="__codelineno-21-48" name="__codelineno-21-48" href="#__codelineno-21-48"></a> <span class="k">return</span> <span class="n">Movies</span><span class="p">([</span>
|
||||
</span><span id="__span-21-49"><a id="__codelineno-21-49" name="__codelineno-21-49" href="#__codelineno-21-49"></a> <span class="n">Movie</span><span class="p">(</span>
|
||||
</span><span id="__span-21-50"><a id="__codelineno-21-50" name="__codelineno-21-50" href="#__codelineno-21-50"></a> <span class="n">id_</span><span class="o">=</span><span class="n">meta</span><span class="p">[</span><span class="s2">"id"</span><span class="p">],</span>
|
||||
</span><span id="__span-21-51"><a id="__codelineno-21-51" name="__codelineno-21-51" href="#__codelineno-21-51"></a> <span class="n">service</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="vm">__class__</span><span class="p">,</span>
|
||||
</span><span id="__span-21-52"><a id="__codelineno-21-52" name="__codelineno-21-52" href="#__codelineno-21-52"></a> <span class="n">name</span><span class="o">=</span><span class="n">meta</span><span class="p">[</span><span class="s2">"title"</span><span class="p">],</span>
|
||||
</span><span id="__span-21-53"><a id="__codelineno-21-53" name="__codelineno-21-53" href="#__codelineno-21-53"></a> <span class="n">year</span><span class="o">=</span><span class="n">meta</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"year"</span><span class="p">)</span> <span class="ow">or</span> <span class="kc">None</span><span class="p">,</span>
|
||||
</span><span id="__span-21-54"><a id="__codelineno-21-54" name="__codelineno-21-54" href="#__codelineno-21-54"></a> <span class="n">language</span><span class="o">=</span><span class="n">meta</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"originalLanguage"</span><span class="p">),</span>
|
||||
</span><span id="__span-21-55"><a id="__codelineno-21-55" name="__codelineno-21-55" href="#__codelineno-21-55"></a> <span class="n">data</span><span class="o">=</span><span class="n">meta</span><span class="p">,</span>
|
||||
</span><span id="__span-21-56"><a id="__codelineno-21-56" name="__codelineno-21-56" href="#__codelineno-21-56"></a> <span class="p">)</span>
|
||||
</span><span id="__span-21-57"><a id="__codelineno-21-57" name="__codelineno-21-57" href="#__codelineno-21-57"></a> <span class="p">])</span>
|
||||
</span><span id="__span-21-58"><a id="__codelineno-21-58" name="__codelineno-21-58" href="#__codelineno-21-58"></a>
|
||||
</span><span id="__span-21-59"><a id="__codelineno-21-59" name="__codelineno-21-59" href="#__codelineno-21-59"></a> <span class="k">def</span><span class="w"> </span><span class="nf">get_tracks</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">title</span><span class="p">:</span> <span class="n">Title_T</span><span class="p">)</span> <span class="o">-></span> <span class="n">Tracks</span><span class="p">:</span>
|
||||
</span><span id="__span-21-60"><a id="__codelineno-21-60" name="__codelineno-21-60" href="#__codelineno-21-60"></a> <span class="n">playback</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">session</span><span class="o">.</span><span class="n">get</span><span class="p">(</span>
|
||||
</span><span id="__span-21-61"><a id="__codelineno-21-61" name="__codelineno-21-61" href="#__codelineno-21-61"></a> <span class="bp">self</span><span class="o">.</span><span class="n">config</span><span class="p">[</span><span class="s2">"endpoints"</span><span class="p">][</span><span class="s2">"playback"</span><span class="p">]</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="nb">id</span><span class="o">=</span><span class="n">title</span><span class="o">.</span><span class="n">id</span><span class="p">)</span>
|
||||
</span><span id="__span-21-62"><a id="__codelineno-21-62" name="__codelineno-21-62" href="#__codelineno-21-62"></a> <span class="p">)</span><span class="o">.</span><span class="n">json</span><span class="p">()</span>
|
||||
</span><span id="__span-21-63"><a id="__codelineno-21-63" name="__codelineno-21-63" href="#__codelineno-21-63"></a> <span class="k">return</span> <span class="n">DASH</span><span class="o">.</span><span class="n">from_url</span><span class="p">(</span>
|
||||
</span><span id="__span-21-64"><a id="__codelineno-21-64" name="__codelineno-21-64" href="#__codelineno-21-64"></a> <span class="n">url</span><span class="o">=</span><span class="n">playback</span><span class="p">[</span><span class="s2">"manifest_url"</span><span class="p">],</span> <span class="n">session</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">session</span>
|
||||
</span><span id="__span-21-65"><a id="__codelineno-21-65" name="__codelineno-21-65" href="#__codelineno-21-65"></a> <span class="p">)</span><span class="o">.</span><span class="n">to_tracks</span><span class="p">(</span><span class="n">language</span><span class="o">=</span><span class="n">title</span><span class="o">.</span><span class="n">language</span><span class="p">)</span>
|
||||
</span><span id="__span-21-66"><a id="__codelineno-21-66" name="__codelineno-21-66" href="#__codelineno-21-66"></a>
|
||||
</span><span id="__span-21-67"><a id="__codelineno-21-67" name="__codelineno-21-67" href="#__codelineno-21-67"></a> <span class="k">def</span><span class="w"> </span><span class="nf">get_chapters</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">title</span><span class="p">:</span> <span class="n">Title_T</span><span class="p">)</span> <span class="o">-></span> <span class="n">Chapters</span><span class="p">:</span>
|
||||
</span><span id="__span-21-68"><a id="__codelineno-21-68" name="__codelineno-21-68" href="#__codelineno-21-68"></a> <span class="k">return</span> <span class="n">Chapters</span><span class="p">()</span>
|
||||
</span><span id="__span-21-69"><a id="__codelineno-21-69" name="__codelineno-21-69" href="#__codelineno-21-69"></a>
|
||||
</span><span id="__span-21-70"><a id="__codelineno-21-70" name="__codelineno-21-70" href="#__codelineno-21-70"></a> <span class="k">def</span><span class="w"> </span><span class="nf">get_widevine_license</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">*</span><span class="p">,</span> <span class="n">challenge</span><span class="p">:</span> <span class="nb">bytes</span><span class="p">,</span> <span class="n">title</span><span class="p">,</span> <span class="n">track</span><span class="p">):</span>
|
||||
</span><span id="__span-21-71"><a id="__codelineno-21-71" name="__codelineno-21-71" href="#__codelineno-21-71"></a> <span class="n">res</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">session</span><span class="o">.</span><span class="n">post</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">config</span><span class="p">[</span><span class="s2">"endpoints"</span><span class="p">][</span><span class="s2">"license"</span><span class="p">],</span> <span class="n">data</span><span class="o">=</span><span class="n">challenge</span><span class="p">)</span>
|
||||
</span><span id="__span-21-72"><a id="__codelineno-21-72" name="__codelineno-21-72" href="#__codelineno-21-72"></a> <span class="n">res</span><span class="o">.</span><span class="n">raise_for_status</span><span class="p">()</span>
|
||||
</span><span id="__span-21-73"><a id="__codelineno-21-73" name="__codelineno-21-73" href="#__codelineno-21-73"></a> <span class="k">return</span> <span class="n">res</span><span class="o">.</span><span class="n">content</span>
|
||||
</span></code></pre></div>
|
||||
<div class="language-yaml highlight"><span class="filename">services/MYSVC/config.yaml</span><pre><span></span><code><span id="__span-21-1"><a id="__codelineno-21-1" name="__codelineno-21-1" href="#__codelineno-21-1"></a><span class="nt">endpoints</span><span class="p">:</span>
|
||||
</span><span id="__span-21-2"><a id="__codelineno-21-2" name="__codelineno-21-2" href="#__codelineno-21-2"></a><span class="w"> </span><span class="nt">metadata</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">https://api.myservice.com/v1/metadata/{id}</span>
|
||||
</span><span id="__span-21-3"><a id="__codelineno-21-3" name="__codelineno-21-3" href="#__codelineno-21-3"></a><span class="w"> </span><span class="nt">playback</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">https://api.myservice.com/v1/playback/{id}</span>
|
||||
</span><span id="__span-21-4"><a id="__codelineno-21-4" name="__codelineno-21-4" href="#__codelineno-21-4"></a><span class="w"> </span><span class="nt">license</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">https://api.myservice.com/v1/license/widevine</span>
|
||||
<div class="language-yaml highlight"><span class="filename">services/MYSVC/config.yaml</span><pre><span></span><code><span id="__span-22-1"><a id="__codelineno-22-1" name="__codelineno-22-1" href="#__codelineno-22-1"></a><span class="nt">endpoints</span><span class="p">:</span>
|
||||
</span><span id="__span-22-2"><a id="__codelineno-22-2" name="__codelineno-22-2" href="#__codelineno-22-2"></a><span class="w"> </span><span class="nt">metadata</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">https://api.myservice.com/v1/metadata/{id}</span>
|
||||
</span><span id="__span-22-3"><a id="__codelineno-22-3" name="__codelineno-22-3" href="#__codelineno-22-3"></a><span class="w"> </span><span class="nt">playback</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">https://api.myservice.com/v1/playback/{id}</span>
|
||||
</span><span id="__span-22-4"><a id="__codelineno-22-4" name="__codelineno-22-4" href="#__codelineno-22-4"></a><span class="w"> </span><span class="nt">license</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">https://api.myservice.com/v1/license/widevine</span>
|
||||
</span></code></pre></div>
|
||||
<p>Try it with:</p>
|
||||
<div class="language-bash highlight"><pre><span></span><code><span id="__span-22-1"><a id="__codelineno-22-1" name="__codelineno-22-1" href="#__codelineno-22-1"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>MYSVC<span class="w"> </span>https://myservice.com/watch/abc123
|
||||
<div class="language-bash highlight"><pre><span></span><code><span id="__span-23-1"><a id="__codelineno-23-1" name="__codelineno-23-1" href="#__codelineno-23-1"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>MYSVC<span class="w"> </span>https://myservice.com/watch/abc123
|
||||
</span></code></pre></div>
|
||||
<hr />
|
||||
<h2 id="checklist">Checklist<a class="headerlink" href="#checklist" title="Permanent link">¶</a></h2>
|
||||
|
||||
Reference in New Issue
Block a user