控制相机平移、倾斜度和缩放

摄像头的平移、倾斜和缩放功能终于可以在网页上控制了。

François Beaufort
François Beaufort

会议室级视频会议解决方案部署了具有平移、倾斜和缩放功能的摄像头 (PTZ) 功能,以便软件将摄像头对准会议 参与者。从 Chrome 87 开始,Chrome 中的平移、倾斜和缩放功能 使用媒体跟踪限制条件的网站可以使用相机 MediaDevices.getUserMedia()MediaStreamTrack.applyConstraints()

使用 API

功能检测

针对硬件的功能检测与您所习惯的检测不同。 以下位置中存在 "pan""tilt""zoom" 限制条件名称: navigator.mediaDevices.getSupportedConstraints()表示浏览器 支持 API 控制摄像头 PTZ,但不支持摄像头硬件 支持它。自 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(): 如下所示。这将提示用户授予 普通摄像头和具有云台拍摄权限的摄像头。

macOS 版 Chrome 中的摄像头云台用户提示屏幕截图。
摄像头云平台用户提示。

返回的 promise 将使用 MediaStream 对象进行解析,该对象用于显示 将摄像头视频串流传送给用户如果摄像头不支持云台摄像头,则用户 将收到常规的相机提示。

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 访问权限。这是事实 (即使相机本身支持云台摄像头)。必须请求该权限 。幸运的是,您可以使用 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”列 点击“视频捕获”标签页;“平移倾斜”和“缩放”分别表示相机支持 “PanTilt(绝对)”和“缩放(绝对)”UVC 控件。“平移倾斜(相对)” 和“缩放(相对)”基于 Chromium 的浏览器不支持 UVC 控件。

ChromeOS 中用于调试 PTZ 摄像头支持的内部页面的屏幕截图。
用于调试 PTZ 摄像头支持的内部页面。

控制摄像头云台摄像头

使用预览版操控摄像头 PTZ 的功能和设置 MediaStreamTrack(从之前获取的 stream 对象中获取)。 MediaStreamTrack.getCapabilities() 会返回一个字典,其中包含受支持的 功能以及范围或允许的值。相应地 MediaStreamTrack.getSettings() 会返回当前设置。

平移、倾斜和缩放功能与设置只有在 且用户已授予摄像头的 PTZ 权限。

<ph type="x-smartling-placeholder">
控制摄像头云台。

使用相应的 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 主要受与媒体捕获和 Streams API。为了响应用户提示,网站可以控制 摄像头云台镜头。

浏览器兼容性

MediaStream API

浏览器支持

  • 55
  • 12
  • 15
  • 11

来源

Permissions API

浏览器支持

  • 43
  • 79
  • 46
  • 16

来源

页面可见性 API

浏览器支持

  • 33
  • 12
  • 18
  • 7

来源

MediaDevices.getUserMedia()

浏览器支持

  • 53
  • 12
  • 36
  • 11

来源

MediaDevices.getSupportedConstraints()

浏览器支持

  • 53
  • 12
  • 44
  • 11

来源

MediaStreamTrack.applyConstraints()

浏览器支持

  • 59
  • 12
  • 43
  • 11

来源

MediaStreamTrack.getCapabilities()

浏览器支持

  • 59
  • 12
  • x
  • 11

来源

MediaStreamTrack.getSettings()

浏览器支持

  • 59
  • 12
  • 50
  • 11

来源

实用链接

致谢

本文由 Joe MedleyThomas Steiner 审核。 感谢 Intel 的 Rijubrata BhaumikEero Häkkinen 在 和实现 主打图片提供方:Christina @ wocintechchat.com,在 Unsplash 网站上。