Wstawianie strumieni dla MediaStreamTrack

Treści z MediaStreamTrack są udostępniane jako strumień, którym można manipulować lub wykorzystywać go do generowania nowych treści.

Tło

W kontekście interfejsu Media Capture and Streams API interfejs MediaStreamTrack reprezentuje pojedynczą ścieżkę multimedialną w strumieniu. Zwykle są to ścieżki audio lub wideo, ale mogą też występować inne typy ścieżek. Obiekty MediaStream składają się z 0 lub większej liczby obiektów MediaStreamTrack, które reprezentują różne ścieżki audio lub wideo. Każdy MediaStreamTrack może mieć co najmniej 1 kanał. Kanał to najmniejsza jednostka strumienia multimediów, np. sygnał audio powiązany z danym głośnikiem, takim jak lewy lub prawy w ścieżce audio stereo.

Co to są strumienie wstawiane w MediaStreamTrack?

Główną ideą strumieni wstawianych w przypadku MediaStreamTrack jest udostępnienie zawartości MediaStreamTrack jako kolekcji strumieni (zgodnie z definicją WHATWG Streams API). Można je modyfikować, aby wprowadzać nowe komponenty.

Udzielenie programistom dostępu do strumienia wideo (lub audio) umożliwia im bezpośrednie wprowadzanie zmian w strumieniu. Z kolei realizacja tego samego zadania manipulacji wideo za pomocą tradycyjnych metod wymaga od programistów używania elementów pośrednich, takich jak elementy <canvas>. (Szczegółowe informacje o tym typie procesu znajdziesz np. w tym artykule).

Obsługa przeglądarek

Wstawiane strumienie dla MediaStreamTrack są obsługiwane od Chrome w wersji 94.

Przypadki użycia

Przykłady zastosowań strumieni wstawianych w przypadku MediaStreamTrack:

  • gadżety do wideokonferencji, takie jak „śmieszne kapelusze” czy wirtualne tła;
  • Przetwarzanie głosu, np. za pomocą wokoderów.

Jak korzystać ze strumieni wstawianych w przypadku MediaStreamTrack

Wykrywanie cech

Wykrywanie funkcji strumieni wstawianych na potrzeby obsługi MediaStreamTrack możesz przeprowadzić w ten sposób:

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

Podstawowe pojęcia

Wstawiane strumienie dla MediaStreamTrack opierają się na koncepcjach zaproponowanych wcześniej przez WebCodecs i dzielą MediaStreamTrack na 2 komponenty:

  • MediaStreamTrackProcessor, który pobiera źródło obiektu MediaStreamTrack i generuje strumień klatek multimedialnych, w szczególności obiekty VideoFrame lub AudioFrame. Możesz to traktować jako ujście ścieżki, które może udostępniać niezakodowane klatki ze ścieżki jako ReadableStream.
  • MediaStreamTrackGenerator, który przetwarza strumień klatek multimedialnych i udostępnia interfejs MediaStreamTrack. Można go przekazywać do dowolnego odbiornika, tak jak ścieżkę z getUserMedia(). Jego danymi wejściowymi są ramki multimedialne.

MediaStreamTrackProcessor

Obiekt MediaStreamTrackProcessor udostępnia jedną właściwość: readable. Umożliwia odczytywanie klatek z MediaStreamTrack. Jeśli ścieżka jest ścieżką wideo, odczytane z readable fragmenty będą obiektami VideoFrame. Jeśli ścieżka jest ścieżką audio, odczytane z readable fragmenty będą obiektami AudioFrame.

MediaStreamTrackGenerator

Obiekt MediaStreamTrackGenerator udostępnia też jedną właściwość writable, która jest obiektem WritableStream umożliwiającym zapisywanie klatek multimedialnych w obiekcie MediaStreamTrackGenerator, który sam jest obiektem MediaStreamTrack. Jeśli atrybut kind ma wartość "audio", strumień akceptuje obiekty AudioFrame, a w przypadku każdego innego typu zwraca błąd. Jeśli typ to "video", strumień akceptuje obiekty VideoFrame i zwraca błąd w przypadku każdego innego typu. Gdy ramka zostanie zapisana w writable, automatycznie wywoływana jest jej metoda close(), dzięki czemu zasoby multimedialne nie są już dostępne z JavaScriptu.

