Статьи

Введение в API getUserMedia

В середине 90-х чат был одним из лучших продуктов, доступных в Интернете. Поднимите руку, если вы были молоды и подумали, как здорово было бы разработать собственное приложение для чата. Одной из их лучших функций была их способность захватывать микрофон аудио и / или видео с веб-камеры и отправлять его через Интернет. Для реализации этих функций разработчики уже давно используют такие плагины, как Flash и Silverlight. Тем не менее, Flash и Silverlight могут быть проблемой, если у вас нет необходимых разрешений или вы не разбираетесь в технологиях. Сегодня такие плагины больше не требуются благодаря проекту WebRTC и связанным с ним API. В этой статье будет представлен API getUserMedia, один из API, полученных из проекта WebRTC.

Что такое API getUserMedia

API getUserMedia обеспечивает доступ к мультимедийным потокам (видео, аудио или обоим) с локальных устройств. Есть несколько вариантов использования этого API. Первый — это общение в реальном времени, но мы также можем использовать его для записи уроков или уроков для онлайн-курсов. Еще один интересный случай использования — наблюдение за вашим домом или работой. Сам по себе этот API способен только получать аудио и видео, но не отправлять данные и не сохранять их в файле. Например, для полноценного рабочего чата нам нужно отправить данные через Интернет. Это можно сделать с помощью API RTCPeerConnection . Для хранения данных мы можем использовать MediaStreamRecorder API .

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

Хотя API getUserMedia существует уже некоторое время, по состоянию на 30 декабря 2013 года он все еще является рабочим проектом W3C. Таким образом, спецификации могут быть подвержены нескольким изменениям. API предоставляет только один метод getUserMedia() , который принадлежит объекту window.navigator . Метод принимает в качестве своих параметров объект ограничений, обратный вызов успеха и обратный вызов сбоя. Параметр constraints — это объект, имеющий одно или оба свойства audio и video . Значением этих свойств является логическое значение, где true означает запрос потока (аудио или видео), а false не запрашивает поток. Итак, чтобы запросить аудио и видео, передайте следующий объект.

 { video: true, audio: true } 

В качестве альтернативы, значение может быть объектом Constraints . Этот тип объекта позволяет нам лучше контролировать запрошенный поток. Фактически, мы можем выбрать источник видео с высоким разрешением, например, 1280 × 720, или с низким, например, 320 × 180. Каждый объект Constraints содержит два свойства, mandatory и optional . mandatory — это объект, который задает набор ограничений, которым должен удовлетворять UA, или же вызвать errorCallback. optional , это массив объектов, который задает набор Ограничений, которые UA должен пытаться выполнить, но может игнорировать, если они не могут быть выполнены.

Допустим, мы хотим аудио и видео пользователя, где видео должно быть как минимум с высоким разрешением и иметь частоту кадров 30. Кроме того, если доступно, мы хотим, чтобы видео было с частотой кадров 60. Для выполнения этой задачи , мы должны передать следующий объект.

 { video: { mandatory: { minWidth: 1280, minHeight: 720, minFrameRate: 30 }, optional: [ { minFrameRate: 60 } ] }, audio: true } 

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

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

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

Поддержка API getUserMedia приличная на настольном компьютере, но довольно слабая на мобильном. Кроме того, большинство браузеров, поддерживающих его, все еще имеют версию с префиксом производителя. В настоящее время настольными браузерами, реализующими API, являются Chrome 21+ (префикс -webkit), Firefox 17+ (префикс -moz) и Opera 12+ (не поддерживается с версии 15-17) с некоторыми проблемами в старых версиях. В мобильных браузерах API поддерживают только Chrome 21+ (префикс -webkit) и Opera 12+ (префикс -webkit из версии 16). Также обратите внимание, что если страница, содержащая инструкции по работе с этим API, открывается через протокол file:// в Chrome, она не будет работать.

Случай с Opera очень интересный и заслуживает заметки. Этот браузер реализовал API, но по неизвестной (для меня) причине, после переключения на движок рендеринга Blink в версии 15, он больше не поддерживал его. Наконец, поддержка API была восстановлена ​​в версии 18. Как будто этого было недостаточно, Opera 18 — первая версия, которая также поддерживает аудиопоток.

