Files
ArtPlayer/docs/document/assets/plugin_audio-track.md.xXnVbPG8.js
T

30 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.
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 E=JSON.parse('{"title":"独立音轨","description":"","frontmatter":{},"headers":[],"relativePath":"plugin/audio-track.md","filePath":"plugin/audio-track.md","lastUpdated":1789504112000}'),p={name:"plugin/audio-track.md"};function l(r,s,h,d,k,c){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/audio-track.html">English</a></p><p>为视频同步播放一个单独的音频文件。插件创建一个 <code>HTMLAudioElement</code>,跟随主视频的播放、暂停、进度、音量和播放速率,不需要额外 SDK,也不提供音轨选择菜单。</p><p>本页描述当前重构分支。生命周期修复和 <code>/runtime</code> 精确类型尚未发布;未固定版本的 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-audio-track</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;"> artplayerPluginAudioTrack </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">from</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> &#39;artplayer-plugin-audio-track&#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-audio-track.js</code>,全局名称为 <code>artplayerPluginAudioTrack</code>。应用应固定依赖版本,并提供浏览器可解码和访问的音频地址。</p><h2 id="完整示例" tabindex="-1">完整示例 <a class="header-anchor" href="#完整示例" aria-label="Permalink to &quot;完整示例&quot;">​</a></h2><p>下面与<a href="https://artplayer.org/?libs=./uncompiled/artplayer-plugin-audio-track/index.js&amp;example=audio.track" target="_blank" rel="noreferrer">在线音轨示例</a>使用同一份代码。站点提供示例媒体和 <code>.artplayer-app</code> 容器;接入自己的应用时替换这些地址和容器。</p>`,10),t("div",{className:"run-code","data-libs":"./uncompiled/artplayer-plugin-audio-track/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-audio-track</span></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">// import artplayerPluginAudioTrack from &#39;artplayer-plugin-audio-track&#39;;</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">var</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> 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/sprite-fight.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;"> artplayerPluginAudioTrack</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/sprite-fight.aac&#39;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> offset: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">0</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, </span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> sync: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">0.3</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><span class="line-number">13</span><br><span class="line-number">14</span><br></div></div><h2 id="配置与同步" tabindex="-1">配置与同步 <a class="header-anchor" href="#配置与同步" aria-label="Permalink to &quot;配置与同步&quot;">​</a></h2><p><code>artplayerPluginAudioTrack(option)</code> 返回插件工厂,<code>option</code> 必须提供。</p><table tabindex="0"><thead><tr><th>字段</th><th>类型与默认值</th><th>行为</th></tr></thead><tbody><tr><td><code>url</code></td><td><code>string</code>,必填</td><td>独立音频文件地址。构造时的空字符串不加载音源。</td></tr><tr><td><code>offset</code></td><td><code>number</code>,默认 <code>0</code></td><td>音频目标时间为视频时间加上此值,单位秒。正数读取音频中更靠后的内容。</td></tr><tr><td><code>sync</code></td><td><code>number</code>,默认 <code>0.3</code></td><td>音频与目标时间的差值绝对值严格大于此值时,才调整音频时间。单位秒。</td></tr></tbody></table><p>例如视频在10秒、offset为0.25时,目标音频时间是10.25秒。这是纠正媒体时间的阈值同步,不是逐采样的专业音频时钟。使用有限、合理的偏移和非负阈值;负目标时间或超过音频时长的目标依赖浏览器的媒体边界行为,插件没有另加延迟启动、循环或补静音功能。</p><p>播放、seek完成和恢复播放时会同步;正常播放期间也根据 timeupdate 校正漂移。等待缓冲、切源清空、原生暂停、seek开始和结束播放会暂停独立音频;主视频继续播放并达到可恢复状态后再恢复。视频暂停时不会仅因canplay事件自行播放音频。</p><h2 id="返回值和更新" tabindex="-1">返回值和更新 <a class="header-anchor" href="#返回值和更新" aria-label="Permalink to &quot;返回值和更新&quot;">​</a></h2><p>安装后通过 <code>art.plugins.artplayerPluginAudioTrack</code> 取得结果:</p><table tabindex="0"><thead><tr><th>字段</th><th>行为</th></tr></thead><tbody><tr><td><code>name</code></td><td>固定为 <code>artplayerPluginAudioTrack</code>。</td></tr><tr><td><code>audio</code></td><td>实际的 <code>HTMLAudioElement</code>;更新音源时保持同一个元素。</td></tr><tr><td><code>update(option)</code></td><td>同步更新部分字段,返回 <code>undefined</code>,不是加载完成的Promise。</td></tr></tbody></table><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;">const</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> track</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> =</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> art.plugins.artplayerPluginAudioTrack;</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">track.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">update</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">({ offset: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">0.25</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, sync: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">0.1</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> });</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">track.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">update</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">({ url: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&#39;/audio/another-language.m4a&#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><span class="line-number">3</span><br></div></div><p>offset/sync更新不会立即强制seek,下一次同步事件才使用新值。只有非空且不同的url会替换音源;相同url不会重新加载,空url也不是停止或清空命令。若主视频正在播放,替换音源会尝试播放;音频的实际加载、解码和错误可从暴露的元素监听。</p><p>调用 <code>art.switchUrl()</code> 只更换主视频,不会自动选择另一份音频;应用需要同时管理视频与音轨的对应关系,并用 <code>track.update()</code> 指定新音源。需要等待媒体可用时监听原生媒体事件,不要把 <code>await track.update(...)</code> 当作等待加载。</p><h2 id="音量、播放失败与销毁" tabindex="-1">音量、播放失败与销毁 <a class="header-anchor" href="#音量、播放失败与销毁" aria-label="Permalink to &quot;音量、播放失败与销毁&quot;">​</a></h2><p>插件不会自动去掉主视频的原声。如果希望独立音轨是唯一声音,使用没有原声音轨的视频源。播放器的音量、静音和倍速会同步到独立音频;设置 <code>art.muted = true</code> 会一起静音,不能用它只关闭主视频声音。</p><p>独立音频的播放仍受浏览器策略约束。活动实例的 <code>audio.play()</code> 拒绝会通过 <code>console.warn</code> 报告,不会变成 <code>update()</code> 的Promise拒绝。主视频播放成功也不等于独立音频已经成功发声;应用可监听 <code>audio</code> 的 playing/error 等原生事件。</p><p>销毁ArtPlayer会移除插件订阅、暂停音频、移除src并释放媒体加载。保留的结果对象仍指向同一个audio,销毁后的update不再重新加载或播放。应用自己添加到audio上的监听器仍由应用负责移除;无需另外调用一个不存在的插件destroy方法。</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> 保留旧 <code>Result.update(Option)</code> 声明,包含必填url,避免改变旧代码的参数提取与函数赋值。运行时一直支持部分字段更新;需要准确的部分更新类型时,选择同一实现的 <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:#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;"> audioTrack </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">from</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> &#39;artplayer-plugin-audio-track/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;"> installTrack</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> =</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> audioTrack</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">({ url: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&#39;/audio/dialogue.m4a&#39;</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;"> 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/silent.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 style="--shiki-light:#E36209;--shiki-dark:#FFAB70;">player</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">) </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=&gt;</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;"> track</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> =</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> installTrack</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(player);</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> track.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">update</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">({ offset: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">0.25</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:#24292E;--shiki-dark:#E1E4E8;"> track;</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><span class="line-number">13</span><br></div></div><p>命名类型包括 <code>Option</code>、<code>UpdateOption</code>、旧 <code>Result</code>、<code>RuntimeResult</code> 与 <code>RuntimeFactory</code>。在线编辑器的全局默认类型也保留旧推导;选择精确更新类型时,可显式使用 <code>artplayerPluginAudioTrack as artplayerPluginAudioTrack.RuntimeFactory</code>。这不会创建第二份插件实现。</p><p>真实桌面测试覆盖音频/视频播放、暂停、seek、更新和销毁;它们不证明所有移动设备、代理播放器、音频格式或长时间同步组合都通过。完整支持范围仍需结合对应浏览器的解码能力与项目验收记录。</p><p>Windows WebKit 的 MP4/AAC 耗尽缓冲仍有原生媒体验证缺口:该复现中视频停滞不可靠地触发 waiting。换源顺序检查通过不代表这一独立问题已关闭。</p>`,22)]))}const u=i(p,[["render",l]]);export{E as __pageData,u as default};