相機的平移、傾斜和縮放功能終於可以在網路上控制。
大規模視訊會議解決方案會部署具備平移、傾斜和縮放 (PTZ) 功能的攝影機,讓軟體將攝影機鏡頭對準會議參與者。自 Chrome 87 版起,凡是使用 MediaDevices.getUserMedia()
和 MediaStreamTrack.applyConstraints()
中媒體追蹤限制的網站,都可以使用相機的平移、傾斜和縮放功能。
使用 API
功能偵測
硬體的功能偵測與您可能習慣的功能不同。navigator.mediaDevices.getSupportedConstraints()
中存在 "pan"
、"tilt"
和 "zoom"
限制名稱,就代表瀏覽器支援 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。
如要要求相機 PTZ 存取權,請呼叫 navigator.mediaDevices.getUserMedia()
並指定 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 也是如此。必須再次要求該權限。幸好,您可以使用 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
頁面,查看「影片擷取」分頁中的「平移、傾斜和縮放」欄位;「平移傾斜」和「縮放」代表相機支援「PanTilt (絕對值)」和「縮放 (絕對值)」。以 Chromium 為基礎的瀏覽器不支援「PanTilt (Relative)」和「Zoom (Relative)」 UVC 控制項。
控制攝影機 PTZ
透過先前取得的 stream
物件中的預覽 MediaStreamTrack
,操作相機 PTZ 功能和設定。MediaStreamTrack.getCapabilities()
會傳回字典,其中包含支援的功能以及範圍或允許的值。因此,MediaStreamTrack.getSettings()
會傳回目前的設定。
只有在相機支援平移、傾斜和縮放功能,且使用者授予相機權限時,才能使用平移、傾斜和縮放功能與設定。
使用適當的 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
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 上提供。