Capturer un flux vidéo à partir de n'importe quel élément

François Beaufort
François Beaufort

L'API Screen Capture vous permet de capturer l'intégralité de l'onglet actuel. L'API Element Capture vous permet de capturer et d'enregistrer un élément HTML spécifique. Il transforme une capture de l'onglet entier en capture d'un sous-arbre DOM spécifique, en ne capturant que les descendants directs de l'élément cible. En d'autres termes, il recadre et supprime le contenu masqué et masquant.

Pourquoi utiliser la capture d'éléments ?

Prendre en compte les exigences d'une application de visioconférence peut vous aider à comprendre où Element Capture est utile. Si vous disposez d'une application de visioconférence qui vous permet d'intégrer des applications tierces dans un iFrame, vous pouvez parfois vouloir capturer cet iFrame sous forme de vidéo et le transmettre à des participants à distance.

Capture d'écran d'un appel en visioconférence dans Chrome.
Elad utilise une application tierce lors d'une visioconférence avec François.

Si vous appelez getDisplayMedia() et que vous laissez l'utilisateur choisir l'onglet actuel, l'intégralité de l'onglet actuel sera transmise. Il est probable que votre propre vidéo soit retransmise. Vous pouvez le supprimer à l'aide de l'option Capturer la région.

Toutefois, que se passe-t-il si le présentateur interagit avec l'application de visioconférence et qu'un contenu, comme une liste déroulante, se superpose au contenu à capturer ?

Capture d'écran d'une liste déroulante masquant le contenu à capturer.
Une liste déroulante s'affiche au-dessus du contenu à capturer.

La capture de région ne vous sera pas utile dans ce cas. Il est possible qu'une partie de la liste déroulante soit visible sur l'écran des participants à distance.

Capture d'écran d'une liste déroulante.
La liste déroulante d'Elad s'affiche au-dessus du contenu reçu par François.

