Por fin, se pueden controlar las funciones de desplazamiento lateral, inclinación y zoom de las cámaras en la Web.
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.

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.

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.
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
API de Permissions
API de Page Visibility
MediaDevices.getUserMedia()
MediaDevices.getSupportedConstraints()
MediaStreamTrack.applyConstraints()
MediaStreamTrack.getCapabilities()
MediaStreamTrack.getSettings()
Vínculos útiles
- Explicación de PTZ
- Borrador de especificaciones
- Repositorio de GitHub
- Entrada de ChromeStatus
- Error de seguimiento de Chrome
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.