23. Информация для установки
соединения
- offer/answer (информация о медиаданных, их типе
и используемых кодеках)
- ice candidates (инфрмация о интерфейсах и портах
для установки p2p соединения)
34. Особенности
- возможность одновременного использования нескольких каналов
- возможность расстановки приоритетов
- надежная и ненадежная семантика доставки
- встроенная система безопасности (DTLS) и контроль перегрузки
- возможность использования с видео и без видео
35. RTCDataChannel
var pc = new RTCPeerConnection({}, {
optional: [{RtpDataChannels: true}]
});
var channel = pc.createDataChannel("sendDataChannel", {
reliable: false
});
channel.send(JSON.stringify({}));
36. RTCDataChannel
var pc = new RTCPeerConnection({}, {
optional: [{RtpDataChannels: true}]
});
var channel;
pc.ondatachannel = function(event){
channel = event.channel;
channel.onmessage = function(event){
//handle message
}
};
Одним из крупнейших челенджей для веба в последнее время стал вопрос коммуникации пользователей с помощью видео и аудио. Так называемый Real Time Communication в сокращении RTC. RTC должен быть так же естественнен в веб приложениях, как обмен текстовыми сообщениями. Без этого мы ограничены в своей способности к инновациям и разработке новых способов взаимодействия.
Так исторически сложилось, что RTC решения были в основном корпоративными, сложными и требующими дорогих аудио и видео технологий. Интеграция RTC в существующие сервисы было делом достаточно сложным и трудоемким, особенно если это касается веба.
Все начало меняться в 2010 году.
Жила была компания on2 tech. Компания занималась разработкой кодеков VP серии. Последний из разработынных компанией кодеков стал VP8, который позиционировался как альтернатива кодекам H.264.
В начале 2010 года компания гугл покупает on2 tech, и публикует разработанные этой компанией решения в open source под названием WebM
В этом же 2010 году гугл покупает компанию глобал айпи солюшнс. Компания занималась разработками в сфере VoIP. Ее продуктами являлись фреймворки для организации VoIP а так же решения в области подавления шума и эха. Непосредственно перед покупкой GIPS был одним из лидеров на рынке в сфере VoIP, поэтому поглощение компании вызвало небольшую панику в сфере, многим пришлось искать альтернативные решения. После покупки GIPS гугл выкладывает разработанные компанией решения в open source предварительно выпилив из них все кодеки, имеющие патентообладателей, заменив их на VP8. А так же добавляет слой JavaScript API для взаимодействия всем этим добром из браузера. Крутая идея!
Далее для обеспечения согласованности в индустрии гугл начинает работы по стандартизации всего этого добра с помощью W3C и IETF.
W3C - организация, разрабатывающая и внедряющая технологические стандарты для веба.
IETF - (Инжене́рный сове́т Интерне́та) — открытое международное сообщество проектировщиков, учёных, сетевых операторов и провайдеров, созданное IAB в 1986 году и занимающееся развитием протоколов и архитектуры Интернета.
Результат не заставил себя долго ждать, решения были стандартизованы и получили название WebRTC.
В мае 2011 года компания Ericsson представила первую имплементацию WebRTC.
WebRTC представляет из себя стандарт для организации общения в браузере с помощью видео и аудио без использования плагинов.
Основными принципами WebRTC являются: ...
WebRTC определяет 3 API
MediaStream - позволяет захватывать устройства подлюченные к компьютеру и получать из них медиа поток
RTCPeerConnection - позволяет устанавливать peer to peer соединение. Т.е после установки соединения 2 webrtc точки могут общаться без помощи сервера.
RTCDataChannel - средство позволяющее передавать текстовые данные через RTCPeerConnection
Начнем с получения медиа данных с устройств подключенных к компьютеру. Осуществляется это с помощью метода getUserMedia. Метод принимает 3 аргумента. Давайте рассмотрим каждый из аргументов.
Первый аргумент - так называемый объект ограничений, в этом объектемы указваем что именно нам нужно от запрашиваемого потока. В основном этот объект выглядит как указано на примере. На самом деле подразумевается, что в будущем можно будет конфигурировать еще и качество медиа данных в потоке. Например размер кадра или fps. Что-то из этого уже поддерживается в браузере Google Chrome.
Следующим аргументом является функция колбэк. Она выполнится когда поток будет успешно захвачен, ссылка на поток придет первым и единственным аргументов в эту ф-цию. Для примера отобразим поток в тэге video с идентификатором myVideo.
Для тех кто знаком с File API в браузере следующая конструкция будет знакома. С помощью объекта URL и его метода createObjectURL мы получаем url для потока. Полученное значение используем в качестве значения атрибута src нашего видео элемента. После выполненных действий поток начнет проигрываться в тэге video.
Третим и последним аргументом является функция errback. Она выполнится если по той или иной причине не удалось получить медиа поток.
Причин может быть несколько:
объект constraints неверного формата
устройства уже захвачены другой программой
или же пользователь запретил использовать устройство
При выполнении метода getUserMedia, браузер спрашивает у пользователя разрешение на использование устройств. Если ресурс запращивающий медиа данные работает по https, то браузер может запомнить ваше решение о разрешении доступа и больше не спрашивать вас об этом. Если же ресурс работает по http, то браузер будет спрашивать резрешение каждый раз при выполнении getUserMedia
Вот мы получили поток. Давайте поймем что мы можем с ним делать.
Во-первых - данные из потока можно анализировать и обрабатывать. Поток может содержать аудио и видео данные одновременно. Для анализа и обработки аудио и видео данных используются разные механизмы. Давайте начнем с аудио
Анализ и обработка аудио осуществляется с помощью Web Audio API. Web Audio API достаточно обширная тема, она заслуживает отдельного доклада.
Я лишь кратко затрону эту тему.
Основной инструмент, который предоставляет Web Audio API для работы с данными - AudioContext
В общей сложности AudioContext представляет из себя цепь изображенную на схеме.
Для аудиокнотекста нам нужно определить сорс и дестинэйшн. Грубо говоря - вход и выход. Помимо различных медиа элементов, таких как audio и video, аудио буфферов и прочего, в качестве сорс можно использовать поток полученный с помощью getUserMedia.
Так же поток можно использовать в качестве дестинэйшн.
В качестве эффектов мы можем использовать любые из набора предоставдяемого Web Audio API ()
Я не собираюсь сильно углублять в Web Audio API, и мы ограничимся только небольшим визуальным примером
Если для обработки аудио у нас есть Web Audio API. То с видео не все так хорошо. Обработка видео осуществляется снятием кадра по интервалу, последующим анализом и модификацией данных из кадра.
давайте представим, что мы уже получили поток и он отображается в теге video с идентификатором myVideo
Для получения кадра в определенный промежуток времени нужно выполнить следующий код.
Мы видм ряд подготовленных переменных. video - html тэг в котором проигрывается видео поток. Переменной canvas мы присвоили только что созданный тэг канвас. Для рисования в канве нам нужно получить 2d контекст. Далее определяем размеры скриншота.
Далее в интервале в канву с помощью контекста рисуем наш тэг видео. После этого у самой канвы мы можем попросить отрисованные в ней данные с помощью команды toDataURL. Этот метод вернет на data URI строку, следующего содержания.
Дальше мы выковыриваем данные из этой строки, анализируем и обрабатываем как нам нужно.
Пахнет костылями, но именно так все делаю за неимением других интсрументов.
На этом слайде ссылки на интересные примеры обработки video
Теперь давайте вернемся к теме нашего доклада. Мы расмотрели API получения потока, теперь давайте рассмотрим API RTCPeerConnection.
RTCPeerConnection является компонентом WebRTC, который обеспечивает стабильную и эффективную связь потоковой передачи данных между пирами.
Для установки p2p соединения пользователям нужно обменятся 2 типами информации:
информация о медиаданных, их типе и используемых кодеках
инфрмация о интерфейсах и портах для установки p2p соединения
Interactive Connectivity Establishment - технология используемая для p2p приложений в сети с участием NAT (network address translators).
Для передачи указанных данных нам не хватает механизма, с помощью которого служебные сообщения будут отправлены от одного клиента другому.
Тут на сцену вступает некоторый signaling server. WebRTC не предоставляет какой-либо сигналинг сервер. Его реализация ложится на плечи разработчика. Он может быть реализован с помощью SIP протокола или xmpp. Может быть проложением на nodejs, а общение между клиентами организовано с помощью webSocket или XHR полинга.
После обмена необходимыми данными устанавливается p2p соединение. На этом этапе сигналинг сервер уже не нужен. Клиенты общаются напрямую.
Но рассмотренный на слайде пример, будет работать только в пределах одной сети, т.к для установки прямого соединения каждому из клиентов нужен уникальный адрес в сети - это IP. За частую в реальном мире мы можем наблюдать следующую схему.
В действительности большинство устройств сидит за одним или несколькими слоями NAT'ов. На устройствах могут стоять антивирусы, которые блокируют определенные порты и протоколы или же доступ сеть может осуществляться через прокси.
В реальности даже домашний wifi роутер может выступать в роли NAT.
WebRTC приложения могут использовать ICE фреймворк, чтобы преодолеть сложности реальной сети. Для того чтобы это произошло нужно передать в RTCPeerConnection адреса ICE серверов. Давайте рассмотрим типы ice серверов
Первый тип - это stun сервер. Он используется для получения внешнего ip адреса. Как только клиент обнаружил свой внешний адрес, он может передать его узлу, с которым проходит соединение.
ICE пытается найти наилучший путь для подключения peer'ов. Он параллельно пробует различные возможности и выбирает наиболее оптимальный вариант, который работает.
ICE сначала пытается установить соединение с использованием адреса хоста, полученное из операционной системы устройства и сетевой карты; если это не удается (что будет в случае если устройство сидит за NAT) ICE получает внешний адрес, используя сервер STUN, а если это не удается, трафик направляется через TURN сервер ретрансляции.
Схематично использование turn сервера изображено на слайде.
Простыми словами:
STUN-сервер используется для получения внешнего сетевого адреса.
TURN-серверы используются для передачи трафика, если напрямую соединиться не удалось.
Каждый turn сервер поддерживает stun. turn сервер это stun сервер с функцией ретрансляции трафика.
Мы разобрались с теоритеческой частью давайте посмотрим как выглядит код установки соединения.
На слайде представлен код установки соединения с вызывающей стороны.
Первое что мы делаем - создаем RTCPeerConnection, в качаестве параметра ему передается объект конфигурации, в котором может содержаться адреса ice серверов, о которых мы говорили ранее
Далее уже известным нам методом getUserMedia запрашиваем медиа поток, полученный поток складываем в peerConnection
Далее создаем offer, как я уже говорил это информация о типе данных передаваемых в потоке
Полученный офер сохраняем в peerConnection и через сигнальный канал отправляем его потенциальному собеседнику.
самые важные события peerConnection это onicecandidate, которое происходит при генерации ice кандидата, и onaddstream, которое происходит когда нам становится доступен медиа стрим опонента
от опонента мы ждем следующие события onAnswer - если на той стороне пользователь “взял трубку”, то он отправит нам свою информацию о устройствах, складываем это в peerConnection с помощью метода setRemoteDescription
все айс кандидаты собеседника мы тоже складываем в peerConnection с помощью метода addIceCandidate
Теперь давайте разберемся с принимающей стороной.
как только нам приходит офер, мы долго не думаем и сразу же создаем RTCPeerConnection
Далее захватывем с камеры поток и добавляем его в наш peerConnection
Сразу же после этого складываем присланный нам офер в peerConnection
После этого можно генерить ансвер, как только получим - отправляем его опоненту
так же как и в первом случае у peerConnection слушаем события onicecandidate и onaddstream
от опонента ждем ice кандидатов
Все! Если не произойдет никаких исключительных ситуаций, то установится p2p соединение, сигналинг канал уже не нужен.
Так же как аудио и видео, WebRTC поддерживает связь в реальном времени для других типов данных.
RTCDataChannel API обеспечивает p2p обмен произвольными данными с низкой задержкой и высокой пропускной способностью.
Особенности:
возможность одновременного использования нескольких каналов
возможность расстановки приоритетов
надежная и ненадежная семантики доставки
встроенная система безопасности (DTLS) и контроль перегрузки
возможность использования с видео и без видео
Протокол датаграмм безопасности транспортного уровня - Datagram Transport Layer Security (DTLS) обеспечивает защищённость соединений для протоколов, использующих датаграммы.
Использовать rtcDataChannel очень просто. На слайде представлен пример кода создающий dataChannel
После создания DataChannel`а у опонента в peerConnection произойдет событие ondatachannel, из которого можно получить канал и подписаться на его сообщения
Для анализа WebRTC соединения в браузере нужно использовать ссылки приведенные на слайде. Они представляют из себя отчеты о текущем соединении. Продоставляют данные о ширине канала, количестве переданных и потерянных пакетов и тд и тп.