docs(site): [SITE-04] document Canvas and Mediabunny proxies

This commit is contained in:
Harvey Zhao committed 2026-09-16 04:06:40 +08:00
1 parent e2bd7c9742
commit 4db9789014
110 files changed
+4876 -2204

No files matched your search

@@ -0,0 +1,53 @@
import{_ as i,o as n,c as e,ak as a,j as t}from"./chunks/framework.xxfEszSJ.js";const c=JSON.parse('{"title":"Mediabunny 视频代理","description":"","frontmatter":{},"headers":[],"relativePath":"proxy/mediabunny.md","filePath":"proxy/mediabunny.md","lastUpdated":null}'),l={name:"proxy/mediabunny.md"};function p(h,s,r,d,k,E){return n(),e("div",null,s[0]||(s[0]=[a('<h1 id="mediabunny-视频代理" tabindex="-1">Mediabunny 视频代理 <a class="header-anchor" href="#mediabunny-视频代理" aria-label="Permalink to &quot;Mediabunny 视频代理&quot;">​</a></h1><p><a href="./../en/proxy/mediabunny.html">English</a></p><p>通过 Mediabunny 读取媒体,由 Canvas 与音频管线提供 video-like 接口,并支持 HLS 音轨/清晰度选择。安装位置是 ArtPlayer 的 proxy 选项。本页描述未发布分支;它不补齐浏览器缺少的解码器或所有 HTMLVideoElement 能力。</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-proxy-mediabunny</span></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br></div></div><p>ESM 使用 <code>import mediabunny from &#39;artplayer-proxy-mediabunny&#39;</code>。script 加载 <code>dist/artplayer-proxy-mediabunny.js</code>,全局为 <code>artplayerProxyMediabunny</code>。下面保留<a href="https://artplayer.org/?libs=./uncompiled/artplayer-proxy-mediabunny/index.js&amp;example=mediabunny" target="_blank" rel="noreferrer">原始 HLS 示例</a>,其远端流不是离线夹具:</p>',6),t("div",{className:"run-code","data-libs":"./uncompiled/artplayer-proxy-mediabunny/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-proxy-mediabunny</span></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">// import artplayerProxyMediabunny from &#39;artplayer-proxy-mediabunny&#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;https://test-streams.mux.dev/x36xhzz/x36xhzz.m3u8&#39;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> autoSize: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">true</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> setting: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">true</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> loop: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">true</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> flip: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">true</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> playbackRate: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">true</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> fullscreen: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">true</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> fullscreenWeb: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">true</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> miniProgressBar: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">true</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> autoPlayback: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">true</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> autoOrientation: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">true</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> proxy: </span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">artplayerProxyMediabunny</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">({</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> m3u8: {</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> quality: {</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> control: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">true</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> setting: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">true</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> getName</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: </span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70;">level</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> =&gt;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> level.height </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">?</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> \`\${</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">level</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">.</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">height</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">}P\`</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> :</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> level.name,</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> title: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&#39;Quality&#39;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> auto: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&#39;Auto&#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;"> audio: {</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> control: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">true</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> setting: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">true</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> getName</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: </span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70;">track</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> =&gt;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> track.name </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">||</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> track.language,</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> title: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&#39;Audio&#39;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> auto: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&#39;Auto&#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>
<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><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><span class="line-number">19</span><br><span class="line-number">20</span><br><span class="line-number">21</span><br><span class="line-number">22</span><br><span class="line-number">23</span><br><span class="line-number">24</span><br><span class="line-number">25</span><br><span class="line-number">26</span><br><span class="line-number">27</span><br><span class="line-number">28</span><br><span class="line-number">29</span><br><span class="line-number">30</span><br><span class="line-number">31</span><br><span class="line-number">32</span><br><span class="line-number">33</span><br><span class="line-number">34</span><br><span class="line-number">35</span><br></div></div><p>工厂接受可选配置,初始化同步返回真实 HTMLCanvasElement,同时设置 <code>art.mediabunny</code>。Canvas 的同名原生成员优先:DOM 事件/属性方法并不自动变成 shim 方法。用 ArtPlayer 的 video:* 事件或显式 shim 访问媒体能力。</p><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></tr></thead><tbody><tr><td><code>source</code></td><td>初始来源;非空值优先于 art.option.url,之后宿主赋值仍可替换</td></tr><tr><td><code>loadTimeout</code></td><td>0,不设置加载期限;有限正数按毫秒限制本次加载</td></tr><tr><td><code>timeupdateInterval</code></td><td>250ms,渲染器的更新间隔,不是精确计时承诺</td></tr><tr><td><code>avSyncTolerance</code></td><td>0.12秒,参与开启丢帧时的迟到阈值计算</td></tr><tr><td><code>dropLateFrames</code></td><td>false;启用后允许跳过超过容差的迟到画面</td></tr><tr><td><code>poster</code></td><td>默认空字符串;视频引擎初始化时捕获的海报地址</td></tr><tr><td><code>preflightRange</code></td><td>false;可选的普通 URL HEAD 检查</td></tr><tr><td><code>volume</code> / <code>muted</code></td><td>0.7 / false 的初始 shim 状态,之后可被播放器设置覆盖</td></tr><tr><td><code>autoplay</code> / <code>loop</code></td><td>默认 false 的兼容读取值;不会仅凭代理配置自行启动/循环</td></tr><tr><td><code>crossOrigin</code></td><td>默认空字符串的兼容读取值;不配置 SDK fetch 的凭据或 CORS</td></tr><tr><td><code>m3u8</code></td><td>可选清晰度/音轨菜单,见下节</td></tr></tbody></table><p>自动播放、循环等播放器行为使用 ArtPlayer 自身配置,并受浏览器播放策略限制。代理 shim 的 autoplay/loop/crossOrigin setter 保留为空操作,不能当作原生 video 设置使用。改变 shim.poster 更新其配置读取值,不保证重绘视频引擎已捕获的海报。</p><p>source 声明接受 URL 字符串、Blob 或 ReadableStream 字节流;运行时也把 SDK Source/SourceRef 交给 SDK 验证。字符串按 <code>.m3u8</code> 后缀(忽略大小写,允许 query/hash)识别 HLS,使用 HLS_FORMATS;其他输入使用 ALL_FORMATS。无此后缀的地址不会仅凭返回内容自动启用本代理的 HLS 菜单状态。可读流能否随机访问/重复加载仍取决于其来源能力。</p><p>Range 检查仅对启用检查的非 HLS 字符串请求 HEAD。没有 accept-ranges 或值为 none 时发出 detail 为 RangeNotSupported Event 的 error,停止该次加载前置过程,但不会设置 shim.error。网络请求异常会警告并继续;HLS 和非字符串跳过 HEAD。它不是完整 Range GET 或编码支持验证。媒体服务器仍需要实际可读响应及 CORS。</p><h2 id="hls-菜单与选择" tabindex="-1">HLS 菜单与选择 <a class="header-anchor" href="#hls-菜单与选择" aria-label="Permalink to &quot;HLS 菜单与选择&quot;">​</a></h2><p>m3u8.quality 和 m3u8.audio 都可配置 control、setting、title、auto、getName。control/setting 都不启用时不显示对应菜单;使用 setting 还需播放器设置面板。</p><table tabindex="0"><thead><tr><th>配置</th><th>默认</th></tr></thead><tbody><tr><td><code>Line truncated
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">const</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> state</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;"> shim.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">getM3u8State</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">();</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">if</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> (state?.levels.</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">length</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">) {</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> await</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> shim.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">switchM3u8Quality</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(state.levels[</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">0</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">].id);</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;">await</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> shim.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">switchM3u8Audio</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&#39;auto&#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><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br></div></div><p>用状态中的数值 id 或字面量 <code>&#39;auto&#39;</code>,不要把 index、显示名或数字字符串当成 id。Auto 重新选择 SDK primary track,不代表代理会测带宽并持续自动切码率。切清晰度时尽量保留可配对音轨,否则重新选 primary pairable audio;音轨变化同样维护视频配对。未知 id 沿用当前轨道;无 HLS 来源时这些方法无操作。</p><p>菜单标识为 mediabunny-quality / mediabunny-audio。metadata/restart 刷新,loadstart/error/销毁清理。新来源缺少对应能力时移除旧 UI,旧菜单回调及过期选择不能覆盖新状态。异步切换失败仍可能拒绝,应处理 Promise。</p><h2 id="shim-成员" tabindex="-1">shim 成员 <a class="header-anchor" href="#shim-成员" aria-label="Permalink to &quot;shim 成员&quot;">​</a></h2><table tabindex="0"><thead><tr><th>成员</th><th>行为</th></tr></thead><tbody><tr><td><code>canvas</code></td><td>原生输出元素</td></tr><tr><td><code>src</code> / <code>currentSrc</code></td><td>来源值;非空 src 赋值发起加载,空值不等同于卸载</td></tr><tr><td><code>play()</code> / <code>pause()</code> / <code>load()</code></td><td>Promise 播放、同步暂停、按当前 src 重新加载;load 不返回完成 Promise</td></tr><tr><td><code>currentTime</code></td><td>秒;写入启动异步 seek,setter 本身不能等待完成</td></tr><tr><td><code>duration</code></td><td>秒;未知可为 NaN,直播可为 Infinity</td></tr><tr><td><code>volume</code> / <code>muted</code></td><td>volume 数值转换并钳制0–1,写 volume 同时取消静音;写 muted 布尔化</td></tr><tr><td><code>playbackRate</code></td><td>默认1,接受转换后大于0且非NaN的值;设置发 ratechange</td></tr><tr><td><code>paused</code> / <code>playing</code> / <code>ended</code> / <code>seeking</code></td><td>播放协调器状态,playing 不是已显示真实帧的证明</td></tr><tr><td><code>readyState</code> / <code>networkState</code> / <code>error</code></td><td>兼容状态及 <code>{code, message}</code> 或 null</td></tr><tr><td><code>videoWidth</code> / <code>videoHeight</code></td><td>视频引擎尺寸</td></tr><tr><td><code>buffered</code> / <code>played</code> / <code>seekable</code></td><td>合成范围:0到时长、0到当前时间、0到时长,不是实际网络缓冲测量</td></tr><tr><td><code>createTimeRanges(start, end)</code></td><td>同一合成范围工具,空范围返回长度0;非空长度1,未实现原生索引越界异常</td></tr><tr><td><code>canPlayType(type)</code></td><td>固定返回 maybe,不检测支持能力</td></tr><tr><td><code>getM3u8State()</code></td><td>Promise,非HLS/失效状态为 null</td></tr><tr><td><code>switchM3u8Quality(value)</code> / <code>switchM3u8Audio(value)</code></td><td>Promise 轨道选择</td></tr><tr><td><code>addEventListener</code> / <code>removeEventListener</code></td><td>shim 媒体事件,不是 Canvas DOM 监听器</td></tr><tr><td><code>getBoundingClientRect()</code></td><td>委托 Canvas</td></tr><tr><td><code>setAttribute(name, value)</code></td><td>shim 方法特殊处理 src/muted,autoplay/loop沿用空setter;其他委托Canvas</td></tr><tr><td><code>destroy()</code></td><td>同步终止 shim 及其引擎,重复调用无操作</td></tr></tbody></table><p>兼容字段 poster、autoplay、loop、crossOrigin 如上。controls=false、playsInline=true、preload=&#39;auto&#39;、defaultMuted=false、defaultPlaybackRate=1;这些字段的 setter 无操作。直接 canvas.setAttribute 使用原生 Canvas 方法,与 shim.setAttribute 不同。正常宿主清理应使用 art.destroy,以同时释放 UI/别名/订阅。</p><p>HlsState 包含 levels、audios、currentLevel、currentAudio、videoMode、audioMode;当前项可为 null,模式为 auto/manual。audios 是与当前视频可配对的音轨,纯音频状态不保证有菜单项。track 类型为 unknown,按应用使用的 SDK 类型缩窄。</p><h2 id="事件、帧回调与清理" tabindex="-1">事件、帧回调与清理 <a class="header-anchor" href="#事件、帧回��ƒ与清理" aria-label="Permalink to &quot;事件、帧回调与清理&quLine truncated
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">import</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> mediabunny </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">from</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> &#39;artplayer-proxy-mediabunny&#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;"> { MediaBunnyPlayer } </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">from</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> &#39;artplayer-proxy-mediabunny&#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:#6F42C1;--shiki-dark:#B392F0;"> MediaBunnyPlayer</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;#player&#39;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, url: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&#39;/movie.m3u8&#39;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> proxy: </span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">mediabunny</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">({ m3u8: { quality: { control: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">true</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:#D73A49;--shiki-dark:#F97583;">async</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> function</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> selectFirstLevel</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:#005CC5;--shiki-dark:#79B8FF;">void</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">&gt; {</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> const</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> shim</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> =</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> art.mediabunny;</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> if</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> (</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">!</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">shim) </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">return</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;"> state</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;"> shim.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">getM3u8State</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">();</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> if</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> (state?.levels.</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">length</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">) </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">await</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> shim.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">switchM3u8Quality</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(state.levels[</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">0</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">].id);</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><p>公开类型为 Option、Result、HlsLevel、HlsAudio、HlsState、MediaBunnyCanvas、MediaBunnyPlayer、MediaBunnyShim、MediaListener、SyntheticFrameCallback、SyntheticFrameMetadata。Canvas 视图保留同名原生成员;Player 别名可缺省且销毁后移除。CommonJS 运行时支持直接工厂和历史 <code>.default</code>,默认工厂类型仍为纯可调用签名。legacy 构建不提供 WebCodecs、Web Audio 或其他浏览器能力的 polyfill。</p>`,29)]))}const y=i(l,[["render",p]]);export{c as __pageData,y as default};