Videostream von einem beliebigen Element erfassen

Beaufort
François Beaufort
Elad Alon
Elad Alon

Mit der Screen Capture API können Sie den gesamten aktuellen Tab erfassen. Mit der Element Capture API können Sie ein bestimmtes HTML-Element erfassen und aufzeichnen. Sie wandelt eine Erfassung des gesamten Tabs in eine Erfassung einer bestimmten DOM-Unterstruktur um, wobei nur direkte Nachfolger des Zielelements erfasst werden. Es werden also sowohl verdeckende als auch verdeckte Inhalte abgeschnitten und entfernt.

Vorteile der Elementerfassung

Wenn Sie die Anforderungen an eine Anwendung für Videokonferenzen berücksichtigen, können Sie besser verstehen, wo Element Capture nützlich ist. Wenn Sie eine Anwendung für Videokonferenzen verwenden, mit der Sie Anwendungen von Drittanbietern in einen iFrame einbetten können, möchten Sie diesen iFrame möglicherweise als Video erfassen und an Remote-Teilnehmer übertragen.

Screenshot eines Videoanrufs in Chrome.
Elad verwendet eine Drittanbieteranwendung in einem Videokonferenzanruf mit François.

Wenn getDisplayMedia() aufgerufen wird und der Nutzer den aktuellen Tab auswählen kann, wird der gesamte aktuelle Tab übertragen. Dadurch werden die eigenen Videos der Nutzer wahrscheinlich an sie zurückgesendet. Mit Region Capture kannst du das Bild zuschneiden.

Was passiert jedoch, wenn der Vortragende mit der Anwendung für Videokonferenzen interagiert und einige Inhalte, z. B. eine Drop-down-Liste, über dem für die Aufnahme vorgesehenen Inhalt zeichnen?

Screenshot einer Drop-down-Liste, die den für die Aufnahme vorgesehenen Inhalt verdeckt
Über dem für die Aufnahme vorgesehenen Inhalt wird eine Drop-down-Liste angezeigt.

Region Capture wäre da nicht hilfreich. Ein Teil der Drop-down-Liste ist möglicherweise auf den Bildschirmen der Remote-Teilnehmer sichtbar.

Screenshot einer aufgenommenen Drop-down-Liste.
Elads Drop-down-Liste wird über den Inhalten angezeigt, die François erhalten hat.

Die Tatsache, dass die Regionserfassung Teile von Elementen auf diese Weise erfasst (sogenannte Verdeckung von Inhalten), führt zu mehreren Problemen:

  • Verdeckende Inhalte können die Sicht auf die Inhalte verdecken, die der Nutzer teilen wollte.
  • Verdeckende Inhalte können privat sein, z. B. Chatbenachrichtigungen.
  • Verdeckende Inhalte können verwirrend sein. (Beispielsweise könnte eine Neuanordnung der App dazu führen, dass die eigenen Videos der Teilnehmer im Homeoffice kurz über dem aufgenommenen Ziel liegen.)

Die Element Capture API löst all diese Probleme, da Sie die Ausrichtung auf das freizugebende Element vornehmen können.

Screenshot des Zielelements ohne Drop-down-Liste in Ansicht
François sieht die Drop-down-Liste von Elad nicht.

Wie verwende ich die Elementerfassung?

Das captureTarget ist ein Element auf Ihrer Seite, das den Inhalt enthält, den der Nutzer erfassen möchte. Sie möchten, dass die Web-App für Videokonferenzen captureTarget erfasst und für Teilnehmer an entfernten Orten freigegeben wird. Sie leiten also ein RestrictionTarget von captureTarget ab. Nach dem Einschränken des Videotracks mit diesem RestrictionTarget bestehen die Frames auf diesem Videotrack nur noch aus den Pixeln, die Teil von captureTarget sind, und aus dessen direkten untergeordneten DOM-Elementen.

Wenn captureTarget sich in Größe, Form oder Position ändert, folgt der Videotrack, ohne dass zusätzliche Eingaben von einer der beiden Web-Apps erforderlich sind. Verdeckende Inhalte, die angezeigt werden, verschwinden oder sich bewegen, erfordern ebenfalls keine besondere Behandlung.

Führen Sie diese Schritte noch einmal durch:

Erlauben Sie den Nutzenden zunächst, den aktuellen Tab zu erfassen.

// Ask the user for permission to start capturing the current tab.
const stream = await navigator.mediaDevices.getDisplayMedia({
 preferCurrentTab: true,
});
const [track] = stream.getVideoTracks();

