mirror of
https://github.com/zhw2590582/ArtPlayer.git
synced 2026-10-09 03:46:16 -08:00
22 lines
16 KiB
JavaScript
22 lines
16 KiB
JavaScript
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":1789498635000}'),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 "自动缩略图""></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 "安装和示例""></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;"> 'artplayer'</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;"> 'artplayer-plugin-auto-thumbnail'</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&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 'artplayer-plugin-auto-thumbnail';</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;">'.artplayer-app'</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;">'/assets/sample/video.mp4'</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 "配置与生成方式""></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 "注册、切源和清理""></a></h2><p>工厂返回异步注册函数,结果仅包含 <code>name: 'artplayerPluginAutoThumbnail'</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 "媒体访问和浏览器边界""></a></h2><p>独立视频固定使用 <code>crossOrigin = 'anonymous'</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 "TypeScript 兼容入口""></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;"> 'artplayer'</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;"> 'artplayer-plugin-auto-thumbnail/runtime'</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;"> 'artplayer-plugin-auto-thumbnail/runtime'</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;"><</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">Result</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">> {</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};
|