Тем не менее, мы можем игнорировать проблемы совместимости благодаря утилите getUserMedia.js . Последний будет тестировать браузер и, если API не реализован, он откатится к Flash.

демонстрация

В этом разделе я покажу вам базовую демонстрацию, чтобы вы могли увидеть, как работает API getUserMedia, и конкретно увидеть его параметры. Цель этой демонстрации — создать «зеркало» в том смысле, что все, что снято с веб-камеры и микрофона, будет транслироваться через экран и аудиодинамики. Мы попросим у пользователя разрешения на доступ к обоим мультимедийным потокам, а затем выведем их с помощью элемента video HTML5. Разметка довольно проста. В дополнение к элементу video у нас есть две кнопки: одна для запуска выполнения и одна для его остановки.

Что касается скриптовой части, мы сначала проверяем поддержку браузера. Если API не поддерживается, мы отображаем сообщение «API не поддерживается» и отключаем две кнопки. Если браузер поддерживает API getUserMedia, мы присоединяем слушателя к событию click кнопок. Если нажать кнопку «Play demo», мы проверяем, имеем ли мы дело со старой версией Opera из-за проблем, описанных в предыдущем разделе. Затем мы запрашиваем аудио и видео данные с устройства пользователя. Если запрос выполнен успешно, мы передаем данные с использованием элемента video ; в противном случае мы показываем ошибку, которая произошла на консоли. Кнопка «Остановить демонстрацию» приводит к остановке видео и остановке потоков.

Демонстрационная версия кода ниже доступна здесь .

 <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"/> <title>getUserMedia Demo</title> <style> body { max-width: 500px; margin: 2em auto; font-size: 20px; } h1 { text-align: center; } .buttons-wrapper { text-align: center; } .hidden { display: none; } #video { display: block; width: 100%; } .button-demo { padding: 0.5em; display: inline-block; margin: 1em auto; } .author { display: block; margin-top: 1em; } </style> </head> <body> <h1>getUserMedia API</h1> <video id="video" autoplay="autoplay" controls="true"></video> <div class="buttons-wrapper"> <button id="button-play-gum" class="button-demo" href="#">Play demo</button> <button id="button-stop-gum" class="button-demo" href="#">Stop demo</button> </div> <span id="gum-unsupported" class="hidden">API not supported</span> <span id="gum-partially-supported" class="hidden">API partially supported (video only)</span> <script> var videoStream = null; var video = document.getElementById("video"); // Test browser support window.navigator = window.navigator || {}; navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia || null; if (navigator.getUserMedia === null) { document.getElementById('gum-unsupported').classList.remove('hidden'); document.getElementById('button-play-gum').setAttribute('disabled', 'disabled'); document.getElementById('button-stop-gum').setAttribute('disabled', 'disabled'); } else { // Opera <= 12.16 accepts the direct stream. // More on this here: http://dev.opera.com/articles/view/playing-with-html5-video-and-getusermedia-support/ var createSrc = window.URL ? window.URL.createObjectURL : function(stream) {return stream;}; // Opera <= 12.16 support video only. var audioContext = window.AudioContext || window.webkitAudioContext || null; if (audioContext === null) { document.getElementById('gum-partially-supported').classList.remove('hidden'); } document.getElementById('button-play-gum').addEventListener('click', function() { // Capture user's audio and video source navigator.getUserMedia({ video: true, audio: true }, function(stream) { videoStream = stream; // Stream the data video.src = createSrc(stream); video.play(); }, function(error) { console.log("Video capture error: ", error.code); }); }); document.getElementById('button-stop-gum').addEventListener('click', function() { // Pause the video video.pause(); // Stop the stream videoStream.stop(); }); } </script> </body> </html> 

Вывод

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

Как мы уже видели, API getUserMedia прост, но очень гибок. Он предоставляет только один метод, но его первый параметр, constraints , позволяет нам требовать аудио- и видеопотоки, которые лучше соответствуют потребностям нашего приложения. Совместимость между браузерами не очень широкая, но она увеличивается, и это хорошая новость! Чтобы лучше понять концепции этой статьи, не забудьте поиграть с предоставленной демоверсией. В заключение, я настоятельно рекомендую вам попытаться изменить код для выполнения какой-либо задачи, например, применить фильтр CSS для изменения способа отображения видеопотока.