L'API Screen Capture permet à l'utilisateur de sélectionner un onglet, une fenêtre ou un écran à capturer en tant que flux multimédia. Ce flux peut ensuite être enregistré ou partagé avec d'autres utilisateurs sur le réseau. Cette documentation présente la mise au point conditionnelle, un mécanisme permettant aux applications Web de contrôler si l'onglet ou la fenêtre capturés seront sélectionnés au début de la capture ou si la page de capture restera sélectionnée.
Prise en charge des navigateurs
La mise au point conditionnelle est disponible à partir de Chrome 109.
Contexte
Lorsqu'une application Web commence à capturer un onglet ou une fenêtre, le navigateur prend une décision : la surface capturée doit-elle être placée au premier plan ou la page de capture doit-elle rester active ? La réponse dépend de la raison pour laquelle getDisplayMedia()
est appelé et de la surface que l'utilisateur finit par sélectionner.
Prenons l'exemple d'une application Web de visioconférence hypothétique. En lisant track.getSettings().displaySurface
et en examinant éventuellement le Capture Handle, l'application Web de visioconférence peut comprendre ce que l'utilisateur a choisi de partager. Ensuite :
- Si l'onglet ou la fenêtre capturés peuvent être contrôlés à distance, maintenez la conférence vidéo au premier plan.
- Sinon, mettez en surbrillance l'onglet ou la fenêtre capturés.
Dans l'exemple ci-dessus, l'application Web de visioconférence conserve la sélection si vous partagez une présentation, ce qui permet à l'utilisateur de faire défiler les diapositives à distance. Toutefois, si l'utilisateur choisit de partager un éditeur de texte, l'application Web de visioconférence passe immédiatement en mode sélection sur l'onglet ou la fenêtre capturés.
Utiliser l'API Conditional Focus
Instanciez une CaptureController
et transmettez-la à getDisplayMedia()
. En appelant setFocusBehavior()
immédiatement après la résolution de la promesse renvoyée par getDiplayMedia()
, vous pouvez contrôler si l'onglet ou la fenêtre capturés seront mis en surbrillance ou non. Cela n'est possible que si l'utilisateur a partagé un onglet ou une fenêtre.
const controller = new CaptureController();
// Prompt the user to share a tab, a window or a screen.
const stream =
await navigator.mediaDevices.getDisplayMedia({ controller });
const [track] = stream.getVideoTracks();
const displaySurface = track.getSettings().displaySurface;
if (displaySurface == "browser") {
// Focus the captured tab.
controller.setFocusBehavior("focus-captured-surface");
} else if (displaySurface == "window") {
// Do not move focus to the captured window.
// Keep the capturing page focused.
controller.setFocusBehavior("focus-capturing-application");
}
Lorsque vous décidez de mettre au point, vous pouvez tenir compte du poignée de capture.
// Retain focus if capturing a tab dialed to example.com.
// Focus anything else.
const origin = track.getCaptureHandle().origin;
if (displaySurface == "browser" && origin == "https://example.com") {
controller.setFocusBehavior("focus-capturing-application");
} else if (displaySurface != "monitor") {
controller.setFocusBehavior("focus-captured-surface");
}
Il est même possible de décider si la mise en surbrillance doit être effectuée avant d'appeler getDisplayMedia()
.
// Focus the captured tab or window when capture starts.
const controller = new CaptureController();
controller.setFocusBehavior("focus-captured-surface");
// Prompt the user to share their screen.
const stream =
await navigator.mediaDevices.getDisplayMedia({ controller });
Vous pouvez appeler setFocusBehavior()
un nombre arbitraire de fois avant la résolution de la promesse, ou au plus une fois immédiatement après la résolution de la promesse. La dernière invocation remplace toutes les invocations précédentes.
Plus précisément :
- La promesse renvoyée par getDisplayMedia()
se résout sur une micro-tâche. Appeler setFocusBehavior()
une fois la microtâche terminée génère une erreur.
- L'appel de setFocusBehavior()
plus d'une seconde après le début de la capture est considéré comme no-op.
Autrement dit, les deux extraits suivants échoueront :
// Prompt the user to share their screen.
const stream =
await navigator.mediaDevices.getDisplayMedia({ controller });
// Too late, because it follows the completion of the task
// on which the getDisplayMedia() promise resolved.
// This will throw.
setTimeout(() => {
controller.setFocusBehavior("focus-captured-surface");
});
// Prompt the user to share their screen.
const stream =
await navigator.mediaDevices.getDisplayMedia({ controller });
const start = new Date();
while (new Date() - start <= 1000) {
// Idle for ≈1s.
}
// Because too much time has elapsed, the browser will have
// already decided whether to focus.
// This fails silently.
controller.setFocusBehavior("focus-captured-surface");
L'appel de setFocusBehavior()
génère également une exception dans les cas suivants :
- la piste vidéo du flux renvoyée par
getDisplayMedia()
n'est pas "en direct". - une fois la promesse renvoyée par
getDisplayMedia()
résolue, si l'utilisateur a partagé un écran (et non un onglet ou une fenêtre).
Échantillon
Vous pouvez tester la mise au point conditionnelle en exécutant la démo sur Glitch. N'oubliez pas de consulter le code source.
Détection de fonctionnalités
Pour vérifier si CaptureController.setFocusBehavior()
est compatible, utilisez:
if (
"CaptureController" in window &&
"setFocusBehavior" in CaptureController.prototype
) {
// CaptureController.setFocusBehavior() is supported.
}
Commentaires
L'équipe Chrome et la communauté des normes Web souhaitent connaître votre avis sur la mise au point conditionnelle.
Parlez-nous de la conception
Y a-t-il quelque chose avec la mise au point conditionnelle qui ne fonctionne 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.
Vous rencontrez un problème lors de l'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 un bon outil pour partager du code.
Montrez votre soutien
Prévoyez-vous d'utiliser la mise au point conditionnelle ? Votre assistance publique aide l'équipe Chrome à hiérarchiser les fonctionnalités et montre aux autres fournisseurs de navigateurs à quel point il est essentiel de les aider.
Envoyez un tweet à @ChromiumDev et dites-nous où et comment vous l'utilisez.
Liens utiles
Remerciements
Image principale par Elena Taranenko.
Merci à Rachel Andrew d'avoir relu cet article.