通过网络,最终可以控制摄像头上的平移、倾斜和缩放功能。
会议室级视频会议解决方案部署具有平移、倾斜和缩放 (PTZ) 功能的摄像头,以便软件可以将摄像头对准会议参与者。从 Chrome 87 开始,使用 MediaDevices.getUserMedia()
和 MediaStreamTrack.applyConstraints()
中的媒体跟踪限制的网站可以使用相机上的平移、倾斜和缩放功能。
使用 API
功能检测
硬件功能检测与您通常熟悉的功能不同。如果 navigator.mediaDevices.getSupportedConstraints()
中存在 "pan"
、"tilt"
和 "zoom"
约束条件名称,则表明浏览器支持使用 API 来控制摄像头 PTZ,但不支持摄像头硬件是否支持该 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
页面,查看“视频拍摄”标签页中的“平移倾斜式缩放”列;“平移倾斜度”和“缩放”分别表示摄像头支持“平移倾斜度(绝对值)”和“缩放(绝对值)”。基于 Chromium 的浏览器不支持“PanTilt(相对)”和“缩放(相对)”UVC 控件。
控制摄像头 PTZ
使用之前获得的 stream
对象中的预览 MediaStreamTrack
操控相机 PTZ 功能和设置。MediaStreamTrack.getCapabilities()
会返回一个包含支持的功能和范围或允许值的字典。相应地,MediaStreamTrack.getSettings()
会返回当前设置。
仅当相机支持且用户已向相机授予 PTZ 权限时,平移、倾斜和缩放功能和设置才可用。
调用 videoTrack.applyConstraints()
并提供适当的 PTZ 高级约束条件来控制相机平移、倾斜度和缩放,如以下示例所示。如果成功,返回的 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
网页可见性 API
MediaDevices.getUserMedia()
MediaDevices.getSupportedConstraints()
MediaStreamTrack.applyConstraints()
MediaStreamTrack.getCapabilities()
MediaStreamTrack.getSettings()
实用链接
致谢
本文由 Joe Medley 和 Thomas Steiner 审核。 感谢 Intel 的 Rijubrata Bhaumik 和 Eero Häkkinen 在规范和实现方面所做的工作。 主打图片由 Christina @ wocintechchat.com 在 Unsplash 用户发布。