Для кого

В этой статье(или дайджесте) я поделюсь ключевыми инструментами, демонстрационными приложениями и открытыми проектами, незаменимыми для практического понимания WebRTC. Здесь не будет туториалов или подробных объяснений о той или иной части WebRTC, а скорее некий дайджест ресурсов, которые помогут лучше разобраться в теме. Если вы работаете с этой технологией уже какое-то время, вряд ли вы найдете что-то новое для себя.

Основы WebRTC: что нужно знать

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

Большинство популярных платформ для видеозвонков (кроме Zoom) используют технологию WebRTC для имплементации своих продуктов в браузерах. Она дефакто является стандартом для создания сервисов коммуникации в реальном времени и поддерживается всеми современными браузерами.

WebRTC состоит из нескольких основных компонентов:

  • API для захвата медиа: оно позволяет получить потоки аудио и видео с камеры и микрофона устройства.

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

  • Кодеки и обработка медиа: WebRTC поддерживает различные аудио и видео кодеки для кодирования и декодирования медиа потоков. Также доступны инструменты для обработки медиа, включая эхоподавление, шумоподавление и автоматическое регулирование усиления.

  • Безопасность: WebRTC использует шифрование для всех передаваемых данных и медиапотоков для обеспечения конфиденциальности и безопасности в сети.

Как работает WebRTC:

  • Сигналлинг: Для начала обмена медиаданными между пирами необходим процесс сигналлинга, который не входит напрямую в спецификацию WebRTC, оставляя разработчикам свободу выбора метода сигнализации (через WebSocket, REST API и др.). Сигналлинг используется для обмена метаинформацией: типа медиа, параметров кодеков, сетевых адресов и портов, необходимых для установления соединения.

  • Установление соединения: После обмена начальной информацией, применяются механизмы ICE (Interactive Connectivity Establishment) с использованием STUN (Session Traversal Utilities for NAT) и TURN (Traversal Using Relays around NAT) серверов для обхода NAT (сетевого адресного преобразователя) и установления прямого соединения между пирами.

  • Передача данных: После установления соединения начинается передача потоковых данных между пирами через защищённое соединение, используя RTP (Real-time Transport Protocol) для медиа и SCTP (Stream Control Transmission Protocol) для данных.

  • Адаптация и обработка: В процессе передачи WebRTC может адаптироваться к изменяющимся сетевым условиям, изменяя качество потока для оптимизации производительности. Также происходит обработка медиа, включая фильтрацию шума, эхоподавление и другие функции для улучшения качества связи.

Далее в трех разделах я расскажу об инструментах/сервисах и демо, которые помогли мне изучить эту технологию в практическом ключе, а затем поделюсь opensource продуктами, которые позволят разобраться в деталях и на практике, как работает WebRTC в больших продуктах.

Инструменты

Chrome Tools

Браузер Chrome предоставляет несколько мощных инструментов для анализа WebRTC:

  • chrome://webrtc‑internals

  • chrome://webrtc-logs

Webrtc-internals

Начнем с chrome://webrtc-internals. Наверное, это самый базовый инструмент, с которым знакомятся в самом начале пути при работе с WebRTC. Там можно найти кучу информации о текущих соединениях, что помогает при дебаггинге и реверс инжиниринге других продуктов.

Здесь можно узнать какие кодеки используются существующими сервисами видеозвонков. Например, присоединившись к звонку в google meets и открыв chrome://webrtc-internals, можно увидеть, что google meets использует AV1 видеокодек.

Информация об исходящем видеопотоке при звонке в Google Meets
Информация об исходящем видеопотоке при звонке в Google Meets

Или например можно посмотреть, количество отправляемых кадров в секунду и их разрешение

Графики, отображающие информацию о видеопотоке в каждые момент времени
Графики, отображающие информацию о видеопотоке в каждые момент времени

Основное ограничение - данные доступны только во время звонка (либо если заранее включить запись), что означает невозможность использования инструмента во время неожиданных проблем.

Больше информации можно найти здесь: https://getstream.io/blog/debugging-webrtc-calls/ 

Webrtc-logs

Этот раздел используется гораздо реже, так как содержит более подробную информацию, и необходим при более детальном анализе сложных проблем. В отличии от chrome://webrtc-internals он содержит логи в текстовом формате о предыдущих сессиях. Таким образом можно посмотреть логи для уже завершенного звонка, chrome://webrtc-internals такое не умеет.

Внутри можно найти информацию о начале и окончании видеовызовов, параметры медиапотоков, кодеки, разрешение видео, частоту кадров и другие метрики качества медиапотока.

