Spec-Zone.ru › Web APIs

MediaDevices: метод getUserMedia()

Базовая Широкодоступная

Эта функция хорошо зарекомендовала себя и работает на многих устройствах и версиях браузеров. Она доступна во всех браузерах с сентября 2017 года.

  • Узнать больше
  • Показать полную совместимость
  • Отправить отзыв

Защищённый контекст: Эта функция доступна только в защищённых контекстах (HTTPS) в некоторых или во всех поддерживающих браузерах.

Метод getUserMedia() интерфейса MediaDevices запрашивает у пользователя разрешение на использование входного устройства мультимедиа, которое создаёт MediaStream с треками, содержащими запрошенные типы мультимедиа.

Этот поток может включать, например, видеотрек (созданный либо аппаратным, либо виртуальным источником видео, таким как камера, устройство записи видео, служба совместного использования экрана и так далее), аудиотрек (аналогично, созданный физическим или виртуальным источником звука, например, микрофон, АЦП и т. п.), и, возможно, другие типы треков.

Он возвращает Promise, который разрешается в объект MediaStream. Если пользователь отклоняет разрешение или соответствующее мультимедиа недоступно, то обещание отклоняется с NotAllowedError или NotFoundError DOMException соответственно.

Примечание: Возвращённое обещание может ничего не разрешить и не отклонить, так как пользователь не обязан принимать решение и может проигнорировать запрос.

Синтаксис

getUserMedia(constraints)

Параметры

constraints

Объект, определяющий типы запрашиваемого мультимедиа и любые требования к каждому типу.

Параметр constraints — это объект с двумя членами: video и audio, описывающие запрашиваемые типы мультимедиа. Один или оба должны быть указаны. Если браузер не может найти все треки мультимедиа с указанными типами, которые удовлетворяют заданным ограничениям, то возвращаемое обещание отклоняется с NotFoundError DOMException.

Для обоих video и audio, значением является либо булево значение, либо объект. Значение по умолчанию — false.

  • Если true указано для типа мультимедиа, результирующий поток должен содержать трек этого типа. Если его нельзя включить по какой-либо причине, возвращаемое обещание будет отклонено.
  • Если false указано для типа мультимедиа, результирующий поток не должен содержать трек этого типа, в противном случае возвращаемое обещание будет отклонено. Поскольку значения по умолчанию для video и audio — false, если объект constraints не содержит ни одного из этих свойств или вообще отсутствует, возвращаемое обещание всегда будет отклонено.
  • Если для типа мультимедиа указан объект, он интерпретируется как словарь MediaTrackConstraints.

Возвращаемое значение

A Promise, обработчик выполнения которого получает объект MediaStream, когда запрошенное мультимедиа было успешно получено.

Исключения

AbortError DOMException

Хотя пользователь и операционная система предоставили доступ к устройству, и не возникло аппаратных проблем, которые могли бы вызвать NotReadableError DOMException, исключение выбрасывается, если возникла какая-либо проблема, которая помешала использованию устройства.

InvalidStateError DOMException

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

NotAllowedError DOMException

Выбрасывается, если одно или несколько из запрошенных устройств не могут быть использованы в данный момент. Это произойдёт, если контекст просмотра небезопасен (то есть страница была загружена с помощью HTTP, а не HTTPS). Также это произойдёт, если пользователь указал, что текущему экземпляру просмотра не разрешен доступ к устройству, пользователь отказал в доступе для текущей сессии или пользователь отказал во всех доступе к устройствам пользовательского мультимедиа в глобальном масштабе. В браузерах, которые поддерживают управление разрешениями на использование мультимедиа с помощью Политики разрешений, эта ошибка возвращается, если Политика разрешений не настроена на разрешение доступа к источнику(ам) ввода.

Примечание: Более старые версии спецификации использовали SecurityError вместо этого; SecurityError получило новое значение.

NotFoundError DOMException

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

NotReadableError DOMException

Выбрасывается, если, хотя пользователь и предоставил разрешение на использование соответствующих устройств, произошла аппаратная ошибка на уровне операционной системы, браузера или веб-страницы, которая помешала доступу к устройству.

OverconstrainedError DOMException

Выбрасывается, если заданные ограничения не позволили найти ни одного подходящего устройства. Ошибка — это объект типа OverconstrainedError, имеющий свойство constraint, строковое значение которого — имя ограничения, которое невозможно выполнить, и свойство message, содержащее удобочитаемую строку, объясняющую проблему.

