Za pomocą interfejsu Screen Capture API możesz uchwycić cały bieżący kartę. Interfejs Element Capture API umożliwia przechwycenie i zapisanie konkretnego elementu HTML. Przekształca ona zrzut całej karty w zrzut konkretnego poddrzewa DOM, obejmujący tylko bezpośrednich potomków elementu docelowego. Inaczej mówiąc, przycina i usuwa zarówno zasłaniające, jak i zasłaniane treści.
Dlaczego warto korzystać z Element Capture?
Zapoznanie się z wymaganiami aplikacji do wideokonferencji może pomóc Ci zrozumieć, w jakich sytuacjach Element Capture może być przydatny. Jeśli masz aplikację do rozmów wideo, która umożliwia umieszczanie aplikacji innych firm w iframe, możesz czasem chcieć przechwycić ten iframe jako film i przesłać go do uczestników zdalnych.

Wywołanie metody getDisplayMedia()
i pozwolenienie użytkownikowi na wybranie bieżącej karty spowoduje przesłanie całej bieżącej karty. Prawdopodobnie przesyła ona filmy do użytkowników. Możesz je przyciąć, korzystając z funkcji Zrzut obszaru.
Co jednak, jeśli prowadzący korzysta z aplikacji do wideokonferencji, a niektóre treści, na przykład lista rozwijana, są nakładane na treści, które mają być rejestrowane?

W tym przypadku nie pomoże Ci przechwytywanie regionu. Część listy może być widoczna na ekranach uczestników zdalnych.

Fakt, że funkcja Region Capture rejestruje w ten sposób części elementów (tzw. zakrywanie treści), powoduje wiele problemów:
- Zasłonięcie treści może uniemożliwić wyświetlenie treści, które użytkownik chce udostępnić.
- Zasłonięte treści mogą być prywatne (np. powiadomienia na czacie).
- Zasłonięcie treści może być mylące. (np. ponowne rozmieszczenie elementów aplikacji może na chwilę spowodować wyświetlenie filmów uczestników zdalnych na uchwyconym obszarze).
Interfejs API Element Capture rozwiązuje wszystkie te problemy, ponieważ pozwala na ukierunkowanie na element, który chcesz udostępnić.

Jak korzystać z Element Capture?
captureTarget
to element na stronie, który zawiera treści, które użytkownik chce uchwycić. Chcesz, aby aplikacja internetowa do rozmów wideo rejestrowała captureTarget
i udostępniała ją uczestnikom zdalnym. W ten sposób uzyskujesz RestrictionTarget
z captureTarget
. Po ograniczeniu ścieżki wideo za pomocą tego RestrictionTarget
ramki na tej ścieżce wideo składają się teraz tylko z pikseli, które są częścią captureTarget
i jego bezpośrednich elementów potomnych w DOM.
Jeśli captureTarget
zmienia rozmiar, kształt lub położenie, ścieżka wideo podąża za nim, nie wymagając żadnych dodatkowych danych z żadnej z aplikacji internetowych. Zasłonięcie treści, które pojawiają się, znikają lub się przemieszczają, również nie wymaga specjalnego traktowania.
Ponownie wykonaj te czynności:
Najpierw zezwól 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();
Zdefiniuj RestrictionTarget
, wywołując funkcję RestrictionTarget.fromElement()
z dowolnym elementem jako argumentem.
// Associate captureTarget with a new RestrictionTarget
const captureTarget = document.querySelector("#captureTarget");
const restrictionTarget = await RestrictionTarget.fromElement(captureTarget);
Następnie wywołaj funkcję restrictTo()
na ścieżce wideo, podając jako dane wejściowe funkcję RestrictionTarget
. Gdy ostatnie obietnice zostaną spełnione, wszystkie kolejne ramki 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 RestrictionTarget.fromElement()
jest obsługiwane, użyj:
if ("RestrictionTarget" in self && "fromElement" in RestrictionTarget) {
// Deriving a restriction target is supported.
}
Tworzenie obiektu RestrictionTarget
Zwróć uwagę na element o nazwie captureTarget
. Aby uzyskać z niego wartość RestrictionTarget
, wywołaj funkcję RestrictionTarget.fromElement(captureTarget)
. W przypadku powodzenia zwrócona obietnica zostanie rozwiązana z nowym obiektem RestrictionTarget
. W przeciwnym razie zostanie odrzucony, jeśli wyemitujesz nieuzasadnione ilości obiektów RestrictionTarget
.
const captureTarget = document.querySelector("#captureTarget");
const restrictionTarget = await RestrictionTarget.fromElement(captureTarget);
W przeciwieństwie do obiektu Element obiekt RestrictionTarget
można zserializować. Można go przekazać do innego dokumentu za pomocą na przykład elementu Window.postMessage()
.
Kierowanie ograniczone
Podczas przechwytywania karty ścieżka wideo ujawnia restrictTo()
. Podczas przechwytywania bieżącej karty można wywołać funkcję restrictTo()
z parametrami null
lub dowolnym parametrem RestrictionTarget
pochodzącym z elementu na bieżącej karcie.
Wywołania funkcji restrictTo(restrictionTarget)
zmieniają ścieżkę wideo na uchwyt captureTarget
, tak jakby była ona rysowana samodzielnie, niezależnie od reszty modelu DOM. Wszystkie potomki elementu captureTarget
są też rejestrowane; elementy pokrewne do captureTarget
są eliminowane z rejestracji. W efekcie wszystkie klatki dostarczone na ścieżce wyglądają tak, jakby zostały przycięte do kontur captureTarget
, a zasłonięte 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)
, które przywracają ścieżkę do jej pierwotnego stanu.
// Stop restricting.
await track.restrictTo(null);
Jeśli wywołanie metody restrictTo()
zakończy się pomyślnie, zwrócona obietnica zostanie rozwiązana, gdy będzie można zagwarantować, że wszystkie kolejne klatki filmu będą ograniczone do captureTarget
.
Jeśli nie uda się tego zrobić, obietnica zostanie odrzucona. Nieudany wywołanie do restrictTo()
może być spowodowany jednym z tych powodów:
- Jeśli
restrictionTarget
został wyemitowany na karcie innej niż ta, która jest rejestrowana. (za pomocą przycisku „Udostępnij tę kartę” użytkownicy mogą w dowolnym momencie zmienić kartę, która ma być przechwycona). - Jeśli
restrictionTarget
pochodzi z elementu, który już nie istnieje. - Jeśli utwór ma kopie. (zobacz problem 1509418).
- Jeśli bieżąca ścieżka nie jest ścieżką z filmem nagranym przez użytkownika.
- Jeśli element, z którego pochodzi
restrictionTarget
, nie kwalifikuje się do ograniczenia.
Uwagi dotyczące samodzielnego rejestrowania
Gdy aplikacja wywołuje getDisplayMedia()
, a użytkownik zdecyduje się na przechwycenie własnej karty aplikacji, nazywamy to „samoprzechwyceniem”.
Metoda restrictTo()
jest dostępna na dowolnym ścieżce wideo z przechwytem karty, a nie tylko w przypadku przechwytu własnego. Element Capture jest obecnie dostępny tylko do samodzielnego nagrywania. Dlatego przed próbą zablokowania utworu należy sprawdzić, czy użytkownik wybrał bieżącą kartę. Można to zrobić za pomocą funkcji chwytania uchwytu. Można też poprosić przeglądarkę o zachęcenie użytkownika do samodzielnego wykonania zdjęcia za pomocą preferCurrentTab
.
Przejrzystość
Klatka filmu, którą aplikacja przesyła do getDisplayMedia()
, nie zawiera kanału alfa. Jeśli aplikacja ustawia cel przechwytywania z częściowo przezroczystym kanałem alfa, usunięcie tego kanału może mieć pewne konsekwencje:
- Kolory mogą się zmienić. Po usunięciu kanału alfa częściowo przezroczyste elementy docelowe narysowane na jasnym tle mogą wydawać się ciemniejsze, a te narysowane na ciemnym tle mogą wydawać się jaśniejsze.
- Kolory, które były niewidoczne lub niewyczuwalne dla użytkownika, gdy kanał alfa był ustawiony na maksimum, będą widoczne po usunięciu tego kanału. Może to na przykład spowodować nieoczekiwane czarne obszary na zarejestrowanych klatkach, jeśli przezroczyste sekcje mają kod RGBA
rgba(0, 0, 0, 0)
.

