稳定音量、实验性超分与集成 skills
当前 SDK 发布版包含这些可选 API;接入旧缓存文件时仍应检测能力再显示控件。两项播放增强都默认关闭,沿用原来的选核、媒体时钟和用户音量控制。
| 功能 | 作用 | 默认及条件 |
|---|---|---|
| 稳定音量 | 使用 RMS 自动增益和峰值保护,减少片段之间忽大忽小 | 默认 None;StableVolume 需要可用的浏览器音频图和可访问的音轨 |
| 实验性超分 | 在渲染器 WebGL2 上下文中运行固定微型 AN CNN | 默认关闭;需要确认兼容的 SDR 输入和设备性能 |
| 集成与排障 skills | 生成 demo,或根据证据排查接入问题 | 两个独立 skill;覆盖原生 JS、React、Vue、Svelte、Angular、Next、Nuxt |
直接操作 demo
官网首页和完整播放器共用播放增强面板;SDK 发布目录中的 index.html / index-cn.html、开发仓库的动态多实例 index.html 和固定双实例 index-multi.html 也采用相同操作。两项功能使用独立开关,每个实例单独控制。
| 操作 | 什么时候可以操作 | 页面显示什么 |
|---|---|---|
| 开启音量均衡 | 创建前可预设;播放中可直接切换,无需重建 | 等待音频、正在处理或当前不可用及原因 |
| 开启超分 | 创建前可预设;创建后可请求开启,无需等 ready 才操作 | 首次默认“高一档”,根据可用档位显示实际输出;等待帧、加载模型或使用原画时显示原因 |
| 更换超分档位 | 播放中可选“高一档”“自动”或当前可用尺寸 | “高一档”使用当前最小可用增强档;“自动”交给 SDK 按标准策略选择 |
| 关闭增强 | 播放中随时关闭 | 音频恢复直通处理;画面恢复原画;用户音量和静音保留 |
| 修改 SDR 声明或应用需要重建的渲染器 | 按面板提示显式重新加载 | 点播从头开始,直播重新接入;不会在切开关时偷偷重载 |
开关表示请求,状态表示实际效果。 首帧未到时可以预先开启,但超分要收到可用视频帧才能决定输出尺寸、加载模型和评估性能。暂停时首次开启可能等待恢复播放。warming 表示评估中,可能已经有增强输出;active 才表示当前输出通过性能评估。
任意片源默认色彩未知。 SDR 确认绑定本次媒体地址;换源后须重新确认新片源,并按提示应用。仅确认兼容 SDR 时选择“已确认 SDR”;这个声明是创建参数,修改后按提示应用并重新加载。它不会通过 set_super_resolution() 热修改。首页自带 SDR 样片可以预先声明;替换为自己的片源时应重新确认。未知色彩、HDR、ERP、无需放大的显示区域或不支持的设备会保持原画并解释原因。
音量均衡用于减少忽大忽小,不是多段 EQ。它在用户音量之前工作,开启后不会自动解除静音;需要试听时仍由用户调节音量。旧 SDK 没有对应 API 时,面板会禁用功能并提示使用当前构建。
Demo 的音量均衡开关只改变均衡请求,不调用播放或用户手势通知。音频仍因激活条件处于 pending 时,播放并激活音频是独立的明确操作:通过该入口的播放处理函数开始或恢复播放,保留用户音量/静音并同步播放按钮状态。
播放环境与托管
官网首页和播放器默认从本站同源地址加载当前 SDK 与 WASM。?sdk=cdn 仅用于固定 CDN 发布版的诊断;移除该参数即回到本站构建。首页使用同源 SDR 样片并启用隔离页面,两项效果仍默认关闭。
完整播放器和 SDK 演示接受任意 URL,默认处于兼容模式。播放路径需要 WASM/共享内存时,点击启用软件解码,页面会带 ?isolation=1 重新加载;切回兼容模式会移除该参数。本标签页恢复媒体地址、内核、音量/静音、增强开关与请求的超分档位。临时记录只存于 sessionStorage,10 分钟过期,尝试恢复后清除。播放会重新建立,不保留正在运行的解码器或点播进度。
?isolation=1 是 demo 的托管约定,不是 SDK API,也不会凭空生成响应头。隔离文档需处于安全上下文,由服务器返回 Cross-Origin-Opener-Policy: same-origin 与 Cross-Origin-Embedder-Policy: require-corp;直接创建的 pthread Worker 脚本还需 COEP。面板读取真实浏览器环境,条件不足时明确提示,不会循环重载。同次构建的 SDK/glue/WASM 要配套,WASM 使用 application/wasm,跨域资源按实际请求方式满足 CORS/CORP。隔离模式的跨域 no-CORS 原生视频需要 CORP,仅有 Access-Control-Allow-Origin 不会改变其请求方式;兼容模式保留原生播放原有的请求行为。
兼容原生视频的超分不要求先开启软件解码。 它仍需满足帧读取、SDR 声明、模型、输出尺寸和 GPU 条件。这些页面控件不改变 SDK 的选核或增强算法。只复用增强面板时,不要给原生超分额外加上环境重载门槛。发布目录另含 demo-environment.js 和 demo-environment.css;需要环境切换时复用完整 demo 的捕获/恢复接线。静态托管仍必须配置响应头,复制 helper 或直接使用普通 python3 -m http.server 不会自动提供隔离。
从普通播放开始
从同一次构建复制三件运行资源。使用超分时,再把完整 models/sr/ 目录及其中的 manifest、权重和许可一起放到 WASM JS 旁。超分保持关闭时,普通播放不下载模型。
sdk/
├── h265web.js
├── h265web_wasm.js
├── h265web_wasm.wasm
└── models/sr/ # 仅超分需要回调应在 build() 前绑定,按业务需要选择;低层帧回调可能影响选核。超分状态独立于媒体错误。
示例中的 ./media/demo.mp4 需要替换成你实际可播放的媒体地址。
const player = H265webjsPlayer();
const hasLeveling = typeof player.set_audio_leveling === 'function' &&
typeof player.get_audio_leveling_state === 'function';
const hasSR = typeof player.set_super_resolution === 'function' &&
typeof player.get_super_resolution_state === 'function';
player.on_ready_show_done_callback = () => console.log('已就绪');
player.on_error_callback = error => console.error(error);
if (hasSR) player.on_super_resolution_state = state => console.log('超分', state);
const config = {
player_id: 'player', width: 960, height: 540,
base_url: './sdk/', wasm_js_uri: 'h265web_wasm.js',
wasm_wasm_uri: 'h265web_wasm.wasm', ignore_audio: false, auto_play: false
};
if (hasLeveling) config.audio_leveling = 'None';
// 只有已确认兼容的 SDR 片源,才声明为 sdr。
if (hasSR) config.super_resolution = { enabled: false, input_color: 'unknown' };
if (!player.build(config)) throw new Error('播放器构建失败');
player.set_voice(0);
player.load_media('./media/demo.mp4');运行前在页面放置 <div id="player"></div>。在真实用户点击处理函数中调用 player.notify_user_gesture() 和 player.play(),满足浏览器激活要求。静音与最终用户音量由接入方控制。
稳定音量与用户音量独立
if (hasLeveling) {
player.set_audio_leveling('StableVolume');
console.log(player.get_audio_leveling_state());
player.set_audio_leveling('None');
}
player.set_voice(0.3); // 用户最终的 0~1 输出音量处理顺序为原始音频 → 自动增益/峰值保护 → 用户音量 → 输出。开关均衡不会移动音量滑块或取消静音;set_voice(0) 仍无声。ignore_audio: true 会跳过音频初始化,之后调音量也不能恢复音轨。
请求接受不等于实际生效。检查 status(disabled、pending、active、unavailable)和 reason。用户激活、AudioWorklet、来源安全和有无音轨共同决定可用性;不可用时保留播放,不为均衡强制换视频核心。它不是 EQ、LUFS 归一化或 true-peak 认证。
实验性超分
仅对已确认兼容的 SDR 片源,在初始 build 配置声明 input_color: 'sdr'。默认 unknown 会旁路;HDR 和广色域不能被误声明为兼容 SDR。
if (hasSR) {
// 高一档:首次开启直接采用当前最小可用增强档。
player.set_super_resolution({ enabled: true, level: 'light', targetKey: null });
// 用户选择“自动”时:
// player.set_super_resolution({ enabled: true, level: 'standard', targetKey: null });
// 后续状态通知到来时,继续刷新档位控件。
// 稍后在另一次用户操作中关闭:player.set_super_resolution(false);
}读取 status、reason、source、output、options,不能把返回 true 当作已经增强。状态包括 off、loading、warming、active、bypass、released。build 后主动读取初态;从未开启的实例不发送无用超分通知。warming 可能已有增强画面,active 还需通过真实 GPU 计时窗口。
至多提供两档保比例候选,倍率来自 1.25/1.5/2。输入短边≤720;输出长边≤1920、短边≤1080、总像素≤2073600,并受显示区域和设备预算限制。720p 可出现 900p/1080p 实验候选;码率不解锁 1440p/4K。这些是增强范围,不限制正常高分辨率原画播放。
| 输入或条件 | 实际行为 |
|---|---|
| 兼容的原生 video、WebCodec VideoFrame 或已验证 I420 | 来源和预算满足条件时使用共享 WebGL2 效果 |
| 已存在的 C++ 渲染器 | 返回 renderer-recreate-required;由用户明确 rebuild 后创建可支持超分的渲染器,不自动重载 |
| 缺可信 I420 descriptor 的旧 WASM | 普通播放继续,超分旁路 |
| 色彩未知、HDR/广色域、ERP、原生画中画/仅视频全屏或不支持的字幕 | 原画并提供原因 |
| 模型失败、GPU 不支持或持续超预算 | 原画并提供原因,不触发超分媒体错误或换核 |
SDK 只有一个固定实验性 AN 模型。WASM/ORT、WebGPU 对比属于研究结果,不是可选的 SDK 超分后端。GPU 数值测试证明实现符合数学配方,不能证明所有片源都更好;移动设备、长时温升/功耗和生产画质仍未验收。
复用同一套开关面板
SDK 发布包中的 demo-enhancements.js 和 demo-enhancements.css 是独立的页面控件,放在页面可访问的 SDK 目录;它们通过公开 API 调用播放器。主 JS、WASM JS、WASM 二进制与 models/sr/ 仍放在 static/。下面片段接到你已有的创建/释放流程,原来的最小播放示例无需重写。
<link rel="stylesheet" href="./sdk/demo-enhancements.css">
<script src="./sdk/static/h265web.js"></script>
<script src="./sdk/demo-enhancements.js"></script>
<div id="player"></div>
<fieldset id="playback-enhancements" data-locale="zh"></fieldset>
<button id="load-media" type="button">创建并加载</button>
<button id="play-media" type="button">播放</button>let player = null;
let recreating = false;
const mediaUrl = './media/demo.mp4';
const config = {
player_id: 'player', width: 960, height: 540,
base_url: './sdk/static/', wasm_js_uri: 'h265web_wasm.js',
wasm_wasm_uri: 'h265web_wasm.wasm', auto_play: false, ignore_audio: false
};
const controls = createPlaybackEnhancementControls(
document.getElementById('playback-enhancements'), () => player,
{recreate: recreatePlayer}
);
function createPlayer() {
const current = H265webjsPlayer();
player = current;
current.on_error_callback = error => console.error(error);
// 先绑定业务回调,再绑定控件,最后 build。
controls.bind(current);
if (!current.build({...config, ...controls.buildConfig(current)})) {
player = null;
controls.unbind();
current.release();
return;
}
current.set_voice(0); // 初次静音;实际应用应保留用户选择的音量。
controls.refresh();
current.load_media(mediaUrl);
}
function recreatePlayer() {
if (recreating) return;
recreating = true;
const previous = player;
player = null;
controls.unbind();
const start = () => { recreating = false; createPlayer(); };
if (previous) previous.release(start);
else start();
}
document.getElementById('load-media').onclick = recreatePlayer;
document.getElementById('play-media').onclick = () => {
if (!player) return;
player.notify_user_gesture();
player.play();
};把 mediaUrl 换成可播放的实际地址,按页面位置调整资源路径。重新加载由用户点击触发;生产组件还需在卸载时使迟到任务失效并等待 release 完成。需要音量、进度、多实例等完整交互时,直接使用发布目录的 中文 Demo 或官网播放器,不必在每份示例里维护一套控件。
使用集成与排障 skills
SDK 仓库提供 skills/h265web-bootstrap/ 和 skills/h265web-troubleshoot/。将完整目录复制到所用编程助手支持的 skill 位置,保留 scripts、references 和 assets。生成本地 demo 时使用同一工作区 SDK。
- 调用
$h265web-bootstrap新建 demo 或接入已有框架;需要稳定音量/超分时明确提出,控件应可选并检测 API 能力。 - 调用
$h265web-troubleshoot检查媒体、HTTP 交付、实际选核、生命周期和功能状态。请求的核心或开启状态不能替代实际出画/增强证据。
组件卸载时通过 player.release(callback) 的完成回调确认清理,再复用容器;快速换源、迟到的脚本/模型加载不能重新唤起旧组件。