Примечание: Поскольку эта ошибка может возникнуть даже тогда, когда пользователь ещё не предоставил разрешение на использование устройства, она потенциально может использоваться как отпечаток пальца.

SecurityError DOMException

Выбрасывается, если поддержка пользовательского мультимедиа отключена в Document, на котором был вызван getUserMedia(). Механизм включения и выключения поддержки пользовательского мультимедиа оставлен на усмотрение каждого пользователя.

TypeError

Выбрасывается, если список указанных ограничений пуст или все ограничения установлены в false. Это также может произойти, если вы пытаетесь вызвать getUserMedia() в небезопасном контексте, так как navigator.mediaDevices undefined в небезопасном контексте.

Конфиденциальность и безопасность

Как API, которое может вызывать значительные проблемы с конфиденциальностью, спецификация getUserMedia() устанавливает широкий спектр требований к конфиденциальности и безопасности, которые браузеры обязаны соблюдать.

getUserMedia() — мощная функция, которая может использоваться только в защищённых контекстах; в небезопасных контекстах navigator.mediaDevices undefined, что препятствует доступу к getUserMedia(). Защищённый контекст — это, коротко, страница, загруженная с помощью HTTPS или схемы file:/// URL, или страница, загруженная из localhost.

Кроме того, для доступа к аудио- и видеовходу пользователя всегда требуется разрешение пользователя. Только контекст верхнего уровня документа окна для допустимого источника может запросить разрешение на использование getUserMedia(), если контекст верхнего уровня явно не предоставляет разрешение данному <iframe> сделать это с помощью Политики разрешений. В противном случае пользователь никогда не будет даже спрошен о разрешении на использование устройств ввода.

Дополнительные сведения о требованиях и правилах, о том, как они отражаются в контексте выполнения вашего кода, и о том, как браузеры управляют проблемами конфиденциальности и безопасности пользователей, читайте ниже.

Конфиденциальность пользователя

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

Не менее важны правила уведомления. Браузеры обязаны отображать индикатор, показывающий, что используется камера или микрофон, помимо любого аппаратного индикатора, который может существовать. Они также должны отображать индикатор, показывающий, что разрешение на использование устройства ввода было предоставлено, даже если устройство в данный момент не записывает.

Например, в Firefox адресная строка отображает мигающий красный значок, чтобы указать, что запись ведётся. Значок становится серым, если разрешение установлено, но запись в данный момент не ведётся. Физический индикатор устройства используется для указания того, активна ли в данный момент запись. Если вы выключили камеру (так называемое «закрытие лица»), индикатор активности вашей камеры выключается, чтобы указать, что камера не активно записывает вас, не отменяя разрешение на возобновление использования камеры по завершении выключения.

Безопасность

Существует множество способов, которыми управление безопасностью и средства контроля в агенте пользователя могут привести к тому, что getUserMedia() вернёт ошибку, связанную с безопасностью.

Политика разрешений

Два директивы Политики разрешений, которые применяются к getUserMedia() , — это camera и microphone.

Например, этот HTTP-заголовок позволит использовать камеру документу и любым встроенным элементам <iframe>, загруженным из того же источника:

Permissions-Policy: camera=(self)

Это запросит доступ к микрофону для текущего источника и конкретного источника https://developer.mozilla.org:

Permissions-Policy: microphone=(self "https://developer.mozilla.org")

Если вы используете getUserMedia() внутри <iframe>, вы можете запросить разрешение только для этой фрейма, что очевидно более безопасно, чем запрос более общего разрешения. Здесь укажите, что нам нужна возможность использования как камеры, так и микрофона:

<iframe src="https://mycode.example.net/etc" allow="camera; microphone">
</iframe>

Защита, основанная на шифровании

Метод getUserMedia() доступен только в безопасных контекстах. Безопасный контекст — это контекст, в котором браузер с достаточной уверенностью может сказать, что документ загружен безопасно, используя HTTPS/TLS, и имеет ограниченный доступ к небезопасным контекстам. Если документ не загружен в безопасном контексте, свойство navigator.mediaDevices будет undefined, что сделает доступ к getUserMedia() невозможным.

Попытка доступа к getUserMedia() в этой ситуации приведёт к TypeError.

Безопасность источника документа

