摄像头的平移、倾斜和缩放功能终于可以在网页上控制了。
会议室级视频会议解决方案部署了具有平移、倾斜和缩放 (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 访问权限,请调用 navigator.mediaDevices.getUserMedia()
并提供 PTZ 约束条件,如下所示。这将提示用户同时向普通摄像头和具有 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 访问权限。即使摄像头本身支持 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
页面,然后查看“视频捕获”标签页中的“Pan-Tilt-Zoom”(平移-倾斜-缩放)列;“Pan-Tilt”(平移-倾斜)和“Zoom”(缩放)分别表示摄像头支持“PanTilt(绝对值)”和“Zoom(绝对值)”UVC 控件。基于 Chromium 的浏览器不支持“PanTilt(相对)”和“Zoom(相对)”UVC 控件。
控制摄像头云台
使用之前获取的 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" } }
});
游乐场
您可以在 Glitch 上运行演示版,试用此 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 在规范和实现方面的工作。 主打图片由 Unsplash 用户 Christina @ wocintechchat.com 提供。