Cómo controlar el desplazamiento lateral, la inclinación y el zoom de la cámara

Por fin, se pueden controlar las funciones de desplazamiento lateral, inclinación y zoom de las cámaras en la Web.

François Beaufort
François Beaufort

Las soluciones de videoconferencias a escala de la sala implementan cámaras con funciones de panorámica, inclinación y zoom (PTZ) para que el software pueda apuntar la cámara a los participantes de la reunión. A partir de Chrome 87, las funciones de panorámica, inclinación y zoom de las cámaras están disponibles para los sitios web que usan restricciones de seguimiento de medios en MediaDevices.getUserMedia() y MediaStreamTrack.applyConstraints().

Usa la API

Detección de características

La detección de funciones para el hardware es diferente de lo que probablemente conoces. La presencia de los nombres de restricciones "pan", "tilt" y "zoom" en navigator.mediaDevices.getSupportedConstraints() indica que el navegador admite la API para controlar la PTZ de la cámara, pero no si el hardware de la cámara la admite. A partir de Chrome 87, se admite el control de PTZ de la cámara en computadoras, mientras que Android sigue admitiendo solo el zoom.

const supports = navigator.mediaDevices.getSupportedConstraints();
if (supports.pan && supports.tilt && supports.zoom) {
  // Browser supports camera PTZ.
}

Solicita acceso PTZ a la cámara

Un sitio web solo puede controlar la cámara PTZ si el usuario otorgó explícitamente el permiso de la cámara con PTZ a través de un mensaje.

Para solicitar acceso PTZ a la cámara, llama a navigator.mediaDevices.getUserMedia() con las restricciones de PTZ, como se muestra a continuación. Esto le solicitará al usuario que otorgue permisos de cámara normales y de cámara con PTZ.

Captura de pantalla de un mensaje del usuario de PTZ de la cámara en Chrome para macOS.
Mensaje del usuario de PTZ de la cámara.

La promesa devuelta se resolverá con un objeto MediaStream que se usa para mostrarle al usuario la transmisión de video de la cámara. Si la cámara no admite PTZ, el usuario recibirá un mensaje de cámara normal.

try {
  // User is prompted to grant both camera and PTZ access in a single call.
  // If camera doesn't support PTZ, it falls back to a regular camera prompt.
  const stream = await navigator.mediaDevices.getUserMedia({
    // Website asks to control camera PTZ as well without altering the
    // current pan, tilt, and zoom settings.
    video: { pan: true, tilt: true, zoom: true }
  });

  // Show camera video stream to user.
  document.querySelector("video").srcObject = stream;
} catch (error) {
  // User denies prompt or matching media is not available.
  console.log(error);
}

Un permiso de cámara otorgado previamente, específicamente uno sin acceso a PTZ, no obtiene automáticamente acceso a PTZ si este se vuelve disponible. Esto es así incluso cuando la cámara admite PTZ. Se debe volver a solicitar el permiso. Afortunadamente, puedes usar la API de Permissions para consultar y supervisar el estado del permiso de PTZ.

try {
  const panTiltZoomPermissionStatus = await navigator.permissions.query({
    name: "camera",
    panTiltZoom: true
  });

  if (panTiltZoomPermissionStatus.state == "granted") {
    // User has granted access to the website to control camera PTZ.
  }

  panTiltZoomPermissionStatus.addEventListener("change", () => {
    // User has changed PTZ permission status.
  });
} catch (error) {
  console.log(error);
}

Para saber si un navegador basado en Chromium admite PTZ para una cámara, ve a la página interna about://media-internals y consulta la columna "Pan-Tilt-Zoom" en la pestaña "Video Capture". "Pan Tilt" y "Zoom" significan, respectivamente, que la cámara admite los controles de UVC "PanTilt (Absolute)" y "Zoom (Absolute)". Los controles UVC "PanTilt (Relative)" y "Zoom (Relative)" no son compatibles con los navegadores basados en Chromium.

Captura de pantalla de la página interna en ChromeOS para depurar la compatibilidad con la cámara PTZ.
Página interna para depurar la compatibilidad con cámaras PTZ.

Controlar la PTZ de la cámara

Manipula la configuración y las capacidades de la cámara PTZ con la vista previa MediaStreamTrack del objeto stream que obtuviste antes. MediaStreamTrack.getCapabilities() devuelve un diccionario con las capacidades admitidas y los rangos o valores permitidos. Del mismo modo, MediaStreamTrack.getSettings() devuelve la configuración actual.