Из-за очевидной проблемы безопасности, связанной с getUserMedia() при неожиданном или ненадлежащем управлении безопасностью, его можно использовать только в безопасных контекстах. Существует множество небезопасных способов загрузки документа, который, в свою очередь, может попытаться вызвать getUserMedia(). Ниже приведены примеры ситуаций, в которых вызов getUserMedia() запрещён:

  • Документ, загруженный в элемент <iframe> с ограничением доступа, не может вызвать getUserMedia() , если у <iframe> не установлен атрибут sandbox со значением allow-same-origin.
  • Документ, загруженный с помощью data:// или blob:// URL без источника (например, когда один из этих URL введён пользователем в адресную строку), не может вызвать getUserMedia(). Эти типы URL, загруженные из кода JavaScript, наследуют разрешения скрипта.
  • Любая другая ситуация, в которой нет источника, например, когда используется атрибут srcdoc для указания содержимого фрейма.

Примеры

Использование getUserMedia()

Обычно вы получите доступ к объекту-синглетону MediaDevices с помощью navigator.mediaDevices, как показано ниже:

async function getMedia(constraints) {
  let stream = null;

  try {
    stream = await navigator.mediaDevices.getUserMedia(constraints);
    /* use the stream */
  } catch (err) {
    /* handle the error */
  }
}

Аналогично, при использовании исходных промисов код выглядит так:

navigator.mediaDevices
  .getUserMedia(constraints)
  .then((stream) => {
    /* use the stream */
  })
  .catch((err) => {
    /* handle the error */
  });

Примечание: Если текущий документ не загружен в безопасном контексте, navigator.mediaDevices будет undefined, и вы не сможете использовать getUserMedia(). Подробности об этой и других проблемах безопасности, связанных с использованием getUserMedia(), см. в разделе Безопасность.

Ниже приведены некоторые примеры параметра constraints.

Следующий запрос включает аудио и видео без каких-либо особых требований:

getUserMedia({
  audio: true,
  video: true,
});

Хотя информация о камерах и микрофонах пользователя недоступна по соображениям конфиденциальности, приложение может запросить необходимые и желаемые функции камеры и микрофона, используя дополнительные ограничения. Следующее выражение предпочтительной разрешения камеры 1280x720:

getUserMedia({
  audio: true,
  video: { width: 1280, height: 720 },
});

Браузер постарается учесть это, но может вернуть другие разрешения, если точное совпадение недоступно или пользователь его отменил.

Чтобы требовать функцию, используйте ключевые слова min, max, или exact (также min === max). Следующее требование минимального разрешения 1280x720:

getUserMedia({
  audio: true,
  video: {
    width: { min: 1280 },
    height: { min: 720 },
  },
});

Если камера с таким или более высоким разрешением отсутствует, то возвращённый промис будет отклонен с OverconstrainedError, и пользователь не будет уведомлён.

Разница в поведении объясняется тем, что ключевые слова min, max, и exact по своей сути обязательны, в то время как простые значения и ключевое слово ideal не являются обязательными. Вот полный пример:

getUserMedia({
  audio: true,
  video: {
    width: { min: 1024, ideal: 1280, max: 1920 },
    height: { min: 576, ideal: 720, max: 1080 },
  },
});

Значение ideal имеет приоритет, то есть браузер постарается найти настройку (и камеру, если у вас их несколько) с наименьшим расстоянием соответствия от идеальных значений.

Простые значения по своей сути идеальны, поэтому первый пример с разрешением мог быть написан так:

getUserMedia({
  audio: true,
  video: {
    width: { ideal: 1280 },
    height: { ideal: 720 },
  },
});

Не все ограничения являются числовыми. Например, на мобильных устройствах следующее предпочтёт переднюю камеру (если она доступна):

getUserMedia({
  audio: true,
  video: { facingMode: "user" },
});

Чтобы требовать заднюю камеру, используйте:

getUserMedia({
  audio: true,
  video: {
    facingMode: { exact: "environment" },
  },
});

Другое нечисловое ограничение — ограничение deviceId. Если у вас есть deviceId из mediaDevices.enumerateDevices(), вы можете использовать его для запроса конкретного устройства:

getUserMedia({
  video: {
    deviceId: myPreferredCameraDeviceId,
  },
});

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

getUserMedia({
  video: {
    deviceId: {
      exact: myExactCameraOrBustDeviceId,
    },
  },
});

Ширина и высота

В данном примере задаётся предпочтение разрешению камеры, а полученный объект MediaStream назначается элементу видео.

