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 app da Web 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, os apps da Web podiam 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 app da Web de todos os tempos, e as pessoas não param de usá-lo, muitas vezes em colaboração. Uma próxima etapa possível é incorporar recursos de conferência virtual. Você decide fazer isso. Você se junta a um provedor de serviços de videoconferência e incorpora o app da Web dele como um iframe de origem cruzada. O app da Web de videoconferência captura a guia atual como uma faixa de vídeo e a transmite aos participantes remotos.
Calma aí… 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 pode ser cortado 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.
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 chamá-lo de mainContentArea
. Você quer que o app da Web de videoconferência capture e compartilhe remotamente a área definida pela caixa de delimitadora desse elemento. Então, você deriva um CropTarget
de mainContentArea
. Você transmite essa CropTarget
para o app da Web de videoconferência. Depois de cortar a faixa de vídeo usando essa CropTarget
, os frames nessa faixa consistem apenas dos pixels que estão dentro da caixa delimitadora de mainContentArea
. Se mainContentArea
mudar de tamanho, forma ou localização, a faixa de vídeo vai acompanhar, sem exigir nenhuma outra entrada de nenhum app da Web.
Vamos revisar estas etapas:
Defina um CropTarget
no seu app da Web chamando CropTarget.fromElement()
com o elemento que você quiser 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 app da Web de videoconferência.
// Send the CropTarget to the video conferencing web app.
const iframe = document.querySelector("#videoConferenceIframe");
iframe.contentWindow.postMessage(cropTarget);
O app da Web de videoconferência pede ao navegador para cortar a faixa na área definida pelo CropTarget
chamando cropTo()
na faixa de vídeo de autocaptura com o alvo do corte recebido do app da Web 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à! Tudo 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.
}
Como 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 desnecessário 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 a guia, a faixa de vídeo é instanciada como uma BrowserCaptureMediaStreamTrack
, que é uma subclasse de MediaStreamTrack
. Essa subclasse expõe cropTo()
. Chame track.cropTo(cropTarget)
para começar a cortar nos contornos de mainContentArea
(o elemento de onde cropTarget foi derivado).
Se for bem-sucedida, a promessa será resolvida quando for possível garantir que todos os frames de vídeo subsequentes consistam nos pixels que se enquadram na caixa delimitadora da mainContentArea
.
Se não for bem-sucedida, a promessa será rejeitada. Isso vai acontecer se:
- O
CropTarget
foi criado em outra guia. Por enquanto, aguarde. - O
CropTarget
foi derivado de um elemento que não existe mais. - A música tem clonagens. Consulte o problema 1509418.
- A faixa atual não é uma faixa de vídeo de autocaptura. Confira abaixo.
O método cropTo()
é exposto em qualquer faixa de vídeo de captura de guias, não apenas para captura própria. 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 reverter para o estado não cortado, chame cropTo()
com null
.
// Stop cropping.
await track.cropTo(null);
Conteúdo obstruído e obstruído
Para a captura de região, somente a posição e o tamanho do destino são importantes, e não o z-index. Os pixels que ocultam o alvo serão capturados. As partes obstruídas do alvo não serão capturadas.
Isso é resultado da captura de região, que é basicamente corte. Uma alternativa, que será a própria API futura, é a captura no nível do elemento, ou seja, capturar apenas os pixels associados ao destino, independentemente das obstruções. Essa API tem um conjunto diferente de requisitos de segurança e privacidade em comparação com o corte simples.
Segurança e privacidade
A captura de região permite que um app da Web que já observa todos os pixels na guia remova alguns deles voluntariamente. Ele é claramente seguro, já que nenhuma nova informação pode ser obtida.
A captura de região pode ser usada para limitar quais informações são enviadas aos participantes remotos. Por exemplo, talvez você queira compartilhar alguns slides, mas não suas anotações do apresentador.
Localmente, o recurso de captura de região não oferece garantias de segurança. Ao transferir uma faixa para outro documento, o documento receptor ainda pode desencerrar a faixa e ter acesso a todos os pixels da guia capturada.
O Chrome mostra uma borda azul ao redor das bordas 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 no Glitch. Não se esqueça de consultar o código-fonte.
Suporte ao navegador
Compatibilidade com navegadores
A captura de região está disponível no Chrome 104 apenas em computadores.
A seguir
Veja uma prévia do que vai melhorar o compartilhamento de tela na Web em um futuro próximo:
- A captura de região é compatível com capturas de outras guias.
- O foco condicional permite que o app da Web 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 sua experiência com a captura de região.
Conte-nos sobre o design
Há algo na captura de região que não funciona como esperado? Ou há métodos ou propriedades que faltam para implementar sua ideia? Tem alguma dúvida 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.
Tem 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. O Glitch é ótimo para compartilhar reprosagens rápidas e fáceis.
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 como é essencial oferecer suporte a eles.
Envie um tweet para @ChromiumDev e diga onde e como você está usando.
Links úteis
Agradecimentos
Agradecemos a Joe Medley por revisar este artigo.