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

Функции панорамирования, наклона и масштабирования на камерах наконец-то можно контролировать через Интернет.

Франсуа Бофор
François Beaufort

В решениях для видеоконференций в масштабе помещения используются камеры с возможностями панорамирования, наклона и масштабирования (PTZ), чтобы программное обеспечение могло направлять камеру на участников собрания. Начиная с Chrome 87, функции панорамирования, наклона и масштабирования на камерах доступны веб-сайтам, использующим ограничения трека мультимедиа в 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 через запрос.

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

Снимок экрана: приглашение пользователя PTZ-камеры в Chrome для macOS.
Подсказка пользователя камеры 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. Разрешение необходимо запросить повторно. К счастью, вы можете использовать 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 и проверьте столбец «Панорамирование-Наклон-Масштаб» на вкладке «Захват видео»; «Панорамирование, наклон» и «зум» соответственно означают, что камера поддерживает элементы управления UVC «Панорамирование (абсолютное)» и «Масштаб (абсолютное)». Элементы управления UVC «PanTilt (Relative)» и «Zoom (Relative)» не поддерживаются в браузерах на базе Chromium.

Скриншот внутренней страницы ChromeOS для отладки поддержки PTZ-камеры.
Внутренняя страница для отладки поддержки PTZ-камеры.

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

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

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

Управление PTZ-камерой.

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

  • камере с разрешением PTZ не предоставляется.
  • оборудование камеры не поддерживает ограничение PTZ.
  • страница не видна пользователю. Используйте 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, запустив демо-версию на Glitch. Обязательно ознакомьтесь с исходным кодом .

Вопросы безопасности

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

Совместимость с браузером

Медиапоток API

Поддержка браузера

  • Хром: 55.
  • Край: 12.
  • Фаерфокс: 15.
  • Сафари: 11.

Источник

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.
  • Firefox: не поддерживается.
  • Сафари: 11.

Источник

MediaStreamTrack.getSettings()

Поддержка браузера

  • Хром: 59.
  • Край: 12.
  • Фаерфокс: 50.
  • Сафари: 11.

Источник

Полезные ссылки

Благодарности

Эту статью рецензировали Джо Медли и Томас Штайнер . Благодарим Риджубрату Бхаумик и Ээро Хаккинена из Intel за работу над спецификацией и реализацией. Героическое изображение Кристины @wocintechchat.com на Unsplash .