Einfügbare Streams für MediaStreamTrack

Der Inhalt einer MediaStreamTrack wird als Stream freigegeben, der manipuliert oder zum Generieren neuer Inhalte verwendet werden kann.

Hintergrund

Im Kontext der Media Capture and Streams API stellt die MediaStreamTrack-Schnittstelle einen einzelnen Medientrack in einem Stream dar. In der Regel sind dies Audio- oder Videotracks, es können aber auch andere Tracktypen vorhanden sein. MediaStream-Objekte bestehen aus null oder mehr MediaStreamTrack-Objekten, die verschiedene Audio- oder Videotracks darstellen. Jede MediaStreamTrack kann einen oder mehrere Kanäle haben. Der Kanal stellt die kleinste Einheit eines Medienstreams dar, z. B. ein Audiosignal, das einem bestimmten Sprecher zugeordnet ist, z. B. links oder rechts in einer Stereo-Audiospur.

Was sind einfügbare Streams für MediaStreamTrack?

Das Grundprinzip hinter einfügbaren Streams für MediaStreamTrack besteht darin, den Inhalt eines MediaStreamTrack als Sammlung von Streams (wie in der WHATWG Streams API definiert) bereitzustellen. Diese Streams können manipuliert werden, um neue Komponenten einzuführen.

Wenn Entwicklern direkt Zugriff auf den Video- oder Audiostream gewährt wird, können sie Änderungen direkt am Stream vornehmen. Im Gegensatz dazu müssen Entwickler, die dieselbe Videomanipulation mit traditionellen Methoden ausführen möchten, Zwischenelemente wie <canvas>-Elemente verwenden. Weitere Informationen zu diesem Verfahren finden Sie beispielsweise unter Video + Canvas = Magie.

Unterstützte Browser

Einfügbare Streams für MediaStreamTrack werden ab Chrome 94 unterstützt.

Anwendungsfälle

Zu den Anwendungsfällen für einfügbare Streams für MediaStreamTrack gehören unter anderem:

  • Gadgets für Videokonferenzen wie „lustige Hüte“ oder virtuelle Hintergründe
  • Sprachverarbeitung wie Software-Vocoder

Einfügbare Streams für MediaStreamTrack verwenden

Funktionserkennung

So kannst du einfügbare Streams für die Unterstützung von MediaStreamTrack erkennen:

if ('MediaStreamTrackProcessor' in window && 'MediaStreamTrackGenerator' in window) {
  // Insertable streams for `MediaStreamTrack` is supported.
}

Wichtige Konzepte

Einfügbare Streams für MediaStreamTrack basieren auf Konzepten, die zuvor von WebCodecs vorgeschlagen wurden. Dabei wird MediaStreamTrack konzeptionell in zwei Komponenten unterteilt:

  • Das MediaStreamTrackProcessor, das die Quelle eines MediaStreamTrack-Objekts nutzt und einen Stream von Medienframes generiert, insbesondere VideoFrame- oder AudioFrame-Objekte. Du kannst dir das als einen Track-Sink vorstellen, der die nicht codierten Frames aus dem Track als ReadableStream freigeben kann.
  • Der MediaStreamTrackGenerator, der einen Stream von Medienframes nutzt und eine MediaStreamTrack-Schnittstelle bereitstellt. Sie kann wie ein Track aus getUserMedia() an jeden beliebigen Abfluss bereitgestellt werden. Sie nimmt Medienframes als Eingabe an.

MediaStreamTrackProcessor

Ein MediaStreamTrackProcessor-Objekt stellt die Eigenschaft readable bereit. Damit können die Frames aus MediaStreamTrack gelesen werden. Wenn es sich bei dem Track um einen Videotrack handelt, sind die aus readable gelesenen Chunks VideoFrame-Objekte. Wenn es sich bei dem Track um einen Audiotrack handelt, sind die aus readable gelesenen Chunks AudioFrame-Objekte.

MediaStreamTrackGenerator

Ein MediaStreamTrackGenerator-Objekt stellt ebenfalls eine Property bereit, writable, eine WritableStream, mit der Medienframes in das MediaStreamTrackGenerator geschrieben werden können, das selbst eine MediaStreamTrack ist. Wenn das kind-Attribut "audio" ist, werden im Stream AudioFrame-Objekte akzeptiert und bei allen anderen Typen kommt es zu einem Fehler. Wenn „kind“ "video" ist, werden im Stream VideoFrame-Objekte akzeptiert und bei jedem anderen Typ tritt ein Fehler auf. Wenn ein Frame in writable geschrieben wird, wird die Methode close() des Frames automatisch aufgerufen, sodass seine Medienressourcen nicht mehr über JavaScript zugänglich sind.

