Przechwytuj strumień wideo z dowolnego elementu

François Beaufort
François Beaufort

Screen Capture API pozwala przechwycić całą bieżącą kartę. Interfejs Element Capture API umożliwia przechwytywanie i rejestrowanie określonego elementu HTML. Przechwytuje całą kartę w formie konkretnego poddrzewa DOM, uwzględniając tylko bezpośrednie elementy potomne elementu docelowego. Inaczej mówiąc, przycina i usuwa zarówno ukryte, jak i zakryte treści.

Dlaczego warto korzystać z funkcji Przechwytywanie elementów?

Rozważenie wymagań dotyczących aplikacji do rozmów wideo może ułatwić zrozumienie, gdzie przydaje się funkcja Element Capture. Jeśli masz aplikację do rozmów wideo, która umożliwia umieszczanie aplikacji innych firm w elemencie iframe, możesz chcieć przechwycić ten element iframe jako film wideo i przesłać go do uczestników zdalnych.

Zrzut ekranu z rozmową wideo w Chrome.
Elad używa aplikacji innej firmy podczas rozmowy wideo z Jankiem.

Wywołanie getDisplayMedia() i umożliwienie użytkownikowi wyboru bieżącej karty spowoduje przesłanie całej bieżącej karty. Jest to prawdopodobnie metoda przesłania filmu wideo innego użytkownika. Możesz przyciąć zdjęcie za pomocą funkcji Region Capture.

Co jednak się stanie, jeśli prowadzący używa aplikacji do rozmów wideo i jakieś treści (np. lista rozwijana) pojawiają się nad materiałem, który ma zostać nagrany?

Zrzut ekranu z listą obejmującą treści przeznaczone do przechwytywania.
U góry treści, które chcesz zarejestrować, pojawi się lista.

Robienie zdjęć regionu nie będzie tu pomocne. Część tej listy może być widoczna na ekranach uczestników zdalnych.

Zrzut ekranu pokazujący listę rozwijaną.
Lista rozwijana przez Ella pojawia się nad treściami otrzymanymi przez François.

Fakt, że funkcja przechwytywania regionów rejestruje części elementów w ten sposób, może powodować wiele problemów:

  • Wykluczone treści mogą zasłaniać treści, które użytkownik zamierzał udostępnić.
  • Zamykanie treści może być prywatne (tak jak w przypadku powiadomień czatu).
  • Wykluczanie treści może być mylące. (Na przykład przeformatowanie aplikacji może na krótko przenieść własne filmy uczestników zdalnych do ujętego celu).

Interfejs Element Capture API rozwiązuje wszystkie te problemy, umożliwiając kierowanie reklam na udostępniany element.

Zrzut ekranu pokazujący element docelowy bez listy.
François nie widzi listy rozwijanej od zespołu Elad.

Jak korzystać z funkcji Przechwytywanie elementów?

captureTarget to element na stronie zawierający treści, które użytkownik chce przechwycić. Chcesz, aby aplikacja internetowa do rozmów wideo rejestrowała te dane (captureTarget) i udostępniała je uczestnikom zdalnym. Uzyskujesz więc wartość RestrictionTarget z zakresu captureTarget. Po ograniczeniu ścieżki wideo za pomocą tego elementu RestrictionTarget klatki na ś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 śladem użytkownika, nie wymagając żadnych dodatkowych działań z aplikacji internetowej. Również treści, które się pojawiają, znikają lub poruszają, nie trzeba w żaden sposób traktować.

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 funkcję RestrictionTarget.fromElement() z wybranym przez siebie elementem jako danymi wejściowymi.

// 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, używając jako danych wejściowych RestrictionTarget. Po spełnieniu 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 cech

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

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

Wygeneruj cel ograniczenia

Zaznacz Element o nazwie captureTarget. Aby wyodrębnić z niego element RestrictionTarget, wywołaj RestrictionTarget.fromElement(captureTarget). Jeśli się powiedzie, zwrócona obietnica zostanie zrealizowana za pomocą nowego obiektu RestrictionTarget. W przeciwnym razie zostanie odrzucony, jeśli uzyskasz nieuzasadnioną liczbę RestrictionTarget obiektów.

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

W przeciwieństwie do Elementu obiekt RestrictionTarget podlega serializacji. Można je przekazać do innego dokumentu, na przykład za pomocą narzędzia Window.postMessage().

Kierowanie ograniczone

Podczas przechwytywania karty ścieżka wideo ujawnia restrictTo(). Podczas przechwytywania bieżącej karty można wywołać funkcję restrictTo() za pomocą null lub dowolnego RestrictionTarget pobranego z elementu na bieżącej karcie.

Wywołania restrictTo(restrictionTarget) mutują ścieżkę wideo do formatu captureTarget, tak jakby była ona rysowana sama, niezależnie od reszty DOM. Przechwytywane są również wszystkie elementy potomne elementu captureTarget; rodzeństwo elementu captureTarget jest wykluczane z rejestracji. W rezultacie wszystkie klatki wyświetlane na ścieżce wyglądają tak, jakby zostały przycięte do obramowań captureTarget, a wszystkie wykluczające i wykluczone 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 wartość obiecana jest zrealizowana, gdy można zagwarantować, że wszystkie kolejne klatki wideo zostaną ograniczone do captureTarget.

