Uso compartido mejorado de las pestañas con Captura de región

François Beaufort
François Beaufort

La plataforma web ya permite que una app web capture un recorrido en video de la pestaña actual. Ahora se incluye en Region Capture, un mecanismo para recortar estas pistas de video. La app web designa una parte de la pestaña actual como su área de interés, y el navegador recorta todos los píxeles fuera de esa área.

Anteriormente, las apps web podían recortar pistas de video "de forma manual". Es decir, podían manipular cada fotograma directamente. No era ni sólido ni eficiente. Region Capture resuelve estas deficiencias. Ahora, la app web puede indicar al navegador que haga el trabajo en su nombre.

Información acerca de la captura de regiones

Creaste un sitio web con Contenido dinámico™. Es la mejor app web que existe, y las personas no pueden dejar de usarla, a menudo de forma colaborativa. Un posible paso a seguir es incorporar capacidades de conferencias virtuales. Entonces, decides hacerlo. Te asocias con un proveedor de servicios de videoconferencia existente y, luego, incorporas su app web como un iframe de origen cruzado. La app web de videoconferencia captura la pestaña actual como una pista de video y la transmite a los participantes remotos.

Captura de pantalla de una ventana del navegador con una app web que destaca el área de contenido principal y el iframe de varios orígenes.
El área de contenido principal está en azul y el iframe de varios orígenes está en rojo.

No tan rápido... No quieres transmitirles los videos de las personas, ¿verdad? Será mejor que recortes esa parte. Pero ¿cómo? El iframe incorporado no sabe qué contenido expones ni dónde, por lo que no puede recortarlo sin ayuda. En teoría, podrías pasar las coordenadas deseadas. Pero, ¿qué sucede si el usuario cambia el tamaño de la ventana? ¿Desplaza la ventana de visualización? ¿Se acerca o se aleja? ¿Interactúa con la página de una manera que produce un cambio de diseño? Incluso si envías las coordenadas nuevas al iframe de captura, los problemas de sincronización podrían generar algunos fotogramas recortados de forma incorrecta.

Entonces, usemos la Captura parcial de pantalla. Hay un Element en tu página, tal vez un <div>, que contiene el contenido principal. Llamemos a esta función mainContentArea. Quieres que la app web de videoconferencias capture y comparta de forma remota el área definida por el cuadro de límite de este elemento. Por lo tanto, obtienes un CropTarget de mainContentArea. Pasa este CropTarget a la app web de videoconferencias. Después de recortar la pista de video con este CropTarget, los fotogramas de esa pista ahora consisten solo en los píxeles que se encuentran dentro del cuadro delimitador de mainContentArea. Si mainContentArea cambia de tamaño, forma o ubicación, la pista de video sigue el proceso, sin necesidad de ninguna entrada adicional de ninguna de las apps web.

Repasemos estos pasos:

Para definir un CropTarget en tu app web, debes llamar a CropTarget.fromElement() con el elemento que elijas como entrada.

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

Pasas el CropTarget a la app web de videoconferencias.

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

La app web de videoconferencia le pide al navegador que recorte la pista en el área definida por CropTarget llamando a cropTo() en la pista de video de autocaptura con el objetivo de recorte recibido de la app 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.

¡Y listo! Ya terminaste.

Análisis detallado

Detección de atributos

Para verificar si CropTarget.fromElement() es compatible, usa lo siguiente:

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

Derivación de un CropTarget

Enfoquémonos en el elemento llamado mainContentArea. Para derivar un CropTarget de él, llama a CropTarget.fromElement(mainContentArea). Si se realiza correctamente, la promesa que se devuelve se resolverá con un nuevo objeto CropTarget. De lo contrario, se rechazará si creaste una cantidad irrazonable de objetos CropTarget.

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

A diferencia de Element, un objeto CropTarget es serializable. Por ejemplo, se puede pasar a otro documento con Window.postMessage().

Recortes

Cuando se captura la pestaña, se crea una instancia de la pista de video como BrowserCaptureMediaStreamTrack, que es una subclase de MediaStreamTrack. Esa subclase expone cropTo(). Llama a track.cropTo(cropTarget) para comenzar a recortar a los contornos de mainContentArea (el elemento del que se derivó recorteTarget).

Si se realiza correctamente, la promesa se resolverá cuando se pueda garantizar que todos los fotogramas de video posteriores consistirán en los píxeles que se encuentran dentro del cuadro de límite de mainContentArea.

