Bessere Bildschirmfreigabe dank bedingtem Fokus

François Beaufort
François Beaufort

Unterstützte Browser

  • Chrome: 109.
  • Edge: 109.
  • Firefox: Nicht unterstützt.
  • Safari: Nicht unterstützt.

Quelle

Mit der Screen Capture API kann der Nutzer einen Tab, ein Fenster oder einen Bildschirm auswählen, der als Medienstream erfasst werden soll. Dieser Stream kann dann aufgezeichnet oder über das Netzwerk mit anderen geteilt werden. In dieser Dokumentation wird der bedingte Fokus beschrieben, ein Mechanismus für Web-Apps, mit dem gesteuert werden kann, ob der erfasste Tab oder das erfasste Fenster beim Start der Aufnahme den Fokus erhält oder ob der Fokus auf der Seite bleibt, die erfasst wird.

Unterstützte Browser

Der bedingte Fokus ist seit Chrome 109 verfügbar.

Hintergrund

Wenn eine Webanwendung mit der Erfassung eines Tabs oder Fensters beginnt, muss der Browser eine Entscheidung treffen: Soll die erfasste Oberfläche in den Vordergrund gebracht werden oder soll der Fokus auf der Seite bleiben, die erfasst wird? Die Antwort hängt davon ab, warum getDisplayMedia() aufgerufen wurde, und von der Oberfläche, die der Nutzer auswählt.

Stellen Sie sich eine hypothetische Webanwendung für Videokonferenzen vor. Wenn die Webanwendung track.getSettings().displaySurface liest und gegebenenfalls den Capture Handle untersucht, kann sie erkennen, was der Nutzer freigegeben hat. Dann:

  • Wenn der Tab oder das Fenster, das aufgenommen wird, per Fernzugriff gesteuert werden kann, halten Sie die Videokonferenz im Fokus.
  • Andernfalls legen Sie den Fokus auf den Tab oder das Fenster, das Sie aufnehmen möchten.

Im Beispiel oben würde die Web-App für Videokonferenzen den Fokus bei der Freigabe einer Präsentation beibehalten, sodass der Nutzer die Folien aus der Ferne durchblättern kann. Wenn der Nutzer jedoch einen Texteditor freigibt, wechselt die Web-App für Videokonferenzen sofort den Fokus zum aufgenommenen Tab oder Fenster.

Conditional Focus API verwenden

Instanziere eine CaptureController und übergebe sie an getDisplayMedia(). Wenn Sie setFocusBehavior() sofort nach der Auflösung des zurückgegebenen Versprechens getDiplayMedia() aufrufen, können Sie festlegen, ob der erfasste Tab oder das erfasste Fenster den Fokus erhält oder nicht. Dies ist nur möglich, wenn der Nutzer einen Tab oder ein Fenster freigegeben hat.

const controller = new CaptureController();

// Prompt the user to share a tab, a window or a screen.
const stream =
    await navigator.mediaDevices.getDisplayMedia({ controller });

const [track] = stream.getVideoTracks();
const displaySurface = track.getSettings().displaySurface;
if (displaySurface == "browser") {
  // Focus the captured tab.
  controller.setFocusBehavior("focus-captured-surface");
} else if (displaySurface == "window") {
  // Do not move focus to the captured window.
  // Keep the capturing page focused.
  controller.setFocusBehavior("focus-capturing-application");
}

Bei der Entscheidung, ob Sie den Fokus festlegen möchten, können Sie den Capture-Griff berücksichtigen.

// Retain focus if capturing a tab dialed to example.com.
// Focus anything else.
const origin = track.getCaptureHandle().origin;
if (displaySurface == "browser" && origin == "https://example.com") {
  controller.setFocusBehavior("focus-capturing-application");
} else if (displaySurface != "monitor") {
  controller.setFocusBehavior("focus-captured-surface");
}

Sie können sogar festlegen, ob Sie sich konzentrieren möchten, bevor Sie getDisplayMedia() aufrufen.

