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

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

Франсуа Бофор
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. Разрешение необходимо запросить повторно. К счастью, для запроса и отслеживания статуса разрешения PTZ можно использовать API разрешений .

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 и проверьте столбец «Pan-Tilt-Zoom» на вкладке «Видеозахват». «Pan-Tilt» и «Zoom» соответственно означают, что камера поддерживает элементы управления UVC «PanTilt (Absolute)» и «Zoom (Absolute)». Элементы управления 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, запустив демо-версию .

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

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

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

API MediaStream

Browser Support

  • Хром: 55.
  • Край: 12.
  • Firefox: 15.
  • Сафари: 11.

Source

API разрешений

Browser Support

  • Хром: 43.
  • Край: 79.
  • Firefox: 46.
  • Сафари: 16.

Source

API видимости страницы

Browser Support

  • Хром: 33.
  • Край: 12.
  • Firefox: 18.
  • Сафари: 7.

Source

MediaDevices.getUserMedia()

Browser Support

  • Хром: 53.
  • Край: 12.
  • Firefox: 36.
  • Сафари: 11.

Source

MediaDevices.getSupportedConstraints()

Browser Support

  • Хром: 53.
  • Край: 12.
  • Firefox: 44.
  • Сафари: 11.

Source

MediaStreamTrack.applyConstraints()

Browser Support

  • Хром: 59.
  • Край: 12.
  • Firefox: 43.
  • Сафари: 11.

Source

MediaStreamTrack.getCapabilities()

Browser Support

  • Хром: 59.
  • Край: 12.
  • Firefox: 132.
  • Сафари: 11.

Source

MediaStreamTrack.getSettings()

Browser Support

  • Хром: 59.
  • Край: 12.
  • Firefox: 50.
  • Сафари: 11.

Source

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

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

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