Leg een videostream vast van elk element

François Beaufort
François Beaufort

Met de Screen Capture API kunt u het volledige huidige tabblad vastleggen. Met de Element Capture API kunt u een specifiek HTML-element vastleggen en opnemen. Hiermee wordt een vastlegging van het volledige tabblad omgezet in een vastlegging van een specifieke DOM-substructuur, waarbij alleen directe afstammelingen van het doelelement worden vastgelegd. Met andere woorden: zowel occluderende als occluderende content wordt bijgesneden en verwijderd.

Waarom Element Capture gebruiken?

Door rekening te houden met de vereisten van een videoconferentie-applicatie, kunt u beter begrijpen waar Element Capture nuttig is. Als u een videoconferentie-applicatie hebt waarmee u applicaties van derden in een iframe kunt insluiten, wilt u die iframe mogelijk als video vastleggen en verzenden naar externe deelnemers.

Schermafbeelding van een videoconferentiegesprek in Chrome.
Elad gebruikt een applicatie van derden tijdens een videoconferentiegesprek met François.

Door getDisplayMedia() aan te roepen en de gebruiker het huidige tabblad te laten kiezen, wordt het volledige huidige tabblad verzonden. Dit zal waarschijnlijk de eigen video van gebruikers naar hen terugsturen. Je kunt dit wegsnijden met Region Capture .

Maar wat als de presentator de videoconferentietoepassing gebruikt en er wordt inhoud, bijvoorbeeld een vervolgkeuzelijst, toegevoegd aan de inhoud die vastgelegd moet worden?

Schermafbeelding van een vervolgkeuzelijst die de vast te leggen inhoud bedekt.
Er wordt een vervolgkeuzelijst weergegeven boven de inhoud die u wilt vastleggen.

Regio-opname helpt je daar niet bij. Een deel van de vervolgkeuzelijst kan zichtbaar zijn op de schermen van externe deelnemers.

Schermafbeelding van een vervolgkeuzelijst gemaakt.
De vervolgkeuzelijst van Elad wordt weergegeven boven de inhoud die François heeft ontvangen.

