Compartilhamento de guias aprimorado com a captura de região

François Beaufort
François Beaufort

A plataforma da Web já permite que um app da Web capture uma faixa de vídeo da guia atual. Agora ele vem com a captura de região, um mecanismo para cortar essas faixas de vídeo. O web app designa uma parte da guia atual como área de interesse, e o navegador corta todos os pixels fora dessa área.

Antes, os apps da Web podiam cortar faixas de vídeo "manualmente", ou seja, manipular cada frame diretamente. Isso não era robusto nem eficiente. A captura de região resolve essas deficiências. Agora, o app da Web pode instruir o navegador a fazer o trabalho em nome dele.

Sobre a captura de região

Você criou um site com o Dynamic Content™. É o melhor web app de todos os tempos, e as pessoas não conseguem parar de usar, muitas vezes de forma colaborativa. Uma possível próxima etapa é incorporar recursos de videoconferência. Você decide fazer isso. Você se une a um provedor de serviços de videoconferência e incorpora o web app dele como um iframe de origem cruzada. O web app de videoconferência captura a guia atual como uma faixa de vídeo e a transmite para os participantes remotos.

Captura de tela de uma janela do navegador com um app da Web destacando a área de conteúdo principal e o iframe entre origens.
A área de conteúdo principal está em azul e o iframe entre origens está em vermelho.

Não tão rápido… Você não quer transmitir os vídeos das pessoas de volta para elas, não é? É melhor cortar essa parte. Mas como? O iframe incorporado não sabe qual conteúdo você expõe e onde, então não é possível cortar sem ajuda. Em teoria, você pode transmitir as coordenadas pretendidas. Mas o que acontece se o usuário redimensionar a janela? Rola a janela de visualização? Aumenta ou diminui o zoom? Interage com a página de uma forma que produz uma mudança de layout? Mesmo que você envie as novas coordenadas para o iframe de captura, problemas de tempo ainda podem levar a alguns frames cortados incorretamente.

Vamos usar a captura de região. Há um Element na sua página, talvez um <div>, que contém o conteúdo principal. Vamos chamar de mainContentArea. Você quer que o web app de videoconferência capture e compartilhe remotamente a área definida pela caixa delimitadora desse elemento. Assim, você deriva um CropTarget de mainContentArea. Você transmite esse CropTarget para o web app de videoconferência. Depois de cortar a faixa de vídeo usando esse CropTarget, os frames nessa faixa consistem apenas nos pixels que estão dentro da caixa delimitadora de mainContentArea. Se mainContentArea mudar de tamanho, forma ou local, a faixa de vídeo vai acompanhar sem exigir nenhuma entrada adicional de qualquer um dos web apps.

Vamos revisar essas etapas:

Você define um CropTarget no seu web app chamando CropTarget.fromElement() com o elemento de sua escolha como entrada.

// In the main web app, associate mainContentArea with a new CropTarget
const mainContentArea = document.querySelector("#mainContentArea");
const cropTarget = await CropTarget.fromElement(mainContentArea);

Você transmite o CropTarget para o web app de videoconferência.

// Send the CropTarget to the video conferencing web app.
const iframe = document.querySelector("#videoConferenceIframe");
iframe.contentWindow.postMessage(cropTarget);

O web app de videoconferência pede ao navegador para cortar a faixa na área definida por CropTarget chamando cropTo() na faixa de vídeo de autocaptura com o destino de corte recebido do web app principal.

// In the embedded video conferencing web app, ask the user for permission
// to start capturing the current tab.
const stream = await navigator.mediaDevices.getDisplayMedia({
  preferCurrentTab: true,
});
const [track] = stream.getVideoTracks();

// Start cropping the self-capture video track using the CropTarget
// received over window.onmessage.
await track.cropTo(cropTarget);

// Enjoy! Transmit remotely the cropped video track with RTCPeerConnection.

Et voilà! Pronto.

Análise detalhada

Detecção de recursos

Para verificar se CropTarget.fromElement() é compatível, use:

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

Derivar um CropTarget

Vamos nos concentrar no elemento chamado mainContentArea. Para derivar um CropTarget dele, chame CropTarget.fromElement(mainContentArea). A promessa retornada será resolvida com um novo objeto CropTarget se for bem-sucedida. Caso contrário, ele será rejeitado se você tiver criado um número irracional de objetos CropTarget.

const mainContentArea = document.querySelector("#mainContentArea");
const cropTarget = await CropTarget.fromElement(mainContentArea);

Ao contrário de um Element, um objeto CropTarget é serializável. Ele pode ser transmitido para outro documento usando Window.postMessage(), por exemplo.

Corte

