Pull to refresh

Использование Media Capture API в браузере

Reading time 5 min
Views 20K
Original author: Dave Voyles
Предлагаю читателям «Хабрахабра» перевод статьи «Using the Media Capture API in the Browser» авторства Dave Voyles.



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

Вы можете найти исходный код проекта в моем GitHub. Здесь есть рабочие демо для ваших экспериментов. В последнем Windows 10 preview release Microsoft впервые добавила поддержку media capture APIs в Microsoft Edge. Значительная часть кода из примера взята с Photo Capture sample, который сделала команда разработчиков Edge на их тестовом сайте.

Для тех из вас, кто хочет узнать чуть болше, Eric Bidelman написал отличную статью на HTML5 rocks, которая рассказывает историю этих API.

Начнем


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

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

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

Функция обнаружения


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

if (Modernizr.getusermedia) {
  var getUM = Modernizr.prefixed('getUserMedia', navigator);
  getUM({video: true}, function( //...
  //...
}

Без Modernizr, как в демонстрируемом примере, используйте это:

	navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia;
 
if (!navigator.getuserMedia) {
  Console.log('You are using a browser that does not support the Media Capture API');
}


Видеоплеер


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

<div class="view--video">
    <video id="videoTag" src="" autoplay muted class="view--video__video"></video>
</div>

Здесь еще нет медиаисточника, но мы сделаем с помощью Javascript.

Получение доступа к устройству


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



Поддержка нескольких камер


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

Установка источника в видеоплеер


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

    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;
        }
    };


Применяем CSS-фильтры


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

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

    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.
// CSS-фильтры var index = 0; var filters = ['grayscale', 'sepia', 'blur', 'invert', 'brightness', 'contrast', '']; и CSS:

/* 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 test drive page.

Сохраняем изображения


Разбираясь в коде, вы могли заметить несколько вещей, которые вам не знакомы. Первой вещью, которая притянула мой взгляд была navigator.msSaveBlob. Blob конструктор позволяет вам легко создавать и манипулировать blob прямо на клиенте. Он поддерживается в IE 10+.

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

  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, который позволит применить больше фильтров, или в реальном времени помещать аудио/видеопоток в интерактивное окружение. Возможно это будет моим следующим проектом…

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

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

По всем найденым ошибкам просьба сообщать в лс.
Tags:
Hubs:
+11
Comments 1
Comments Comments 1

Articles