Het feit dat Region Capture op deze manier delen van elementen vastlegt (ook wel 'occluderen van content ' genoemd) zorgt voor meerdere problemen:

  • Het verbergen van inhoud kan ertoe leiden dat de inhoud die de gebruiker wilde delen, niet meer zichtbaar is.
  • Het verbergen van inhoud kan privé zijn (denk aan chatmeldingen).
  • Het verbergen van content kan verwarrend zijn. (Bijvoorbeeld, een nieuwe lay-out van de applicatie zou de video's van de deelnemers op afstand kortstondig over de vastgelegde content heen kunnen weergeven.)

De Element Capture API lost al deze problemen op. U kunt namelijk zelf bepalen welk element u wilt delen.

Schermafbeelding van het doelelement, zonder dat er een vervolgkeuzelijst zichtbaar is.
François ziet de vervolgkeuzelijst van Elad niet.

Hoe gebruik ik Element Capture?

captureTarget is een element op uw pagina dat de content bevat die de gebruiker wil vastleggen. U wilt dat de webapp voor videoconferenties captureTarget vastlegt en deelt met externe deelnemers. Daarom leidt u een RestrictionTarget af van captureTarget . Nadat u de videotrack hebt beperkt met behulp van deze RestrictionTarget , bestaan ​​de frames op die videotrack nu alleen uit de pixels die deel uitmaken van captureTarget en de directe DOM-afstammelingen.

Als captureTarget van grootte, vorm of locatie verandert, volgt het videospoor dit, zonder dat er extra invoer van een van de webapps nodig is. Ook het verbergen van content die verschijnt, verdwijnt of beweegt, vereist geen speciale behandeling.

Bekijk deze stappen nog eens:

Begin door de gebruiker de mogelijkheid te geven het huidige tabblad vast te leggen.

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

Definieer een RestrictionTarget door RestrictionTarget.fromElement() aan te roepen met een element naar keuze als invoer.

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

Roep vervolgens restrictTo() aan op het videospoor met RestrictionTarget als invoer. Zodra de laatste promise is verwerkt, worden alle volgende frames beperkt.

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

Diepe duik

Functiedetectie

Om te controleren of RestrictionTarget.fromElement() wordt ondersteund, gebruikt u:

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

Een RestrictionTarget afleiden

Focus op het element captureTarget . Om hier een RestrictionTarget van af te leiden, roept u RestrictionTarget.fromElement(captureTarget) aan. De geretourneerde Promise wordt, indien succesvol, omgezet in een nieuw RestrictionTarget -object. Anders wordt deze afgewezen als u een onredelijk aantal RestrictionTarget objecten hebt gemint.

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

In tegenstelling tot een Element is een RestrictionTarget object serialiseerbaar . Het kan bijvoorbeeld via Window.postMessage() aan een ander document worden doorgegeven.

Beperken

Bij het vastleggen van een tabblad geeft de videotrack restrictTo() weer. Bij het vastleggen van het huidige tabblad is het geldig om restrictTo() aan te roepen met null of een RestrictionTarget afgeleid van een Element binnen het huidige tabblad.

Aanroepen van restrictTo(restrictionTarget) muteren het videospoor naar een capture van captureTarget , alsof het zelfstandig getekend is, onafhankelijk van de rest van de DOM. Alle afstammelingen van captureTarget worden ook vastgelegd; verwanten van captureTarget worden uit de vastlegging verwijderd. Het resultaat is dat alle frames die op het spoor worden afgeleverd, eruit zien alsof ze zijn bijgesneden tot de contouren van captureTarget , en alle occluderende en geoccludeerde content wordt verwijderd.

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

Met restrictTo(null) -aanroepen wordt het spoor teruggezet naar de oorspronkelijke staat.

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

Als de aanroep van restrictTo() succesvol is, wordt de geretourneerde Promise opgelost wanneer gegarandeerd kan worden dat alle volgende videoframes beperkt zullen worden tot captureTarget .

Als dit niet lukt, wordt de Promise afgewezen. Een mislukte aanroep van restrictTo() kan een van de volgende oorzaken hebben:

  • Als de restrictionTarget is gemaakt in een ander tabblad dan het tabblad dat wordt vastgelegd. (Let op: met de knop 'Dit tabblad delen' kunnen gebruikers op elk gewenst moment wijzigen welk tabblad wordt vastgelegd.)
  • Als de restrictionTarget is afgeleid van een Element dat niet meer bestaat.
  • Als het spoor klonen heeft. (Zie probleem 1509418. )
  • Als het huidige nummer geen zelf opgenomen videonummer is.
  • Als het element waarvan restrictionTarget is afgeleid, niet in aanmerking komt voor beperking.

Overwegingen voor zelfvastlegging

Wanneer een app getDisplayMedia() aanroept en de gebruiker kiest ervoor om het tabblad van de app zelf vast te leggen, noemen we dat "zelfvastlegging".

De restrictTo() -methode is beschikbaar op elke tab-capture videotrack, en niet alleen voor zelfcapture. Element Capture is echter voorlopig alleen ingeschakeld voor zelfcapture. Het is daarom raadzaam om te controleren of de gebruiker het huidige tabblad heeft geselecteerd voordat u de track probeert te beperken. Dit kan worden gedaan met Capture Handle . Het is ook mogelijk om de browser te vragen de gebruiker richting zelfcapture te sturen met preferCurrentTab .

Transparantie

Videoframes die de app via getDisplayMedia() ontvangt, bevatten geen alfakanaal. Als een app een gedeeltelijk transparant opnamedoel instelt, kan het verwijderen van het alfakanaal enkele mogelijke gevolgen hebben:

  • Kleuren kunnen veranderen. Gedeeltelijk transparante doelelementen die op een lichte achtergrond worden getekend, kunnen donkerder lijken wanneer het alfakanaal wordt verwijderd, en elementen die op een donkere achtergrond worden getekend, kunnen lichter lijken.
  • Kleuren die onzichtbaar of onwaarneembaar waren voor de gebruiker toen het alfakanaal maximaal was ingesteld, zouden verschijnen zodra het alfakanaal werd verwijderd. Dit zou bijvoorbeeld kunnen leiden tot onverwachte zwarte gebieden in de opgenomen frames als de transparante gedeelten de RGBA-code rgba(0, 0, 0, 0) hadden.
Schermafbeelding van het resultaat van een niet-rechthoekig transparant vangdoel.
De niet-rechthoekige, transparante doelvideostream (rechts) is een rechthoek met een zwarte achtergrond waarin een ondoorzichtige blauwe cirkel is opgenomen.

Niet-in aanmerking komende vangstdoelen

Het is altijd mogelijk om een ​​track te beperken tot elk geldig capture-target. Frames worden echter niet geproduceerd onder bepaalde omstandigheden , bijvoorbeeld als het element of een voorouder display:none is. De algemene redenatie is dat de beperking alleen van toepassing is op een element dat bestaat uit één samenhangend, tweedimensionaal, rechthoekig gebied, waarvan de pixels logischerwijs los van eventuele bovenliggende of verwante elementen kunnen worden bepaald.

Een belangrijke overweging om ervoor te zorgen dat het element in aanmerking komt voor beperking, is dat het een eigen stapelcontext moet vormen. Om dit te garanderen, kunt u de CSS-eigenschap ' isolatie' specificeren en deze instellen op isolate .

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

Houd er rekening mee dat het doelelement op elk willekeurig moment kan wisselen tussen in aanmerking komend en niet in aanmerking komend voor beperking, bijvoorbeeld als de app zijn CSS-eigenschappen wijzigt. Het is aan de app om redelijke capture targets te gebruiken en te voorkomen dat hun eigenschappen onverwachts worden gewijzigd. Als het doelelement niet langer in aanmerking komt, worden er simpelweg geen nieuwe frames op de track uitgezonden totdat het doelelement weer in aanmerking komt voor beperking.

Browserondersteuning

Element Capture is alleen beschikbaar in Chrome 132 op desktop.

Beveiliging en privacy

Raadpleeg het gedeelte Privacy- en beveiligingsoverwegingen in de Element Capture-specificatie voor meer informatie over de beveiligingsafwegingen.

De Chrome-browser tekent een blauwe rand rond de randen van vastgelegde tabbladen.

Demonstratie

Je kunt Element Capture uitproberen door de demo op Glitch te draaien. Bekijk zeker ook de broncode .

Feedback

Het Chrome-team en de webstandaardencommunity willen graag uw ervaringen met Element Capture horen.

Vertel ons over het ontwerp

Werkt Element Capture niet zoals verwacht? Of ontbreken er methoden of eigenschappen die u nodig hebt om uw idee te implementeren? Heeft u een vraag of opmerking over het beveiligingsmodel?

  • Dien een spec-probleem in op de GitHub-repository of voeg uw mening toe over een bestaand probleem.

Probleem met de implementatie?

Heb je een bug gevonden in de implementatie van Chrome? Of wijkt de implementatie af van de specificatie?

  • Meld een bug op https://new.crbug.com . Zorg ervoor dat je zoveel mogelijk details en eenvoudige instructies voor reproductie verstrekt.

Dankbetuigingen

Foto door Paul Skorupskas op Unsplash