Часть информации из этих логов можно использовать для построения метрик, похожих на те, что есть в chrome://webrtc-internals. К сожалению, Chrome не предоставляет такой функциональности, однако существует открытый продукт, который помогает в решении этой задачи.

Этот инструмент идеально подходит, если произошла проблема на одном из реальных звонков, и когда анализ в реальном времени недоступен. Данные логи по дефолту сохраняются в директорию …/Google/Chrome/Default/WebRTC Logs/<log_name>.gz, что позволяет собирать эти данные с нетехнических пользователей, кто готов помочь в анализе проблемы.

TestRTC

Ссылка

analyzeRTC от сервиса testRTC находится в чем-то вроде бета тестирования. Вся платформа - платная, но проанализировать ваш дамп можно можно совершенно бесплатно. В целом ничего нового после chrome://webrtc-internals здесь найти не получится, так как источник данных у них одинаковый. Но вот отображение этих данных в analyzeRTC гораздо лучше. 

Например, информация о видеопотоке представлена особенно удобно:

Информация о видеопотоке в том же звонке Google Meets, но с использованием логов и TestRTC
Информация о видеопотоке в том же звонке Google Meets, но с использованием логов и TestRTC

А еще здесь можно посмотреть общую оценку звонка и качества аудио:

Score — это общий балл сценария от 0 до 10, учитывающий аудио и видео по всем каналам. Он помогает оценить производительность службы и требует субъективной интерпретации на основе опыта с приложением. MOS (Mean Opinion Score) оценивает только аудиоканалы сценария, представляя субъективное качество звука по шкале от 1 до 5, где выше 3 считается хорошим качеством, от 2 до 3 — удовлетворительным, а ниже 2 — плохим.

Короткий видео туториал можно найти здесь

Демонстрационные приложения

Official Demos

Ссылка

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

Каждая ссылка содержит работающее демо и ссылку на исходный код на GitHub. Используя только эти примеры можно уже понять, как разработать довольно сложное веб приложение с функционалом видео звонков. В целом эти примеры помогают лучше разобраться с каждым аспектом WebRTC на практике, чтобы лучше закрепить теоретические знания.

Официальное демо по инициализации соединения между двумя участниками видеоконференции
Официальное демо по инициализации соединения между двумя участниками видеоконференции

SDP Explanation

Ссылка

Пример объяснения каждой строчки SDP с помощью интерактивного веб приложения
Пример объяснения каждой строчки SDP с помощью интерактивного веб приложения

Далее поговорим об SDP - протоколе, использующимся для установки соединения перед началом звонка. Сам формат описан в RFC 8866, он предназначен для того, чтобы перед звонком согласовать параметры медиапотока, такие как форматы кодеков, разрешение видео и типы медиа (аудио, видео, данные), необходимые для установления соединения и обмена медиаданными.

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

В интерактивном режиме можно прочитать про каждую строчку из SDP протокола, экономя время на поиск объяснений в RFC.

Media test

Ссылка

Гибкая конфигурация тестов обработки видеопотока перед его отправкой
Гибкая конфигурация тестов обработки видеопотока перед его отправкой

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

Здесь можно экспериментировать с различными аспектами видеопотоков, такими как создание потока с нуля или с камеры, выбор разрешения видео и частоты кадров. Можно также применять трансформации к кадрам, например, изменение цвета, конвертация в черно-белый формат, кодирование/декодирование в H.264, и добавление наложений для отслеживания времени отображения в элементе <video>.

После экспериментов можно узнать результаты обработки, включая время обработки на разных этапах (например, преобразование в RGBX, добавление фона и наложений), время отображения кадра, общее время от начала до конца обработки, а также время ожидания в очереди. Каждый показатель включает количество обработанных кадров, среднее, медианное, минимальное и максимальное значения времени обработки. Эти данные помогают оценить производительность и эффективность обработки видео в приложении и понять, сколько “стоит” каждая операция.

Слайды от авторов.

Simulcast Playgrounds

Первая

Ссылка

Настройки simulcast в simulcast playground
Настройки simulcast в simulcast playground

Еще одно демо, в этот раз неофициальное, но все еще с открытым исходным кодом. Здесь мы фокусируемся на Simulcast. Это такой подход, который позволяет участникам конференции с разной пропускной способностью сети получать от вас видео в разном разрешении (чем больше пропускная способность - тем лучше разрешение). 

Для того, чтобы не использовать ресурсы сервера, каждый участник отправляет несколько видопотоков в разных разрешениях. Именно этот алгоритм и симулируется в данном примере. Он позволяет настраивать параметры передачи видео, включая выбор разрешения, частоты кадров, кодеков и специфических настроек для Simulcast, таких как добавление и удаление слоев, изменение приоритетов и настройки параметров кодировщика.

