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

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

François Beaufort
François Beaufort

會議室規模的視訊會議解決方案會部署具備平移、傾斜和變焦 (PTZ) 功能的攝影機,讓軟體將攝影機對準會議參與者。自 Chrome 87 版起,網站可透過 MediaDevices.getUserMedia()MediaStreamTrack.applyConstraints() 中的媒體軌限制,使用攝影機的平移、傾斜和變焦功能。

使用 API

特徵偵測

硬體的功能偵測方式與您習慣的方式可能不同。 如果 "pan""tilt""zoom" 限制名稱出現在 navigator.mediaDevices.getSupportedConstraints() 中,表示瀏覽器支援用來控制攝影機 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 存取權,請呼叫 navigator.mediaDevices.getUserMedia(),並設定 PTZ 限制,如下所示。系統會提示使用者授予一般攝影機和具備 PTZ 功能攝影機的權限。

macOS 版 Chrome 中的攝影機 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 也是如此。您必須再次要求權限。幸好,您可以使用 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 頁面,然後查看「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(),即可控制攝影機的平移、傾斜和變焦功能,如下例所示。 如果成功,傳回的 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 的權限主要與媒體擷取和串流 API 相同。回應使用者提示後,網站只能在使用者看到頁面時控制攝影機 PTZ。

瀏覽器相容性

MediaStream API

Browser Support

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

Source

Permissions API

Browser Support

  • Chrome: 43.
  • Edge: 79.
  • Firefox: 46.
  • Safari: 16.

Source

Page Visibility API

Browser Support

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

Source

MediaDevices.getUserMedia()

Browser Support

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

Source

MediaDevices.getSupportedConstraints()

Browser Support

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

Source

MediaStreamTrack.applyConstraints()

Browser Support

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

Source

MediaStreamTrack.getCapabilities()

Browser Support

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

Source

MediaStreamTrack.getSettings()

Browser Support

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

Source

實用連結

特別銘謝

本文由 Joe MedleyThomas Steiner 審查。 感謝 Intel 的 Rijubrata BhaumikEero Häkkinen 參與規格制定和實作。主頁橫幅圖片來源:Christina @ wocintechchat.com,發表於 Unsplash