Definieren Sie ein RestrictionTarget, indem Sie RestrictionTarget.fromElement() mit einem Element Ihrer Wahl als Eingabe aufrufen.

// Associate captureTarget with a new RestrictionTarget
const captureTarget = document.querySelector("#captureTarget");
const restrictionTarget = await RestrictionTarget.fromElement(captureTarget);

Rufen Sie dann restrictTo() für den Videotrack mit RestrictionTarget als Eingabe auf. Sobald das letzte Promise aufgelöst ist, werden alle nachfolgenden Frames eingeschränkt.

// Start restricting the self-capture video track using the RestrictionTarget.
await track.restrictTo(restrictionTarget);

// Enjoy! Transmit remotely.

Im Detail

Funktionserkennung

Mit dem folgenden Befehl kannst du prüfen, ob RestrictionTarget.fromElement() unterstützt wird:

if ("RestrictionTarget" in self && "fromElement" in RestrictionTarget) {
  // Deriving a restriction target is supported.
}

RestrictionTarget ableiten

Legen Sie den Fokus auf das ElementcaptureTarget“. Rufen Sie RestrictionTarget.fromElement(captureTarget) auf, um RestrictionTarget daraus abzuleiten. Das zurückgegebene Promise wird bei Erfolg mit einem neuen RestrictionTarget-Objekt aufgelöst. Andernfalls wird sie abgelehnt, wenn Sie eine unangemessene Anzahl von RestrictionTarget-Objekten erstellt haben.

const captureTarget = document.querySelector("#captureTarget");
const restrictionTarget = await RestrictionTarget.fromElement(captureTarget);

Im Gegensatz zu einem Element ist ein RestrictionTarget-Objekt serialisierbar. Sie kann beispielsweise mithilfe von Window.postMessage() an ein anderes Dokument übergeben werden.

Eingeschränkt

Beim Aufnehmen eines Tabs wird im Videotrack restrictTo() angezeigt. Beim Erfassen des aktuellen Tabs ist es zulässig, restrictTo() mit null oder einer beliebigen RestrictionTarget aufzurufen, die von einem Element auf dem aktuellen Tab abgeleitet ist.

Aufrufe von restrictTo(restrictionTarget) wandeln den Videotrack in eine Erfassung von captureTarget um, so als würde er allein und unabhängig vom restlichen DOM gezeichnet. Alle Nachfolger von captureTarget werden ebenfalls erfasst. Geschwister von captureTarget werden aus der Aufnahme entfernt. Das führt dazu, dass alle im Track übermittelten Frames so aussehen, als wären sie auf die Konturen von captureTarget zugeschnitten. Verdeckte Inhalte werden entfernt.

// Start restricting the self-capture video track using the RestrictionTarget.
await track.restrictTo(restrictionTarget);

Durch Aufrufe von restrictTo(null) wird der Originalzustand des Titels wiederhergestellt.

// Stop restricting.
await track.restrictTo(null);

Wenn der Aufruf von restrictTo() erfolgreich ist, wird das zurückgegebene Promise aufgelöst, wenn garantiert werden kann, dass alle nachfolgenden Videoframes auf captureTarget beschränkt sind.

Wenn der Vorgang nicht erfolgreich ist, wird das Versprechen abgelehnt. Ein fehlgeschlagener Aufruf von restrictTo() kann einen der folgenden Gründe haben:

  • Ob das restrictionTarget auf einem anderen Tab als dem aufgezeichneten erstellt wurde. Beachten Sie, dass Nutzer über die Schaltfläche „Stattdessen diesen Tab teilen“ jederzeit ändern können, welcher Tab aufgenommen wird.
  • Gibt an, ob das restrictionTarget von einem Element abgeleitet wurde, das nicht mehr existiert.
  • Ob der Titel Klone enthält (Siehe Problem 1509418.)
  • Wenn der aktuelle Track kein Videotrack ist, das keine Selbstaufnahme ist.
  • Das Element, von dem restrictionTarget abgeleitet wurde, kann nicht eingeschränkt werden.

Überlegungen zur Selbstaufnahme

Wenn eine App getDisplayMedia() aufruft und der Nutzer entscheidet, den eigenen Tab der App aufzunehmen, bezeichnen wir das als „Selbstaufnahme“.

Die Methode restrictTo() wird bei jedem Videotrack mit Tabs verwendet, nicht nur bei der Selbstaufnahme. Die Elementerfassung ist derzeit jedoch nur für die Selbstaufnahme aktiviert. Bevor Sie versuchen, den Track einzuschränken, sollten Sie daher überprüfen, ob der Nutzer den aktuellen Tab ausgewählt hat. Dazu kannst du den Alias aufnehmen. Sie können den Browser auch mit preferCurrentTab auffordern, den Nutzer zu einer Selbstaufnahme zu bewegen.

