L'API Screen Capture consente all'utente di selezionare una scheda, una finestra o uno schermo da acquisire come flusso multimediale. Questo flusso può essere registrato o condiviso con altri utenti tramite la rete. Questa documentazione introduce Conditional Focus, un meccanismo per le app web che consente di controllare se la scheda o la finestra acquisita verrà messa a fuoco all'avvio dell'acquisizione o se la pagina di acquisizione rimarrà a fuoco.
Supporto browser
Conditional Focus è disponibile a partire da Chrome 109.
Sfondo
Quando un'app web inizia ad acquisire una scheda o una finestra, il browser deve prendere una decisione: la superficie acquisita deve essere portata in primo piano o la pagina di acquisizione deve rimanere a fuoco? La risposta dipende dal motivo della chiamata a getDisplayMedia() e dalla superficie selezionata dall'utente.
Considera 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 può essere controllata da remoto, mantieni la videoconferenza a fuoco.
- In caso contrario, metti a fuoco la scheda o la finestra acquisita.
Nell'esempio precedente, l'app web di videoconferenza manterrebbe lo stato attivo se condividesse una presentazione diapositive, consentendo all'utente di sfogliare le diapositive da remoto; tuttavia, se l'utente scegliesse di condividere un editor di testo, l'app web di videoconferenza passerebbe immediatamente lo stato attivo alla scheda o alla finestra acquisita.
Utilizzo dell'API Conditional Focus
Crea un'istanza di CaptureController e passala a getDisplayMedia(). Chiamando setFocusBehavior() immediatamente dopo la risoluzione della promessa restituita da getDiplayMedia(), puoi controllare se la scheda o la finestra acquisita verrà messa a fuoco 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 prendere in considerazione l'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");
}
È anche possibile decidere se mettere a fuoco prima di chiamare 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 arbitrario di volte prima che la promessa venga risolta 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()viene risolta in un microtask. La chiamata asetFocusBehavior()dopo il completamento del microtask genera un errore. - La chiamata a
setFocusBehavior()più di un secondo dopo l'avvio dell'acquisizione è un'operazione senza effetto.
Ovvero, 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");
La chiamata a setFocusBehavior() genera anche un'eccezione nei seguenti casi:
- La traccia video del flusso restituito da
getDisplayMedia()non è "live". - Dopo la risoluzione della promessa restituita da
getDisplayMedia(), se l'utente ha condiviso uno schermo (non una scheda o una finestra).
Esempio
Puoi sperimentare Conditional Focus eseguendo la demo.
Presentazione della funzionalità
Per verificare se CaptureController.setFocusBehavior() è supportato, utilizza:
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 Conditional Focus.
Parlaci del design
C'è qualcosa in Conditional Focus che non funziona come previsto? Oppure mancano metodi o proprietà di cui hai bisogno 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 i tuoi pensieri a una segnalazione esistente.
Problemi con l'implementazione?
Hai trovato un bug nell'implementazione di Chrome? Oppure l'implementazione è diversa dalle specifiche?
- Invia un bug all'indirizzo https://new.crbug.com. Assicurati di includere il maggior numero di dettagli possibile e le istruzioni per la riproduzione.
Mostra il tuo sostegno
Hai intenzione di utilizzare Conditional Focus? Il tuo sostegno 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 a @ChromiumDev e comunicaci dove e come lo utilizzi.
Link utili
Ringraziamenti
Grazie a Rachel Andrew per aver esaminato questo documento.