Amélioration du partage d'écran avec la mise au point conditionnelle

François Beaufort
François Beaufort
Elad Alon
Elad Alon

Navigateurs pris en charge

  • 109
  • 109
  • x
  • x

Source

L'API Screen Capture permet à l'utilisateur de sélectionner un onglet, une fenêtre ou un écran à capturer comme flux multimédia. Cette diffusion peut ensuite être enregistrée ou partagée 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 sera sélectionné 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 depuis Chrome 109.

Contexte

Lorsqu'une application Web commence à capturer un onglet ou une fenêtre, le navigateur doit prendre une décision : la surface capturée doit-elle être mise au premier plan ou la page de capture doit-elle rester ciblée ? La réponse dépend du motif de l'appel de getDisplayMedia(), et de l'écran 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 éventuellement en examinant l'identifiant de capture, 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, laissez le curseur de la visioconférence sélectionné.
  • Sinon, sélectionnez l'onglet ou la fenêtre capturés.

Dans l'exemple ci-dessus, l'application Web de visioconférence conserve le focus si vous partagez une présentation, ce qui permet à l'utilisateur de la faire défiler à distance. En revanche, si l'utilisateur choisit de partager un éditeur de texte, l'application Web de visioconférence bascule immédiatement le curseur sur l'onglet ou la fenêtre capturés.

Utiliser l'API de mise au point conditionnelle

Instanciez un CaptureController et transmettez-le à 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 doivent être sélectionnés ou non. Cette action ne peut être effectuée 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");
}

Pour faire la mise au point ou non, vous pouvez prendre en compte la poignée de la 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 de se concentrer ou non 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() de manière arbitraire avant la résolution de la promesse ou tout au plus une fois immédiatement après. Le dernier appel remplace tous les appels précédents.

Plus précisément : - La promesse getDisplayMedia() renvoyée se résout au niveau d'une microtâche. L'appel de setFocusBehavior() une fois la microtâche terminée génère une erreur. - Appeler setFocusBehavior() plus d'une seconde après le début de la capture est sans effet.

Autrement dit, les deux extraits de code 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 des erreurs dans les cas suivants:

  • la piste vidéo du flux renvoyée par getDisplayMedia() n'est pas "en direct".
  • Une fois que la promesse getDisplayMedia() renvoyée est résolue, si l'utilisateur a partagé un écran (et non un onglet ou une fenêtre).

Échantillon

Vous pouvez jouer avec la mise au point conditionnelle en exécutant la démonstration sur Glitch. Pensez à 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 en savoir plus sur votre expérience avec la mise au point conditionnelle.

Parlez-nous de la conception

Y a-t-il quelque chose qui ne fonctionne pas comme prévu avec la mise au point conditionnelle ? Ou manque-t-il des méthodes ou des propriétés dont vous avez besoin pour mettre en œuvre 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 faites part de vos commentaires à un problème existant.

Un problème d'implémentation ?

Avez-vous détecté un bug dans l'implémentation de Chrome ? Ou la mise en œuvre est-elle différente des spécifications ?

  • Pour signaler un bug, rendez-vous sur https://new.crbug.com. Veillez à inclure autant de détails que possible, ainsi que des instructions simples pour reproduire le bug. Glitch est idéal 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 prendre en charge.

Envoyez un tweet à @ChromiumDev pour nous indiquer où et comment vous l'utilisez.

Remerciements

Image principale créée par Elena Taranenko.

Merci à Rachel Andrew d'avoir consulté cet article.