Com a API Screen Capture, você pode capturar toda a guia atual. A API Element Capture permite capturar e gravar um elemento HTML específico. Ela transforma uma captura de toda a guia em uma captura de uma subárvore do DOM específica, capturando somente descendentes diretos do elemento-alvo. Em outras palavras, ele corta e remove o conteúdo escondido.
Por que usar a captura de elementos?
Considerar os requisitos de um aplicativo de videoconferência pode ajudar a entender onde o Element Capture é útil. Se você tiver um aplicativo de videoconferência que permite incorporar aplicativos de terceiros em um iframe, talvez queira capturar esse iframe como um vídeo e transmiti-lo aos participantes remotos.
Chamar getDisplayMedia()
e permitir que o usuário escolha a guia atual transmitiria toda a guia atual. Isso provavelmente transmitirá o vídeo das pessoas de volta para elas. Você pode cortar usando a Captura de região.
Mas e se o apresentador usar o aplicativo de videoconferência e algum conteúdo, como uma lista suspensa, for sobreposto ao conteúdo destinado à captura?
A captura de região não ajudaria nisso. Parte da lista suspensa pode acabar visível nos participantes telas.
O fato de a captura de região capturar partes dos elementos dessa maneira (conhecido como conteúdo de obstrução) cria vários problemas:
- A obstrução pode impedir a visualização do conteúdo que o usuário pretendia compartilhar.
- A obstrução de conteúdo pode ser particular, por exemplo, notificações de chat.
- A obstrução de conteúdo pode ser confusa. Por exemplo, um novo layout do aplicativo poderia trazer brevemente os próprios vídeos dos participantes remotos para o alvo capturado.
A API Element Capture resolve todos esses problemas, permitindo que você direcione o elemento que quer compartilhar.
Como uso a Captura de elementos?
O captureTarget
é um elemento da página que tem o conteúdo que o usuário quer capturar. Você quer que o app da Web de videoconferência capture captureTarget
e compartilhe com os participantes remotos. Então, você deriva um RestrictionTarget
de captureTarget
. Depois de restringir a faixa de vídeo usando este RestrictionTarget
, os frames nessa faixa de vídeo agora consistem apenas nos pixels que fazem parte de captureTarget
e dos descendentes diretos do DOM.
Se captureTarget
mudar de tamanho, forma ou localização, a faixa de vídeo vai acompanhar, sem exigir nenhuma outra entrada de nenhum app da Web. A obstrução de conteúdo que aparece, desaparece ou se move por aí não requer tratamento especial.
Revise estas etapas:
Comece permitindo que o usuário capture a guia atual.
// Ask the user for permission to start capturing the current tab.
const stream = await navigator.mediaDevices.getDisplayMedia({
preferCurrentTab: true,
});
const [track] = stream.getVideoTracks();
Defina um RestrictionTarget
chamando RestrictionTarget.fromElement()
com um elemento da sua escolha como entrada.
// Associate captureTarget with a new RestrictionTarget
const captureTarget = document.querySelector("#captureTarget");
const restrictionTarget = await RestrictionTarget.fromElement(captureTarget);
Em seguida, chame restrictTo()
na faixa de vídeo com o RestrictionTarget
como entrada. Quando a última promessa for resolvida, todos os frames subsequentes serão restritos.
// Start restricting the self-capture video track using the RestrictionTarget.
await track.restrictTo(restrictionTarget);
// Enjoy! Transmit remotely.
Análise detalhada
Detecção de recursos
Para verificar se RestrictionTarget.fromElement()
é compatível, use:
if ("RestrictionTarget" in self && "fromElement" in RestrictionTarget) {
// Deriving a restriction target is supported.
}
Derivar um RestrictionTarget
Concentre-se no Elemento chamado captureTarget
. Para derivar um RestrictionTarget
com base nele, chame RestrictionTarget.fromElement(captureTarget)
. A promessa retornada será resolvida com um novo objeto RestrictionTarget
se for bem-sucedida. Caso contrário, ela será rejeitada se você tiver criado um número desnecessário de objetos RestrictionTarget
.
const captureTarget = document.querySelector("#captureTarget");
const restrictionTarget = await RestrictionTarget.fromElement(captureTarget);
Ao contrário de um elemento, um objeto RestrictionTarget
é serializável. Ele pode ser transmitido para outro documento usando Window.postMessage()
, por exemplo.
Restrito
Ao capturar uma guia, a faixa de vídeo expõe restrictTo()
. Ao capturar a guia atual, é válido chamar restrictTo()
com null
ou qualquer RestrictionTarget
derivada de um elemento na guia atual.
As chamadas para restrictTo(restrictionTarget)
modificam a faixa de vídeo em uma captura de captureTarget
, como se ela fosse desenhada sozinha, independentemente do restante do DOM. Todos os descendentes de captureTarget
também são capturados. irmãos de captureTarget
são eliminados da captura. O resultado é que todos os frames enviados na faixa aparecem como se tivessem sido cortados de acordo com os contornos de captureTarget
, e qualquer conteúdo obstruído é removido.
// Start restricting the self-capture video track using the RestrictionTarget.
await track.restrictTo(restrictionTarget);
As chamadas para restrictTo(null)
revertem a faixa ao estado original.
// Stop restricting.
await track.restrictTo(null);
Se a chamada para restrictTo()
for bem-sucedida, a promessa retornada será resolvida quando for possível garantir que todos os frames de vídeo subsequentes serão restritos a captureTarget
.
Se falhar, a promessa vai ser rejeitada. Uma chamada malsucedida para restrictTo()
vai ocorrer por um dos seguintes motivos:
- Se a
restrictionTarget
foi criada em uma guia diferente da que está sendo capturada. Ao usar o botão "compartilhar esta guia em vez disso", os usuários podem alterar a guia capturada a qualquer momento. - Se o
restrictionTarget
tiver sido derivado de um elemento que não existe mais. - Se a faixa tiver clones. Consulte o problema 1509418 (link em inglês).
- Se a faixa atual não for uma faixa de vídeo com captura automática.
- Se o elemento do qual
restrictionTarget
foi derivado não estiver qualificado para restrição.
Considerações sobre a autocaptura
Quando um app chama getDisplayMedia()
e o usuário opta por capturar a própria guia, chamamos isso de "autocaptura".
O método restrictTo()
é exposto em qualquer faixa de vídeo de captura de guia, e não apenas na autocaptura. No entanto, a Captura de elementos só está ativada para autocaptura por enquanto. Portanto, é aconselhável verificar se o usuário selecionou a guia atual antes de tentar restringir a faixa. Para isso, use o Capture Handle. Também é possível pedir ao navegador para orientar o usuário a fazer a autocaptura usando o preferCurrentTab
.
Transparência
Os frames de vídeo que o app recebe pelo getDisplayMedia()
não incluem um canal alfa. Se um aplicativo definir um destino de captura parcialmente transparente, a remoção do canal alfa terá algumas consequências possíveis:
- As cores podem mudar. Elementos alvo parcialmente transparentes desenhados sobre um fundo claro podem parecer mais escuros quando o canal alfa é removido, e aqueles desenhados sobre um fundo escuro podem parecer mais claros.
- Cores que eram invisíveis ou imperceptíveis para o usuário quando o Canal Alfa estava definido para o máximo apareceriam quando o Canal Alfa fosse removido. Por exemplo, isso poderia levar a regiões pretas inesperadas nos frames capturados se as seções transparentes tivessem o código RGBA
rgba(0, 0, 0, 0)
.
Destinos de captura não qualificados
É sempre possível começar a restringir uma faixa a qualquer destino de captura válido. No entanto, os frames não serão produzidos sob determinadas condições, por exemplo, se o elemento ou um ancestral for display:none
. A lógica geral é que a restrição se aplica somente a um elemento que compreende uma área retangular única, coesa, bidimensional, cujos pixels podem ser determinados logicamente isoladamente de qualquer elemento pai ou irmão.
Uma consideração importante para garantir que o elemento esteja qualificado para restrição é que ele precisa formar o próprio contexto de empilhamento. Para garantir isso, especifique a propriedade CSS de isolamento, definindo-a como isolate
.
<div id="captureTarget" style="isolation: isolate;"></iframe>
O elemento de destino pode alternar entre estar qualificado e não qualificado para restrições a qualquer momento, por exemplo, se o app mudar as propriedades de CSS. Cabe ao app usar destinos de captura razoáveis e evitar mudanças inesperadas nas propriedades. Se o elemento de destino se tornar inelegível, os novos frames não serão emitidos na faixa até que esse elemento volte a estar qualificado para restrição.
Como ativar a captura de elementos
A API Element Capture está disponível no Chrome para computadores com a sinalização Element Capture e pode ser ativada em chrome://flags/#element-capture
.
Esse recurso também está entrando em um teste de origem do Chrome 121 para computadores. Com ele, os desenvolvedores podem ativar o recurso para que os visitantes dos sites coletem dados de usuários reais. Consulte Introdução aos testes de origem para mais informações.
Segurança e privacidade
Para entender os prós e contras da segurança, consulte a seção Considerações sobre privacidade e segurança da especificação Element Capture.
O navegador Chrome desenha uma borda azul ao redor das bordas das guias capturadas.
Demonstração
Você pode testar a Captura de elementos executando a demonstração no Glitch. Não se esqueça de conferir o código-fonte.
Feedback
A equipe do Chrome e a comunidade de padrões da Web querem saber mais sobre suas experiências com o Element Capture.
Conte-nos sobre o design
Alguma coisa na captura de região não funciona como você esperava? Ou faltam métodos ou propriedades que você precisa para implementar sua ideia? Tem uma pergunta ou comentário sobre o modelo de segurança?
- Registre um problema de especificação no repositório do GitHub (link em inglês) ou adicione sua opinião a um problema.
Problemas com a implementação?
Você encontrou um bug na implementação do Chrome? Ou a implementação é diferente das especificações?
- Registre um bug em https://new.crbug.com. Certifique-se de incluir o máximo de detalhes possível e instruções simples para reproduzi-los. O Glitch é ótimo para compartilhar repetições rápidas e fáceis.
Links úteis
Agradecimentos
Foto de Paul Skorupskas no Unsplash