// Focus the captured tab or window when capture starts.
const controller = new CaptureController();
controller.setFocusBehavior("focus-captured-surface");

// Prompt the user to share their screen.
const stream =
    await navigator.mediaDevices.getDisplayMedia({ controller });

Sie können setFocusBehavior() beliebig oft vor oder höchstens einmal direkt nach der Auflösung des Versprechens aufrufen. Die letzte Aufrufe überschreibt alle vorherigen Aufrufe.

Genauer gesagt: – Das von getDisplayMedia() zurückgegebene Versprechen wird in einem Mikrotask aufgelöst. Wenn setFocusBehavior() nach Abschluss dieses Microtasks aufgerufen wird, wird ein Fehler ausgegeben. – Wenn setFocusBehavior() mehr als eine Sekunde nach Beginn der Erfassung aufgerufen wird, hat das keine Auswirkungen.

Das bedeutet, dass beide folgenden Snippets fehlschlagen:

// Prompt the user to share their screen.
const stream =
    await navigator.mediaDevices.getDisplayMedia({ controller });

// Too late, because it follows the completion of the task
// on which the getDisplayMedia() promise resolved.
// This will throw.
setTimeout(() => {
  controller.setFocusBehavior("focus-captured-surface");
});
// Prompt the user to share their screen.
const stream =
    await navigator.mediaDevices.getDisplayMedia({ controller });

const start = new Date();
while (new Date() - start <= 1000) {
  // Idle for ≈1s.
}

// Because too much time has elapsed, the browser will have
// already decided whether to focus.
// This fails silently.
controller.setFocusBehavior("focus-captured-surface");

In den folgenden Fällen wird auch eine Fehlermeldung ausgegeben, wenn setFocusBehavior() aufgerufen wird:

  • Der Videotrack des von getDisplayMedia() zurückgegebenen Streams ist nicht "live".
  • nach der Auflösung des zurückgegebenen Promises von getDisplayMedia(), wenn der Nutzer einen Bildschirm (keinen Tab oder ein Fenster) geteilt hat.

Beispiel

Sie können mit dem bedingten Fokus experimentieren, indem Sie die Demo auf Glitch ausführen. Sehen Sie sich den Quellcode an.

Funktionserkennung

So prüfen Sie, ob CaptureController.setFocusBehavior() unterstützt wird:

if (
  "CaptureController" in window &&
  "setFocusBehavior" in CaptureController.prototype
) {
  // CaptureController.setFocusBehavior() is supported.
}

Feedback

Das Chrome-Team und die Webstandards-Community möchten von Ihnen wissen, welche Erfahrungen Sie mit der bedingten Fokussierung gemacht haben.

Designbeschreibung

Funktioniert der bedingte Fokus nicht wie erwartet? Oder fehlen Methoden oder Eigenschaften, die Sie für die Implementierung Ihrer Idee benötigen? Haben Sie eine Frage oder einen Kommentar zum Sicherheitsmodell?

  • Reichen Sie ein Spezifikationsproblem im GitHub-Repository ein oder fügen Sie Ihre Gedanken zu einem bestehenden Problem hinzu.

Probleme bei der Implementierung?

Haben Sie bei der Implementierung von Chrome einen Fehler gefunden? Oder unterscheidet sich die Implementierung von der Spezifikation?

  • Melden Sie den Fehler unter https://new.crbug.com. Geben Sie dabei so viele Details wie möglich an und machen Sie eine einfache Anleitung zur Reproduktion. Glitch eignet sich gut zum Teilen von Code.

Unterstützung zeigen

Planen Sie, den bedingten Fokus zu verwenden? Ihre öffentliche Unterstützung hilft dem Chrome-Team, Funktionen zu priorisieren, und zeigt anderen Browseranbietern, wie wichtig es ist, sie zu unterstützen.

Senden Sie uns einen Tweet an @ChromiumDev und teilen Sie uns mit, wo und wie Sie es verwenden.

Danksagungen

Hero-Image von Elena Taranenko.

Vielen Dank an Rachel Andrew für die Überprüfung dieses Artikels.