Статьи

GetUserMedia: Использование Media Capture и Streams API

Конечный продукт
Что вы будете создавать

Сегодня я хотел бы поэкспериментировать с API Media Capture и Streams , разработанным совместно на W3C Рабочей группой Web-коммуникаций в реальном времени и Рабочей группой API устройств . Некоторые разработчики могут знать его просто как getUserMedia , который является основным интерфейсом, который позволяет веб-страницам получать доступ к устройствам захвата мультимедиа, таким как веб-камеры и микрофоны.

Вы можете найти исходный код этого проекта на моем GitHub. Кроме того, вот рабочая демонстрация, с которой вы можете поэкспериментировать. В последней предварительной версии Windows 10 Microsoft впервые добавила поддержку API захвата мультимедиа в браузере Microsoft Edge . Большая часть этого кода была взята из образца Photo Capture, который команда разработчиков Edge создала на своем сайте тест-драйва.

Для тех из вас, кто хочет погрузиться немного глубже, у Эрика Бидельмана есть отличная статья на HTML5 Rocks, которая входит в историю этого API.

Метод getUserMedia () является хорошей отправной точкой для понимания API Media Capture. getUserMedia() принимает MediaStreamConstraints в качестве входного аргумента, который определяет предпочтения и / или требования для устройств захвата и захваченных потоков мультимедиа, таких как facingMode камеры, громкость микрофона и разрешение видео.

С помощью MediaStreamConstraints вы также можете выбрать определенное захваченное устройство, используя его deviceId , который может быть получен из метода enumerateDevices() . Как только пользователь предоставит разрешение, getUserMedia() вернет обещание с объектом MediaStream, если конкретные MediaStreamConstraints могут быть выполнены.

Все это без необходимости загружать плагин! В этом примере мы углубимся в API и создадим несколько аккуратных фильтров для видео и изображений, которые мы будем захватывать. Ваш браузер поддерживает это? Ну, getUserMedia() существует с Chrome 21, Opera 18 и Firefox 17, и теперь работает в Edge .

Функция обнаружения включает в себя простую проверку существования navigator.getUserMedia . Это большой проект для проверки в каждом браузере, поэтому я бы предложил просто использовать Modernizr для проверки. Вот как это работает:

