Acquisisci uno stream video da qualsiasi elemento

Francesco Beaufort
François Beaufort
Elad Alon
Elad Alon

Con l'API Screen Capture, puoi acquisire l'intera scheda corrente. L'API Element Capture ti consente di acquisire e registrare uno specifico elemento HTML. Trasforma un'acquisizione dell'intera scheda in un'acquisizione di una specifica sottostruttura DOM, acquisendo solo i discendenti diretti dell'elemento target. In altre parole, ritaglia e rimuove sia i contenuti occlusivi che quelli nascosti.

Perché utilizzare l'acquisizione di elementi?

Considerare i requisiti di un'applicazione per videoconferenze può aiutarti a capire dove è utile Cattura elementi. Se hai un'applicazione per videoconferenze che ti consente di incorporare applicazioni di terze parti in un iframe, a volte potresti voler acquisire quell'iframe come video e trasmetterlo ai partecipanti remoti.

Screenshot di una videochiamata in Chrome.
Elad utilizza un'applicazione di terze parti in una videochiamata con Franco.

Se chiami getDisplayMedia() e consenti all'utente di scegliere la scheda corrente, viene trasmessa l'intera scheda corrente. È molto probabile che questi video vengano ritrasmessi agli utenti. Puoi ritagliarlo utilizzando Region Capture.

Tuttavia, cosa succede se il presentatore utilizza l'applicazione per videoconferenze e alcuni contenuti, come un elenco a discesa, vengono visualizzati sopra quelli che si vogliono acquisire?

Screenshot di un elenco a discesa che copre i contenuti destinati all'acquisizione.
Viene visualizzato un elenco a discesa sopra i contenuti destinati all'acquisizione.

Region Capture non ti sarebbe stato utile. Parte dell'elenco a discesa potrebbe risultare visibile sugli schermi dei partecipanti remoti.

Screenshot di un elenco a discesa acquisito.
L'elenco a discesa di Elad viene visualizzato in cima ai contenuti ricevuti da Franco.

Il fatto che Region Capture acquisisca parti degli elementi in questo modo (noto come contenuti di occultamento) crea diversi problemi:

  • L'occultamento dei contenuti potrebbe impedire la visualizzazione di quelli che l'utente intendeva condividere.
  • L'occultamento dei contenuti potrebbe essere privato (pensa alle notifiche della chat).
  • L'occultamento dei contenuti potrebbe creare confusione. Ad esempio, un re-layout dell'applicazione potrebbe portare brevemente al di sopra del target acquisito i video dei partecipanti remoti.

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

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

Come si utilizza l'acquisizione di elementi?

captureTarget è un Elemento della pagina che include i contenuti che l'utente desidera acquisire. Vuoi che l'app web per videoconferenze acquisisca captureTarget e la condivida con i partecipanti da remoto. Quindi ottieni un RestrictionTarget da captureTarget. Dopo aver limitato la traccia video utilizzando questo RestrictionTarget, i frame su quella traccia video ora sono composti solo dai pixel che fanno parte di captureTarget e dei relativi discendenti diretti DOM.

Se captureTarget cambia dimensione, forma o posizione, la traccia video continua a seguire, senza richiedere alcun input aggiuntivo da entrambe le app web. Coprendo i contenuti che vengono visualizzati, scompaiono o spostati, allo stesso modo non richiede alcun trattamento speciale.

Rivedi questi passaggi:

Per prima cosa, 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 verranno limitati.

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

// Enjoy! Transmit remotely.

Esegui un'analisi dettagliata

Rilevamento delle funzionalità

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

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

Ricava un RestrictionTarget

Imposta lo stato attivo sull'Elemento chiamato captureTarget. Per ricavare un valore RestrictionTarget da questo codice, chiama RestrictionTarget.fromElement(captureTarget). In caso di esito positivo, la promessa restituita verrà risolta con un nuovo oggetto RestrictionTarget. In caso contrario, verrà rifiutato se hai creato un numero irragionevole di RestrictionTarget oggetti.

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 espone 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 uno screenshot di captureTarget, come se fosse tracciato da solo, indipendentemente dal resto del DOM. Vengono acquisiti anche tutti i discendenti di captureTarget; i fratelli di captureTarget vengono eliminati dall'acquisizione. Il risultato è che i frame inseriti nella traccia sembrano tagliati secondo i contorni di captureTarget e gli eventuali contenuti oscurati e nascosti 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() ha esito positivo, la promessa restituita viene risolta quando è possibile garantire che tutti i frame video successivi saranno limitati a captureTarget.

