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'intégralité de l'onglet 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 à la fois le contenu masqué et le contenu masqué.
Pourquoi utiliser Element Capture ?
En tenant compte des exigences d'une application de visioconférence, vous pouvez déterminer dans quels cas 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 aux participants à distance.
Appeler getDisplayMedia()
et laisser l'utilisateur choisir l'onglet actuel transmettrait l'intégralité de l'onglet actuel. Cela risque de leur transmettre leur propre vidéo. Vous pouvez le rogner à l'aide de la fonctionnalité Capturer la zone.
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 ?
La capture de région ne vous aidera pas. Une partie de la liste déroulante peut être visible sur les écrans des participants à distance.
Le fait que la capture de région capture des parties d'éléments de cette manière (appelée masquage du contenu) crée plusieurs problèmes:
- Le contenu masqué peut masquer le contenu que l'utilisateur souhaite partager.
- Le contenu masqué peut être privé (par exemple, les notifications de chat).
- Masquer du contenu peut prêter à confusion. (par exemple, une nouvelle mise en page de l'application pourrait brièvement afficher les vidéos des participants à distance sur 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.
Comment utiliser Element Capture ?
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 la 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 cet élément RestrictionTarget
, les frames de cette piste ne consistent plus qu'en pixels faisant partie de captureTarget
et de ses descendants DOM directs.
Si captureTarget
change de taille, de forme ou d'emplacement, la piste vidéo suit, sans nécessiter d'entrée supplémentaire de la part de l'une ou l'autre des applications Web. De même, l'occlusion de contenu qui apparaît, disparaît ou se déplace ne nécessite aucun traitement spécial.
Suivez à nouveau ces étapes:
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, tous les frames suivants seront limités.
// 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 fonctionnalités
Pour vérifier si RestrictionTarget.fromElement()
est compatible, utilisez:
if ("RestrictionTarget" in self && "fromElement" in RestrictionTarget) {
// Deriving a restriction target is supported.
}
Déduire un RestrictionTarget
Concentrez-vous sur l'élément appelé captureTarget
. Pour en dériver un RestrictionTarget
, appelez RestrictionTarget.fromElement(captureTarget)
. Si la requête aboutit, 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, vous pouvez 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 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. Les frères et sœurs de captureTarget
sont éliminés de la capture. Par conséquent, tous les frames diffusés sur le canal apparaissent comme s'ils étaient recadrés selon les contours de captureTarget
, et tout contenu masquant et masqué 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 du canal.
// Stop restricting.
await track.restrictTo(null);
Si l'appel à restrictTo()
aboutit, la promesse renvoyée est résolue lorsqu'il est possible de garantir que tous les frames vidéo suivants seront limités à captureTarget
.
Si l'opération échoue, la promesse est rejetée. Un appel à restrictTo()
qui échoue est dû à l'une des raisons suivantes:
- Si l'
restrictionTarget
a été créé dans un onglet autre que celui capturé. (Notez que les utilisateurs peuvent modifier l'onglet capturé à tout moment à l'aide du bouton "Partager cet onglet à la place".) - Si
restrictionTarget
a été dérivé d'un élément qui n'existe plus. - Si le canal comporte des clones. (Consultez le problème 1509418.)
- Si la piste actuelle n'est pas une piste vidéo auto-capturée.
- Si l'élément à partir duquel
restrictionTarget
a été dérivé ne peut pas être soumis à des restrictions.
Considérations concernant la capture automatique
Lorsqu'une application appelle getDisplayMedia()
et que l'utilisateur choisit de capturer l'onglet de l'application, nous appelons cela "autocapture".
La méthode restrictTo()
est exposée sur n'importe quelle piste vidéo de capture d'onglet, et pas seulement pour la capture de soi-même. Cependant, la capture d'éléments n'est pour le moment disponible que pour les selfies. Il est donc conseillé de vérifier si l'utilisateur a sélectionné l'onglet actuel avant d'essayer de limiter le canal. Pour ce faire, utilisez Capture Handle. Vous pouvez également demander au navigateur d'inciter l'utilisateur à se prendre en photo à l'aide de preferCurrentTab
.
Transparence
Les cadres 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, le décapage 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 sombres lorsque le canal alpha est supprimé, et ceux dessinés sur un arrière-plan sombre peuvent apparaître plus clairs.
- Les couleurs qui étaient invisibles ou imperceptibles par l'utilisateur lorsque le canal alpha était défini sur sa valeur maximale apparaissaient une fois le canal alpha supprimé. Par exemple, cela peut entraîner des régions noires inattendues dans les images capturées si les sections transparentes ont le code RGBA
rgba(0, 0, 0, 0)
.
Cibles de capture non éligibles
Vous pouvez toujours commencer à limiter une piste à n'importe quelle cible de capture valide. Toutefois, les cadres ne sont pas générés dans certaines conditions, par exemple si l'élément ou un ancêtre est display:none
. En règle générale, la restriction ne s'applique qu'à un élément qui comprend une zone rectangulaire bidimensionnelle, cohérente et unique, dont les pixels peuvent être déterminés logiquement indépendamment de tout élément parent ou frère.
Pour que l'élément puisse être soumis à des restrictions, il doit former son propre contexte d'empilement. Pour vous en assurer, vous pouvez spécifier la propriété CSS isolation, en la définissant sur isolate
.
<div id="captureTarget" style="isolation: isolate;"></iframe>
Notez que l'élément cible peut être éligible ou non à la restriction à tout moment, par exemple si l'application modifie ses propriétés CSS. Il appartient à 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 n'est plus éligible, de nouveaux frames ne seront tout simplement pas émis sur le canal tant que l'élément cible ne sera pas à nouveau éligible à la restriction.
Activer la capture d'éléments
L'API Element Capture est disponible dans Chrome sur ordinateur derrière l'indicateur Element Capture et peut être activée à l'adresse chrome://flags/#element-capture
.
Cette fonctionnalité est également en phase d'évaluation à partir de Chrome 121 sur ordinateur, ce qui permet aux développeurs d'activer la fonctionnalité pour les visiteurs de leurs sites afin de collecter des données auprès d'utilisateurs réels. Pour en savoir plus sur les essais d'origine, consultez Premiers pas avec les essais d'origine.
Sécurité et confidentialité
Pour comprendre les compromis de sécurité, consultez la section 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 Element Capture en exécutant la démo sur Glitch. N'oubliez pas de consulter le code source.
Commentaires
L'équipe Chrome et la communauté des normes Web souhaitent connaître votre expérience avec Element Capture.
Parlez-nous de la conception
La capture de région ne fonctionne-t-elle pas comme prévu ? Ou 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 de spécification dans le dépôt GitHub ou ajoutez vos commentaires à un problème existant.
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 ?
- Signalez un bug sur https://new.crbug.com. Veillez à inclure autant de détails que possible et des instructions simples pour reproduire le problème. Glitch est idéal pour partager des reproductions rapidement et facilement.
Liens utiles
Remerciements
Photo de Paul Skorupskas sur Unsplash