javascript

Как Chrome и Firefox договариваются о передаче двух видеопотоков

  • вторник, 1 августа 2017 г. в 03:14:37
https://habrahabr.ru/company/Voximplant/blog/334498/
  • Разработка мобильных приложений
  • Разработка веб-сайтов
  • Программирование
  • JavaScript
  • Блог компании Voximplant



Среди подводных камней WebRTC один особенный. Это то, как браузеры договариваются между собой о передаче медиа-потоков. Кодеки, битрейты, разрешение видео, – вся вот эта история. Кода медиа-поток один — все хорошо. Но когда их два (а видео со звуком, это, на секундочку, два медиа-потока: один для видео, другой для звука), то мнения браузеров о формате описания ситуации резко разделяются. Сделать видеозвонок из Chrome в Firefox можно довольно легко. А вот видеозвонок со звуком — уже нет. Под катом небольшая история, почему так повелось, что запилили в новой Safari и какой особый путь у Microsoft Edge.

Комбайн на поле голосовых и видеозвонков


WebRTC — это комбайн. Множество протоколов и разных JavaScript API под одним названием, который делает разные штуки:

  • Захват видео с камеры и/или голоса с микрофона.
  • Кодирование и декодирование разными кодеками, которые поддерживает браузер.
  • Установка Peer-to-Peer подключения между браузерами с использованием подхода ICE и указанных серверов. STUN серверов для изучения топологии сети и TURN серверов, если не удалось пробить NAT и нужно подключаться через внешний сервер.
  • Передача видео и аудио по сети. Кроме того, анализ ширины канала и подстройка под него битрейта кодека.
  • Воспроизведение полученного.
  • Передача данных в UDP или TCP стиле.
  • Screen Sharing.

Самое сложное в этой истории – установить Peer-to-Peer подключение. Если это не локальное общение между вкладками, устройства не в одной сети или у них нет реальных IP-адресов с открытыми портами, то нужны какие-то промежуточные серверы, чтобы «договориться». Обычно эти сервера поднимает разработчик, который хочет воспользоваться WebRTC. За исключением STUN эхо серверов, которые отвечают на вопрос «какой у меня публичный IP» и есть публичные от Google.

В зависимости от того, что разработчик собирается передавать: голос, видео или произвольные данные, – установливается Peer-to-Peer подключение. WebRTC формирует текстовые пакеты «offer», «answer» и «ice candidate», которые разработчик должен как-то передавать между подключающимися друг к другу браузерами (обычно через собственный signaling сервер). В этих пакетах оба браузера описывают свои возможности и что будет происходить, а WebRTC пытается выбрать оптимальный способ подключения.

SDP-наследие телефонии


Пакеты, которыми WebRTC обменивается руками разработчика, используют формат SDP. Он очень старый, текстовый, пришел из телефонии (WebRTC старается минимизировать усилия разработчика при звонке из браузера в телефонные сети и обратно) и похож на HTTP. Вот так выглядит SDP-пакет «этот браузер хочет установить Peer-to-Peer подключение к другому браузеру, но пока не знает, что будет передавать по сети».

Если разработчик хочет начать/закончить передавать данные, голос или видео, то WebRTC сразу требует от него «renegotiation» – перезапуск Peer-to-Peer подключения, чтобы проверить оптимальность сетевого маршрута для передаваемых данных и передоговориться о кодеках. Вот так выглядит SDP-пакет, в котором WebRTC сообщает о желании передавать видео:

Скрытый текст