Jeśli się nie uda, obietnica zostanie odrzucona. Nieudane połączenie z numerem restrictTo() może mieć następujące przyczyny:

  • Jeśli restrictionTarget został wygenerowany na innej karcie niż ta, która została zarejestrowana. Pamiętaj, że korzystając z przycisku „Udostępnij tę kartę”, użytkownicy mogą w każdej chwili zmienić wyświetlaną kartę.
  • Jeśli wartość restrictionTarget pochodzi z elementu, który już nie istnieje.
  • czy utwór ma kopie. (Patrz problem 1509418).
  • Jeśli bieżący utwór nie jest ścieżką wideo nagranych samodzielnie.
  • Jeśli Element, z którego pochodzi wartość restrictionTarget, nie kwalifikuje się do ograniczenia.

Uwagi na temat robienia własnych zdjęć

Gdy aplikacja wywołuje funkcję getDisplayMedia(), a użytkownik decyduje się zarejestrować jej własną kartę, nazywamy to „zrobieniem własnym”.

Metoda restrictTo() jest widoczna w przypadku każdej ścieżki wideo utworzonej za pomocą karty, a nie tylko w przypadku samonagrania. Na razie przechwytywanie elementów jest dostępne tylko do samodzielnego robienia zdjęć. Dlatego przed próbą ograniczenia ścieżki warto sprawdzić, czy użytkownik wybrał bieżącą kartę. Użyj nicka przechwytywania. Możesz też poprosić przeglądarkę o zachęcenie użytkownika do samodzielnego zdjęcia za pomocą preferCurrentTab.

Przejrzystość

Klatki wideo, które aplikacja dociera przez getDisplayMedia(), nie zawierają kanału alfa. Jeśli aplikacja ma częściowo przezroczyste pole do przechwytywania, usunięcie kanału alfa może mieć pewne możliwe konsekwencje:

  • Kolory mogą się zmienić. Częściowo przezroczyste elementy docelowe rysowane 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 niewidoczne dla użytkownika przy ustawionym maksymalnym poziomie kanału alfa, będą widoczne po usunięciu kanału alfa. Może to na przykład prowadzić do nieoczekiwanego czarnego obszaru na przechwyconych klatkach, jeśli przezroczyste sekcje miały kod RGBA (rgba(0, 0, 0, 0)).
Zrzut ekranu pokazujący wynik przezroczystego celu przechwytywania, który nie jest prostokątny.
Docelowy strumień wideo z przezroczystością nieprzejrzystą (nieprostokątny) to prostokąt na czarnym tle z nieprzezroczystym niebieskim okręgiem.

Nieodpowiednie cele przechwytywania

Zawsze możesz zacząć ograniczać ścieżkę do dowolnego prawidłowego celu przechwytywania. Klatki nie będą jednak tworzone w określonych warunkach, np. jeśli element lub element nadrzędny ma wartość display:none. Główne uzasadnienie jest takie, że ograniczenie dotyczy tylko elementu, który składa się z jednego, spójnego, dwuwymiarowego, prostokątnego obszaru, którego piksele można określić logicznie niezależnie od elementów nadrzędnych lub potomnych.

Ważną kwestią, którą należy wziąć pod uwagę, aby zagwarantować, że element kwalifikuje się do nałożenia ograniczeń, jest konieczność tworzenia własnego kontekstu nakładania. Aby to zagwarantować, możesz określić właściwość CSS isolation, ustawiając ją na isolate.

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

Pamiętaj, że element docelowy może się w każdej chwili zmienić z „Odpowiedni” lub „Niekwalifikujący się do nałożenia ograniczeń”, np. wtedy, gdy aplikacja zmieni swoje właściwości CSS. Od aplikacji zależy, czy zostaną użyte uzasadnione cele przechwytywania, a także unikać nieoczekiwanej zmiany ich właściwości. Jeśli element docelowy przestanie się kwalifikować, nowe klatki nie będą pojawiać się na ścieżce do czasu, aż 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 komputery za flagą Element Capture i można go włączyć na stronie chrome://flags/#element-capture.

W ramach tej funkcji rozpoczyna się też okres próbny origin Chrome 121 na komputerze, dzięki któremu deweloperzy mogą włączyć tę funkcję użytkownikom swoich witryn w celu zbierania danych od prawdziwych użytkowników. Więcej informacji o testowaniu origin znajdziesz w artykule Pierwsze kroki z testowaniem origin.

Prywatność i bezpieczeństwo

Więcej informacji o wadach związanych z bezpieczeństwem znajdziesz w sekcji Uwagi na temat prywatności i bezpieczeństwa w specyfikacji funkcji Przechwytywanie elementów.

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

Pokaz

Aby wypróbować funkcję Element Capture, uruchom wersję demonstracyjną aplikacji Glitch. Koniecznie zapoznaj się z kodem źródłowym.

Prześlij opinię

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

Opowiedz nam o projekcie

Czy jest coś, co w funkcji Zrób zdjęcie regionu nie działa zgodnie z oczekiwaniami? A może brakuje Ci metod lub właściwości, które pozwolą Ci zrealizować Twój pomysł? Masz pytanie lub komentarz na temat modelu zabezpieczeń?

Problem z implementacją?

Czy wystąpił błąd z implementacją Chrome? Czy implementacja różni się od specyfikacji?

  • Zgłoś błąd na stronie https://new.crbug.com. Podaj jak najwięcej szczegółów i podaj proste instrukcje odtworzenia. Usługa Glitch świetnie nadaje się do szybkiego i łatwego udostępniania poprawek.

Poświadczenia

Zdjęcie: Paul Skorupskas, Unsplash