De lo contrario, se rechazará la promesa. Esto sucederá en los siguientes casos:

  • El CropTarget se acuñó en otra pestaña. (Por ahora, no te pierdas las novedades).
  • El CropTarget se derivó de un elemento que ya no existe.
  • La pista tiene clones. (Consulta el problema 1509418).
  • La pista actual no es una pista de video de captura automática; consulta a continuación.

El método cropTo() se expone en cualquier pista de video de captura de pestañas, no solo para la captura automática. Por lo tanto, se recomienda verificar si el usuario seleccionó la pestaña actual antes de intentar recortar la pista. Esto se puede lograr con el control de captura. También es posible solicitarle al navegador que guíe al usuario para que tome su foto con preferCurrentTab.

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

Para volver al estado sin recortar, llama a cropTo() con null.

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

Contenido ocluyente y ocluido

En el caso de la Captura de región, solo importan la posición y el tamaño del objetivo, no el índice z. Se capturarán los píxeles que oculten el objetivo. No se capturarán las partes ocultas del objetivo.

Esto es una consecuencia de que la Captura de regiones es, en esencia, un recorte. Una alternativa, que será su propia API en el futuro, es la captura a nivel del elemento, es decir, capturar solo los píxeles asociados con el objetivo, independientemente de las oclusiones. Esta API tiene un conjunto de requisitos de seguridad y privacidad diferente al del simple recorte.

Imagen de diferentes resultados de la API de Captura de regiones y Captura a nivel del elemento.
Comportamiento de la Captura de regiones con contenido ocluyente.

Seguridad y privacidad

La Captura de regiones permite que una app web que ya observa todos los píxeles de la pestaña quite voluntariamente algunos de ellos. Es evidentemente seguro, ya que no se puede obtener información nueva.

La Captura de región se puede usar para limitar la información que se envía a los participantes remotos. Por ejemplo, tal vez quieras compartir algunas diapositivas, pero no tus notas del orador.

Captura de pantalla de una ventana del navegador que contiene diapositivas y notas del orador.
Una app web que contiene diapositivas y notas del orador.
No es recomendable compartir las notas de forma remota. Captura de región de indicaciones

Ten en cuenta que, de forma local, la Captura de región no agrega ninguna garantía de seguridad. Cuando se pasa una pista a otro documento, este puede desrecortar la pista y obtener acceso a todos los píxeles de la pestaña capturada.

Chrome dibuja un borde azul alrededor de los bordes de las pestañas capturadas. Cuando se recorta, Chrome suele dibujar el borde azul alrededor del objetivo recortado.

Demostración

Para jugar con Region Capture, ejecuta la demostración en Glitch. Asegúrate de consultar el código fuente.

Navegadores compatibles

Navegadores compatibles

  • Chrome: 104.
  • Edge: 104.
  • Firefox: No es compatible.
  • Safari: No se admite.

La Captura de región solo está disponible a partir de Chrome 104 en computadoras.

¿Qué sigue?

Aquí tienes un adelanto de lo que puedes esperar en un futuro cercano para mejorar la función de compartir pantalla en la Web:

  • La Captura de región admitirá capturas de otras pestañas.
  • El enfoque condicional permitirá que la app web de captura le indique al navegador que cambie el enfoque a la superficie de visualización capturada o que evite ese cambio.
  • Es posible que se proporcione una API de captura de nivel de elemento.

Comentarios

El equipo de Chrome y la comunidad de estándares de la Web quieren saber sobre tu experiencia con Region Capture.

Cuéntanos sobre el diseño

¿Hay algo relacionado con la Captura de regiones que no funciona como esperabas? ¿O faltan métodos o propiedades que necesitas para implementar tu idea? ¿Tienes alguna pregunta o comentario sobre el modelo de seguridad?

  • Informa un problema de especificación en el repositorio de GitHub o agrega tus comentarios a un problema existente.

¿Tienes problemas con la implementación?

¿Encontraste un error en la implementación de Chrome? ¿O la implementación es diferente de la especificación?

  • Informa un error en https://new.crbug.com. Asegúrate de incluir tantos detalles como sea posible y de proporcionar instrucciones sencillas para reproducirlo. Glitch funciona muy bien para compartir repros rápidos y fáciles.

Expresar apoyo

¿Planeas usar Region Capture? Tu asistencia pública ayuda al equipo de Chrome a priorizar funciones y les muestra a otros proveedores de navegadores la importancia de brindar compatibilidad con ellas.

Envía un tuit a @ChromiumDev y cuéntanos dónde y cómo lo usas.

Agradecimientos

Gracias a Joe Medley por leer este artículo.