摘要
FAO: @Falco ![]()
AI 披露:此 bug 由代理自动调查,原因及修复建议由 Opus 5.5 提供。
在 Brave 浏览器中,在 Live 房间开启背景模糊功能时,始终会显示错误提示:“无法启动背景模糊,因此已将其关闭。” 在同一台机器上,使用 Google Chrome 访问相同的用户、论坛和房间则运行正常。

原因在于 BackgroundBlurManager#setup() 创建但从未插入文档的隐藏 <video> 元素。Brave 拒绝在其上执行 play(),并抛出以下错误:
AbortError: The play() request was interrupted because the media was removed from the document.
在调用 play() 之前将该元素(不可见地)插入文档即可解决 Brave 中的问题。
环境
- Discourse
2026.10.0-latest.1(568a006ad8),捆绑的 Live 插件,discourse_voice_assets0.2.0 - Linux 系统上的 Brave (Chromium 155),Wayland,Intel GPU;WebGL2 和 WebGPU 硬件加速已启用
- 同一台机器上的 Google Chrome:运行正常
复现步骤
- 在 Brave 中打开一个 Live 房间并打开摄像头。
- 启用背景模糊。
- 出现提示框且模糊功能被关闭。
诊断
我在 Brave 控制台中逐步运行了插件自身的模糊处理流程(与 background-blur.js 使用相同的资源路径、模型、委托和运行模式),分别测试了开启和关闭 Brave 指纹保护的情况:
| 步骤 | Brave,开启指纹保护 | Brave,关闭指纹保护 |
|---|---|---|
vision_bundle.js 导入,WASM 加载 |
ok | ok |
ImageSegmenter.createFromOptions,GPU 和 CPU 委托 |
ok | ok |
getUserMedia({ video: true }),轨道状态 |
ok,live |
ok,live |
对带有摄像头流的分离静音 <video> 执行 play()(即插件当前的做法) |
AbortError | AbortError |
对追加到 document.body 的同类型 <video>(1px,透明)执行 play() |
ok | ok |
因此,MediaPipe、WebGL 和摄像头均无问题。只有分离状态的 play() 失败,而 Brave 的指纹保护设置对此没有影响。无头 Chromium 可以无错误地播放分离的 <video>,这与 Chrome 表现一致。
建议修复方案
在 plugins/live/assets/javascripts/discourse/lib/live/background-blur.js 的 setup() 中:在 video.play() 之前将隐藏的 video 添加到文档中,并在 teardown() 中移除它。例如:
video.setAttribute("aria-hidden", "true");
video.style.cssText =
"position:fixed;width:1px;height:1px;opacity:0;pointer-events:none";
document.body.appendChild(video);
// ... await video.play() as now ...
// teardown():
this.#video?.remove();
据我观察,这是插件中唯一播放分离媒体元素的地方。
两个相关观察
-
真正的错误被吞没了。
local-video-manager.js中的#createBackgroundBlur()使用了空的catch {},并调用liveLog.warn("[live] failed to start background blur")但未包含错误信息。即使启用了live_verbose_logging,控制台也从未说明模糊失败的原因。将捕获的错误传递给liveLog.warn(该方法已对其进行清理)本可以让错误更快暴露出来。 -
在不支持的环境中也提供了模糊选项。
BackgroundBlurManager.isSupported()仅检查canvas.captureStream和WebAssembly。在没有 WebGL 的浏览器中,MediaPipe 的分段器在使用 GPU 和 CPU 委托时都会失败(Service "kGpuService" ... cannot be created: emscripten_webgl_create_context() returned error 0),因为分段后处理器无论如何都需要 GL 上下文。在isSupported()中添加 WebGL2 检查可以在用户开启该功能之前隐藏或禁用模糊控件,而不是让用户开启后才失败。(通过桩函数模拟getContext("webgl*")在无头 Chromium 中复现,实际环境中未见此情况。)
感谢 Live - 除了这个问题之外,它在我们的使用中运行良好。