1
2
3
4
5
if (Modernizr.getusermedia) {
  var getUM = Modernizr.prefixed(‘getUserMedia’, navigator);
  getUM({video: true}, function( //…
  //…
}

Без Modernizr, как показано в этом примере, вам пришлось бы использовать:

1
2
3
4
5
navigator.getUserMedia = navigator.getUserMedia ||
  
if (!navigator.getuserMedia) {
  Console.log(‘You are using a browser that does not support the Media Capture API’);
}

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

1
2
3
<div class=»view—video»>
    <video id=»videoTag» src=»» autoplay muted class=»view—video__video»></video>
</div>

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

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

GetUserMedia принимает несколько параметров. Первый — это объект, определяющий детали и требования для каждого типа носителя, к которому вы хотите получить доступ. Для доступа к веб-камере первым параметром должен быть {video: true} . Кроме того, чтобы использовать микрофон и камеру, передайте {video: true, audio: true} .

Всплывающее окно для GetUserMedia

Здесь вещи действительно становятся интересными. В этом примере мы также используем метод MediaDevices.enumerateDevices . Это собирает информацию об устройствах ввода / вывода мультимедиа, доступных в вашей системе, таких как микрофоны, камеры и динамики. Это обещание, которое будет возвращать несколько свойств, включая тип (тип) устройства, например, videoinput , audioinput или audiooutput . Кроме того, он может генерировать уникальный идентификатор в форме строки с уникальным идентификатором ( videoinput: id = csO9c0YpAf274OuCPUA53CNE0YHlIr2yXCi+SqfBZZ8= ) и, наконец, метку для описания устройства, например FaceTime HD Camera (Built-in) . Это все еще экспериментальная технология, и на CanIUse.com ее еще нет.

В функции initalizeVideoStream вы можете видеть, что мы получаем тег видео с нашей страницы и устанавливаем его источник для потока, который мы передаем. Сам поток — это большой двоичный объект. Если браузер не поддерживает атрибут srcObject , он создает URL-адрес из медиа-потока и устанавливает его.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
// initializeVideoStream() — Callback function when getUserMedia() returns successfully with a mediaStream object
   // 1. Set the mediaStream on the video tag
   // 2. Use ‘srcObject’ attribute to determine whether to use the standard-based API or the legacy version
 
   var initializeVideoStream = function(stream) {
       mediaStream = stream;
 
       var video = document.getElementById(‘videoTag’);
       if (typeof (video.srcObject) !== ‘undefined’) {
           video.srcObject = mediaStream;
       }
       else {
           video.src = URL.createObjectURL(mediaStream);
       }
       if (webcamList.length > 1) {
           document.getElementById(‘switch’).disabled = false;
       }
   };

Я не очень хорош в съемке фотографий, поэтому я часто полагаюсь на фильтры, которые мне предоставляет Instagram. Но что, если бы вы могли применить свои собственные фильтры к вашему видео или статическому изображению? Ну, вы можете!

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

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
// changeCssFiltersOnVid() — Cycle through CSS filters applied to the video stream
   // 1. Grab a reference to the video tag
   // 2. Keep the original CSS classes while still adding the filters
   // 3. Loop through all of the filters
 
   var changeCssFilterOnVid = function () {
       var el = document.getElementById(‘videoTag’);
       el.className = ‘view—video__video’;
 
       var effect = filters[index++ % filters.length]
       if (effect) {
           el.classList.add(effect);
           console.log(el.classList);
       }
   }

В верхней части класса у меня есть массив фильтров для цикла. Они хранятся в виде строки, которая соответствует классам с одинаковыми именами в CSS.

1
// CSS filters var index = 0;

И в CSS:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
/* image * video filters */
.grayscale {
    -webkit-filter: grayscale(1);
    -moz-filter: grayscale(1);
    -ms-filter: grayscale(1);
    filter: grayscale(1);
}
  
.sepia {
    -webkit-filter: sepia(1);
    -moz-filter: sepia(1);
    -ms-filter: sepia(1);
    filter: sepia(1);
}
  
.blur {
    -webkit-filter: blur(3px);
    -moz-filter: blur(3px);
    -ms-filter: blur(3px);
    filter: blur(3px);
}

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

Копаясь в коде, вы можете увидеть некоторые другие функции, с которыми вы не знакомы сразу. Первое, что бросилось в глаза, был navigator.msSaveBlob . Конструктор BLOB- объектов позволяет вам легко создавать и управлять BLOB-объектами (в основном, файлами) непосредственно на клиенте. Поддерживается в IE 10+.

Метод msSaveBlob позволяет сохранить этот объект blob (в нашем случае это наш снимок) на диск. У него также есть родственный метод msSaveOrOpenBlob , который также позволяет открывать изображение из браузера.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// savePhoto() — Function invoked when user clicks on the canvas element
// 1. If msSaveBlob is supported, get the photo blob from the canvas and save the image file
// 2. Otherwise, set up the download attribute of the anchor element and download the image file
 
   var savePhoto = function() {
       if (photoReady) {
           var canvas = document.getElementById(‘canvasTag’);
           if (navigator.msSaveBlob) {
               var imgData = canvas.msToBlob(‘image/jpeg’);
               navigator.msSaveBlob(imgData, ‘myPhoto.jpg’);
           }
           else {
               var imgData = canvas.toDataURL(‘image/jpeg’);
               var link = document.getElementById(‘saveImg’);
               link.href = imgData;
               link.download = ‘myPhoto.jpg’;
               link.click();
           }
           canvas.removeEventListener(‘click’, savePhoto);
           document.getElementById(‘photoViewText’).innerHTML = »;
           photoReady = false;
       }
   };

Если браузер поддерживает этот метод, он сократит объем кода, который нам нужно написать, чтобы сохранить изображение.

Это только начало. Мы также можем использовать WebGL, что позволяет применять еще больше фильтров, а также иметь видео / аудио канал в реальном времени, встроенный в высокоинтерактивные среды. Может быть, это будет мой следующий проект …

Кроме того, вы можете подключиться к API Web Audio, чтобы применить частотную модуляцию к вашему аудиовыходу. Этот пример из тюнера Web Audio хорошо это иллюстрирует. Некоторые люди больше интересуются визуальным обучением, поэтому ознакомьтесь с этим примером от Microsoft.

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

Не стесняйтесь проверить исходный код и увидеть рабочий образец .

У Microsoft есть много бесплатного обучения по многим темам JavaScript с открытым исходным кодом, и мы стремимся создать намного больше с Microsoft Edge . Вот некоторые, чтобы проверить:

И несколько бесплатных инструментов для начала работы: Visual Studio Code , Azure Trial и кросс-браузерные инструменты тестирования — все это доступно для Mac, Linux или Windows.

Эта статья является частью серии технологий веб-разработки от Microsoft. Мы рады поделиться с вами Microsoft Edge и новым механизмом рендеринга EdgeHTML . Получите бесплатные виртуальные машины или проведите удаленное тестирование на устройстве Mac, iOS, Android или Windows @ http://dev.modern.ie/ .