// Prefer camera resolution nearest to 1280x720.
const constraints = {
  audio: true,
  video: { width: 1280, height: 720 },
};

navigator.mediaDevices
  .getUserMedia(constraints)
  .then((mediaStream) => {
    const video = document.querySelector("video");
    video.srcObject = mediaStream;
    video.onloadedmetadata = () => {
      video.play();
    };
  })
  .catch((err) => {
    // always check for errors at the end.
    console.error(`${err.name}: ${err.message}`);
  });

Частота кадров

В некоторых случаях предпочтительны более низкие частоты кадров, например, в трансляциях WebRTC с ограничениями пропускной способности.

const constraints = {
  video: { frameRate: { ideal: 10, max: 15 } },
};

Передняя и задняя камеры

На мобильных телефонах.

let front = false;
document.getElementById("flip-button").onclick = () => {
  front = !front;
};

const constraints = {
  video: { facingMode: front ? "user" : "environment" },
};

Примечание: В некоторых случаях может потребоваться освободить текущий режим ориентации камеры перед переключением на другой. Для обеспечения переключения камеры рекомендуется освободить ресурсы медиа, вызвав метод «stop()» для трека перед запросом другого режима ориентации.

Спецификации

Спецификация
Захват медиа и потоки
# dom-mediadevices-getusermedia

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

Рабочий стол Мобильное устройство
Chrome Edge Firefox Opera Safari Chrome Android Firefox for Android Opera Android Safari на IOS Samsung Internet WebView Android
getUserMedia
53Если вам нужна эта возможность до версии 53, обратитесь к navigator.webkitGetUserMedia, префиксной форме устаревшего API navigator.getUserMedia.
12
36["Если вам нужна эта возможность до версии 36, обратитесь к navigator.mozGetUserMedia, префиксной форме устаревшего API navigator.getUserMedia.", "До Firefox 55, getUserMedia() неправильно возвращает NotSupportedError, когда список ограничений пустой или все ограничения установлены в false. Начиная с Firefox 55, эта ситуация теперь правильно вызывает обработчик ошибок с TypeError.", "При использовании специфичного для Firefox ограничения video под названием mediaSource для запроса захвата экрана, Firefox 66 и более поздние версии рассматривают значения screen и window как приводящие к отображению списка экранов и окон.", "Начиная с Firefox 66, getUserMedia() больше не может использоваться в защищенных <iframe> или data URL, введённых пользователем в адресной строке."]
40Если вам нужна эта возможность до версии 40, обратитесь к navigator.webkitGetUserMedia, префиксной форме устаревшего API navigator.getUserMedia.
11
53Если вам нужна эта возможность до версии 53, обратитесь к navigator.webkitGetUserMedia, префиксной форме устаревшего API navigator.getUserMedia.
36["Если вам нужна эта возможность до версии 36, обратитесь к navigator.mozGetUserMedia, префиксной форме устаревшего API navigator.getUserMedia.", "До Firefox for Android 55, getUserMedia() неправильно возвращает NotSupportedError, когда список ограничений пустой или все ограничения установлены в false. Начиная с Firefox for Android 55, эта ситуация теперь правильно вызывает обработчик ошибок с TypeError.", "При использовании специфичного для Firefox for Android ограничения video под названием mediaSource для запроса захвата экрана, Firefox for Android 66 и более поздние версии рассматривают значения screen и window как приводящие к отображению списка экранов и окон.", "Начиная с Firefox for Android 66, getUserMedia() больше не может использоваться в защищенных <iframe> или data URL, введённых пользователем в адресной строке."]
41Если вам нужна эта возможность до версии 41, обратитесь к navigator.webkitGetUserMedia, префиксной форме устаревшего API navigator.getUserMedia.
11 6.0 53
secure_context_required 53 79 68 40 11 53 68 41 11 6.0 53

См. также

  • Устаревший API Navigator.getUserMedia()
  • MediaDevices.enumerateDevices(): Список доступных устройств ввода-вывода
  • API WebRTC
  • API захвата медиа и потоков
  • API захвата экрана: Захват содержимого экрана как MediaStream
  • MediaDevices.getDisplayMedia(): Получение потока, содержащего содержимое экрана
  • Снятие фото с веб-камеры: Урок по использованию getUserMedia() для снятия фото, а не видео

© 2005–2024 MDN contributors.
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.
https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/getUserMedia

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API