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 può essere controllata da remoto, mantieni in primo piano la videoconferenza.
- In caso contrario, seleziona la scheda o la 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()
immediatamente dopo la risoluzione della promessa restituita da getDiplayMedia()
, puoi controllare se la scheda o la finestra acquisita sarà o meno attiva. 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");
}
È persino possibile decidere se attivare la messa 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 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 un microtask. L'istruzione setFocusBehavior()
viene richiamata dopo il completamento del microtask e viene generato 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, 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 lo stato attivo condizionale.
Parlaci del design
C'è qualcosa relativo al controllo condizionale che non funziona come previsto? Oppure mancano metodi o proprietà necessari 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 dalla specifica?
- 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 è ideale per condividere 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.
Link utili
Ringraziamenti
Immagine hero di Elena Taranenko.
Grazie a Rachel Andrew per aver esaminato questo articolo.