Files
ArtPlayer/docs/document/assets/plugin_auto-thumbnail.md.C3_dIXZf.js
T

22 lines
16 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.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import{_ as i,o as n,c as e,ak as a,j as t}from"./chunks/framework.xxfEszSJ.js";const u=JSON.parse('{"title":"自动缩略图","description":"","frontmatter":{},"headers":[],"relativePath":"plugin/auto-thumbnail.md","filePath":"plugin/auto-thumbnail.md","lastUpdated":null}'),l={name:"plugin/auto-thumbnail.md"};function p(h,s,r,d,k,o){return n(),e("div",null,s[0]||(s[0]=[a(`<h1 id="自动缩略图" tabindex="-1">自动缩略图 <a class="header-anchor" href="#自动缩略图" aria-label="Permalink to &quot;自动缩略图&quot;">​</a></h1><p><a href="./../en/plugin/auto-thumbnail.html">English</a></p><p>使用独立视频元素读取画面,在浏览器内逐步生成 JPEG 雪碧图,并更新播放器进度条的缩略图配置。本页描述未发布的重构分支;在线示例及未固定版本的 npm/CDN 包不等于当前候选。</p><h2 id="安装和示例" tabindex="-1">安装和示例 <a class="header-anchor" href="#安装和示例" aria-label="Permalink to &quot;安装和示例&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-auto-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;"> artplayerPluginAutoThumbnail </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">from</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> &#39;artplayer-plugin-auto-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>使用 script 时先加载 ArtPlayer,再加载 <code>dist/artplayer-plugin-auto-thumbnail.js</code>,全局名为 <code>artplayerPluginAutoThumbnail</code>。以下代码保留<a href="https://artplayer.org/?libs=./uncompiled/artplayer-plugin-auto-thumbnail/index.js&amp;example=auto.thumbnail" target="_blank" rel="noreferrer">原在线示例</a>。工厂参数对象必填,使用 <code>{}</code> 选择默认值。</p>`,7),t("div",{className:"run-code","data-libs":"./uncompiled/artplayer-plugin-auto-thumbnail/index.js"},"▶ Run Code",-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-auto-thumbnail</span></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">// import artplayerPluginAutoThumbnail from &#39;artplayer-plugin-auto-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/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;"> artplayerPluginAutoThumbnail</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">({</span></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> //</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="配置与生成方式" tabindex="-1">配置与生成方式 <a class="header-anchor" href="#配置与生成方式" aria-label="Permalink to &quot;配置与生成方式&quot;">​</a></h2><table tabindex="0"><thead><tr><th>字段</th><th>类型</th><th>默认值</th><th>含义</th></tr></thead><tbody><tr><td><code>url</code></td><td><code>string</code></td><td>当前 <code>art.option.url</code></td><td>独立解码器读取的媒体地址;显式非空地址优先</td></tr><tr><td><code>width</code></td><td><code>number</code></td><td><code>160</code></td><td>每格缩略图宽度,单位像素</td></tr><tr><td><code>number</code></td><td><code>number</code></td><td><code>100</code></td><td>目标采样数量,通常使用正整数</td></tr><tr><td><code>scale</code></td><td><code>number</code></td><td><code>1</code></td><td>传给播放器的预览显示缩放,不降低生成画布尺寸</td></tr><tr><td><code>height</code></td><td><code>number</code></td><td>按视频宽高比计算</td><td>历史参数,实际忽略;精确 runtime 类型接受它</td></tr></tbody></table><p>这些默认值沿用 <code>value || default</code> 规则,例如 <code>width: 0</code> 回退为 160。width 和 number 回退后需要为可转换成有限正数的值;旧 JavaScript 数值字符串和小数计数行为保留,但类型示例使用数字与正整数。生成高度为 <code>Math.floor(width * videoHeight / videoWidth)</code>,每行固定十列。媒体必须有有限的正时长和尺寸,不适用于直播无限时长。</p><p>采样时刻为 <code>duration * index / number</code>,从 index 0 开始,不包含媒体终点。时长与画布尺寸在独立视频 metadata 时固定;每次画出一格后编码整张 JPEG,再发布新的 <code>art.thumbnails</code> 配置。因此生成期间后面的格子可能尚未填充,并不是所有缩略图同时就绪。</p><p>较大的 width 和 number 会增加画布、解码和反复编码成本;尺寸校验不是浏览器内存预算保证。选择适合视频长度和目标设备的配置,或使用预先制作的 <a href="./vtt-thumbnail.html">VTT 缩略图</a>。</p><h2 id="注册、切源和清理" tabindex="-1">注册、切源和清理 <a class="header-anchor" href="#注册、切源和清理" aria-label="Permalink to &quot;注册、切源和清理&quot;">​</a></h2><p>工厂返回异步注册函数,结果仅包含 <code>name: &#39;artplayerPluginAutoThumbnail&#39;</code>。注册 Promise 在安装播放器事件后完成,不等待缩略图生成,也不表示媒体已成功读取。没有公开的进度、生成完成、update、stop 或 destroy 方法。</p><p>每次 <code>video:loadedmetadata</code> 启动新一轮提取,并重新读取原配置对象;之后修改原对象会影响下一轮。插件不补发安装之前已经过去的 metadata 事件。<code>restart</code> 取消旧提取,后续 metadata 才启动新任务。旧的异步帧和编码回调不能覆盖新任务。</p><p>独立解码器的 metadata、每帧就绪和每次 JPEG 编码各有 30 秒等待上限,不是整个任务的总时限。媒体、画布或编码失败会清理当前任务,通过 <code>console.warn</code> 报告,并保留最后一张可用预览;已完成的注册 Promise 不会因此重新拒绝。</p><p>完成或取消后释放独立视频与画布;最后的图片 URL 保留至被新的可用图替换或播放器销毁。只撤销插件生成的 URL,不撤销应用自己的外部缩略图地址。销毁同时移除监听器;直接调用已保留的注册函数且播放器已销毁时,只返回名称,不分配解码器,这不改变核心 <code>plugins.add()</code> 的销毁检查。</p><h2 id="媒体访问和浏览器边界" tabindex="-1">媒体访问和浏览器边界 <a class="header-anchor" href="#媒体访问和浏览器边界" aria-label="Permalink to &quot;媒体访问和浏览器边界&quot;">​</a></h2><p>独立视频固定使用 <code>crossOrigin = &#39;anonymous&#39;</code>,静音且不主动播放。媒体必须允许浏览器原生读取和 Canvas 像素访问,跨域服务需要正确的 CORS 响应。播放器的自定义加载器、SDK、请求头或代理不会自动安装到这个独立解码器;必要时用 <code>url</code> 提供它能直接读取的媒体。</p><p>独立视频会以隐藏但具有渲染尺寸的节点挂到文档中;这不表示新增可见播放器。真实解码和首帧正确性仍依赖浏览器。当前 Windows WebKit 首帧问题尚未完成验收,不能把类型、导航或其它浏览器通过当作该问题已解决,也不代表真实 Safari/手机已验证。</p><h2 id="typescript-兼容入口" tabindex="-1">TypeScript 兼容入口 <a class="header-anchor" href="#typescript-兼容入口" aria-label="Permalink to &quot;TypeScript 兼容入口&quot;">​</a></h2><p>根入口和 <code>/legacy</code> 保留 npm 1.1.0 的同步结果声明,工厂对象必填,根 Option 没有 height。需要实际 Promise、旧 height 参数或 <code>.default</code> 自引用类型时,使用同一实现的 <code>/runtime</code>:</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:#D73A49;--shiki-dark:#F97583;"> type</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;"> autoThumbnail </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">from</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> &#39;artplayer-plugin-auto-thumbnail/runtime&#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:#D73A49;--shiki-dark:#F97583;"> type</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> { Option, Result } </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">from</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> &#39;artplayer-plugin-auto-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;"> options</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">:</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> Option</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> =</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> { width: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">160</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, number: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">100</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, scale: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">1</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;">async</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> function</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> registerThumbnails</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70;">art</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">:</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> Artplayer</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">)</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">:</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> Promise</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">&lt;</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">Result</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">&gt; {</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> return</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> await</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> autoThumbnail</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(options)(art); </span><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">// Registration only, not extraction completion.</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></div></div><p>runtime 导出 <code>Option</code>、<code>Result</code>、<code>Factory</code>、<code>RuntimeFactory</code>;Factory 是普通异步工厂,RuntimeFactory 还描述可写的 <code>.default</code> 自引用。实际 CommonJS 支持直接调用及 <code>.default(...)</code>。更早 1.0.x 的 <code>export =</code> 和 height 声明与 1.1.0 不同,需要旧导入形式时可迁到 runtime 的 <code>import = require</code>。根 NodeNext 模块形状保留,准确的可调用默认导入使用 runtime;经典 Node10 默认导入需要 <code>esModuleInterop</code>。</p>`,18)]))}const g=i(l,[["render",p]]);export{u as __pageData,g as default};