Start · Sprachen · JavaScript · Referenz · CaptureController.setFocusBehavior()

CaptureController.setFocusBehavior()

Methode

Legt fest, ob ein per <code>getDisplayMedia()</code> geteilter Tab bzw. ein geteiltes Fenster nach dem Start der Aufnahme in den Vordergrund geholt wird oder die aufnehmende App den Fokus behält.

seit JavaScript Experimentell: Chromium 109+ (Chrome, Edge, Opera) Kategorie: webapi

Signatur

CaptureController.prototype.setFocusBehavior(focusBehavior)

Beschreibung

Wenn Nutzer über navigator.mediaDevices.getDisplayMedia() einen Browser-Tab oder ein Fenster zum Teilen auswählen, holt der Browser diese Oberfläche normalerweise in den Vordergrund. Mit setFocusBehavior() eines CaptureController-Objekts kann die aufnehmende Anwendung das steuern. Sie kann den Fokus auf die geteilte Oberfläche wechseln lassen ("focus-captured-surface") oder selbst im Vordergrund bleiben ("no-focus-change").

Das ist vor allem für Videokonferenz- und Präsentations-Apps nützlich. Wer zum Beispiel ein Folien-Fenster teilt, will meist sofort dorthin wechseln. Wer dagegen einen Tab nur zur Vorschau oder Aufnahme mitschneidet, will oft in der eigenen Oberfläche bleiben, etwa um die Videokacheln der Teilnehmer im Blick zu behalten.

Den Controller übergibt man im Optionsobjekt als controller an getDisplayMedia(). Die Methode lässt sich vor dem Aufruf von getDisplayMedia() oder unmittelbar nach dem Erfüllen des Promise aufrufen. Im zweiten Fall kann man je nach Art der gewählten Oberfläche entscheiden, die man über track.getSettings().displaySurface ausliest. Wartet man zu lange, nimmt der Browser sein Standardverhalten an (Fokuswechsel), und spätere Aufrufe lösen einen Fehler aus.

Die Methode gilt nur für Tabs (displaySurface === "browser") und Fenster ("window"). Bei einem ganzen Bildschirm ("monitor") gibt es keinen Fokus, der gewechselt werden könnte.

Parameter

Name Typ Default Beschreibung
$focusBehavior Pflicht "focus-captured-surface" | "no-focus-change" "focus-captured-surface": Der geteilte Tab bzw. das geteilte Fenster wird in den Vordergrund geholt (Standardverhalten des Browsers). "no-focus-change": Der Fokus bleibt auf der aufnehmenden Seite.

Rückgabewert

Typ
undefined
Beschreibung
Die Methode gibt nichts zurück. Sie wirkt nur als Nebeneffekt auf das Fokusverhalten.

Beispiele

Fokus je nach gewählter Oberfläche steuern

const shareScreen = async () => {
  const controller = new CaptureController();

  const stream = await navigator.mediaDevices.getDisplayMedia({
    video: true,
    controller,
  });

  // Direkt nach dem Erfüllen des Promise entscheiden – nicht erst später!
  const [track] = stream.getVideoTracks();
  const { displaySurface } = track.getSettings();

  if (displaySurface === 'browser') {
    // Geteilten Tab in den Vordergrund holen
    controller.setFocusBehavior('focus-captured-surface');
  } else if (displaySurface === 'window') {
    // Bei Fenstern in der eigenen App bleiben
    controller.setFocusBehavior('no-focus-change');
  }

  console.log('Geteilt wird:', displaySurface);
  return stream;
};

document.querySelector('#share').addEventListener('click', shareScreen);
Geteilt wird: browser

Fokus schon vor dem Aufruf festlegen

const startRecording = async () => {
  const controller = new CaptureController();
  // Vor getDisplayMedia() gesetzt: gilt unabhängig von der Auswahl
  controller.setFocusBehavior('no-focus-change');

  const stream = await navigator.mediaDevices.getDisplayMedia({
    video: true,
    controller,
  });

  document.querySelector('video#preview').srcObject = stream;
  console.log('Aufnahme läuft, Fokus bleibt in der App.');
};

document.querySelector('#record').addEventListener('click', startRecording);
Aufnahme läuft, Fokus bleibt in der App.

Feature-Erkennung mit Fehlerbehandlung

const share = async (keepFocus) => {
  const options = { video: true };
  let controller;

  if ('CaptureController' in window &&
      'setFocusBehavior' in CaptureController.prototype) {
    controller = new CaptureController();
    options.controller = controller;
  }

  const stream = await navigator.mediaDevices.getDisplayMedia(options);

  try {
    controller?.setFocusBehavior(
      keepFocus ? 'no-focus-change' : 'focus-captured-surface'
    );
  } catch (err) {
    // z. B. InvalidStateError, wenn der Zeitpunkt verpasst wurde
    console.warn('Fokusverhalten nicht gesetzt:', err.name);
  }
  return stream;
};

document.querySelector('#share').addEventListener('click', () => share(true));

// Wichtig · Fallstricke

  • Zeitfenster: Nach dem Erfüllen des Promise muss der Aufruf sofort erfolgen, also im selben Task ohne weiteres await auf langsame Vorgänge. Andernfalls greift das Standardverhalten, und die Methode wirft einen InvalidStateError.
  • InvalidStateError tritt außerdem auf, wenn die Aufnahme bereits beendet ist, der Track also den Zustand "ended" hat, oder wenn der Controller schon an einen anderen Aufruf gebunden ist. Je Aufnahme ist ein eigener CaptureController nötig.
  • Nur Tabs und Fenster: Bei displaySurface === "monitor" hat die Methode keinen sinnvollen Effekt. Prüfe die Oberfläche deshalb vorher mit getSettings().
  • Kompatibilität: Die Methode ist experimentell und bisher nur in Chromium-Browsern ab Version 109 verfügbar, nicht auf Mobilgeräten. Firefox und Safari unterstützen sie nicht. Verwende Feature-Erkennung.
  • Es gelten die Voraussetzungen von getDisplayMedia(): ein sicherer Kontext (HTTPS), eine Nutzeraktion wie ein Klick sowie gegebenenfalls die Permissions-Policy display-capture in iframes.