现在,您可以在网页上控制摄像头的平移、倾斜和缩放功能。
会议室级视频会议解决方案部署了具有平移、倾斜和缩放 (PTZ) 功能的摄像头,以便软件可以将摄像头对准会议参与者。从 Chrome 87 开始,网站可以使用 MediaDevices.getUserMedia() 和 MediaStreamTrack.applyConstraints() 中的媒体轨道限制条件来使用摄像头的平移、倾斜和缩放功能。
使用 API
功能检测
硬件的功能检测可能与您习惯的方式不同。
navigator.mediaDevices.getSupportedConstraints() 中存在 "pan"、"tilt" 和 "zoom" 限制条件名称,这表明浏览器支持用于控制摄像头 PTZ 的 API,但并不表示摄像头硬件支持该 API。从 Chrome 87 开始,桌面设备支持控制摄像头 PTZ,而 Android 仍然仅支持缩放。
const supports = navigator.mediaDevices.getSupportedConstraints();
if (supports.pan && supports.tilt && supports.zoom) {
// Browser supports camera PTZ.
}
请求摄像头 PTZ 访问权限
只有在用户通过提示明确授予摄像头 PTZ 权限后,网站才能控制摄像头 PTZ。
如需请求摄像头 PTZ 访问权限,请使用 PTZ 限制调用 navigator.mediaDevices.getUserMedia(),如下所示。这将提示用户同时授予常规摄像头权限和 PTZ 摄像头权限。
返回的 promise 会解析为 MediaStream 对象,用于向用户显示摄像头视频流。如果摄像头不支持 PTZ,用户会收到常规摄像头提示。
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);
}
如果之前授予的相机权限(特别是没有 PTZ 访问权限的相机权限)可用,则不会自动获得 PTZ 访问权限。即使摄像头本身支持 PTZ,也是如此。必须再次请求该权限。幸运的是,您可以使用 Permissions API 查询和监控 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);
}
如需了解基于 Chromium 的浏览器是否支持摄像头的 PTZ 功能,请前往内部 about://media-internals 页面,然后查看“视频拍摄”标签页中的“平移-倾斜-缩放”列;“平移倾斜”和“缩放”分别表示摄像头支持“平移倾斜(绝对)”和“缩放(绝对)”UVC 控件。
基于 Chromium 的浏览器不支持“PanTilt(相对)”和“Zoom(相对)”UVC 控件。
控制摄像头 PTZ
使用之前获取的 stream 对象中的预览 MediaStreamTrack,操控相机 PTZ 功能和设置。MediaStreamTrack.getCapabilities() 会返回一个字典,其中包含支持的功能以及范围或允许的值。相应地,MediaStreamTrack.getSettings() 会返回当前设置。
只有在摄像头支持且用户已向摄像头授予 PTZ 权限的情况下,才能使用平移、倾斜和缩放功能及设置。
使用适当的 PTZ 高级限制调用 videoTrack.applyConstraints(),以控制摄像头平移、倾斜和缩放,如示例所示。
如果成功,返回的 promise 会解析。如果出现以下任一情况,则会拒绝:
- 未授予对具有 PTZ 功能的摄像头的权限。
- 摄像头硬件不支持 PTZ 限制。
- 用户看不到该页面。使用 Page Visibility API 检测网页可见性变化。
// 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...
}
您还可以通过调用 navigator.mediaDevices.getUserMedia() 并传入一些理想的摄像头 PTZ 限制值,来配置摄像头的平移、倾斜和缩放。如果提前知道摄像头 PTZ 功能,此功能会非常有用。请注意,此处不允许使用强制性限制条件(最小值、最大值、确切值)。
const stream = await navigator.mediaDevices.getUserMedia({
// Website asks to reset known camera pan.
video: { pan: 0, deviceId: { exact: "myCameraDeviceId" } }
});
游乐场
您可以通过运行演示来体验该 API。
安全注意事项
规范作者在设计和实现此 API 时,充分考虑了用户控制、透明度和易用性等核心要素。使用此 API 的能力主要由与 Media Capture and Streams API 相同的权限模型控制。在响应用户提示时,只有当用户可以看到网页时,网站才能控制摄像头 PTZ。
浏览器兼容性
MediaStream API
Permissions API
Page Visibility API
MediaDevices.getUserMedia()
MediaDevices.getSupportedConstraints()
MediaStreamTrack.applyConstraints()
MediaStreamTrack.getCapabilities()
MediaStreamTrack.getSettings()
实用链接
致谢
本文由 Joe Medley 和 Thomas Steiner 审核。 感谢 Intel 的 Rijubrata Bhaumik 和 Eero Häkkinen 在规范和实现方面所做的工作。