In caso di esito negativo, la promessa viene rifiutata. Una chiamata al numero restrictTo() non riuscita per uno dei seguenti motivi:

  • Se restrictionTarget è stato creato 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 dato momento.
  • Se restrictionTarget è stato ricavato da un Elemento che non esiste più.
  • Se la traccia contiene cloni. (vedi il problema 1509418.)
  • Se la traccia corrente non è una traccia video acquisita autonomamente.
  • Se l'Elemento da cui è derivato restrictionTarget non è idoneo per la limitazione.

Considerazioni sull'acquisizione automatica

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

Il metodo restrictTo() viene mostrato in qualsiasi traccia video dell'acquisizione di schede, non solo per l'acquisizione automatica. Al momento, tuttavia, l'acquisizione degli elementi è abilitata solo per l'acquisizione automatica. Pertanto, è consigliabile verificare se l'utente ha selezionato la scheda corrente prima di tentare di limitare la traccia. Questa operazione può essere eseguita utilizzando l'handle di acquisizione. È anche possibile chiedere al browser di spingere l'utente ad acquisire automaticamente un'immagine utilizzando preferCurrentTab.

Trasparenza

I frame video trasmessi dall'app tramite getDisplayMedia() non includono un canale alfa. 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 tracciati su uno sfondo scuro potrebbero apparire più chiari.
  • I colori invisibili o impercettibili per l'utente quando il canale alfa è stato impostato sul valore massimo vengono visualizzati dopo la rimozione del canale alfa. Ad esempio, se le sezioni trasparenti avevano il codice RGBA rgba(0, 0, 0, 0), questo potrebbe causare aree nere impreviste nei frame acquisiti.
Screenshot del risultato di un target di acquisizione trasparente non rettangolare.
Lo stream video target di acquisizione trasparente non rettangolare (a destra) è un rettangolo con sfondo nero che contiene un cerchio blu opaco.

Target di acquisizione non idonei

È sempre possibile iniziare a limitare una traccia a qualsiasi destinazione di acquisizione valida. Tuttavia, i frame non verranno prodotti in determinate condizioni, ad esempio se l'elemento o un predecessore è display:none. La motivazione generale è che la restrizione si applica solo a un elemento che comprende una singola area rettangolare, coesa, bidimensionale, i cui pixel possono essere logicamente determinati in modo isolato da qualsiasi elemento principale o di pari livello.

Una considerazione importante per garantire che l'elemento sia idoneo per la limitazione è che deve formare un proprio contesto di stack. Per farlo, puoi specificare la proprietà CSS di isolamento, impostandola su isolate.

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

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

Attivazione dell'acquisizione dell'elemento

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

Inoltre, per questa funzionalità è prevista una prova dell'origine da Chrome 121 su computer, che consente agli sviluppatori di attivare la funzionalità per consentire ai visitatori dei loro siti di raccogliere dati dagli utenti reali. Consulta la Guida introduttiva alle prove dell'origine per saperne di più sulle prove dell'origine.

Sicurezza e privacy

Per comprendere i compromessi in termini di sicurezza, consulta la sezione Considerazioni sulla privacy e sulla sicurezza della specifica Element Capture.

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

Demo

Puoi giocare con Cattura elemento 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.

Descrivi il design

C'è qualcosa in Acquisizione della regione che non funziona come previsto? Oppure mancano metodi o proprietà di cui hai bisogno per implementare la tua idea? Hai domande o commenti sul modello di sicurezza?

  • Segnala un problema relativo alle specifiche nel repository GitHub o aggiungi la tua opinione su un problema 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 possibile di dettagli e di semplici istruzioni per la riproduzione. Glitch è ottimo per condividere riproduzioni facili e veloci.

Attestazioni

Foto di Paul Skorupskas su Unsplash