Transparenz

Videoframes, die die App über getDisplayMedia() sieht, enthalten keinen Alphakanal. Wenn eine App ein teilweise transparentes Erfassungsziel festlegt, kann das Entfernen des Alphakanals einige mögliche Folgen haben:

  • Die Farben können sich ändern. Teilweise transparente Zielelemente, die über einem hellen Hintergrund gezeichnet wurden, können dunkler erscheinen, wenn der Alphakanal entfernt wird. Die vor einem dunklen Hintergrund gezeichneten Elemente erscheinen eventuell heller.
  • Farben, die bei der Einstellung des Maximalwerts für den Alphakanal unsichtbar oder nicht wahrnehmbar waren, werden nach dem Entfernen des Alphakanals wieder angezeigt. Dies kann beispielsweise zu unerwarteten schwarzen Bereichen in den erfassten Frames führen, wenn die transparenten Abschnitte den RGBA-Code rgba(0, 0, 0, 0) hätten.
Screenshot des Ergebnisses eines nicht rechteckigen, transparenten Erfassungsziels.
Der nicht rechteckige Videostream für das transparente Erfassungsziel (rechts) ist ein schwarzer Hintergrund mit einem undurchsichtigen blauen Kreis.

Unzulässige Erfassungsziele

Es ist immer möglich, einen Track auf jedes gültige Erfassungsziel zu beschränken. Unter bestimmten Bedingungen werden jedoch keine Frames erstellt, z. B. wenn das Element oder ein Ancestor display:none ist. Die allgemeine Begründung ist, dass die Einschränkung nur für ein Element gilt, das einen einzelnen, zusammenhängenden, zweidimensionalen, rechteckigen Bereich umfasst, dessen Pixel unabhängig von übergeordneten oder gleichgeordneten Elementen logisch ermittelt werden können.

Damit das Element für die Einschränkung infrage kommt, muss es einen eigenen Stacking-Kontext bilden. Um dies sicherzustellen, können Sie die CSS-Eigenschaft isolation angeben und sie auf isolate setzen.

<div id="captureTarget" style="isolation: isolate;"></iframe>

Das Zielelement kann an jedem beliebigen Punkt zwischen „Aktiv“ und „Nicht zulässig für die Einschränkung“ wechseln, z. B. wenn die App die Preisvergleichsportal-Eigenschaften ändert. Die App muss angemessene Erfassungsziele verwenden und ihre Eigenschaften nicht unerwartet ändern. Wenn das Zielelement nicht mehr infrage kommt, werden neue Frames einfach nicht mehr im Track ausgegeben, bis das Zielelement wieder für die Einschränkung infrage kommt.

Elementerfassung aktivieren

Die Element Capture API ist in Chrome auf Computern hinter dem Element Capture-Flag verfügbar und kann unter chrome://flags/#element-capture aktiviert werden.

Für diese Funktion wird auch ein Ursprungstest von Chrome 121 auf dem Computer durchgeführt, mit dem Entwickler die Funktion für Besucher ihrer Websites aktivieren können, um Daten von echten Nutzern zu erheben. Weitere Informationen zu Ursprungstests finden Sie unter Erste Schritte mit Ursprungstests.

Sicherheit und Datenschutz

Informationen zu den Vor- und Nachteilen der Sicherheit finden Sie im Abschnitt Datenschutz und Sicherheitsaspekte der Element Capture-Spezifikation.

Im Chrome-Browser wird ein blauer Rahmen um die Ränder erfasster Tabs gezogen.

Demo

Du kannst mit der Elementaufnahme experimentieren, indem du die Demo auf Glitch ausführst. Prüfen Sie unbedingt den Quellcode.

Feedback

Das Chrome-Team und die Webstandards-Community möchten wissen, welche Erfahrungen Sie mit Element Capture gemacht haben.

Erzählen Sie uns mehr über das Design

Gibt es bei Region Capture etwas, 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?

  • Sie können ein Spezifikationsproblem im GitHub-Repository melden oder Ihre Meinung zu einem bereits bestehenden Problem hinzufügen.

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 und eine einfache Anleitung zum Reproduzieren an. Mit Glitch lassen sich schnell und einfach Reproduktionen durchführen.

Danksagung

Foto von Paul Skorupskas auf Unsplash