Ao capturar uma guia, a faixa de vídeo é instanciada como um BrowserCaptureMediaStreamTrack, que é uma subclasse de MediaStreamTrack. Essa subclasse expõe cropTo(). Chame track.cropTo(cropTarget) para começar a cortar de acordo com os contornos de mainContentArea (o elemento de que cropTarget foi derivado).

Se for bem-sucedida, a promessa será resolvida quando for possível garantir que todos os frames de vídeo subsequentes consistirão nos pixels que estão dentro da caixa delimitadora do mainContentArea.

Se não for possível, a promessa será rejeitada. Isso vai acontecer se:

  • O CropTarget foi cunhado em outra guia. (Por enquanto. Fique por dentro.)
  • O CropTarget foi derivado de um elemento que não existe mais.
  • A faixa tem clones. Consulte o problema 1509418.
  • A faixa atual não é de um vídeo gravado por você. Consulte abaixo.

O método cropTo() é exposto em qualquer faixa de vídeo de captura de tela, não apenas para autocaptura. Portanto, é recomendável verificar se o usuário selecionou a guia atual antes de tentar cortar a faixa. Isso pode ser feito usando o Capture Handle. Também é possível pedir ao navegador para incentivar o usuário a fazer a autocaptura usando preferCurrentTab.

// Start cropping the self-capture video track using the CropTarget.
await track.cropTo(cropTarget);

Para voltar ao estado sem corte, chame cropTo() com null.

// Stop cropping.
await track.cropTo(null);

Conteúdo oclusivo e ocluído

Para a captura de região, apenas a posição e o tamanho da meta são importantes, não o z-index. Os pixels que ocluem o alvo serão capturados. As partes ocultas do destino não serão capturadas.

Isso é uma consequência de a captura de região ser essencialmente um corte. Uma alternativa, que será uma API futura, é a captura no nível do elemento. Ou seja, capturar apenas pixels associados ao destino, independente de oclusões. Uma API desse tipo tem um conjunto diferente de requisitos de segurança e privacidade do que um simples corte.

Imagem de diferentes resultados para a API Region Capture e Element-level Capture.
Comportamento da captura de região com conteúdo oclusivo.

Segurança e privacidade

A captura de região permite que um app da Web que já está observando todos os pixels na guia remova voluntariamente alguns deles. Ela é claramente segura, já que não é possível obter novas informações.

A captura de região pode ser usada para limitar as informações enviadas aos participantes remotos. Por exemplo, talvez você queira compartilhar alguns slides, mas não as anotações do apresentador.

Captura de tela de uma janela do navegador com slides e anotações do apresentador.
Um app da Web com slides e anotações do apresentador.
Não é recomendável compartilhar as anotações remotamente. Captura da região da sugestão.

No entanto, no local, a captura de região não adiciona garantias de segurança. Ao transferir uma faixa para outro documento, o documento de destino ainda pode remover o corte e acessar todos os pixels da guia capturada.

O Chrome desenha uma borda azul ao redor das guias capturadas. Ao cortar, o Chrome geralmente desenha a borda azul ao redor do alvo cortado.

Demonstração

Para testar a captura de região, execute a demonstração.

Suporte ao navegador

Browser Support

  • Chrome: 104.
  • Edge: 104.
  • Firefox: not supported.
  • Safari: not supported.

Source

A captura de região está disponível apenas no Chrome 104 para computadores.

A seguir

Confira uma prévia do que esperar em breve para melhorar o compartilhamento de tela na Web:

  • A captura de região vai oferecer suporte a capturas de outras guias.
  • O foco condicional permite que o web app de captura instrua o navegador a mudar o foco para a superfície de exibição capturada ou evitar essa mudança.
  • Uma API de captura no nível do elemento pode ser fornecida.

Feedback

A equipe do Chrome e a comunidade de padrões da Web querem saber sobre suas experiências com a captura de região.

Fale sobre o design

Há algo na captura de região que não funciona como esperado? Ou há métodos ou propriedades ausentes que você precisa implementar sua ideia? Tem uma dúvida ou um comentário sobre o modelo de segurança?

  • Registre um problema de especificação no repositório do GitHub ou adicione suas ideias a um problema existente.

Problemas com a implementação?

Você encontrou um bug na implementação do Chrome? Ou a implementação é diferente da especificação?

  • Registre um bug em https://new.crbug.com. Inclua o máximo de detalhes possível e instruções simples para reproduzir o problema.

Mostrar apoio

Você planeja usar a captura de região? Seu apoio público ajuda a equipe do Chrome a priorizar recursos e mostra a outros fornecedores de navegadores a importância de oferecer suporte a eles.

Envie um tweet para @ChromiumDev e informe onde e como você está usando.

Agradecimentos

Agradecemos a Joe Medley por revisar este artigo.