Przechwytuj strumień wideo z dowolnego elementu

François Beaufort
François Beaufort
Elad Alon
Elad Alon

Interfejs Screen Capture API umożliwia przechwytywanie całej bieżącej karty. Interfejs Element Capture API umożliwia przechwycenie i zarejestrowanie określonego elementu HTML. Przekształca przechwycony obszar karty w konkretne poddrzewo DOM, rejestrując tylko bezpośrednie elementy podrzędne elementu docelowego. Oznacza to, że przycina i usuwa zarówno przesłonięte, jak i zasłonięte treści.

Dlaczego warto korzystać z funkcji przechwytywania elementów?

Zrozumienie wymagań związanych z aplikacjami do rozmów wideo pomoże Ci zrozumieć, w jakich obszarach funkcja Element Capture jest przydatna. Jeśli masz aplikację do obsługi rozmów wideo, która umożliwia umieszczanie aplikacji innych firm w elemencie iframe, możesz przechwycić ten element jako film i przesłać go do zdalnych uczestników.

Zrzut ekranu przedstawiający rozmowę wideo w Chrome.
Elad podczas rozmowy wideo z François używa aplikacji zewnętrznej.

Wywołanie getDisplayMedia() i pozwolenie użytkownikowi na wybranie bieżącej karty spowoduje przesłanie całej bieżącej karty. W ten sposób można przesłać obraz wideo użytkownika. Możesz przyciąć ten element za pomocą funkcji Region Capture.

Co się stanie, jeśli osoba prowadząca skorzysta z aplikacji do rozmów wideo, a niektóre treści, na przykład lista rozwijana, zostaną wyświetlone nad materiałem przeznaczonym do nagrywania?

Zrzut ekranu z listą zasłaniającą treści przeznaczone do rejestrowania
Na górze treści przeznaczonej do rejestracji wyświetla się lista.

Nie da się tutaj zrobić zdjęcia regionu. Część listy może być widoczna na ekranach użytkowników zdalnych.

Zrzut ekranu z listą rozwijaną.
Lista rozwijana Elabie wyświetla się nad treściami otrzymanymi przez François.

Wiele problemów wynika z tego, że funkcja przechwytywania ruchu regionalnego rejestruje części elementów (tzw. treści zasłaniające):

  • Ukrywanie treści może zasłaniać treści, które użytkownik zamierzał udostępnić.
  • Treści mogą być prywatne (dotyczy to na przykład powiadomień z czatu).
  • Pomijanie treści może być mylące. (Na przykład ponowne opublikowanie aplikacji może pozwolić na krótkie przeniesienie filmów użytkowników zdalnych na obszar docelowy).

Interfejs Element Capture API rozwiązuje wszystkie te problemy, umożliwiając kierowanie elementu, który chcesz udostępnić.

Zrzut ekranu przedstawiający element docelowy bez widocznej listy.
François nie widzi listy rozwijanej.

Jak używać funkcji Przechwytywanie elementów?

captureTarget to Element na stronie zawierający treść, którą użytkownik chce przechwycić. Chcesz, aby aplikacja internetowa do obsługi rozmów wideo przechwytywała urządzenie captureTarget i udostępniała go uczestnikom zdalnym. Uzyskujesz więc RestrictionTarget z captureTarget. Po ograniczeniu ścieżki wideo za pomocą obiektu RestrictionTarget klatki na tej ścieżce wideo składają się teraz tylko z pikseli, które są częścią elementu captureTarget, i jego bezpośrednich elementów podrzędnych DOM.

Jeśli captureTarget zmieni rozmiar, kształt lub lokalizację, ścieżka wideo będzie podążać za ścieżką, nie wymagając przy tym żadnych dodatkowych działań z aplikacji internetowej. Treści, które się pojawią, znikają lub się poruszają, nie wymagają dodatkowego traktowania.

Jeszcze raz wykonaj te czynności:

Zacznij od zezwolenia użytkownikowi na przechwycenie bieżącej karty.

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

Określ RestrictionTarget, wywołując RestrictionTarget.fromElement() z wybranym przez Ciebie elementem jako danych wejściowych.

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

