Condivisione schermo migliorata con la funzionalità Conditional Focus

François Beaufort
François Beaufort

Supporto dei browser

  • Chrome: 109.
  • Edge: 109.
  • Firefox: non supportato.
  • Safari: non supportato.

Origine

L'API Screen Capture consente all'utente di selezionare una scheda, una finestra o una schermata da acquisire come stream multimediale. Questo stream può essere registrato o condiviso con altri utenti della rete. Questa documentazione introduce lo stato attivo condizionale, un meccanismo per le app web che consente di controllare se la scheda o la finestra acquisita sarà attiva all'avvio dell'acquisizione o se la pagina di acquisizione rimarrà attiva.

Supporto browser

Lo stato attivo condizionale è disponibile a partire da Chrome 109.

Sfondo

Quando un'app web inizia a acquisire una scheda o una finestra, il browser deve prendere una decisione: la superficie acquisita deve essere messa in primo piano o la pagina di acquisizione deve rimanere attiva? La risposta dipende dal motivo della chiamata a getDisplayMedia() e dalla piattaforma selezionata dall'utente.

Prendiamo in considerazione un'app web di videoconferenza ipotetica. Leggendo track.getSettings().displaySurface e potenzialmente esaminando l'handle di acquisizione, l'app web di videoconferenza può capire cosa ha scelto di condividere l'utente. Quindi:

  • Se la scheda o la finestra acquisita possono essere controllate da remoto, mantieni lo stato attivo della videoconferenza.
  • In caso contrario, imposta lo stato attivo sulla scheda o sulla finestra acquisita.

Nell'esempio precedente, l'app web di videoconferenza manterrebbe lo stato attivo se si condivide una presentazione, consentendo all'utente di sfogliare le diapositive da remoto. Tuttavia, se l'utente sceglie di condividere un editor di testo, l'app web di videoconferenza sposterà immediatamente lo stato attivo sulla scheda o sulla finestra acquisita.

Utilizzo dell'API Conditional Focus

Crea un'istanza di CaptureController e passala a getDisplayMedia(). Chiamando setFocusBehavior() subito dopo la risoluzione della promessa restituita da getDiplayMedia(), puoi controllare se lo stato attivo della scheda o della finestra acquisita verrà o meno. Questa operazione può essere eseguita solo se l'utente ha condiviso una scheda o una finestra.

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");
}

Quando decidi se mettere a fuoco, puoi tenere conto dell'handle di acquisizione.

// 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");
}

Puoi persino decidere se concentrarti prima di chiamare il numero 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 });

Puoi chiamare setFocusBehavior() un numero qualsiasi di volte prima della risoluzione della promessa o al massimo una volta immediatamente dopo la risoluzione della promessa. L'ultima chiamata sostituisce tutte le chiamate precedenti.

Più precisamente: - La promessa restituita da getDisplayMedia() si risolve in una microattività. Chiamare setFocusBehavior() al termine della microattività genera un errore. - La chiamata a setFocusBehavior() più di un secondo dopo l'inizio dell'acquisizione non ha alcun effetto.

In altre parole, entrambi gli snippet seguenti non andranno a buon fine:

// 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'istruzione setFocusBehavior() viene lanciata anche nei seguenti casi:

  • la traccia video dello stream restituita da getDisplayMedia() non è "live".
  • dopo la risoluzione della promessa restituita da getDisplayMedia(), se l'utente ha condiviso una schermata (non una scheda o una finestra).

Esempio

Puoi provare la funzionalità di messa a fuoco condizionale eseguendo la demo su Glitch. Assicurati di controllare il codice sorgente.

Rilevamento di funzionalità

Per verificare se CaptureController.setFocusBehavior() è supportato, usa:

if (
  "CaptureController" in window &&
  "setFocusBehavior" in CaptureController.prototype
) {
  // CaptureController.setFocusBehavior() is supported.
}

Feedback

Il team di Chrome e la community degli standard web vogliono conoscere le tue esperienze con lo stato attivo condizionale.

Parlaci del design

C'è qualcosa relativo al controllo condizionale che non funziona come previsto? Oppure mancano metodi o proprietà che ti servono per implementare la tua idea? Hai una domanda o un commento sul modello di sicurezza?

  • Invia una segnalazione relativa alle specifiche nel repository GitHub o aggiungi il tuo parere a una segnalazione esistente.

Problemi con l'implementazione?

Hai trovato un bug nell'implementazione di Chrome? Oppure l'implementazione è diversa dalle specifiche?

  • Segnala un bug all'indirizzo https://new.crbug.com. Assicurati di includere il maggior numero di dettagli possibile e istruzioni semplici per la riproduzione. Glitch funziona bene per la condivisione del codice.

Mostrare il proprio sostegno

Hai intenzione di utilizzare la funzionalità Concentrazione condizionale? Il tuo supporto pubblico aiuta il team di Chrome a dare la priorità alle funzionalità e mostra ad altri fornitori di browser quanto sia fondamentale supportarle.

Invia un tweet all'account @ChromiumDev e facci sapere dove e come lo utilizzi.

Ringraziamenti

Immagine hero di Elena Taranenko.

Grazie a Rachel Andrew per aver esaminato questo articolo.