Niekwalifikujące się cele przechwytywania
W każdej chwili możesz zacząć ograniczać ścieżkę do dowolnego prawidłowego celu przechwytywania. Jednak w pewnych warunkach nie będą one tworzone, np. gdy element lub jego przodek ma wartość display:none
. Ogólnie chodzi o to, że ograniczenie dotyczy tylko elementu, który składa 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 elementów siostrza.
Aby element mógł zostać objęty ograniczeniem, musi mieć własny kontekst nakładania się. Aby to zrobić, możesz ustawić właściwość CSS isolation na isolate
.
<div id="captureTarget" style="isolation: isolate;"></iframe>
Pamiętaj, że element docelowy może w dowolnym momencie stać się odpowiedni lub nieodpowiedni do ograniczenia, np. gdy aplikacja zmieni swoje właściwości CSS. Aplikacja musi używać odpowiednich celów przechwytywania i nie zmieniać ich właściwości w nieoczekiwany sposób. Jeśli element docelowy nie spełnia kryteriów, nowe klatki nie będą emitowane na ścieżce, dopóki element docelowy nie będzie ponownie spełniał kryteriów ograniczenia.
Obsługa przeglądarek
Element Capture jest dostępny w Chrome 132 tylko na komputerach.
Bezpieczeństwo i prywatność
Aby dowiedzieć się więcej o kompromisach w zakresie bezpieczeństwa, zapoznaj się z sekcją Uwzględnianie prywatności i zabezpieczeń w specyfikacji Element Capture.
Przeglądarka Chrome rysuje niebieską ramkę wokół krawędzi przechwyconych kart.
Prezentacja
Możesz wypróbować Element Capture, uruchamiając demo na Glitch. Pamiętaj, aby sprawdzić kod źródłowy.
Prześlij opinię
Zespół Chrome i społeczność zajmująca się standardami internetowymi chce poznać Twoje wrażenia z korzystania z Element Capture.
Opowiedz nam o projektie
Czy Element Capture nie działa zgodnie z oczekiwaniami? A może brakuje metod lub właściwości, których potrzebujesz do wdrożenia swojego pomysłu? Masz pytania lub uwagi dotyczące modelu zabezpieczeń?
- Zgłoś problem ze specyfikacją w repozytorium GitHub lub podziel się opinią na temat istniejącego problemu.
Problem z implementacją?
Czy znalazłeś/znalazłaś 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 odtwarzania problemu.
Przydatne linki
Podziękowania
Zdjęcie: Paul Skorupskas z Unsplash