Современные браузеры позволяют выбирать устройства ввода и вывода, включая камеры, микрофоны и динамики.
Например:
- На телефоне выберите фронтальную или тыловую камеру.
- На ноутбуке выберите внутренние динамики или динамик, подключенный по Bluetooth.
- Для видеочата выберите внутренний или внешний микрофон или камеру.
Вся эта функциональность предоставляется объектом MediaDevices, который возвращается navigator.mediaDevices
.
MediaDevices имеет два метода, оба реализованы в Chrome 47 на настольных компьютерах и Android: enumerateDevices()
и getUserMedia()
.

enumerateDevices()
Возвращает Promise, предоставляющий доступ к массиву объектов MediaDeviceInfo
для доступных устройств.
Метод похож на MediaStreamTrack.getSources()
, но в отличие от этого метода (который был реализован только в Chrome) он соответствует стандартам и включает устройства вывода звука. Вы можете попробовать это с помощью демонстраций ниже.
Вот немного упрощенный код из одной из демонстраций:
navigator.mediaDevices.enumerateDevices()
.then(gotDevices)
.catch(errorCallback);
...
function gotDevices(deviceInfos) {
...
for (var i = 0; i !== deviceInfos.length; ++i) {
var deviceInfo = deviceInfos[i];
var option = document.createElement('option');
option.value = deviceInfo.deviceId;
if (deviceInfo.kind === 'audioinput') {
option.text = deviceInfo.label ||
'Microphone ' + (audioInputSelect.length + 1);
audioInputSelect.appendChild(option);
} else if (deviceInfo.kind === 'audiooutput') {
option.text = deviceInfo.label || 'Speaker ' +
(audioOutputSelect.length + 1);
audioOutputSelect.appendChild(option);
} else if (deviceInfo.kind === 'videoinput') {
option.text = deviceInfo.label || 'Camera ' +
(videoSelect.length + 1);
videoSelect.appendChild(option);
}
...
}
Получив идентификаторы доступных устройств с помощью enumerateDevices()
, вы можете использовать setSinkId()
(определенный в API устройств вывода звука ) для изменения назначения вывода звука для видео- или аудиоэлемента:
element.setSinkId(sinkId)
.then(function() {
console.log('Audio output device attached: ' + sinkId);
})
.catch(function(error) {
// ...
});
Этот метод устанавливает выходное устройство для аудио из элемента. После вызова setSinkId()
вы можете получить идентификатор текущего выходного аудиоустройства для элемента с помощью свойства sinkId
.
получитьUserMedia()
Это заменяет navigator.getUserMedia()
, но вместо использования обратного вызова возвращает Promise, который дает доступ к MediaStream
. Разработчикам рекомендуется использовать MediaDevices.getUserMedia()
, но нет никаких планов по удалению navigator.getUserMedia()
: он остается частью спецификации .
Демоверсия доступна на сайте примеров WebRTC .
Вот фрагмент кода из демо:
navigator.mediaDevices.getUserMedia(constraints)
.then(function(stream) {
var videoTracks = stream.getVideoTracks();
console.log('Got stream with constraints:', constraints);
console.log('Using video device: ' + videoTracks[0].label);
stream.onended = function() {
console.log('Stream ended');
};
window.stream = stream; // make variable available to console
video.srcObject = stream;
})
.catch(function(error) {
// ...
}
Поднятие флага
Метод enumerateDevices()
в Chrome не имеет флагов, тогда как для MediaDevices.getUserMedia()
вам все равно нужно включить функции экспериментальной веб-платформы в chrome://flags или использовать следующий флаг командной строки:
--enable-blink-features=GetUserMedia
Аналогично для setSinkId()
: включите функции экспериментальной веб-платформы или используйте флаг:
--enable-blink-features=AudioOutputDevices
Более подробная информация о поддержке браузеров приведена ниже.
Будущее
Предложенный обработчик событий ondevicechange
делает то, что заявлено: событие devicechange
запускается, когда изменяется набор доступных устройств, и в обработчике можно вызвать enumerateDevices()
, чтобы получить новый список устройств. Это пока не реализовано ни в одном браузере.
Проект Screen Capture — это расширение API Media Capture, которое предлагает метод MediaDevices.getDisplayMedia()
, позволяющий использовать области дисплея пользователя в качестве источника медиапотока. Существует также предложение расширения MediaDevices
для getSupportedConstraints()
, которое предоставляет информацию о том, какие ограничения могут использоваться для вызова getUserMedia()
: аудио- и видеовозможности, поддерживаемые браузером.
Демо
- получитьUserMedia()
- enumerateDevices():
- Прокладка MediaDevices
Узнать больше
- Сеть разработчиков Mozilla: Медиаустройства
- Статус реализации
- Захват мультимедиа и потоки. Редакторский черновик: MediaDevices
- API устройств вывода звука