Вы когда-нибудь задумывались, как работают ваши повседневные чат-приложения, такие как Gmeet, MS Teams или Zoom? Что ж, теперь в этой статье вы узнаете, как это работает, и создадите свое приложение для видеозвонков с использованием WebRTC.

Что такое WebRTC?

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

WebRTC — это средство для прямой связи в реальном времени (голос, видео и произвольные данные) с помощью веб-браузера.

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

Хорошо, тогда! Теперь посмотрим, как это работает.

Как это работает?

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

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

Аудио и видео

Основным аспектом WebRTC является аудио и видео. Это первое, что вы заметите в WebRTC.

WebRTC использует кодеки для аудио и видео. В WebRTC можно использовать разные кодеки, ссылка на которые будет в справочном разделе.

WebRTC использует методы VoIP для обработки и отправки мультимедиа по SRTP (протокол безопасной передачи в реальном времени) — безопасной и зашифрованной версии RTP (протокол передачи в реальном времени).

Вы также можете передавать данные с помощью WebRTC, используя RTCDataChannel.

Защищенная передача с использованием NAT Traversal

WebRTC взаимодействует напрямую через браузеры, но это не всегда безопасно.

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

Из-за этой сложности сеанс WebRTC следует следующим шагам:

  • Отправьте предложение SDP на веб-сервер. В этом SDP-сообщении указывается, какими мультимедийными каналами устройство хочет обмениваться, и как их найти.
  • Получите ответ SDP через веб-сервер с другого устройства.
  • Инициируйте процедуру под названием ICE Negotiation, предназначенную для выяснения, доступны ли устройства напрямую, в одноранговой сети или требуют ретрансляции мультимедиа через TURN. Этот процесс лучше всего осуществлять с помощью струйного ДВС.
  • После этого медиаданные передаются непосредственно между устройствами.

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

Конечные точки API WebRTC

WebRTC имеет три основных конечных точки API:

  1. получитьпользовательмедиа
  2. Равноправное соединение
  3. Канал данных

GetUserMedia

Конечная точка getUserMedia предоставит пользователю доступ к камере, микрофону и экрану. Это полезно для тех, кому нужно делать что-то локально, не используя диалоги в реальном времени.

некоторые варианты использования getUserMedia:

  • Собирайте образцы аудио и отправляйте их в механизм преобразования речи в текст.
  • Записывайте аудио и видео без ухудшения качества из-за потери пакетов.
  • Возьмите фотографию профиля пользователя.

одноранговое соединение

PeerConnection или RTCPeerConnection является сердцем WebRTC, а также наиболее сложным для реализации.

  • Реализует ICE для подключения медиаканалов, используя реле TURN, если это необходимо.
  • Обрабатывает все обмены сообщениями SDP.
  • Кодирует и декодирует мультимедийные данные в режиме реального времени.
  • Отправляет и получает мультимедиа по сети.
  • Он также решает локальные проблемы со звуком, используя такие алгоритмы, как подавление акустического эха.

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

канал данных

Интерфейс DataChannel или RTCDataChannel представляет собой сетевой канал, используемый для двунаправленной одноранговой передачи произвольных данных. Каждый канал данных связан с RTCPeerConnection. Каждое одноранговое соединение может иметь теоретическое максимальное количество 65 534 каналов данных (фактическое ограничение может варьироваться в зависимости от браузера).

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

Каналы данных были разработаны для работы на уровне API, аналогичном WebSocket, поэтому вы можете думать об этом так же, как только откроете его.

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

Создание приложения для видеочата

Для создания этого приложения мы будем использовать HTML, CSS, javascript, WebRTC и Firebase для хранения данных.

Настройка проекта

Во-первых, мы начинаем с инициализации проекта. Мы будем использовать npm для установки пакетов.

Во-первых, нам нужно установить firebase.

npm i firebase

Теперь файловая структура проекта

Начнем с HTML и CSS!

Для простого приложения для видеочата нам понадобится несколько вещей:

  • Видеоэлементы для локального (веб-камеры) видео и входящего видео.
  • Кнопки для начала, ответа и завершения вызова.
  • Кнопка для предоставления доступа к аудио и видео со стороны пользователя.
  • Элемент ввода, в котором будет присутствовать клавиша приглашения для видеовызова.

Вот как будет выглядеть HTML-файл. Однако у вас может отличаться от этого.