Если вы никогда не слышали про Simulcast лучше потратить немного времени на теорию прежде чем подходить к изучению этого демо. Я бы рекомендовал посмотреть на этот материалы на хабре:

https://habr.com/ru/companies/flashphoner/articles/564714/ (Ищите по ключевому слову ‘simulcast’, если нет желания читать всю статью)

Вторая

Ссылка

Статистика simulcast потоков
Статистика simulcast потоков

Другая вариация демо simulcast, совсем не гибкая, зато сильно более репрезентативная. Можно увидеть стандартную конфигурацию с тремя параллельными потоками и метриками из chrome://webrtc-internals. Выглядит более привычно и не отвлекает дополнительными настройками. Отличное дополнение к тому инструменту, что описан выше.

Pagination Demo App

Ссылка

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

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

Самый интересный компонент это ‘components/PaginatedGrid.js’, в нем находится практически вся логика по управлению отрисовки и управления потоками. Описание исходного кода и вообще всего приложения можно найти в официальной документации.

Opensource продукты

Jitsi Meet

GitHub репозитоий

Один из самых популярных продуктов с открытым исходным кодом для разработки связанной с видеозвонками в браузере. На самом деле jitsi содержит не только веб клиент, но и все остальные необходимые части для построения всего продукта. Это прекрасный ресурс для того, чтобы очень глубоко погрузиться в тему RTC, но на это уйдет уйма времени, так как jitsi очень гибкий и довольно старый продукт с огромной кодовой базой. 

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

Janus

GitHub репозиторий

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

Для Janus доступна очень подробная документация и целая куча отдельных демо (которые кстати не вошли в предыдущий раздел, но я все равно рекомендовал бы с ними ознакомиться). 

Mediasoup

GitHub репозиторий

MediaSoup представляет собой еще один сервер WebRTC. В отличие от Jitsi Meet и Janus Gateway, Он решает те же задачи, что и Janus Gateway с тем отличием, что mediasoup имеет как серверную, так и клиентскую часть.

Другие продукты

На самом деле существует целая куча opensource продуктов для постороения видео звонков, я указал те, которые считаю наиболее полезными и удобными при изучении технологий и подходов, которые используются в WebRTC.
Узнать о других продуктах можно по ссылке (на английском).

Вместо выводов

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

Комментарии (8)


  1. arheops
    16.03.2024 16:19

    о. вопрос.

    У меня в webrtc при видео с Chrome на Firefox все тулзы показывают поток, но видео - нету на принимающей стороне. Иногда проскакивает пару кадров и все.

    Это так у всех или только у sip.js?


    1. wataru
      16.03.2024 16:19

      Из хрома на хром работает? Какие настройки у видео?


      1. arheops
        16.03.2024 16:19

        Не работает только из хрома в фаерфокс. хром сафари и хром хром - все ок. фаерофокс в хром - тоже ок.

        Настроек никаких, sip.js их не предоставляет в упрощенной версии.

        Медиа потоки не меняются(rtpengine)


        1. wataru
          16.03.2024 16:19

          С таким не сталкивался. Кидайте баг репорты разработчикам sip.js и firefox.


          1. arheops
            16.03.2024 16:19

            А что вы используете как js клиент?


            1. wataru
              16.03.2024 16:19

              Чистый js. Иногда. Я, вообще, над самим webrtc в хроме работаю. Если бы проблема была на стороне отправителя, мог бы логи какие-нибудь посмотреть. Firefox, конечно, очень много кода из хромовского webrtc взял, но может там много всяких правок, так что оно вполне может по другому себя вести.


              1. arheops
                16.03.2024 16:19

                Я подозреваю, что он считает фреймы битыми. Но хз как это смотреть. Показывает получил 200пакетов в секунду, 0 фреймов декодировал.


  1. alekssamos
    16.03.2024 16:19

    У меня в Safari на iOS 16 + на некоторых сайтах проблема.
    Если я делаю звонки в локальной сети (192.168...), всё хорошо.
    В настоящем интернете соединения нет.

    Но при этом на других устройствах, например, Android смартфон или компьютер, на этих же сайтах всё хорошо и соединение не устанавливается.
    Это значит, что iPhone плохо поддерживает STUN и TURN ?

    Есть и такие сайты, где всё в порядке, в том числе на iPhone.

    Примеры:
    chatfish . ru - проблема;
    nekto . me/audiochat - всё хорошо.

    Что это может быть?
    Что должны учитывать разработчики для полноценной работы даже на iOS?