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 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 di destinazione. In altre parole, ritaglia e rimuove sia i contenuti che occludono sia quelli occlusi.

Perché utilizzare l'acquisizione elementi?

Considerare i requisiti di un'applicazione di videoconferenza può aiutarti a capire in quali casi Element Capture è utile. 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.

La chiamata a getDisplayMedia() e la possibilità per l'utente di scegliere la scheda corrente trasmetterebbe l'intera scheda corrente. che probabilmente trasmetterà il video della persona. Puoi ritagliare questa parte utilizzando Acquisisci regione.

Tuttavia, cosa succede se il presentatore interagisce con l'applicazione di videoconferenza e alcuni contenuti, come un elenco a discesa, vengono visualizzati sopra i contenuti che devono essere acquisiti?

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

La funzionalità di acquisizione della regione non ti sarà d'aiuto. Parte dell'elenco a discesa potrebbe essere visibile sugli schermi dei partecipanti da remoto.

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 l'acquisizione regione acquisisca parti di elementi in questo modo (noto come occlusione dei contenuti) crea diversi problemi:

  • L'occlusione dei contenuti potrebbe impedire la visualizzazione dei contenuti che l'utente intendeva condividere.
  • I contenuti che vengono oscurati potrebbero essere privati (ad esempio le notifiche di chat).
  • L'occlusione dei contenuti potrebbe creare confusione. Ad esempio, una riorganizzazione del layout dell'applicazione potrebbe spostare brevemente i video dei partecipanti remoti sopra il target acquisito.

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

Screenshot dell'elemento di destinazione senza un elenco a discesa in visualizzazione.
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 lo condivida con i partecipanti da remoto. Quindi, derivi un RestrictionTarget da captureTarget. Dopo aver limitato la traccia video utilizzando questo RestrictionTarget, i frame di questa traccia video ora sono costituiti solo dai pixel che fanno parte di captureTarget e dei relativi discendenti DOM diretti.

Se captureTarget cambia dimensioni, forma o posizione, la traccia video lo segue, senza richiedere alcun input aggiuntivo da parte dell'app web. Anche l'occlusione di contenuti che appaiono, scompaiono o si spostano non richiede un trattamento speciale.

Rivedi questi passaggi:

Inizia consentendo 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.

Approfondimento

Rilevamento delle funzionalità

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

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

Deriva un RestrictionTarget

Concentrati sull'elemento chiamato captureTarget. Per derivare 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 creato 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. Può essere passato a un altro documento utilizzando Window.postMessage(), ad esempio.

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 un'acquisizione di captureTarget, come se fosse disegnata da sola, indipendentemente dal resto del DOM. Vengono acquisiti anche tutti i discendenti di captureTarget, mentre i relativi fratelli vengono eliminati dall'acquisizione.captureTarget Il risultato è che tutti i fotogrammi forniti sulla traccia vengono visualizzati come se fossero stati ritagliati in base ai contorni di captureTarget e tutti i contenuti occlusivi e occlusi 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 fotogrammi video successivi saranno limitati a captureTarget.

In caso di esito negativo, la promessa viene rifiutata. Una chiamata senza esito a restrictTo() può essere dovuta a uno dei seguenti motivi:

  • Se l'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 determinato momento.
  • Se restrictionTarget è stato derivato da un elemento che non esiste più.
  • Se la traccia ha cloni. (vedi problema 1509418).
  • Se la traccia attuale non è una traccia video di autoacquisizione.
  • Se l'elemento da cui è stato derivato restrictionTarget non è idoneo per la limitazione.

Considerazioni sull'autoacquisizione

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

Il metodo restrictTo() è esposto su qualsiasi traccia video di acquisizione delle schede e non solo per l'autoacquisizione. Tuttavia, l'acquisizione degli elementi è attualmente abilitata solo per l'autoacquisizione. Pertanto, è consigliabile verificare se l'utente ha selezionato la scheda corrente prima di tentare di limitare la traccia. Puoi farlo utilizzando Capture Handle. È anche possibile chiedere al browser di invitare l'utente a eseguire l'autocattura utilizzando preferCurrentTab.

Trasparenza

I fotogrammi video che l'app riceve tramite getDisplayMedia() non includono un canale alfa. Se un'app imposta un target di acquisizione parzialmente trasparente, la rimozione 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 viene rimosso il canale alfa, 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 sul valore massimo, sarebbero apparsi una volta rimosso il canale alfa. Ad esempio, questo potrebbe comportare la visualizzazione di regioni nere impreviste nei frame acquisiti, se le sezioni trasparenti avevano il codice RGBA rgba(0, 0, 0, 0).
Screenshot del risultato di un target di acquisizione trasparente non rettangolare.
Il flusso video del target di acquisizione trasparente non rettangolare (a destra) è un rettangolo nero con 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 elemento principale è 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 in isolamento da qualsiasi elemento principale o fratello.

Un aspetto importante da considerare per garantire l'idoneità dell'elemento alla limitazione è che deve formare un proprio contesto di sovrapposizione. 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 di destinazione può passare dall'idoneità all'inidoneità alla limitazione in qualsiasi momento arbitrario, ad esempio se l'app modifica le proprietà CSS. Spetta all'app utilizzare target di acquisizione ragionevoli ed evitare di modificare le proprietà in modo imprevisto. Se l'elemento target non è più idoneo, non verranno emessi nuovi fotogrammi sulla traccia finché l'elemento target non tornerà a essere idoneo per la limitazione.

Supporto browser

Acquisizione elementi è disponibile solo su computer a partire da Chrome 132.

Sicurezza e privacy

Per comprendere i compromessi in termini di sicurezza, consulta la sezione Considerazioni su privacy e sicurezza delle specifiche di acquisizione degli elementi.

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

Demo

Puoi provare Element Capture eseguendo la demo.

Feedback

Il team di Chrome e la community degli standard web vogliono conoscere le tue esperienze con l'acquisizione di elementi.

Descrivi il design

C'è qualcosa in Element Capture 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 i tuoi commenti a una segnalazione esistente.

Problemi con l'implementazione?

Hai trovato un bug nell'implementazione di Chrome? L'implementazione è diversa dalla specifica?

  • Invia una segnalazione di bug all'indirizzo https://new.crbug.com. Assicurati di includere il maggior numero di dettagli possibile e istruzioni semplici per la riproduzione.

Riconoscimenti

Foto di Paul Skorupskas su Unsplash