Le fait que la capture de région capture des parties d'éléments de cette manière (ce que l'on appelle masquer du contenu) pose plusieurs problèmes :

  • Le contenu masqué peut empêcher de voir le contenu que l'utilisateur souhaitait partager.
  • Le contenu masqué peut être privé (par exemple, les notifications de chat).
  • Le contenu masqué peut être déroutant. (Par exemple, une réorganisation de la mise en page de l'application peut brièvement faire passer les vidéos des participants à distance au-dessus de la cible capturée.)

L'API Element Capture résout tous ces problèmes en vous permettant de cibler l'élément que vous souhaitez partager.

Capture d'écran de l'élément cible sans liste déroulante visible.
François ne voit pas la liste déroulante d'Elad.

Comment utiliser la capture d'éléments ?

captureTarget est un élément de votre page qui contient le contenu que l'utilisateur souhaite capturer. Vous souhaitez que l'application Web de visioconférence capture captureTarget et le partage avec les participants à distance. Vous dérivez donc un RestrictionTarget à partir de captureTarget. Après avoir limité la piste vidéo à l'aide de ce RestrictionTarget, les images de cette piste vidéo ne sont désormais constituées que des pixels qui font partie de captureTarget et de ses descendants DOM directs.

Si captureTarget change de taille, de forme ou d'emplacement, la piste vidéo suit le mouvement, sans nécessiter d'intervention supplémentaire de la part de l'application Web. De même, l'occlusion de contenu qui apparaît, disparaît ou se déplace ne nécessite aucun traitement spécial.

Reprenez les étapes suivantes :

Commencez par autoriser l'utilisateur à capturer l'onglet actuel.

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

Définissez un RestrictionTarget en appelant RestrictionTarget.fromElement() avec un élément de votre choix comme entrée.

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

Appelez ensuite restrictTo() sur la piste vidéo avec RestrictionTarget comme entrée. Une fois la dernière promesse résolue, toutes les images suivantes seront limitées.

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

// Enjoy! Transmit remotely.

Présentation détaillée

Détection de caractéristiques

Pour vérifier si RestrictionTarget.fromElement() est compatible, utilisez la commande suivante :

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

Dériver un RestrictionTarget

Concentrez-vous sur l'élément appelé captureTarget. Pour en dériver un RestrictionTarget, appelez RestrictionTarget.fromElement(captureTarget). Si l'opération réussit, la promesse renvoyée sera résolue avec un nouvel objet RestrictionTarget. Sinon, il sera refusé si vous avez créé un nombre déraisonnable d'objets RestrictionTarget.

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

Contrairement à un élément, un objet RestrictionTarget est sérialisable. Il peut être transmis à un autre document à l'aide de Window.postMessage(), par exemple.

Restriction

Lorsque vous capturez un onglet, la piste vidéo expose restrictTo(). Lors de la capture de l'onglet actuel, il est possible d'appeler restrictTo() avec null ou tout RestrictionTarget dérivé d'un élément de l'onglet actuel.

Les appels à restrictTo(restrictionTarget) transforment la piste vidéo en une capture de captureTarget, comme si elle était dessinée par elle-même, indépendamment du reste du DOM. Tous les descendants de captureTarget sont également capturés, tandis que les frères et sœurs de captureTarget sont éliminés de la capture. Par conséquent, toutes les images fournies sur la piste apparaissent comme recadrées selon les contours de captureTarget, et tout contenu masqué ou masquant est supprimé.

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

Les appels à restrictTo(null) rétablissent l'état d'origine de la piste.

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

Si l'appel à restrictTo() réussit, la promesse renvoyée est résolue lorsqu'il est garanti que toutes les images vidéo suivantes seront limitées à captureTarget.

Si l'opération échoue, la promesse est rejetée. Un appel infructueux à restrictTo() peut être dû à l'une des raisons suivantes :

  • Si le restrictionTarget a été créé dans un onglet autre que celui qui est capturé. (Notez que les utilisateurs peuvent changer d'onglet à tout moment en cliquant sur le bouton "Partager cet onglet à la place".)
  • Si le restrictionTarget a été dérivé d'un élément qui n'existe plus.
  • Si le titre a des clones. (Consultez le problème 1509418.)
  • Si la piste actuelle n'est pas une piste vidéo de capture personnelle.
  • Si l'élément à partir duquel restrictionTarget a été dérivé ne peut pas être soumis à une restriction.

Points à prendre en compte pour l'auto-capture

Lorsqu'une application appelle getDisplayMedia() et que l'utilisateur choisit de capturer son propre onglet, on parle d'auto-capture.

La méthode restrictTo() est exposée sur n'importe quelle piste vidéo de capture d'onglet, et pas seulement pour l'autocapture. Toutefois, la capture d'éléments n'est activée que pour l'autocapture pour le moment. Il est donc conseillé de vérifier si l'utilisateur a sélectionné l'onglet actuel avant de tenter de restreindre la piste. Pour ce faire, utilisez Capture Handle. Il est également possible de demander au navigateur d'inciter l'utilisateur à effectuer lui-même la capture à l'aide de preferCurrentTab.

Transparence

Les frames vidéo que l'application reçoit via getDisplayMedia() n'incluent pas de canal alpha. Si une application définit une cible de capture partiellement transparente, la suppression du canal alpha peut avoir plusieurs conséquences :

  • Les couleurs peuvent changer. Les éléments cibles partiellement transparents dessinés sur un arrière-plan clair peuvent apparaître plus foncés lorsque le canal alpha est supprimé, et ceux dessinés sur un arrière-plan sombre peuvent apparaître plus clairs.
  • Les couleurs invisibles ou imperceptibles pour l'utilisateur lorsque le canal alpha était défini sur sa valeur maximale s'affichaient une fois le canal alpha supprimé. Par exemple, cela pourrait entraîner des régions noires inattendues dans les frames capturées si les sections transparentes avaient le code RGBA rgba(0, 0, 0, 0).
Capture d'écran du résultat d'une cible de capture transparente non rectangulaire.
Le flux vidéo cible de capture transparent non rectangulaire (à droite) est un rectangle à fond noir contenant un cercle bleu opaque.

Cibles de capture non éligibles

Il est toujours possible de restreindre une piste à n'importe quelle cible de capture valide. Toutefois, des frames ne seront pas produits dans certaines conditions, par exemple si l'élément ou un ancêtre est display:none. La logique générale est que la restriction ne s'applique qu'à un élément qui comprend une zone rectangulaire bidimensionnelle unique et cohérente, dont les pixels peuvent être déterminés de manière logique indépendamment de tout élément parent ou frère.

Pour s'assurer que l'élément peut être soumis à une restriction, il est important de noter qu'il doit former son propre contexte de superposition. Pour ce faire, vous pouvez spécifier la propriété CSS isolation et la définir sur isolate.

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

Notez que l'élément cible peut passer d'éligible à non éligible à la restriction à tout moment, par exemple si l'application modifie ses propriétés CSS. Il incombe à l'application d'utiliser des cibles de capture raisonnables et d'éviter de modifier leurs propriétés de manière inattendue. Si l'élément cible devient inéligible, de nouvelles images ne seront tout simplement pas émises sur la piste tant que l'élément cible ne sera pas à nouveau éligible à la restriction.

Prise en charge des navigateurs

La capture d'éléments est disponible à partir de Chrome 132 sur ordinateur uniquement.

Sécurité et confidentialité

Pour comprendre les compromis en termes de sécurité, consultez la section Privacy and Security Considerations (Considérations sur la confidentialité et la sécurité) de la spécification Element Capture.

Le navigateur Chrome dessine une bordure bleue autour des bords des onglets capturés.

Démo

Vous pouvez tester la capture d'éléments en exécutant la démonstration.

Commentaires

L'équipe Chrome et la communauté des normes Web souhaitent connaître votre expérience avec Element Capture.

Parlez-nous de la conception

Y a-t-il quelque chose concernant la capture d'éléments qui ne fonctionne pas comme prévu ? Manque-t-il des méthodes ou des propriétés dont vous avez besoin pour implémenter votre idée ? Vous avez une question ou un commentaire sur le modèle de sécurité ?

  • Signalez un problème lié aux spécifications dans le dépôt GitHub ou ajoutez vos commentaires à un problème existant.

Vous rencontrez un problème d'implémentation ?

Avez-vous trouvé un bug dans l'implémentation de Chrome ? Ou l'implémentation est-elle différente de la spécification ?

Remerciements

Photo de Paul Skorupskas sur Unsplash