Acquisisci uno stream video da qualsiasi elemento

François Beaufort
François Beaufort

Con l'API Screen Capture, puoi acquisire l'intera scheda corrente. L'API Element Capture ti consente di acquisire e registrare un elemento HTML specifico. Trasforma un'acquisizione dell'intera scheda in un'acquisizione di un sottoalbero DOM specifico, acquisendo solo i discendenti diretti dell'elemento target. In altre parole, ritaglia e rimuove i contenuti che coprono e che sono coperti.

Perché utilizzare Element Capture?

Tenere conto dei requisiti di un'applicazione di videoconferenza può aiutarti a capire dove è utile Element Capture. Se hai un'applicazione di videoconferenza che ti consente di incorporare applicazioni di terze parti in un iframe, a volte potresti voler acquisire l'iframe come video e trasmetterlo ai partecipanti remoti.

Screenshot di una chiamata di videoconferenza in Chrome.
Elad utilizza un'applicazione di terze parti in una chiamata di videoconferenza con François.

Se chiami getDisplayMedia() e lasci che sia l'utente a scegliere la scheda corrente, verrà trasmessa l'intera scheda corrente. È probabile che le persone ricevano di nuovo il proprio video. Puoi ritagliarlo utilizzando Acquisizione regione.

Tuttavia, cosa succede se il presentatore interagisce con l'applicazione di videoconferenza e alcuni contenuti, ad esempio un elenco a discesa, vengono sovrapposti ai contenuti che devono essere acquisiti?

Screenshot di un elenco a discesa che copre i contenuti destinati all'acquisizione.
Sopra i contenuti da acquisire viene visualizzato un elenco a discesa.

La funzionalità di acquisizione della regione non ti aiuterà. Parte dell'elenco a discesa potrebbe essere visibile sugli schermi dei partecipanti remoti.

Screenshot di un elenco a discesa acquisito.
L'elenco a discesa di Elad viene visualizzato sopra i contenuti ricevuti da François.

Il fatto che la funzionalità di acquisizione di regioni acquisisca parti di elementi in questo modo (noto come contenuti che coprono) crea diversi problemi:

  • L'occultamento dei contenuti potrebbe impedire la visualizzazione dei contenuti che l'utente intendeva condividere.
  • I contenuti coperti potrebbero essere privati (ad esempio le notifiche della chat).
  • L'occultamento dei contenuti potrebbe creare confusione. Ad esempio, un nuovo layout dell'applicazione potrebbe mostrare brevemente i video dei partecipanti remoti sul target acquisito.

L'API Element Capture risolve tutti questi problemi, consentendoti di scegliere come target l'elemento che vuoi condividere.

Screenshot dell'elemento target senza un elenco a discesa visualizzato.
François non vede l'elenco a discesa di Elad.

Come faccio a utilizzare Element Capture?

captureTarget è un elemento della pagina che contiene i contenuti che l'utente vuole acquisire. Vuoi che l'app web di videoconferenza acquisisca captureTarget e la condivida con i partecipanti remoti. Quindi derivi un RestrictionTarget da captureTarget. Dopo aver limitato la traccia video utilizzando questo RestrictionTarget, i frame della traccia video ora consistono solo dei pixel che fanno parte di captureTarget e dei suoi discendenti DOM diretti.

Se captureTarget cambia dimensioni, forma o posizione, la traccia video segue, senza richiedere alcun input aggiuntivo da parte di nessuna delle app web. Allo stesso modo, l'occultamento di contenuti che appaiono, scompaiono o si spostano non richiede un trattamento speciale.

Rivedi questi passaggi:

Per iniziare, consenti all'utente di acquisire la scheda corrente.

// Ask the user for permission to start capturing the current tab.
const stream = await navigator.mediaDevices.getDisplayMedia({
 preferCurrentTab: true,
});
const [track] = stream.getVideoTracks();

Definisci un RestrictionTarget chiamando RestrictionTarget.fromElement() con un elemento a tua scelta come input.

// Associate captureTarget with a new RestrictionTarget
const captureTarget = document.querySelector("#captureTarget");
const restrictionTarget = await RestrictionTarget.fromElement(captureTarget);

Quindi chiama restrictTo() sulla traccia video con RestrictionTarget come input. Una volta risolta l'ultima promessa, tutti i frame successivi saranno limitati.

// Start restricting the self-capture video track using the RestrictionTarget.
await track.restrictTo(restrictionTarget);

// Enjoy! Transmit remotely.

Approfondimento

Rilevamento di funzionalità

Per verificare se RestrictionTarget.fromElement() è supportato, utilizza:

if ("RestrictionTarget" in self && "fromElement" in RestrictionTarget) {
  // Deriving a restriction target is supported.
}

Dedurre un RestrictionTarget

Concentrati sull'elemento denominato captureTarget. Per ricavare un RestrictionTarget, chiama RestrictionTarget.fromElement(captureTarget). Se l'operazione va a buon fine, la promessa restituita verrà risolta con un nuovo oggetto RestrictionTarget. In caso contrario, verrà rifiutato se hai coniato un numero irragionevole di oggetti RestrictionTarget.

const captureTarget = document.querySelector("#captureTarget");
const restrictionTarget = await RestrictionTarget.fromElement(captureTarget);

A differenza di un elemento, un oggetto RestrictionTarget è serializzabile. Ad esempio, può essere passato a un altro documento utilizzando Window.postMessage().

Con limitazioni

Quando acquisisci una scheda, la traccia video mostra restrictTo(). Quando acquisisci la scheda corrente, è valido chiamare restrictTo() con null o qualsiasi RestrictionTarget derivato da un elemento all'interno della scheda corrente.

