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

François Beaufort
François Beaufort

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 en tant que flux multimédia. Ce flux peut ensuite être enregistré ou partagé avec d'autres utilisateurs du réseau. Cette documentation présente le ciblage conditionnel, un mécanisme permettant aux applications Web de contrôler si l'onglet ou la fenêtre capturée sera sélectionné au début de la capture, ou si la page de capture restera active.

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 du motif de l'appel de getDisplayMedia() 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 éventuellement en examinant le identifiant de capture, l'application Web de visioconférence peut comprendre ce que l'utilisateur a choisi de partager. Alors :

  • Si l'onglet ou la fenêtre capturés peuvent être contrôlés à distance, gardez la visioconférence active.
  • Sinon, sélectionnez l'onglet ou la fenêtre capturés.

Dans l'exemple ci-dessus, l'application Web de visioconférence conserverait le focus si elle partage 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 bascule immédiatement sur l'onglet ou la fenêtre capturés.

Utiliser l'API Conditional Focus

Instanciez un CaptureController et transmettez-le à getDisplayMedia(). En appelant setFocusBehavior() immédiatement après la résolution de la promesse getDiplayMedia() renvoyée, vous pouvez contrôler si l'onglet ou la fenêtre capturés est sélectionné 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");
}

Pour décider si vous devez effectuer la mise au point, vous pouvez tenir compte du identifiant 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() de manière arbitraire plusieurs fois avant la résolution de la promesse ou tout au plus une fois immédiatement après la résolution de la promesse. 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 cette 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 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 les cas suivants:

  • la piste vidéo du flux renvoyé par getDisplayMedia() n'est pas "en direct".
  • Une fois la promesse renvoyée getDisplayMedia() 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. N'oubliez pas de consulter le code source.

Détection de caractéristiques

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 s'il manque 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 ajoutez vos commentaires à un problème existant.

Vous rencontrez un problème lors de l'implémentation ?

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

  • Signalez un bug sur la page https://new.crbug.com. Veillez à fournir autant de détails que possible et des instructions simples pour reproduire le bug. Glitch fonctionne bien 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 indiquez-nous où et comment vous l'utilisez.

Remerciements

Image héros par Elena Taranenko.

Merci à Rachel Andrew d'avoir lu cet article.