MediaStreamTrackGenerator to ścieżka, w przypadku której można wdrożyć niestandardowe źródło, zapisując klatki multimedialne w jej polu writable.

Wszystko w jednym miejscu

Główny pomysł polega na utworzeniu łańcucha przetwarzania w ten sposób:

Ścieżka platformy → Procesor → Przekształcanie → Generator → Elementy docelowe platformy

Przykład poniżej ilustruje ten łańcuch w przypadku aplikacji skanera kodów kreskowych, która wyróżnia wykryty kod kreskowy w transmisji wideo na żywo.

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;

Prezentacja

Demonstrację skanera kodów QR z sekcji powyżej możesz zobaczyć w akcji w przeglądarce na komputerze lub urządzeniu mobilnym. Przytrzymaj kod QR przed aparatem, a aplikacja go wykryje i wyróżni. Kod źródłowy aplikacji możesz zobaczyć na GitHubie.

Skaner kodów QR działający w karcie przeglądarki na komputerze stacjonarnym, który wykrywa i podświetla kod QR na telefonie trzymanym przez użytkownika przed kamerą laptopa.

Kwestie związane z bezpieczeństwem i prywatnością

Bezpieczeństwo tego interfejsu API zależy od istniejących mechanizmów na platformie internetowej. Gdy dane są udostępniane za pomocą interfejsów VideoFrameAudioFrame, obowiązują reguły tych interfejsów dotyczące danych z zanieczyszczonym pochodzeniem. Na przykład nie można uzyskać dostępu do danych z zasobów pochodzących z innych domen ze względu na istniejące ograniczenia dostępu do takich zasobów (np. nie można uzyskać dostępu do pikseli obrazu lub elementu wideo pochodzącego z innej domeny). Dodatkowo dostęp do danych multimedialnych z kamer, mikrofonów lub ekranów wymaga autoryzacji użytkownika. Dane o mediach udostępniane przez ten interfejs API są już dostępne w ramach innych interfejsów API.

Prześlij opinię

Zespół Chromium chce poznać Twoje wrażenia związane z używaniem strumieni wstawianych w przypadku MediaStreamTrack.

Opisz projekt interfejsu API

Czy coś w API nie działa tak, jak oczekujesz? Czy brakuje metod lub właściwości, które są potrzebne do realizacji Twojego pomysłu? Masz pytania lub uwagi dotyczące modelu zabezpieczeń? Zgłoś problem ze specyfikacją w odpowiednim repozytorium GitHub lub dodaj swoje uwagi do istniejącego problemu.

Zgłaszanie problemu z implementacją

Czy udało Ci się znaleźć błąd w implementacji Chromium? A może implementacja różni się od specyfikacji? Zgłoś błąd na stronie new.crbug.com. Podaj jak najwięcej szczegółów, proste instrukcje odtwarzania i wpisz Blink>MediaStream w polu Komponenty.

Wyrażanie poparcia dla interfejsu API

Czy planujesz używać strumieni do wstawiania w przypadku MediaStreamTrack? Twoje publiczne wsparcie pomaga zespołowi Chromium ustalać priorytety funkcji i pokazuje innym dostawcom przeglądarek, jak ważne jest ich obsługiwanie.

Wyślij tweeta do @ChromiumDev z hasztagiem #InsertableStreams i napisz, gdzie i jak korzystasz z tej funkcji.

Podziękowania

Specyfikację strumieni wstawianych dla MediaStreamTrack opracowali Harald AlvestrandGuido Urdaneta. Ten artykuł został sprawdzony przez Harald Alvestrand, Joe Medley, Ben Wagner, Huib KleinhoutFrançois Beaufort. Baner powitalny autorstwa Chrisa Montgomery'egoUnsplash.