Live: Hintergrund-Unschärfe schlägt in Brave Browser immer fehl („Hintergrund-Unschärfe konnte nicht gestartet werden“) – getrenntes <video>.play() wird abgebrochen

Zusammenfassung

FAO: @Falco :smiling_face_with_sunglasses:
KI-Disklosure: Dieser Fehler wurde agentisch untersucht; Ursache und Lösung wurden von Opus 5.5 vorgeschlagen.

Im Brave Browser führt das Aktivieren der Hintergrundunschärfe in einem Live-Raum immer zu einer Fehlermeldung: “Der Hintergrund-Blur konnte nicht gestartet werden und wurde daher deaktiviert.” Derselbe Benutzer, dasselbe Forum und derselbe Raum funktionieren einwandfrei in Google Chrome auf demselben Gerät.

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

Die Ursache ist das versteckte <video>-Element, das BackgroundBlurManager#setup() erstellt, aber nie in das Dokument einfügt. Brave lehnt play() darauf mit folgendem Fehler ab:

AbortError: The play() request was interrupted because the media was removed from the document.

Das Element (unsichtbar) vor dem Aufruf von play() in das Dokument einzufügen, behebt das Problem in Brave.

Umgebung

  • Discourse 2026.10.0-latest.1 (568a006ad8), gebündeltes Live-Plugin, discourse_voice_assets 0.2.0
  • Brave (Chromium 155) unter Linux, Wayland, Intel-GPU; WebGL2 und WebGPU hardwarebeschleunigt
  • Google Chrome auf demselben Gerät: funktioniert

Schritte zur Reproduktion

  1. Öffne einen Live-Raum in Brave und schalte die Kamera ein.
  2. Aktiviere die Hintergrundunschärfe.
  3. Die Meldung erscheint und der Blur wird ausgeschaltet.

Diagnose

Ich habe die eigene Blur-Pipeline des Plugins Schritt für Schritt in der Brave-Konsole ausgeführt (gleicher Asset-Pfad, Modell, Delegate und Ausführungsmodus wie in background-blur.js), wobei Braves Fingerprinting-Schutz zunächst aktiviert und dann deaktiviert war:

Schritt Brave, Fingerprinting-Schutz aktiv Brave, Fingerprinting-Schutz inaktiv
Import von vision_bundle.js, WASM-Load ok ok
ImageSegmenter.createFromOptions, GPU- und CPU-Delegates ok ok
getUserMedia({ video: true }), Track-Zustand ok, live ok, live
play() auf einem losgelösten, stummen <video> mit dem Kamerastream (was das Plugin tut) AbortError AbortError
play() auf einer gleichartigen <video>, die an document.body angehängt ist (1px, transparent) ok ok

Somit sind MediaPipe, WebGL und die Kamera alle in Ordnung. Nur das losgelöste play() schlägt fehl, und Braves Fingerprinting-Schutz macht keinen Unterschied. Headless Chromium spielt ein losgelöstes <video> ohne Fehler ab, was damit übereinstimmt, dass es in Chrome funktioniert.

Vorschlag zur Behebung

In plugins/live/assets/javascripts/discourse/lib/live/background-blur.js, setup(): Hänge das versteckte Video vor video.play() an das Dokument an und entferne es in teardown(). Zum Beispiel:

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() wie bisher ...

// teardown():
this.#video?.remove();

Soweit ich sehen kann, ist dies der einzige Ort im Plugin, an dem ein losgelöstes Medienelement abgespielt wird.

Zwei verwandte Beobachtungen

  1. Der eigentliche Fehler wird unterdrückt. #createBackgroundBlur() in local-video-manager.js verwendet eine nackte catch {}-Anweisung und ruft liveLog.warn("[live] failed to start background blur") ohne den Fehler auf. Selbst wenn live_verbose_logging aktiviert ist, sagt die Konsole nie, warum der Blur fehlgeschlagen ist. Das Übergeben des erfassten Fehlers an liveLog.warn (der ihn bereits bereinigt) hätte den Fehler schneller offengelegt.

  2. Blur wird angeboten, wo er niemals funktionieren kann. BackgroundBlurManager.isSupported() prüft nur canvas.captureStream und WebAssembly. In einem Browser ohne WebGL schlägt MediaPipes Segmenter mit beiden Delegates (GPU und CPU) fehl (Service "kGpuService" ... cannot be created: emscripten_webgl_create_context() returned error 0), da der Segmentierungs-Postprozesser entwederfalls einen GL-Kontext benötigt. Eine WebGL2-Prüfung in isSupported() würde die Blur-Steuerung ausblenden oder deaktivieren, anstatt nach dem Einschalten durch den Benutzer zu fehlschlagen. (Reproduziert in headless Chromium durch Stubbing von getContext("webgl*"), in der Praxis nicht beobachtet.)

Danke für Live – abgesehen davon läuft es bei uns gut.

1 „Gefällt mir“

Auf den ersten Blick sieht das gut aus. Möchtest du einen PR mit dem Fix einreichen?