Bessere Bildschirmfreigabe dank bedingtem Fokus

François Beaufort
François Beaufort

Unterstützte Browser

  • 109
  • 109
  • x
  • x

Quelle

Über die Screen Capture API können Nutzer einen Tab, ein Fenster oder einen Bildschirm auswählen, um sie als Medienstream aufzunehmen. Dieser Stream kann dann aufgezeichnet oder über das Netzwerk mit anderen Nutzern geteilt werden. In dieser Dokumentation wird der bedingte Fokus vorgestellt, ein Mechanismus für Web-Apps, mit dem gesteuert wird, ob der erfasste Tab oder das erfasste Fenster zu Beginn der Erfassung fokussiert wird oder ob die Erfassungsseite fokussiert bleiben soll.

Unterstützte Browser

Der bedingte Fokus ist ab Chrome 109 verfügbar.

Hintergrund

Wenn eine Webanwendung beginnt, einen Tab oder ein Fenster zu erfassen, steht der Browser einer Entscheidung gegenüber – sollte die erfasste Oberfläche in den Vordergrund gestellt werden oder sollte die Erfassungsseite im Fokus bleiben? Die Antwort hängt vom Grund für den Aufruf von getDisplayMedia() ab. Je nachdem, warum der Nutzer die App letztendlich auswählt.

Stellen Sie sich eine hypothetische Web-App für Videokonferenzen vor. Lesen Sie sich track.getSettings().displaySurface durch und sehen Sie sich gegebenenfalls auch den Alias erfassen an, um zu verstehen, was der Nutzer geteilt hat. Dann:

  • Wenn der aufgenommene Tab oder das aufgenommene Fenster aus der Ferne gesteuert werden kann, lassen Sie die Videokonferenz im Fokus.
  • Andernfalls setzen Sie den Fokus auf den erfassten Tab oder das aufgenommene Fenster.

Im obigen Beispiel würde die Web-App für Videokonferenzen den Fokus beibehalten, wenn eine Präsentation geteilt wird, sodass der Nutzer aus der Ferne durch die Folien blättern kann. Wenn der Nutzer jedoch einen Texteditor freigibt, würde die Web-App für Videokonferenzen den Fokus sofort auf den aufgenommenen Tab oder das aufgenommene Fenster verschieben.

Conditional Focus API verwenden

Instanziieren Sie eine CaptureController und übergeben Sie sie an getDisplayMedia(). Indem du setFocusBehavior() aufrufst, unmittelbar nachdem das zurückgegebene getDiplayMedia()-Promise aufgelöst wurde, kannst du steuern, ob der erfasste Tab oder das erfasste Fenster fokussiert wird oder nicht. Das 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 der Fokus liegt, kann der Erfassungsziehpunkt berücksichtigt werden.

// 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 });

Du kannst setFocusBehavior() beliebig oft aufrufen, bevor das Versprechen aufgelöst wird, oder höchstens einmal, nachdem das Versprechen aufgelöst wurde. Der letzte Aufruf überschreibt alle vorherigen Aufrufe.

Genauer gesagt: – Das zurückgegebene Versprechen von getDisplayMedia() löst eine Mikroaufgabe auf. Wenn setFocusBehavior() nach Abschluss dieser Mikroaufgabe aufgerufen wird, wird ein Fehler ausgegeben. – Der Aufruf von setFocusBehavior() länger als eine Sekunde nach Beginn der Erfassung ist kein Vorgang.

Das bedeutet, dass die beiden 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");

Der Aufruf von setFocusBehavior() löst außerdem in den folgenden Fällen aus:

  • Der Videotrack des von getDisplayMedia() zurückgegebenen Streams ist nicht "live".
  • nachdem das von getDisplayMedia() zurückgegebene Versprechen aufgelöst wurde, wenn der Nutzer einen Bildschirm (keinen Tab oder ein Fenster) freigegeben hat.

Beispiel

Du kannst mit dem bedingten Fokus spielen, indem du die Demo zu Glitch ausführst. Sehen Sie sich unbedingt 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 mehr über Ihre Erfahrungen mit Conditional Focus erfahren.

Erzähl uns etwas über das Design

Gibt es etwas am bedingten Fokus, das nicht wie erwartet funktioniert? Oder fehlen Methoden oder Eigenschaften, die du zur Umsetzung deiner Idee benötigst? 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 weicht die Implementierung von der Spezifikation ab?

  • Melde den Fehler unter https://new.crbug.com. Gib dabei so viele Details wie möglich und eine einfache Anleitung für die Reproduktion an. Glitch eignet sich gut zum Teilen von Code.

Support anzeigen

Möchtest du den bedingten Fokus verwenden? Ihr öffentlicher Support hilft dem Chrome-Team dabei, Funktionen zu priorisieren, und zeigt anderen Browseranbietern, wie wichtig ein Support für sie ist.

Schicken Sie uns einen Tweet an @ChromiumDev und teilen Sie uns mit, wo und wie Sie Gemini verwenden.

Danksagungen

Hero-Image von Elena Taranenko.

Vielen Dank an Rachel Andrew für die Bewertung dieses Artikels.