Las capacidades y la configuración de desplazamiento horizontal, vertical y zoom solo están disponibles si la cámara las admite y el usuario le otorgó permiso de PTZ.

Cómo controlar la PTZ de la cámara.

Llama a videoTrack.applyConstraints() con las restricciones avanzadas de PTZ adecuadas para controlar la panorámica, la inclinación y el zoom de la cámara, como se muestra en el siguiente ejemplo. La promesa devuelta se resolverá si la operación se realiza correctamente. De lo contrario, se rechazará si se cumple alguna de las siguientes condiciones:

  • No se otorgó el permiso de PTZ a la cámara.
  • El hardware de la cámara no admite la restricción de PTZ.
  • El usuario no puede ver la página. Usa la API de Page Visibility para detectar cambios en la visibilidad de la página.
// Get video track capabilities and settings.
const [videoTrack] = stream.getVideoTracks();
const capabilities = videoTrack.getCapabilities();
const settings = videoTrack.getSettings();

// Let the user control the camera pan motion if the camera supports it
// and PTZ access is granted.
if ("pan" in settings) {
  const input = document.querySelector("input[type=range]");
  input.min = capabilities.pan.min;
  input.max = capabilities.pan.max;
  input.step = capabilities.pan.step;
  input.value = settings.pan;

  input.addEventListener("input", async () => {
    await videoTrack.applyConstraints({ advanced: [{ pan: input.value }] });
  });
}

if ("tilt" in settings) {
  // similar for tilt...
}
if ("zoom" in settings) {
  // similar for zoom...
}

También es posible configurar el desplazamiento lateral, la inclinación y el zoom de la cámara llamando a navigator.mediaDevices.getUserMedia() con algunos valores ideales de restricción de PTZ de la cámara. Esto es útil cuando las capacidades de PTZ de la cámara se conocen de antemano. Ten en cuenta que aquí no se permiten las restricciones obligatorias (mín., máx., exacto).

const stream = await navigator.mediaDevices.getUserMedia({
  // Website asks to reset known camera pan.
  video: { pan: 0, deviceId: { exact: "myCameraDeviceId" } }
});

Área de juegos

Puedes probar la API ejecutando la demostración.

Consideraciones de seguridad

Los autores de las especificaciones diseñaron e implementaron esta API con el núcleo, que incluye el control del usuario, la transparencia y la ergonomía. La capacidad de usar esta API se limita principalmente con el mismo modelo de permisos que la API de Media Capture and Streams. En respuesta a una instrucción del usuario, el sitio web puede controlar la PTZ de la cámara solo cuando la página es visible para el usuario.

Compatibilidad del navegador

API de MediaStream

Browser Support

  • Chrome: 55.
  • Edge: 12.
  • Firefox: 15.
  • Safari: 11.

Source

API de Permissions

Browser Support

  • Chrome: 43.
  • Edge: 79.
  • Firefox: 46.
  • Safari: 16.

Source

API de Page Visibility

Browser Support

  • Chrome: 33.
  • Edge: 12.
  • Firefox: 18.
  • Safari: 7.

Source

MediaDevices.getUserMedia()

Browser Support

  • Chrome: 53.
  • Edge: 12.
  • Firefox: 36.
  • Safari: 11.

Source

MediaDevices.getSupportedConstraints()

Browser Support

  • Chrome: 53.
  • Edge: 12.
  • Firefox: 44.
  • Safari: 11.

Source

MediaStreamTrack.applyConstraints()

Browser Support

  • Chrome: 59.
  • Edge: 12.
  • Firefox: 43.
  • Safari: 11.

Source

MediaStreamTrack.getCapabilities()

Browser Support

  • Chrome: 59.
  • Edge: 12.
  • Firefox: 132.
  • Safari: 11.

Source

MediaStreamTrack.getSettings()

Browser Support

  • Chrome: 59.
  • Edge: 12.
  • Firefox: 50.
  • Safari: 11.

Source

Vínculos útiles

Agradecimientos

Joe Medley y Thomas Steiner revisaron este artículo. Gracias a Rijubrata Bhaumik y Eero Häkkinen de Intel por su trabajo en la especificación y la implementación. Imagen hero de Christina @ wocintechchat.com en Unsplash.