Краткое описание
FAO: @Falco ![]()
Раскрытие использования ИИ: Этот баг был исследован агентно, и причина и решение были предложены Opus 5.5.
В браузере Brave при включении размытия фона в Live-комнате всегда появляется уведомление об ошибке: «Не удалось запустить размытие фона, поэтому оно было отключено». У того же пользователя на той же машине форум и комната работают нормально в Google Chrome.

Причиной является скрытый элемент <video>, который создаётся методом BackgroundBlurManager#setup(), но никогда не вставляется в документ. 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 - Brave (Chromium 155) на Linux, Wayland, GPU Intel; аппаратное ускорение WebGL2 и WebGPU
- Google Chrome на той же машине: работает
Шаги для воспроизведения
- Откройте Live-комнату в Brave и включите камеру.
- Включите размытие фона.
- Появляется уведомление об ошибке, и размытие отключается.
Диагностика
Я последовательно запустил собственный конвейер размытия плагина в консоли Brave (с тем же путём к ассетам, моделью, делегатом и режимом работы, как в background-blur.js), сначала с включённой защитой от фингерпринтинга Brave, а затем с выключенной:
| Шаг | Brave, защита от фингерпринтинга вкл. | Brave, защита от фингерпринтинга выкл. |
|---|---|---|
Импорт vision_bundle.js, загрузка WASM |
ок | ок |
ImageSegmenter.createFromOptions, GPU и CPU делегаты |
ок | ок |
getUserMedia({ video: true }), состояние трека |
ок, live |
ок, live |
play() для отключённого заглушённого <video> с потоком камеры (что делает плагин) |
AbortError | AbortError |
play() для такого же <video>, добавленного в document.body (1px, прозрачный) |
ок | ок |
Таким образом, MediaPipe, WebGL и камера работают исправно. Срабатывает ошибка только при отключённом play(), и защита от фингерпринтинга Brave не имеет значения. Headless Chromium проигрывает отключённый <video> без ошибок, что соответствует работе в Chrome.
Предлагаемое исправление
В файле plugins/live/assets/javascripts/discourse/lib/live/background-blur.js, метод setup(): добавьте скрытое видео в документ перед вызовом video.play() и удалите его в 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() как сейчас ...
// teardown():
this.#video?.remove();
Насколько я вижу, это единственное место в плагине, где проигрывается отключённый медиаэлемент.
Два связанных наблюдения
-
Реальная ошибка подавляется. Метод
#createBackgroundBlur()вlocal-video-manager.jsиспользует пустой блок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. Добавление проверки WebGL2 вisSupported()позволило бы скрыть или отключить управление размытием вместо того, чтобы терпеть неудачу после включения пользователем. (Воспроизведено в headless Chromium с помощью подменыgetContext("webgl*"), в реальной среде не наблюдалось.)
Спасибо за Live — помимо этого, он отлично у нас работает.