Live: размытие фона в Brave всегда не работает («Не удалось запустить размытие фона») — отключённый .play() в <video> прерывается

Краткое описание

FAO: @Falco :smiling_face_with_sunglasses:
Раскрытие использования ИИ: Этот баг был исследован агентно, и причина и решение были предложены Opus 5.5.

В браузере Brave при включении размытия фона в Live-комнате всегда появляется уведомление об ошибке: «Не удалось запустить размытие фона, поэтому оно было отключено». У того же пользователя на той же машине форум и комната работают нормально в Google Chrome.

error: "Background blur couldn't be started, so it was turned off."

Причиной является скрытый элемент <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_assets 0.2.0
  • Brave (Chromium 155) на Linux, Wayland, GPU Intel; аппаратное ускорение WebGL2 и WebGPU
  • Google Chrome на той же машине: работает

Шаги для воспроизведения

  1. Откройте Live-комнату в Brave и включите камеру.
  2. Включите размытие фона.
  3. Появляется уведомление об ошибке, и размытие отключается.

Диагностика

Я последовательно запустил собственный конвейер размытия плагина в консоли 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();

Насколько я вижу, это единственное место в плагине, где проигрывается отключённый медиаэлемент.

Два связанных наблюдения

  1. Реальная ошибка подавляется. Метод #createBackgroundBlur() в local-video-manager.js использует пустой блок catch {} и вызывает liveLog.warn("[live] failed to start background blur") без передачи объекта ошибки. Даже при включённом live_verbose_logging в консоли никогда не указывается, почему не сработало размытие. Передача перехваченной ошибки в liveLog.warn (который уже выполняет санацию данных) позволила бы быстрее выявить проблему.

  2. Размытие предлагается там, где оно никогда не сможет работать. Метод 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 — помимо этого, он отлично у нас работает.

1 лайк

С первого взгляда всё выглядит хорошо. Хотел бы ты отправить PR с исправлением?