USB 权限与 HEVC 解码是两条独立链路。授权成功不会启用解码器,解码失败也不需要重新设置 USB 权限。
为什么我的 Chrome 没有使用 WebCodecs 解码 HEVC?
WebCodecs 是调用浏览器解码器的接口,不保证支持所有编码、profile 或分辨率。存在 VideoDecoder 不等于当前 HEVC 配置可解码;SDK 会先实际解码测试帧,失败时尝试已注册的软件解码器。example-hevc-fallback.mjs 为可选文件,不存在或加载失败时仅使用 WebCodecs;不会因该文件缺失而直接中断初始化。若 WebCodecs 也不能解码 HEVC,则仍无法初始化,请更新浏览器或部署可用的软件解码器。
实时预览标题右侧显示当前流的解码方式。软件后备表示该配置未能使用 WebCodecs 出帧,具体原因需要结合浏览器能力和系统驱动排查;WebCodecs 本身也不等于硬件加速。
如何排查与处理?
- 更新 Chrome,确认使用 HTTPS/localhost;在 Chrome「设置 → 系统」检查图形加速设置,修改后重启浏览器。
- 在地址栏手动打开 chrome://gpu,检查 Video Acceleration Information 是否列出 HEVC,以及 Problems Detected。只有“Video Decode: Hardware accelerated”不足以证明当前 HEVC 可用。
- Linux 管理员可用已安装的 vainfo 检查 VA-API 是否初始化成功并列出 HEVC 解码能力;nvidia-smi 正常、GPU 渲染正常或 FFmpeg 能解码,均不能单独证明 Chrome 能使用该路径。驱动适配需按实际系统单独验证,不建议依靠强开实验参数作为交付要求。
- 已部署软件解码器时,可继续使用软件后备。性能不足时先停流,再选择设备真实支持的 1080p HEVC;能力表没有该配置时无法切换。修改 VideoDecoder 的宽高不会把 2K 码流变成 1080p。
可在当前页面开发者工具控制台查询一个 2K HEVC 配置(仅报告配置支持,最终仍需实际解码;实际码流的 codec/profile 也需匹配):
const config = {
codec: 'hev1.1.6.L150.90', codedWidth: 2560, codedHeight: 1440,
optimizeForLatency: true
};
console.log(typeof VideoDecoder === 'function'
? await VideoDecoder.isConfigSupported(config)
: {supported: false, reason: '当前上下文没有 VideoDecoder'});
参考:Chrome WebCodecs 使用说明 · Chromium VA-API 文档。
Chrome 连接步骤与 USB 权限配置(含示例)
连接需要两层权限:Chrome 对当前网站的设备授权,以及操作系统允许当前用户访问设备。HTML 可以通过 SDK 发起前者;不能执行 sudo、修改系统权限或跳过浏览器确认。看到设备名称不代表系统已允许打开设备。
- 使用新版 Chrome,通过 HTTPS 或 localhost 打开页面;确认网站的 USB 设备权限未被禁止。可在 Chrome「设置 → 隐私和安全 → 网站设置 → 更多权限 → USB 设备」检查;受管理的浏览器还需管理员允许访问。
- 插好有线设备,点击「连接设备」,在 Chrome 选择框中选中目标设备,再点弹窗内的「连接」。选择框由浏览器管理。SDK 必须由点击直接调用,不要先等待网络请求或定时器。
- 页面显示「已连接」后,手动开启图传。若系统拒绝访问,按下述系统配置完成授权,再回到页面重试。
页面调用示例(USB 选择与连接细节由 SDK 内部处理):
connectButton.onclick = () => {
sdk.connect_device_wired().catch(error => {
status.textContent = error.message;
// USB_ACCESS_DENIED:先处理系统访问权限,再手动重试。
});
};
Linux:临时授权
在本工程根目录运行下列命令,按终端提示输入本机密码。脚本只为当前设备节点增加当前用户的读写权限,拔插后需要重做:
bash scripts/grant_wasm_usb.sh
仅拿到静态发布文件、没有工程脚本时,可在普通用户终端手动操作。先用 lsusb 查找设备;以下 BBB/DDD 必须替换为输出中的三位 Bus 和 Device 编号(每次拔插可能变化)。setfacl/getfacl 由系统的 acl 工具提供。
lsusb -d fc69:f19a
# 将输出中的 Bus 和 Device 编号分别填入 BBB 和 DDD
sudo setfacl -m "u:$(id -un):rw" /dev/bus/usb/BBB/DDD
getfacl /dev/bus/usb/BBB/DDD
test -r /dev/bus/usb/BBB/DDD && test -w /dev/bus/usb/BBB/DDD && echo "当前用户可读写"
Linux:持久配置 udev(由管理员执行)
下面为当前 SDK 匹配的设备 fc69:f19a 配置专用用户组。规则只允许 root 和组成员读写;部署时使用实际 USB 标识,VID/PID 使用小写十六进制且不带 0x。不要把设备设置成所有用户可写。
先在运行 Chrome 的普通用户终端执行,确保 id -un 是实际桌面用户:
sudo groupadd -f device-usb
sudo usermod -aG device-usb "$(id -un)"
sudoedit /etc/udev/rules.d/70-device-usb.rules
在上述规则文件中加入这一行并保存(已有文件请保留其他规则):
SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", ATTR{idVendor}=="fc69", ATTR{idProduct}=="f19a", MODE="0660", GROUP="device-usb"
重载规则后,注销桌面并重新登录以更新组身份,重新打开 Chrome,然后拔插设备:
sudo udevadm control --reload-rules
# 重新登录、拔插后验证;BBB/DDD 改为最新节点编号
id -nG
ls -l /dev/bus/usb/BBB/DDD
test -r /dev/bus/usb/BBB/DDD && test -w /dev/bus/usb/BBB/DDD && echo "当前用户可读写"
id -nG 应包含 device-usb,设备组应为 device-usb,且当前用户可读写。此后拔插会重新应用规则,无需反复设置临时 ACL;Chrome 的网站授权仍独立存在。
其他系统与排查
- Windows:目标 USB 接口需要 WinUSB 驱动绑定。由设备供应方提供驱动或固件自动绑定支持;在设备管理器检查目标接口,Linux 的 ACL/udev 命令不适用。
- macOS:通常无需额外权限规则;目标接口不能被其他程序或内核驱动占用。
- Android Chrome:选择设备后,还需在系统提示中允许 Chrome 访问 USB;不使用上述 Linux 桌面规则。
- 仍然失败:关闭占用设备的其他程序/标签页,确认 USB 线支持数据;Linux 再核对最新节点权限。被取消的选择返回 CANCELLED,可再次点击连接。
参考:Chrome WebUSB 授权说明 · 各系统 USB 配置要求。本页示例用于手动配置,不会自动修改系统。
解码提醒能否关闭?
点击预览提醒右侧的 × 即可关闭。该条提醒在本次连接中不再遮挡画面,完整内容保留在「日志」;不同的新提醒仍会显示,重新连接后重新提示。关闭提醒不会改变解码方式或设备图传配置。