Управление панорамированием, наклоном и масштабированием вебкамеры

Решения для видеоконференцсвязи предполагают применение видеокамер с функциями панорамирования (pan), наклона (tilt) и масштабирования (zoom) — PTZ, чтобы программное обеспечение могло направлять камеру на участников собрания. Начиная с Chrome 87, функции панорамирования, наклона и масштабирования для видеокамер стали доступны для веб-сайтов при использовании медиа-ограничений MediaDevices.getUserMedia() и MediaStreamTrack.applyConstraints().

Использование API

Обнаружение методов

Обнаружение функций для оборудования может отличаться от привычного способа. Наличие названий ограничений pan, tilt и zoom в navigator.mediaDevices.getSupportedConstraints() сообщает, что браузер поддерживает API для управления PTZ камеры, но не говорит о том, поддерживает ли его оборудование видеокамеры.

const supports = navigator.mediaDevices.getSupportedConstraints();
if (supports.pan && supports.tilt && supports.zoom) {
  // Браузер поддерживает PTZ для видеокамеры.
}

Запрос доступа к PTZ видеокамеры

Веб-сайту может быть разрешено управлять PTZ видеокамеры только в том случае, если пользователь явно предоставил такое разрешение в ответ на запрос.

Чтобы запросить доступ к PTZ камеры, надо вызвать метод navigator.mediaDevices.getUserMedia() с ограничениями PTZ, как показано ниже. Это будет запросом для пользователя предоставить разрешения для доступа видеокамере и PTZ (даже если камера не умеет).

Запрос разрешений для доступа к видеокамере и PTZ
Запрос разрешений для доступа к видеокамере и PTZ

Метод возвращает обещание (promise), которое разрешается объектом MediaStream, используемым для отображения пользователю видеопотока с камеры. Если видеокамера не поддерживает PTZ, пользователь получит обычный запрос для доступа к камере.

try {
  // Одним вызовом пользователю предлагается предоставить доступ к видеокамере и PTZ.
  // Если камера не поддерживает PTZ, вернётся запрос разрешений для обычной видеокамеры.
  const stream = await navigator.mediaDevices.getUserMedia({
    // Веб-сайт запрашивает доступ к PTZ камеры без изменения
    // существующих настроек pan, tilt и zoom.
    video: { pan: true, tilt: true, zoom: true }
  });

  // Показывать пользователю видеопоток с камеры.
  document.querySelector("video").srcObject = stream;
} catch (error) {
  // Если пользователь отклонит запрос или носитель недоступен.
  console.log(error);
}

Ранее предоставленное разрешение использования видеокамеры, в частности, без доступа к PTZ, не получает автоматически доступ к PTZ, если он становится доступным. Это верно даже тогда, когда сама камера поддерживает PTZ. Необходимо повторно запросить разрешение. Для запроса и отслеживания статуса разрешения PTZ можно использовать Permissions API.

try {
  const panTiltZoomPermissionStatus = await navigator.permissions.query({
    name: "camera",
    panTiltZoom: true
  });

  if (panTiltZoomPermissionStatus.state == "granted") {
    // Пользователь предоставил веб-сайту доступ к управлению PTZ камеры.
  }

  panTiltZoomPermissionStatus.addEventListener("change", () => {
    // Пользователь изменил состояние разрешения для PTZ.
  });
} catch (error) {
  console.log(error);
}

Чтобы узнать, поддерживает ли браузер на основе Chromium PTZ для видеокамеры, можно перейти на встроенную страницу about://media-internals и проверить столбец «Pan-Tilt-Zoom» во вкладке «Video Capture». pan, tilt и zoom соответственно означают, что камера поддерживает элементы управления UVC «PanTilt (Absolute)» и «Zoom (Absolute)». В браузерах на основе Chromium не поддерживаются элементы управления UVC «PanTilt (Relative)» и «Zoom (Relative)».

Внутренняя страница для проверки поддержки камеры PTZ
Внутренняя страница для проверки поддержки камеры PTZ

Примечание: страница about://media-internals будет удалена в Chrome 91. Вместо неё следует использовать панель «Media» в инструментах разработчика.

Управление PTZ видеокамеры

Управляйте возможностями и настройками PTZ видеокамеры с помощью предпросмотра MediaStreamTrack из полученного ранее объекта stream. Метод MediaStreamTrack.getCapabilities() возвращает справочник поддерживаемых возможностей и диапазонов или допустимых значений. Соответственно, MediaStreamTrack.getSettings() возвращает текущие настройки.

Изменение настроек панорамирования, наклона и масштабирования доступно только в том случае, если они поддерживаются видеокамерой и пользователь предоставил разрешение для доступа к управлению PTZ камеры.

Управление PTZ видеокамеры.

Вызовите videoTrack.applyConstraints() с учётом соответствующих ограничений PTZ для управления панорамированием, наклоном и масштабированием камеры, как показано в примере ниже. Возвращаемое обещание (promise) разрешится в случае успеха. В противном случае оно будет отклонено, если:

  • камера с разрешениями PTZ отсутствует
  • оборудование камеры не поддерживает разрешения PTZ
  • страница не видна пользователю, тогда надо использовать Page Visibility API для обнаружения изменений состояния видимости страницы.
// Получение возможностей и настроек видеодорожки
const [videoTrack] = stream.getVideoTracks();
const capabilities = videoTrack.getCapabilities();
const settings = videoTrack.getSettings();

// Позволить пользователю управлять панорамированием камеры,
// если камера это поддерживает
// и доступ к PTZ был разрешён.
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) {
  // то же самое для tilt...
}
if ("zoom" in settings) {
  // то же самое для zoom...
}

Песочница

See this code PTZ on x.xhtml.ru.

Если к компьютеру не подключена камера с поддержкой PTZ, для симуляции видеокамеры можно запустить Chrome с переключателем --use-fake-device-for-media-stream.

Соображения безопасности

Авторы спецификации разработали и реализовали этот API, включая контроль пользователем, прозрачность и эргономику. Реализация использования этого API в основном обеспечивается той же моделью разрешений, что и Media Capture и Streams API. После запроса и получения разрешений у пользователя, веб-сайту разрешено управлять PTZ камеры только тогда, когда страница видна пользователю.