WebRTC на Android: как разработать нативный видеочат

Об особенностях технологии разработки видео чатов и конференций WebRTC на Android.

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

Вкратце о WebRTC

WebRTC - технология разработки видео чатов и конференций. Она позволяет создавать peer-to-peer соединение между мобильными устройствами и браузерами для передачи медиа потоков. Более подробную информацию, как она устроена и об общих принципах работы можно найти в нашей статье про WebRTC простым языком.

2 способа реализации видеосвязи с WebRTC на Android

  1. Самый простой и быстрый вариант - воспользоваться одним из множества коммерческих проектов, например, Twilio или LiveSwitch. Они предоставляют свои SDK для различных платформ и реализуют функциональность из коробки, но имеют минусы. Они платные и функционал ограничен: вы сможете сделать только те функции, которые в них есть, а не любые, какие придумаете.
  1. Другой вариант - использовать одну из существующих библиотек. Этот подход требует большего количества кода, но сэкономит деньги и даст большую гибкость в реализации функциональности. В этой статье мы рассмотрим второй вариант, а в качестве библиотеки используем https://webrtc.github.io/webrtc-org/native-code/android/

Создание соединения

Создание WebRTC соединения состоит из двух этапов:

  1. Установка логического соединения - устройства должны договориться о формате данных, кодеках и т.п.
  2. Установка физического соединения - устройства должны знать адреса друг друга

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

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

Логическое соединение

Логическое соединение устанавливается с использованием Session Description Protocol (SDP), для этого один пир:

  1. Создает объект PeerConnection
  2. Формирует на SDP-offer - объект, содержащий данные о предстоящей сессии, и при помощи сигнального механизма отправляет его собеседнику.
WebRTC на Android: как разработать нативный видеочат, image #1

В свою очередь, другой пир:

  1. Также создает объект PeerConnection
  2. При помощи сигнального механизма получает SDP-offer, отравленный первым пиром, и сохраняет его у себя
  3. Формирует SDP-answer и отправляет его обратно, также при помощи сигнального механизма
WebRTC на Android: как разработать нативный видеочат, image #2

Первый пир, получив SDP-answer, сохраняет его у себя.

WebRTC на Android: как разработать нативный видеочат, image #3

После успешного обмена объектами SessionDescription, логическое соединение считается установленным.

Физическое соединение

Теперь необходимо установить физическое соединение между устройствами, что чаще всего является нетривиальной задачей. Обычно устройства в интернете не имеют публичных адресов, поскольку располагаются за роутерами и межсетевыми экранами. Для решения этой проблемы в WebRTC используется технология ICE (Interactive Connectivity Establishment).

Важной составляющей ICE являются Stun и Turn сервера. Они служат одной цели - установке связи между устройствами, которые не имеют публичных адресов.

Stun-сервер

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

Turn-сервер

В некоторых случаях роутер может иметь ограничение “Symmetric NAT”. Это ограничение не позволит установить прямое соединение между устройствами. В этом случае используется Turn-сервер. Он выступает в качестве посредника и все данные идут через него. Подробнее можно почитать в документации по WebRTC от Mozilla.

Как мы увидели, STUN и TURN сервера играют важную роль в установке физического соединения между устройствами. Именно для этой цели мы, при создании объекта PeerConnection, передаем список с доступными ICE-серверами.

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

WebRTC на Android: как разработать нативный видеочат, image #4

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

WebRTC на Android: как разработать нативный видеочат, image #5

Теперь, когда пиры обменялись своими адресами, можно приступать к передаче и приему данных.

Получение данных

Библиотека, после установки логического и физического соединений с собеседником, вызовет колбэк onAddTrack и передаст в него объект MediaStream, содержащий VideoTrack и AudioTrack собеседника

WebRTC на Android: как разработать нативный видеочат, image #6

Дальше получаем VideoTrack из MediaStream и отобразить его на экране.

WebRTC на Android: как разработать нативный видеочат, image #7

Для отображения VideoTrack, необходимо передать ему объект, реализующий интерфейс VideoSink. Для этих целей библиотека предоставляет класс SurfaceViewRenderer.

WebRTC на Android: как разработать нативный видеочат, image #8

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

WebRTC на Android: как разработать нативный видеочат, image #9

Например, так можно замьютить собеседника

WebRTC на Android: как разработать нативный видеочат, image #10

Отправка данных

Отправка видео и аудио со своего устройства также начинается с создания объекта PeerConnection и отправки IceCandidate-ов. Но в отличие от создания SDPOffer при получении видеопотока собеседника, в данном случае мы должны сначала создать объект MediaStream, который включает в себя AudioTrack и VideoTrack.

Для отправки своих аудио и видеопотоков, нужно создать объект PeerConnection, после чего при помощи сигнального механизма обменяться IceCandidate и SDP пакетами. Но вместо того, чтобы получить от библиотеки медиапоток собеседника, мы должны получить медиапоток нашего устройства и передать его в библиотеку, чтобы она передала его собеседнику

WebRTC на Android: как разработать нативный видеочат, image #11

Теперь нам нужно создать объект MediaStream и передать в него объекты AudioTrack и VideoTrack

WebRTC на Android: как разработать нативный видеочат, image #12

Получить AudioTrack можно следующим образом

WebRTC на Android: как разработать нативный видеочат, image #13

Получение VideoTrack происходит чуть сложнее. Сначала получаем список всех камер устройства:

WebRTC на Android: как разработать нативный видеочат, image #14

Далее нужно создать объект CameraVideoCapturer, который и будет захватывать изображение

WebRTC на Android: как разработать нативный видеочат, image #15

Теперь, после получения CameraVideoCapturer начинаем захватывать изображение и добавляем его в MediaStream

WebRTC на Android: как разработать нативный видеочат, image #16

После создания MediaStream и добавления его в PeerConnection, библиотека формирует SDP-offer и происходит описанный выше обмен SDP-пакетами через сигнальный механизм. По завершению этого процесса собеседник начнет получать наш видео поток. Поздравляю, с этого момента соединение установлено.

Many-to-Many

Мы рассмотрели вариант подключения one-to-one. WebRTC также позволяет создавать подключения many-to-many. В самом простом варианте делается это точно также как и при подключении one-to-one. Разница в том, что объект PeerConnection, так же как и обмен SDP-пакетами и ICE-кандидатами, делается не один раз, а для каждого участника. У этого подхода есть минусы:

  1. Устройство сильно нагружается, поскольку ему необходимо отправлять одинаковый поток данных каждому собеседнику
  2. Реализация дополнительных фич, таких как запись видео, транскодинг и т.д. сложна либо вообще невозможна

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

Заключение

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

Также, для лучшего понимания работы WebRTC можно обратиться к следующим ресурсам:

Документация по WebRTC от Mozilla

Статья Fora Soft о WebRTC простым языком

Статья Fora Soft о безопасности WebRTC.

Михаил, Android-разработчик.

117 views·3 shares
117 views