Le chiamate a restrictTo(restrictionTarget) trasformano la traccia video in un'acquisizione di captureTarget, come se fosse disegnata da sola, indipendentemente dal resto del DOM. Vengono acquisiti anche tutti i discendenti di captureTarget; i fratelli di captureTarget vengono eliminati dall'acquisizione. Di conseguenza, tutti i fotogrammi caricati sulla traccia vengono visualizzati come se fossero ritagliati in base ai contorni di captureTarget e tutti i contenuti che coprono e vengono coperti vengono rimossi.

// Start restricting the self-capture video track using the RestrictionTarget.
await track.restrictTo(restrictionTarget);

Le chiamate a restrictTo(null) ripristinano lo stato originale della traccia.

// Stop restricting.
await track.restrictTo(null);

Se la chiamata a restrictTo() va a buon fine, la Promise restituita viene risolta quando è possibile garantire che tutti i fotogrammi video successivi saranno limitati a captureTarget.

In caso di esito negativo, la promessa viene rifiutata. Una chiamata a restrictTo() non andrà a buon fine per uno dei seguenti motivi:

  • Se il token restrictionTarget è stato coniato in una scheda diversa da quella acquisita. Tieni presente che, utilizzando il pulsante "Condividi questa scheda", gli utenti possono modificare la scheda acquisita in un determinato momento.
  • Se restrictionTarget è stato derivato da un elemento che non esiste più.
  • Se la traccia ha dei cloni. (vedi issue 1509418).
  • Se la traccia corrente non è una traccia video acquisita autonomamente.
  • Se l'elemento da cui è stato dedotto restrictionTarget non è idoneo per le limitazioni.

Considerazioni sulla cattura autonoma

Quando un'app chiama getDisplayMedia() e l'utente sceglie di acquisire la scheda dell'app, si parla di "acquisizione autonoma".

Il metodo restrictTo() è esposto su qualsiasi traccia video di acquisizione di schede e non solo per l'acquisizione autonoma. Tuttavia, al momento la funzionalità di acquisizione di elementi è attiva solo per i selfie. È quindi consigliabile verificare se l'utente ha selezionato la scheda corrente prima di tentare di limitare il canale. Questo può essere ottenuto utilizzando Capture Handle. È anche possibile chiedere al browser di indurre l'utente a scattare un selfie utilizzando preferCurrentTab.

Trasparenza

I fotogrammi video acquisiti dall'app tramite getDisplayMedia() non includono un canale alpha. Se un'app imposta un target di acquisizione parzialmente trasparente, l'eliminazione del canale alfa ha alcune possibili conseguenze:

  • I colori potrebbero cambiare. Gli elementi target parzialmente trasparenti disegnati su uno sfondo chiaro potrebbero apparire più scuri quando il canale alfa viene rimosso, mentre quelli disegnati su uno sfondo scuro potrebbero apparire più chiari.
  • I colori invisibili o impercettibili per l'utente quando il canale alfa era impostato al massimo, vengono visualizzati una volta rimosso il canale alfa. Ad esempio, ciò potrebbe portare a regioni nere impreviste nei frame acquisiti, se le sezioni trasparenti avessero il codice RGBA rgba(0, 0, 0, 0).
Screenshot del risultato di un target di acquisizione trasparente non rettangolare.
Lo stream video target di acquisizione trasparente non rettangolare (a destra) è un rettangolo di sfondo nero contenente un cerchio blu opaco.

Target di acquisizione non idonei

È sempre possibile iniziare a limitare una traccia a qualsiasi target di acquisizione valido. Tuttavia, i frame non verranno prodotti in determinate condizioni, ad esempio se l'elemento o un suo antenato è display:none. Il principio generale è che la limitazione si applica solo a un elemento che comprende un'area rettangolare bidimensionale singola e coesa, i cui pixel possono essere determinati logicamente indipendentemente da eventuali elementi principali o fratelli.

Un aspetto importante per garantire che l'elemento sia idoneo alla limitazione è che deve formare il proprio contesto di accodamento. Per assicurarti che ciò avvenga, puoi specificare la proprietà CSS isolation impostandola su isolate.

<div id="captureTarget" style="isolation: isolate;"></iframe>

Tieni presente che l'elemento target può passare da idoneo a non idoneo per la limitazione in qualsiasi momento, ad esempio se l'app modifica le sue proprietà CSS. Spetta all'app utilizzare target di acquisizione ragionevoli ed evitare di modificarne le proprietà in modo imprevisto. Se l'elemento target non è più idoneo, i nuovi frame non verranno semplicemente emessi nel canale finché l'elemento target non sarà nuovamente idoneo alla limitazione.

Attivazione di Acquisizione elementi

L'API Element Capture è disponibile in Chrome su computer dietro il flag Element Capture e può essere attivata all'indirizzo chrome://flags/#element-capture.

Questa funzionalità è in fase di prova in Chrome 121 per i computer, il che consente agli sviluppatori di attivarla per i visitatori dei loro siti al fine di raccogliere dati da utenti reali. Per ulteriori informazioni sulle prove delle origini, consulta la sezione Iniziare a utilizzare le prove delle origini.

Sicurezza e privacy

Per comprendere i compromessi relativi alla sicurezza, consulta la sezione Considerazioni su privacy e sicurezza della specifica di Element Capture.

Il browser Chrome disegna un bordo blu attorno ai bordi delle schede acquisite.

Demo

Puoi provare Element Capture eseguendo la demo su Glitch. Assicurati di controllare il codice sorgente.

Feedback

Il team di Chrome e la community degli standard web vogliono conoscere le tue esperienze con Element Capture.

Parlaci del design

C'è qualcosa in merito a Acquisizione regione 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 riproduzioni rapide e semplici.

Riconoscimenti

Foto di Paul Skorupskas su Unsplash