라이브: Brave 브라우저에서 배경 흐림이 항상 실패함("Background blur couldn't be started") - 분리된 `<video>`.play()가 중단됨

요약

FAO: @Falco :smiling_face_with_sunglasses:
AI 고지: 이 버그는 에이전트적으로 조사되었으며, 원인과 해결책은 Opus 5.5가 제안했습니다.

Brave 브라우저에서 Live 룸의 배경 흐림을 켜면 항상 다음 오류 토스트가 표시됩니다: “배경 흐림을 시작할 수 없으므로 꺼졌습니다.” 동일한 사용자, 포럼 및 룸은 같은 기기의 Google Chrome에서는 정상적으로 작동합니다.

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

원인은 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_assets 0.2.0
  • Linux, Wayland, Intel GPU 환경의 Brave (Chromium 155); WebGL2 및 WebGPU 하드웨어 가속 사용
  • 동일 기기의 Google Chrome: 정상 작동

재현 단계

  1. Brave에서 Live 룸을 열고 카메라를 켭니다.
  2. 배경 흐림을 활성화합니다.
  3. 토스트 메시지가 표시되고 흐림이 꺼집니다.

진단

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() 호출 전에 숨겨진 비디오를 문서에 추가하고, 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. 실제 오류가 무시됩니다. local-video-manager.js의 #createBackgroundBlur()는 빈 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 컨텍스트가 필요하기 때문입니다. isSupported()에 WebGL2 검사를 추가하면 사용자가 흐림을 켠 후에 실패하는 대신 흐림 컨트롤을 숨기거나 비활성화할 수 있습니다. (헤드리스 Chromium에서 getContext("webgl*")를 스텁으로 대체하여 재현했으며, 실제 환경에서는 확인되지 않았습니다.)

Live에 감사합니다 - 이 문제를 제외하고는 우리에게는 잘 작동하고 있습니다.

1개의 좋아요

한눈에 봐도 괜찮은 것 같습니다. 수정 사항을 PR로 제출하고 싶으셨나요?