Ein MediaStreamTrackGenerator ist ein Track, für den eine benutzerdefinierte Quelle implementiert werden kann, indem Mediaframes in das Feld writable geschrieben werden.

Zusammenfassung

Der Grundgedanke besteht darin, eine Verarbeitungskette so zu erstellen:

Plattform-Track → Prozessor → Transformation → Generator → Plattform-Senke

Das folgende Beispiel veranschaulicht diese Kette für eine Barcode-Scanner-Anwendung, die erkannte Barcodes in einem Live-Videostream hervorhebt.

const stream = await getUserMedia({ video: true });
const videoTrack = stream.getVideoTracks()[0];

const trackProcessor = new MediaStreamTrackProcessor({ track: videoTrack });
const trackGenerator = new MediaStreamTrackGenerator({ kind: 'video' });

const transformer = new TransformStream({
  async transform(videoFrame, controller) {
    const barcodes = await detectBarcodes(videoFrame);
    const newFrame = highlightBarcodes(videoFrame, barcodes);
    videoFrame.close();
    controller.enqueue(newFrame);
  },
});

trackProcessor.readable.pipeThrough(transformer).pipeTo(trackGenerator.writable);

const videoBefore = document.getElementById('video-before');
const videoAfter = document.getElementById('video-after');
videoBefore.srcObject = stream;
const streamAfter = new MediaStream([trackGenerator]);
videoAfter.srcObject = streamAfter;

Demo

Sie können sich die Demo des QR-Code-Scanners aus dem Abschnitt oben in einem Desktop- oder mobilen Browser ansehen. Halten Sie einen QR-Code vor die Kamera. Die App erkennt ihn und hebt ihn hervor. Den Quellcode der Anwendung finden Sie auf Glitch.

QR-Code-Scanner, der in einem Browsertab auf einem Computer ausgeführt wird und auf dem Smartphone, das der Nutzer vor der Kamera des Laptops hält, einen erkannten und hervorgehobenen QR-Code zeigt.

Überlegungen zu Sicherheit und Datenschutz

Die Sicherheit dieser API basiert auf den vorhandenen Mechanismen der Webplattform. Da Daten über die Schnittstellen VideoFrame und AudioFrame freigegeben werden, gelten die Regeln dieser Schnittstellen für den Umgang mit Daten mit fraglichem Ursprung. Beispielsweise kann auf Daten aus plattformübergreifenden Ressourcen nicht zugegriffen werden, da es Einschränkungen für den Zugriff auf solche Ressourcen gibt. So ist es beispielsweise nicht möglich, auf die Pixel eines plattformübergreifenden Bild- oder Videoelements zuzugreifen. Außerdem ist der Zugriff auf Mediendaten von Kameras, Mikrofonen oder Bildschirmen an die Nutzerautorisierung gebunden. Die von dieser API bereitgestellten Mediendaten sind bereits über andere APIs verfügbar.

Feedback

Das Chromium-Team möchte von Ihnen wissen, wie Sie die einfügbaren Streams für MediaStreamTrack finden.

Informationen zum API-Design

Funktioniert die API nicht wie erwartet? Oder fehlen Methoden oder Eigenschaften, die Sie zur Umsetzung Ihrer Idee benötigen? Haben Sie Fragen oder Anmerkungen zum Sicherheitsmodell? Reichen Sie ein Spezifikationsproblem im entsprechenden GitHub-Repository ein oder fügen Sie Ihre Gedanken zu einem vorhandenen Problem hinzu.

Problem mit der Implementierung melden

Haben Sie einen Fehler in der Chromium-Implementierung gefunden? Oder unterscheidet sich die Implementierung von der Spezifikation? Melden Sie einen Fehler unter new.crbug.com. Geben Sie so viele Details wie möglich und eine einfache Anleitung für die Reproduktion an. Geben Sie dann Blink>MediaStream in das Feld Komponenten ein. Glitch eignet sich hervorragend, um schnell und einfach Reproduktionen zu teilen.

Unterstützung für die API anzeigen

Möchten Sie einfügbare Streams für MediaStreamTrack verwenden? Ihre öffentliche Unterstützung hilft dem Chromium-Team, Funktionen zu priorisieren, und zeigt anderen Browseranbietern, wie wichtig es ist, sie zu unterstützen.

Schicken Sie uns unter dem Hashtag #InsertableStreams einen Tweet an @ChromiumDev und teilen Sie uns mit, wo und wie Sie den Tweet verwenden.

Danksagungen

Die einfügbaren Streams für die MediaStreamTrack-Spezifikation wurden von Harald Alvestrand und Guido Urdaneta geschrieben. Dieser Artikel wurde von Harald Alvestrand, Joe Medley, Ben Wagner, Huib Kleinhout und François Beaufort geprüft. Hero-Image von Chris Montgomery auf Unsplash