Files
ArtPlayer/docs/document/assets/en_plugin_vtt-thumbnail.md.CI6T1LST.js
T

37 lines
19 KiB
JavaScript
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import{_ as e,o as i,c as n,ak as a,j as t}from"./chunks/framework.xxfEszSJ.js";const u=JSON.parse('{"title":"VTT Thumbnail","description":"","frontmatter":{},"headers":[],"relativePath":"en/plugin/vtt-thumbnail.md","filePath":"en/plugin/vtt-thumbnail.md","lastUpdated":null}'),l={name:"en/plugin/vtt-thumbnail.md"};function p(r,s,h,o,d,c){return i(),n("div",null,s[0]||(s[0]=[a(`<h1 id="vtt-thumbnail" tabindex="-1">VTT Thumbnail <a class="header-anchor" href="#vtt-thumbnail" aria-label="Permalink to &quot;VTT Thumbnail&quot;">​</a></h1><p><a href="./../../plugin/vtt-thumbnail.html">中文</a></p><p>Load a WebVTT thumbnail index and show the selected sprite region when hovering over the progress bar. Generate the index and images beforehand; this plugin does not scan the video or require another SDK.</p><p>This page describes the current refactor branch. Parser and lifecycle fixes and the precise <code>/runtime</code> types are not published yet. An unpinned npm or CDN installation is not evidence of this branch&#39;s behavior.</p><h2 id="installation" tabindex="-1">Installation <a class="header-anchor" href="#installation" aria-label="Permalink to &quot;Installation&quot;">​</a></h2><div class="language-sh vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">sh</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">yarn</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> add</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> artplayer</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> artplayer-plugin-vtt-thumbnail</span></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br></div></div><div class="language-js vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">import</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> Artplayer </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">from</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> &#39;artplayer&#39;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">;</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">import</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> artplayerPluginVttThumbnail </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">from</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> &#39;artplayer-plugin-vtt-thumbnail&#39;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">;</span></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br></div></div><p>For script loading, load ArtPlayer first, followed by <code>dist/artplayer-plugin-vtt-thumbnail.js</code>. The global is <code>artplayerPluginVttThumbnail</code>. Pin dependency versions and make the VTT and images accessible. Cross-origin VTT requests require appropriate server CORS headers.</p><h2 id="complete-example" tabindex="-1">Complete example <a class="header-anchor" href="#complete-example" aria-label="Permalink to &quot;Complete example&quot;">​</a></h2><p>This is the exact code from the <a href="https://artplayer.org/?libs=./uncompiled/artplayer-plugin-vtt-thumbnail/index.js&amp;example=vtt.thumbnail" target="_blank" rel="noreferrer">online thumbnail example</a>. The demo site supplies the media and <code>.artplayer-app</code> container; replace them in your application.</p>`,10),t("div",{className:"run-code","data-libs":"./uncompiled/artplayer-plugin-vtt-thumbnail/index.js"},null,-1),a(`<div class="language-js vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">// npm i artplayer-plugin-vtt-thumbnail</span></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">// import artplayerPluginVttThumbnail from &#39;artplayer-plugin-vtt-thumbnail&#39;;</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">const</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> art</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> =</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> new</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> Artplayer</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">({</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> container: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&#39;.artplayer-app&#39;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> url: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&#39;/assets/sample/bbb-video.mp4&#39;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> plugins: [</span></span>
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> artplayerPluginVttThumbnail</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">({</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> vtt: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&#39;/assets/sample/bbb-thumbnails.vtt&#39;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> }),</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> ],</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">})</span></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br></div></div><h2 id="options" tabindex="-1">Options <a class="header-anchor" href="#options" aria-label="Permalink to &quot;Options&quot;">​</a></h2><p>The options object passed to <code>artplayerPluginVttThumbnail(option)</code> is required.</p><table tabindex="0"><thead><tr><th>Field</th><th>Type</th><th>Behavior</th></tr></thead><tbody><tr><td><code>vtt</code></td><td><code>string</code>, optional in the declaration</td><td>VTT file URL. Supply a valid URL in practice: omission fetches an empty URL, meaning the current page, rather than disabling the plugin.</td></tr><tr><td><code>style</code></td><td>Optional <code>Partial&lt;CSSStyleDeclaration&gt;</code></td><td>Initial inline styles on the thumbnail control, such as <code>borderRadius: &#39;4px&#39;</code>.</td></tr></tbody></table><p>Rendering updates display, width, height, left, backgroundImage and backgroundPosition. Initial styles cannot permanently override these properties. Each cue supplies the crop dimensions; the plugin does not automatically scale the sprite.</p><h2 id="index-format-and-image-paths" tabindex="-1">Index format and image paths <a class="header-anchor" href="#index-format-and-image-paths" aria-label="Permalink to &quot;Index format and image paths&quot;">​</a></h2><div class="language-text vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">text</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span>WEBVTT</span></span>
<span class="line"><span></span></span>
<span class="line"><span>00:00.000 --&gt; 00:05.000</span></span>
<span class="line"><span>bbb-sprite.jpg#xywh=0,0,128,72</span></span>
<span class="line"><span></span></span>
<span class="line"><span>00:05.000 --&gt; 00:10.000</span></span>
<span class="line"><span>bbb-sprite.jpg#xywh=128,0,128,72</span></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br></div></div><p>The four values <code>x,y,w,h</code> are the left position, top position, width and height within the image, in pixels. x/y must be nonnegative and w/h positive; all four must be finite numbers. Each cue has one image URL line with a crop fragment. Ordinary subtitle text is not a thumbnail index.</p><p>Relative images are joined to the directory of the <strong>supplied VTT URL</strong>. For example, <code>bbb-sprite.jpg</code> inside <code>/assets/sample/bbb-thumbnails.vtt</code> becomes <code>/assets/sample/bbb-sprite.jpg</code>. Root-relative URLs and full URLs with supported protocols are kept as supplied. The directory is not recalculated from a redirected HTTP response URL. Prefer explicit image URLs when redirects or complex relative paths are involved.</p><p>The parser supports a BOM, common line endings, optional cue identifiers and timing settings, and skips NOTE, STYLE and REGION blocks. It is a thumbnail index parser, not a complete WebVTT subtitle layout engine.</p><h2 id="timing-and-display-boundaries" tabindex="-1">Timing and display boundaries <a class="header-anchor" href="#timing-and-display-boundaries" aria-label="Permalink to &quot;Timing and display boundaries&quot;">​</a></h2><p>For historical compatibility, start and end times are rounded down to whole seconds. Both interval endpoints are included, and the first matching cue in file order wins. At exactly 5 seconds in the example above, the first image still applies; the second appears after 5 seconds. Do not assume millisecond precision or exclusive end times.</p><p>Desktop hover selects a cue using the progress percentage multiplied by the video duration. Gaps hide the preview, and previews near the edges are aligned inward. The mobile path responds to progress dragging with an input event and hides about 500ms after the last drag update. Desktop coverage does not establish real touch-device support.</p><h2 id="asynchronous-registration-errors-and-cleanup" tabindex="-1">Asynchronous registration, errors and cleanup <a class="header-anchor" href="#asynchronous-registration-errors-and-cleanup" aria-label="Permalink to &quot;Asynchronous registration, errors and cleanup&quot;">​</a></h2><p>Registration fetches and parses the VTT and actually returns a Promise. Its success result contains only <code>name: &#39;artplayerPluginVttThumbnail&#39;</code>. Installation through the constructor&#39;s plugins array is asynchronous; do not assume that the result is registered immediately after construction.</p><p>To wait explicitly and handle request or parse errors, call <code>art.plugins.add()</code> once after constructing the player:</p><div class="language-ts vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">ts</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">import</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> Artplayer </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">from</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> &#39;artplayer&#39;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">;</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">import</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> thumbnails </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">from</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> &#39;artplayer-plugin-vtt-thumbnail/runtime&#39;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">;</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">const</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> art</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> =</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> new</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> Artplayer</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">({</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> container: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&#39;.artplayer-app&#39;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> url: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&#39;/video/movie.mp4&#39;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">});</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">async</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> function</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> installThumbnails</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">() {</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> try</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> {</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> const</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> result</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> =</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> await</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> art.plugins.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">add</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">thumbnails</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">({ vtt: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&#39;/video/movie.vtt&#39;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> }));</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> console.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">log</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(result.name);</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> }</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> catch</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> (error) {</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> console.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">error</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&#39;Unable to load thumbnails&#39;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, error);</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> }</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">}</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">void</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> installThumbnails</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">();</span></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br></div></div><p>Request and format errors reject registration; format errors include a line number. Registration completion establishes that the VTT was parsed and the control created, not that every image has decoded. Images load when the browser displays them; a later image failure does not reject an already settled registration Promise.</p><p>There is no update, reload or independent destroy method. Switching the main video does not refetch the VTT. For a different video and thumbnail set, you can destroy and recreate the player. Removing a control is not a complete uninstall; repeated installation is not an update API.</p><p>Destroying the player cancels outstanding requests where AbortController is available, settles canceled registration, removes owned listeners and timers, and removes the control only if this installation still owns it. Cancellation still returns the name object, so the name alone does not prove an image is available. Late requests cannot remount the interface.</p><h2 id="typescript-compatibility" tabindex="-1">TypeScript compatibility <a class="header-anchor" href="#typescript-compatibility" aria-label="Permalink to &quot;TypeScript compatibility&quot;">​</a></h2><p>The root and <code>/legacy</code> entrances preserve the latest published 1.1.0 synchronous return declaration and replacement-function shape, although registration is asynchronous at runtime. The <code>/runtime</code> entrance above uses the same JavaScript implementation and accurately declares the Promise and runtime <code>.default</code> self-alias. It also exposes <code>Option</code>, <code>Result</code>, <code>Factory</code> and <code>RuntimeFactory</code> types.</p><p>The older 1.0.x <code>export =</code> shape cannot preserve the same type extraction as the 1.1.0 default export. TypeScript consumers relying on those earlier CommonJS declarations should migrate to <code>/runtime</code>. NodeNext ESM consumers should also prefer this entrance to avoid the historical namespace shape retained by the root. Legal older JavaScript calls and distribution file entrances remain available.</p><p>Browser checks cover cropping and cleanup with published and candidate cores. Complete mobile, plugin combination and release-artifact acceptance remains tracked separately.</p>`,24)]))}const m=e(l,[["render",p]]);export{u as __pageData,m as default};