Następnie wywołaj restrictTo() na ścieżce wideo, podając RestrictionTarget jako dane wejściowe. Po rozwiązaniu ostatniej obietnicy wszystkie kolejne klatki zostaną ograniczone.

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

// Enjoy! Transmit remotely.

Szczegółowa analiza

Wykrywanie funkcji

Aby sprawdzić, czy funkcja RestrictionTarget.fromElement() jest obsługiwana, użyj:

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

Wygeneruj cel ograniczenia

Skup się na elemencie o nazwie captureTarget. Aby uzyskać z niego RestrictionTarget, wywołaj funkcję RestrictionTarget.fromElement(captureTarget). Jeśli operacja się uda, zwrócona obietnica zostanie rozpatrzona za pomocą nowego obiektu RestrictionTarget. W przeciwnym razie zostanie ona odrzucona, jeśli wygenerujesz nieuzasadnioną liczbę obiektów RestrictionTarget.

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

W odróżnieniu od Elementów obiekty RestrictionTargetserializowalne. Można go na przykład przekazać do innego dokumentu za pomocą Window.postMessage().

Kierowanie ograniczone

Podczas przechwytywania karty ścieżka wideo wyświetla restrictTo(). Przechwytując bieżącą kartę, możesz wywołać funkcję restrictTo() z użyciem null lub dowolnej wartości RestrictionTarget pobranej z elementu na bieżącej karcie.

Wywołania restrictTo(restrictionTarget) zmieniają ścieżkę wideo w przechwycenie captureTarget, jak gdyby była ona narysowana samodzielnie niezależnie od reszty DOM. Wszystkie elementy potomne elementu captureTarget są też rejestrowane. Elementy potomne captureTarget są też usuwane z przechwycenia. W efekcie wszystkie klatki wyświetlane na ścieżce wyglądają tak, jakby zostały przycięte do konturu elementu captureTarget, a wszystkie przesłaniające i zasłonięte treści są usuwane.

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

Wywołania restrictTo(null) przywracają oryginalny stan utworu.

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

Jeśli wywołanie funkcji restrictTo() się powiedzie, zwrócona obietnica zostanie zrealizowana, gdy można zagwarantować, że wszystkie kolejne klatki wideo będą ograniczone do captureTarget.

Jeśli się nie powiedzie, obietnica zostanie odrzucona. Nieudane wywołanie do restrictTo() może mieć następujące przyczyny:

  • Jeśli restrictionTarget został wygenerowany na karcie innej niż ta, która jest przechwytywana. (Zauważ, że używając przycisku „Udostępnij tę kartę”, użytkownicy mogą w każdej chwili zmienić przechwyconą kartę).
  • Jeśli właściwość restrictionTarget pochodzi z elementu, który już nie istnieje.
  • czy ścieżka ma klony, (patrz numer 1509418).
  • Bieżąca ścieżka wideo nie jest ścieżką wideo zarejestrowaną samodzielnie.
  • Jeśli element, z którego pochodzi restrictionTarget, nie podlega ograniczeniom.

Uwagi na temat zdjęć robionych samodzielnie

Jeśli aplikacja wywołuje funkcję getDisplayMedia(), a użytkownik zdecyduje się zarejestrować kartę aplikacji, mamy do czynienia z „selfie”.

Metoda restrictTo() jest widoczna w przypadku każdej ścieżki wideo nagranej za pomocą karty, a nie tylko przy robieniu zdjęć samodzielnie. Jednak na razie funkcja Przechwytywanie elementów działa tylko przy samo zrobieniu zdjęć. Dlatego przed próbą ograniczenia ścieżki warto sprawdzić, czy użytkownik wybrał bieżącą kartę. Możesz to zrobić za pomocą nicka przechwytywania. Możesz też poprosić przeglądarkę o zachęcenie użytkownika do zrobienia zdjęcia samodzielnie za pomocą preferCurrentTab.

Przejrzystość

