控制相機的平移、傾斜和縮放功能

攝影機的平移、傾斜和縮放功能終於可在網頁上控制。

François Beaufort
François Beaufort

房間規模視訊會議解決方案會部署具備平移、傾斜和變焦 (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 存取權,請呼叫 navigator.mediaDevices.getUserMedia(),並附上 PTZ 限制條件,如下所示。這會提示使用者同時授予一般攝影機和具備 PTZ 權限的攝影機權限。

macOS 版 Chrome 中的攝影機 PTZ 使用者提示螢幕截圖。
攝影機 PTZ 使用者提示。

傳回的承諾會以 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,也一樣適用。必須再次要求權限。幸好,您可以使用權限 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 頁面,並查看「Video Capture」分頁中的「Pan-Tilt-Zoom」欄,其中「pan tilt」和「zoom」分別代表攝影機支援「PanTilt (Absolute)」和「Zoom (Absolute)」UVC 控制項。以 Chromium 為基礎的瀏覽器不支援「PanTilt (Relative)」和「Zoom (Relative)」UVC 控制項。

ChromeOS 內部頁面的螢幕截圖,用於偵錯 PTZ 攝影機支援功能。
內部頁面,用於偵錯 PTZ 攝影機支援功能。

控制攝影機 PTZ

使用先前取得的 stream 物件中的預覽 MediaStreamTrack 操控攝影機 PTZ 功能和設定。MediaStreamTrack.getCapabilities() 會傳回字典,其中包含支援的功能和範圍或允許的值。MediaStreamTrack.getSettings() 會傳回目前的設定。

只有在相機支援平移、傾斜和縮放功能,且使用者已授予相機 PTZ 權限時,才能使用這些功能和設定。

控制攝影機 PTZ。

請使用適當的 PTZ 進階限制呼叫 videoTrack.applyConstraints(),以便控制攝影機的平移、傾斜和縮放功能,如以下範例所示。如果成功,系統會解析傳回的承諾。否則,如果發生下列情況,系統就會拒絕:

  • 攝影機未授予 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

瀏覽器支援

  • Chrome:55。
  • Edge:12。
  • Firefox:15.
  • Safari:11。

資料來源

Permissions API

瀏覽器支援

  • Chrome:43。
  • Edge:79。
  • Firefox:46。
  • Safari:16 歲。

資料來源

Page Visibility API

瀏覽器支援

  • Chrome:33。
  • Edge:12。
  • Firefox:18 歲。
  • Safari:7.

資料來源

MediaDevices.getUserMedia()

瀏覽器支援

  • Chrome:53。
  • Edge:12。
  • Firefox:36.
  • Safari:11。

資料來源

MediaDevices.getSupportedConstraints()

瀏覽器支援

  • Chrome:53。
  • Edge:12。
  • Firefox:44。
  • Safari:11。

資料來源

MediaStreamTrack.applyConstraints()

瀏覽器支援

  • Chrome:59。
  • Edge:12。
  • Firefox:43。
  • Safari:11。

資料來源

MediaStreamTrack.getCapabilities()

瀏覽器支援

  • Chrome:59。
  • Edge:12。
  • Firefox:132。
  • Safari:11。

資料來源

MediaStreamTrack.getSettings()

瀏覽器支援

  • Chrome:59。
  • Edge:12。
  • Firefox:50。
  • Safari:11。

資料來源

實用連結

特別銘謝

本文由 Joe MedleyThomas Steiner 審查。感謝 Intel 的 Rijubrata BhaumikEero Häkkinen 在規格和實作方面付出的努力。主頁橫幅圖片由 Christina @ wocintechchat.com 提供,圖片來源:Unsplash