Когда мы настроим файл HTML, мы можем сделать некоторые базовые стили с помощью CSS.

На этом фронтенд-часть проекта готова. Вы также можете использовать интерфейсные фреймворки и библиотеки, такие как React, Vue, Angular и т. д.

Теперь давайте сразу перейдем к части javascript. Часть javascript будет состоять из следующих разделов:

  • Импорт firebase, firestore и инициализация firestore.
  • Создание экземпляра firestore.
  • Настройка конфигурации сервера и некоторых глобальных состояний.
  • Импорт элементов DOM.
  • Добавление слушателей событий для всех видов событий.

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

После получения конфигурации firebase импортируйте firebase, а затем вы можете инициализировать firebase.

Затем мы можем создать экземпляр firebase.

Затем добавляем сервер STUN, через который передаются данные. К счастью, у нас есть бесплатные iceServers от Google. Затем мы инициализируем PeerConnection, а также устанавливаем для локального и удаленного потоков значение null.

Мы можем получить доступ ко всем элементам в HTML, используя DOM.

Теперь давайте добавим прослушиватель событий в webcamButton, чтобы включить звук и видео с вашего устройства. Для этого у нас есть встроенный метод навигатор. Затем мы устанавливаем удаленный поток как экземпляр MediaStream и передаем дорожки из локального потока в peerConnection, так как нам нужно, чтобы эти данные отправлялись на другое устройство во время разговора. Затем мы устанавливаем локальный поток и удаленный поток на webcamVideo и remoteVideo. Наконец, мы отключаем webcamButton и включаем callButton и answerButton.

Теперь нам нужно добавить прослушиватель событий к callButton, чтобы инициировать вызов. Во-первых, нам нужно сослаться на коллекции из firestore. CallDoc — это основная коллекция, а offerCandiates и answerCandidates — вложенные коллекции в callDoc. Теперь нам нужно сгенерировать callId. Мы можем использовать идентификатор callDoc как callId. Как правило, если у коллекции нет идентификатора, firestore автоматически присваивает ей идентификатор при вызове. Теперь, когда у нас есть callId, мы можем приступить к созданию предложения.

Для создания предложения мы используем createOffer(), а затем устанавливаем предложение в peerConnection в качестве локального описания. Затем мы создаем объект предложения, который мы устанавливаем в callDoc. После этого peerConnection начинает получать iceCandidates, которые мы сохраняем в firestore при прослушивании слушателя событий onicecandidate . Данные, хранящиеся в firestore, будут использоваться для отправки данных в удаленный поток.

Теперь мы установили предложение и сохранили данные в firestore. Во время потоковой передачи данные, хранящиеся в firestore, постоянно изменяются. Таким образом, чтобы обновить поток, мы используем onSnapshot() для получения данных в каждом снимке и обновляем remoteDescription с помощью метода setRemoteDescription(). Наконец, мы включаем кнопку завершения вызова, чтобы завершить вызов.

Чтобы ответить на инициированный вызов, нам нужно добавить прослушиватель событий к кнопке ответа. AnswerButton работает аналогично callButton.

  • Сначала мы получаем CallId, с помощью которого инициируется вызов.
  • Мы получаем данные этого конкретного звонка из firestore, используя callId.
  • Мы получаем подколлекцию answerCandidates и offerCandidates. Мы получаем callData из данных CallDoc.
  • Затем мы устанавливаем для callData.offer значение offerDescription, и мы устанавливаем remoteDescription с offerDescription, и мы устанавливаем localDescription с answerDescription.

Теперь, аналогично offer, мы создаем ответ с той же конфигурацией и обновляем с его помощью callDoc. Как только это будет сделано, peerConnection начнет получать iceCandidates, и мы можем использовать прослушиватель событий onicecandidate, чтобы обновить то же самое в answerCandidates в firestore.

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

Заключение

Это все, что нужно для создания простого приложения для видеовызовов с использованием WebRTC!

WebRTC все еще растет. По оценкам, пользователи браузера Chrome совершают более 1,5 миллиарда минут аудио/видеозвонков в неделю, используя WebRTC и используемые в популярных приложениях, таких как Google Meet, Facebook Messenger, Discord, Amazon Chime и т. д.

Ссылка

WebRTC — Официальный сайт, YouTube

Кодеки для WebRTC —Кодеки WebRTC MDN

Эта статья опубликована в разделе Клуб исследований и разработок пауков, NIT Trichy в веб-среде!