Klatki wideo wyświetlane przez aplikację do getDisplayMedia() nie zawierają kanału alfa. Jeśli aplikacja ustawia częściowo przezroczysty cel przechwytywania, usunięcie kanału alfa ma pewne możliwe konsekwencje:

  • Kolory mogą się zmienić. Częściowo przezroczyste docelowe elementy na jasnym tle mogą być ciemniejsze po usunięciu kanału alfa, a te na ciemnym tle – jaśniejsze.
  • Kolory, które były niewidoczne lub niedostrzegalne dla użytkownika przy ustawionym maksymalnym kanale alfa, będą wyświetlane po jego usunięciu. Jeśli na przykład przezroczyste sekcje miały kod RGBA rgba(0, 0, 0, 0), mógł wystąpić nieoczekiwane czarne obszary w przechwyconych ramkach.
Zrzut ekranu z wynikiem przezroczystego celu przechwytywania nieprostokątnego.
Docelowy strumień wideo przechwycony przezroczysty (nieprostokątny) (po prawej) to czarny prostokąt w tle, który zawiera nieprzezroczyste niebieskie kółko.

Nieodpowiednie elementy docelowe przechwytywania

Zawsze możesz zacząć ograniczać utwór do dowolnego prawidłowego miejsca docelowego. Ramki nie będą jednak tworzone w określonych warunkach, na przykład jeśli element lub element nadrzędny to display:none. Ogólnie rzecz biorąc, ograniczenie odnosi się tylko do elementu składającego się z jednego, spójnego, dwuwymiarowego, prostokątnego obszaru, którego piksele można logicznie określić niezależnie od elementów nadrzędnych lub równorzędnych.

Jedną z ważnych kwestii, które trzeba wziąć pod uwagę, jeśli chcesz, aby dany element był objęty ograniczeniami, jest to, że musi on tworzyć własny kontekst grupowania. Aby to zapewnić, możesz określić właściwość CSS isolation na isolate.

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

Pamiętaj, że w dowolnym momencie element docelowy może się przełączać między stanem „Odpowiednia” a „Nie spełnia wymogów”, np. gdy aplikacja zmieni swoje właściwości CSS. To aplikacja decyduje o tym, czy ma odpowiednie cele przechwytywania, i unika nieoczekiwaną zmianę ich właściwości. Jeśli element docelowy przestanie spełniać warunki, nowe klatki nie będą wysyłane na ścieżce do momentu, gdy element docelowy znów będzie kwalifikował się do ograniczenia.

Włączam przechwytywanie elementów

Interfejs Element Capture API jest dostępny w Chrome na komputerach za pomocą flagi Element Capture i można go włączyć na stronie chrome://flags/#element-capture.

Ta funkcja rozpoczyna też korzystanie z wersji próbnej origin Chrome 121 na komputery, która umożliwia deweloperom jej włączenie na potrzeby zbierania danych od prawdziwych użytkowników. Więcej informacji na ten temat znajdziesz w artykule Pierwsze kroki z testami origin.

Prywatność i bezpieczeństwo

Aby zapoznać się z zaletami w zakresie bezpieczeństwa, zapoznaj się z sekcją Uwagi na temat prywatności i bezpieczeństwa w specyfikacji Element Capture.

Przeglądarka Chrome rysuje niebieskie obramowanie wokół krawędzi przechwyconych kart.

Wersja demonstracyjna

Możesz pobawić się funkcją przechwytywania elementów, uruchamiając prezentację w Glitch. Pamiętaj, by przejrzeć kod źródłowy.

Prześlij opinię

Zespół Chrome i społeczność zajmująca się standardami internetowymi chcą poznać Twoją opinię o funkcji Element Capture.

Opowiedz nam o projekcie

Czy jest coś, co nie działa zgodnie z Twoimi oczekiwaniami? A może brakuje metod lub właściwości, których potrzebujesz do realizacji swojego pomysłu? Masz pytanie lub komentarz na temat modelu zabezpieczeń?

  • Zgłoś problem ze specyfikacją w repozytorium GitHub lub dodaj swoje uwagi na temat istniejącego problemu.

Problem z implementacją?

Czy wystąpił błąd w implementacji Chrome? A może implementacja różni się od specyfikacji?

  • Zgłoś błąd na stronie https://new.crbug.com. Podaj jak najwięcej szczegółów i proste instrukcje odtworzenia. Glitch to doskonały sposób na szybkie i łatwe udostępnianie kopii.

Poświadczenia

Zdjęcie: Paul Skorupskas, Unsplash