Wstawianie strumieni dla MediaStreamTrack

Opublikowano: 4 maja 2021 r.

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.

Czym są strumienie wstawiane w przypadku MediaStreamTrack?

Główną ideą strumieni wstawianych w przypadku MediaStreamTrack jest udostępnianie zawartości MediaStreamTrack jako kolekcji strumieni (zgodnie z definicją w Streams API WHATWG). 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. W przeciwieństwie do tego 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 w przypadku MediaStreamTrack są obsługiwane od Chrome 94.

Przypadki użycia

Przykłady zastosowań strumieni wstawianych w przypadku MediaStreamTrack:

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

Jak korzystać ze strumieni wstawianych w przypadku MediaStreamTrack

Wykrywanie funkcji strumieni wstawianych na potrzeby obsługi MediaStreamTrack:

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 miejsce docelowe ś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 udostępnić dowolnemu odbiorcy, tak jak utwór z getUserMedia(). Na wejściu otrzymuje 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 innych typów zwraca błąd. Jeśli rodzaj 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, dla której można wdrożyć niestandardowe źródło, zapisując ramki multimedialne w jej polu writable.

Wszystko w jednym miejscu

Główna idea polega na utworzeniu łańcucha przetwarzania w ten sposób:

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

Poniższy przykład 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 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 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 pytanie lub komentarz dotyczący 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 w implementacji Chromium występuje błąd? Czy implementacja różni się od specyfikacji? Zgłoś błąd na stronie new.crbug.com. Podaj jak najwięcej szczegółów i instrukcje odtwarzania oraz wpisz Blink>MediaStream w polu Komponenty.

Pomoc dotycząca interfejsu API

Czy planujesz używać strumieni wstawianych 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 Alvestrand i Guido Urdaneta. Recenzentami byli Harald Alvestrand, Joe Medley, Ben Wagner, Huib KleinhoutFrançois Beaufort.