Браузеры без webrtc. Что такое WebRTC и чем он опасен? Как отключить webrtc. Отключение WebRTC Chrome

WebRTC (Web Real Time Communications) — это стандарт, который описывает передачу потоковых аудиоданных, видеоданных и контента от браузера и к браузеру в режиме реального времени без установки плагинов или иных расширений. Стандарт позволяет превратить браузер в оконечный терминал видеоконференцсвязи, достаточно просто открыть веб-страницу, чтобы начать общение.

Что такое WebRTC?

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

Что нужно знать про WebRTC?

Эволюция стандартов и технологий видеосвязи Сергей Юцайтис, Cisco, Видео+Конференция 2016 Как работает WebRTCНа стороне клиента
  • Пользователь открывает страницу, содержащую HTML5 тег .
  • Браузер запрашивает доступ к веб-камере и микрофону пользователя.
  • JavaScript код на странице пользователя контролирует параметры соединения (IP-адреса и порты сервера WebRTC или других WebRTC клиентов) для обхода NAT и Firewall.
  • При получении информации о собеседнике или о потоке со смикшированной на сервере конференцией, браузер начинает согласование используемых аудио и видео кодеков.
  • Начинается процесс кодирования и передача потоковых данных между WebRTC клиентами (в нашем случае, между браузером и сервером).
На стороне WebRTC сервера

Для обмена данными между двумя участниками видеосервер не требуется, но если нужно объединить в одной конференции несколько участников, сервер необходим.



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

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

Преимущества стандарта
  • Не требуется установка ПО.
  • Очень высокое качество связи, благодаря:
    • Использованию современных видео (VP8, H.264) и аудиокодеков (Opus).
    • Автоматическое подстраивание качества потока под условия соединения.
    • Встроенная система эхо- и шумоподавления.
    • Автоматическая регулировка уровня чувствительности микрофонов участников (АРУ).
  • Высокий уровень безопасности: все соединения защищены и зашифрованы согласно протоколам TLS и SRTP.
  • Есть встроенный механизм захвата контента, например, рабочего стола.
  • Возможность реализации любого интерфейса управления на основе HTML5 и JavaScript.
  • Возможность интеграции интерфейса с любыми back-end системами с помощью WebSockets.
  • Проект с открытым исходным кодом — можно внедрить в свой продукт или сервис.
  • Настоящая кросс-платформенность: одно и то же WebRTC приложение будет одинаково хорошо работать на любой операционной системе, десктопной или мобильной, при условии, что браузер поддерживает WebRTC. Это значительно экономит ресурсы на разработку ПО.
Недостатки стандарта
  • Для организации групповых аудио и видеоконференций требуется сервер ВКС, который бы микшировал видео и звук от участников, т.к. браузер не умеет синхронизировать несколько входящих потоков между собой.
  • Все WebRTC решения несовместимы между собой, т.к. стандарт описывает лишь способы передачи видео и звука, оставляя реализацию способов адресации абонентов, отслеживания их доступности, обмена сообщениями и файлами, планирования и прочего за вендором.
  • Другими словами вы не сможете позвонить из WebRTC приложения одного разработчика в WebRTC приложение другого разработчика.
  • Микширование групповых конференций требует больших вычислительных ресурсов, поэтому такой тип видеосвязи требует покупки платной подписки либо инвестирования в свою инфраструктуру, где на каждую конференцию требуется 1 физическое ядро современного процессора.
Секреты WebRTC: как вендоры извлекают пользу из прорывной веб-технологии


Цахи Левент-Леви, Bloggeek.me, Видео+Конференция 2015 WebRTC для рынка ВКСУвеличение числа ВКС-терминалов

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

Использование в специализированных решениях

Использование различных JavaScript библиотек и API облачных сервисов с поддержкой WebRTC позволяет легко добавить поддержку видеосвязи в любые веб-проекты. Ранее для передачи данных в реальном времени разработчикам приходилось изучать принципы работы протоколов и использовать наработки других компаний, которые чаще всего требовали дополнительного лицензирования, что увеличивало расходы. Уже сейчас WebRTC активно используется в сервисах вида “Позвонить с сайта”, “Онлайн-чат поддержки”, и т.п.

Ex-пользователям Skype для Linux

В 2014 году Microsoft объявила об прекращении поддержки проекта Skype для Linux, что вызвало большое раздражение у IT-специалистов. Технология WebRTC не привязана к операционной системе, а реализована на уровне браузера, т.е. Linux пользователи смогут увидеть в продуктах и сервисах на основе WebRTC полноценную замену Skype.

Конкуренция с Flash

WebRTC и HTML5 стали смертельным ударом для технологии Flash, которая и так переживала свои далеко не лучшие годы. С 2017 года ведущие браузеры официально перестали поддерживать Flash и технология окончательно исчезла с рынка. Но нужно отдать Flash должное, ведь именно он создал рынок веб-конференций и предложил технические возможности для живого общения в браузерах.

Видеопрезентации WebRTC

Дмитрий Одинцов, TrueConf, Видео+Конференция октябрь 2017

Кодеки в WebRTCАудиокодеки

Для сжатия аудио-трафика в WebRTC используются кодеки Opus и G.711.

G.711 — самый старый голосовой кодек с высоким битрейтом (64 kbps), который чаще всего применяется в системах традиционной телефонии. Основным достоинством является минимальная вычислительная нагрузка из-за использования легких алгоритмов сжатия. Кодек отличается низким уровнем компрессии голосовых сигналов и не вносит дополнительной задержки звука во время общения между пользователями.

G.711 поддерживается большим количеством устройств. Системы, в которых используется этот кодек, более легкие в применении, чем те, которые основаны на других аудиокодеках (G.723, G.726, G.728 и т.д.). По качеству G.711 получил оценку 4.2 в тестировании MOS (оценка в пределах 4-5 является самой высокой и означает хорошее качество, аналогичное качеству передачи голосового трафика в ISDN и даже выше).

Opus — это кодек с низкой задержкой кодирования (от 2.5 мс до 60 мс), поддержкой переменного битрейта и высоким уровнем сжатия, что идеально подходит для передачи потокового аудиосигнала в сетях с переменной пропускной способностью. Opus - гибридное решение, сочетающее в себе лучшие характеристики кодеков SILK (компрессия голоса, устранение искажений человеческой речи) и CELT (кодирование аудиоданных). Кодек находится в свободном доступе, разработчикам, которые его используют, не нужно платить отчисления правообладателям. По сравнению с другими аудиокодеками, Opus, несомненно, выигрывает по множеству показателей. Он затмил довольно популярные кодеки с низким битрейтом, такие, как MP3, Vorbis, AAC LC. Opus восстанавливает наиболее приближенную к оригиналу “картину” звука, чем AMR-WB и Speex. За этим кодеком - будущее, именно поэтому создатели технологии WebRTC включили его в обязательный ряд поддерживаемых аудиостандартов.

Видеокодеки

Вопросы выбора видеокодека для WebRTC заняли у разработчиков несколько лет, в итоге решили использовать H.264 и VP8. Практически все современные браузеры поддерживают оба кодека. Серверам видеоконференций для работы с WebRTC достаточно поддержать только один.

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

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

Компании Google и Mozilla активно продвигают кодек VP8, а Microsoft, Apple и Cisco — H.264 (для обеспечения совместимости с традиционными системами видеоконференцсвязи). И вот тут возникакет очень большая проблема для разработчиков облачных WebRTC решений, ведь если в конференции все участники используют один браузер, то конференцию достаточно микшировать один раз одним кодеком, а если браузеры разные и среди них есть Safari / Edge, то конференцию придётся кодировать два раза разными кодеками, что в два раза повысит системные требования к медиа-серверу и как следствие, стоимость подписок на WebRTC сервисы.

WebRTC API

Технология WebRTC базируется на трех основных API:

  • (отвечает за принятие веб-браузером аудио и видеосигнала от камер или рабочего стола пользователя).
  • RTCPeerConnection (отвечает за соединение между браузерами для “обмена” полученными от камеры, микрофона и рабочего стола, медиаданными. Также в “обязанности” этого API входит обработка сигнала (очистка его от посторонних шумов, регулировка громкости микрофона) и контроль над используемыми аудио и видеокодеками).
  • RTCData Channel (обеспечивает двустороннюю передачу данных через установленное соединение).

Прежде чем получить доступ к микрофону и камере пользователя, браузер запрашивает на это разрешение. В Google Chrome можно заранее настроить доступ в разделе “Настройки”, в Opera и Firefox выбор устройств осуществляется непосредственно в момент получения доступа, из выпадающего списка. Запрос на разрешение будет появляться всегда при использовании протокола HTTP и однократно, если использовать HTTPS:


RTCPeerConnection . Каждый браузер, участвующий в WebRTC конференции, должен иметь доступ к данному объекту. Благодаря использованию RTCPeerConnection медиаданные от одного браузера к другому могут проходить даже через NAT и сетевые экраны. Для успешной передачи медиапотоков участники должны обменяться следующими данными с помощью транспорта, например, веб-сокетов:

  • участник-инициатор направляет второму участнику Offer-SDP (структура данных, с характеристиками медиапотока, которые он будет передавать);
  • второй участник формирует “ответ” — Answer-SDP и пересылает его инициатору;
  • затем между участниками организуется обмен ICE-кандидатами, если таковые обнаружены (если участники находятся за NAT или сетевыми экранами).

После успешного завершения данного обмена между участниками организуется непосредственно передача медиапотоков (аудио и видео).

RTCData Channel . Поддержка протокола Data Channel появилась в браузерах сравнительно недавно, поэтому данный API можно рассматривать исключительно в случаях использования WebRTC в браузерах Mozilla Firefox 22+ и Google Chrome 26+. С его помощью участники могут обмениваться текстовыми сообщениями в браузере.

Подключение по WebRTCПоддерживаемые десктопные браузеры
  • Google Chrome (17+) и все браузеры на основе движка Chromium;
  • Mozilla FireFox (18+);
  • Opera (12+);
  • Safari (11+);
Поддерживаемые мобильные браузеры для Android
  • Google Chrome (28+);
  • Mozilla Firefox (24+);
  • Opera Mobile (12+);
  • Safari (11+).
WebRTC, Microsoft и Internet Explorer

Очень долго Microsoft хранила молчание по поводу поддержки WebRTC в Internet Explorer и в своём новым браузере Edge. Ребята из Редмонда не очень любят давать в руки пользователей технологии, которые они не контролируют, вот такая вот политика. Но постепенно дело сдвинулось с мёртвой точки, т.к. игнорировать WebRTC далее было уже нельзя, и был анонсирован проект ORTC, производный от стандарта WebRTC.

По словам разработчиков ORTC — это расширение стандарта WebRTC с улучшенным набором API на основе JavaScript и HTML5, что в переводе на обычный язык означает, что всё будет то же самое, только контролировать стандарт и его развитие будет Microsoft, а не Google. Набор кодеков расширен поддержкой H.264 и некоторым аудиокодеками серии G.7ХХ, используемыми в телефонии и аппаратных ВКС системах. Возможно появится встроенная поддержка RDP (для передачи контента) и обмена сообщениями. Кстати, пользователям Internet Explorer не повезло, поддержка ORTC будет только в Edge. Ну и, естественно, такой набор протоколов и кодеков малой кровью стыкуется со Skype for Business, что открывает для WebRTC ещё больше бизнес применений.

Как известно, многие современные браузеры поддерживают протокол WebRTC , что может быть причиной утечки реального IP -адреса даже при использовании VPN. Тема уже поднималась в моем блоге, настал черёд рассказать об этом в подробностях, с конкретными советами как определить и, при необходимости, отключить Real-Time Communications (с англ. "коммуникации в реальном времени") в популярных программах , Chrome, Yandex.Browser, Opera и Vivaldi.

WebRTC – общедоступный проект, поддерживаемый компаниями Google и Mozilla, который разрешает онлайн-передачу потоковых данных без плагинов, только при помощи API на базе Javascript. В WebRTC задействованы видеокодеки VP8 и H.264, а также два аудиокодека, G711 и OPUS. Благодаря технологии, веб-серферы имеют возможность общаться между собой, а сайты – организовывать голосовые и видеочаты с посетителями.

Вроде бы "полезность" востребованная, в чем подвох?

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

  • обычные проверки IP -адреса показывают только адрес VPN -сервера, а не реальный IP компьютера;
  • проверка утечки WebRTC фиксирует локальный и удаленный IP -адрес десктопа (ноутбука).

Другими словами, Real-Time Communications дают сайтам максимум идентифицирующей информации, даже при "сидении" на VPN или прокси.

Проверяем использование WebRTC в браузере

Все просто: в и обозревателях на его движке (Opera / / Vivaldi) скопируйте в адресную строку команду chrome://webrtc-internals и нажмите "Enter ", дабы отобразить соответствующие соединения.

Аналогичным образом, в Mozilla Firefox откройте страницу about:webrtc , где обратите внимание на раздел "Статистика сессии ".

Important!

Отображение WebRTC -соединений не означает, что была 100% утечка вашего локального и удаленного IP .

Отключаем WebRTC в Firefox, Chrome, Яндекс.Браузере, Opera, Vivaldi

  • Для блокировки утечки в Firefox наберите в адресной строке about:config и задействуйте клавишу "Enter " → не пугаясь "грозной" надписи, щелкните по "Я обещаю, что буду осторожен!" → скопируйте в окно поиска media.peerconnection.enabled и дважды кликните по найденному параметру, сменив значение с "true " на "false ".

  • К чести , деактивация WebRTC интегрирована в основные настройки программы, смотрите в меню "Инструменты " одноименный пункт ("горячая" комбинация "Alt + P ") → "Приватность " → снимите галку с опции "Транслировать IP для лучшей производительности WebRTC ".
  • Дабы отключить "коммуникации в реальном времени" в Chrome / Yandex.Browser / Opera, найдите в Интернет-магазине Google и установите в браузер расширение uBlock Origin либо WebRTC Leak Prevent.

Important!

Дмитрий dmitry_spb Евдокимов

Как отключить WebRTC в браузере

Использование WebRTC позволяет определяет ваш фактический IP-адрес. Если у вас нет необходимости использовать этот протокол, то лучше всего будет отключить его использование в .

Протокол WebRTC (Web Real-Time Communication) позволяет передавать видеопоток без программного обеспечения, плагинов и с минимальной задержкой. WebRTC поддерживается всеми основными браузерами: , Safari, Microsoft Edge и . Но проблема в том, что этот протокол может раскрыть ваш реальный IP-адрес, даже если вы пользуетесь VPN-сервисами. При отправке запросов на серверы STUN можно получить внешние и локальные IP-адреса пользователя.


Лучшим решением защиты от утечки IP-адреса будет отключение WebRTC в . Проверьте, .

Как отключить WebRTC в браузерах Chrome, Firefox, Opera и Яндекс

В самых популярных браузерах надёжнее всего будет воспользоваться . Скачать:

  • Для Google Chrome: WebRTC Control
  • Для Mozilla Firefox: WebRTC Control
  • Для Opera:WebRTC Control
  • Для Яндекс.Браузера: WebRTC Control (УСТАНОВКА через Дополнения)
Как отключить WebRTC в Microsoft Edge

Для частичного отключения WebRTC в браузере Microsoft Edge:

1. Введите about:flags в адресной строке браузера.

2. Включите Скрывать мой локальный IP-адрес при использовании подключений WebRTC .

3. Перезапустите браузер.

Как отключить WebRTC в браузере Safari на macOS

1. Safari > Настройки > Дополнения .

2. Включите Показывать меню «Разработка» строке в меню .

3. Перейдите в меню Разработка > Экспериментальные функции

4. Включите Remove Legacy WebRTC API .

Как отключить WebRTC в Chrome на Android

Для отключения WebRTC в браузере Google Chrome на введите в адресной строке браузера следующий текст:

Chrome://flags/#disable-webrtc

Установите параметр в значение enable . Перезапустите Google Chrome и после этого WebRTC будет отключен.

Как отключить WebRTC в Safari на iOS

Для отключения WebRTC в Safari на зайдите в настройки ОС:

1. Откройте: Настройки > Safari > Дополнения > Experimental Features .

2. Включите функцию Remove Legacy WebRTC API для отключения технологии WebRTC на iOS.

Спасибо, что читаете! Подписывайтесь на мой канал в Telegram и Яндекс.Дзен . Только там последние обновления блога и новости мира информационных технологий. Также, читайте меня в социальных сетях:

Технологиям для звонков из браузера уже много лет: Java, ActiveX, Adobe Flash... В последние несколько лет стало ясно, что плагины и левые виртуальные машины не блещут удобством (зачем мне вообще что-то устанавливать?) и, самое главное, безопасностью. Что же делать? Выход есть!

До последнего времени в IP-сетях использовалось несколько протоколов для IP-телефонии или видео: SIP, наиболее распространенный протокол, сходящие со сцены H.323 и MGCP, Jabber/Jingle (используемый в Gtalk), полуоткрытые Adobe RTMP* и, конечно, закрытый Skype. Проект WebRTC, инициированный Google, пытается перевернуть положение дел в мире IP- и веб-телефонии, сделав ненужными все программные телефоны, включая Skype. WebRTC не просто реализует все коммуникационные возможности непосредственно внутри браузера, установленного сейчас практически на каждом устройстве, но пытается одновременно решить более общую задачу коммуникаций между пользователями браузеров (обмен различными данными, трансляция экранов, совместная работа с документами и многое другое).

WebRTC со стороны веб-разработчика

С точки зрения веб-разработчика WebRTC состоит из двух основных частей:

  • управление медиапотоками от локальных ресурсов (камеры, микрофона или экрана локального компьютера) реализуется методом navigator.getUserMedia, возвращающим объект MediaStream;
  • peer-to-peer коммуникации между устройствами, генерирующими медиапотоки, включая определение способов связи и непосредственно их передачу - объекты RTCPeerConnection (для отправки и получения аудио- и видеопотоков) и RTCDataChannel (для отправки и получения данных из браузера).
Что будем делать?

Мы разберемся, как организовать простейший многопользовательский видеочат между браузерами на основе WebRTC с использованием веб-сокетов. Экспериментировать начнем в Chrome/Chromium, как наиболее продвинутых в плане WebRTC браузерах, хотя вышедший 24 июня Firefox 22 почти их догнал. Нужно сказать, что стандарт еще не принят, и от версии к версии API может меняться. Все примеры проверялись в Chromium 28. Для простоты не будем следить за чистотой кода и кросс-браузерностью.

MediaStream

Первый и самый простой компонент WebRTC - MediaStream. Он предоставляет браузеру доступ к медиапотокам с камеры и микрофона локального компьютера. В Chrome для этого необходимо вызвать функцию navigator.webkitGetUserMedia() (так как стандарт еще не завершен, все функции идут с префиксом, и в Firefox эта же функция называется navigator.mozGetUserMedia()). При ее вызове пользователю будет выведен запрос о разрешении доступа к камере и микрофону. Продолжить звонок можно будет только после того, как пользователь даст свое согласие. В качестве параметров этой функции передаются параметры требуемого медиапотока и две callback-функции: первая будет вызвана в случае успешного получения доступа к камере/микрофону, вторая - в случае ошибки. Для начала создадим HTML-файл rtctest1.html с кнопкой и элементом :

WebRTC - первое знакомство video { height: 240px; width: 320px; border: 1px solid grey; } getUserMedia

Microsoft CU-RTC-Web

Microsoft не была бы Microsoft, если бы в ответ на инициативу Google не выпустила немедленно свой собственный несовместимый нестандартный вариант под названием CU-RTC-Web (html5labs.interoperabilitybridges.com/cu-rtc-web/cu-rtc-web.htm). Хотя доля IE, и так небольшая, продолжает сокращаться, количество пользователей Skype дает Microsoft надежду потеснить Google, и можно предположить, что именно этот стандарт будет использоваться в браузерной версии Skype. Стандарт Google ориентирован в первую очередь на коммуникации между браузерами; в то же время основная часть голосового трафика по-прежнему остается в обычной телефонной сети, и шлюзы между ней и IP-сетями необходимы не только для удобства использования или более быстрого распространения, но и в качестве средства монетизации, которое позволит большему числу игроков их развивать. Появление еще одного стандарта может не только привести к неприятной необходимости разработчикам поддерживать сразу две несовместимых технологии, но и в перспективе дать пользователю более широкий выбор возможного функционала и доступных технических решений. Поживем - увидим.

Включение локального потока

Внутри тегов нашего HTML-файла объявим глобальную переменную для медиапотока:

Var localStream = null;

Первым параметром методу getUserMedia необходимо указать параметры запрашиваемого медиапотока - например просто включить аудио или видео:

Var streamConstraints = { "audio": true, "video": true }; // Запрашиваем доступ и к аудио, и к видео

Либо указать дополнительные параметры:

Var streamConstraints = { "audio": true, "video": { "mandatory": { "maxWidth": "320", "maxHeight": "240", "maxFrameRate": "5" }, "optional": } };

Вторым параметром методу getUserMedia необходимо передать callback-функцию, которая будет вызвана в случае его успешного выполнения:

Function getUserMedia_success(stream) { console.log("getUserMedia_success():", stream); localVideo1.src = URL.createObjectURL(stream); // Подключаем медиапоток к HTML-элементу localStream = stream; // и сохраняем в глобальной переменной для дальнейшего использования }

Третий параметр - callback-функция обработчик ошибки, который будет вызван в случае ошибки

Function getUserMedia_error(error) { console.log("getUserMedia_error():", error); }

Собственно вызов метода getUserMedia - запрос доступа к микрофону и камере при нажатии на первую кнопку

Function getUserMedia_click() { console.log("getUserMedia_click()"); navigator.webkitGetUserMedia(streamConstraints, getUserMedia_success, getUserMedia_error); }

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

NavigatorUserMediaError {code: 1, PERMISSION_DENIED: 1}"

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

Выбрать устройства, к которым получит доступ Chrome, можно в Settings («Настройки»), линк Show advanced settings («Показать дополнительные настройки»), раздел Privacy («Личные данные»), кнопка Content («Настройки контента»). В браузерах Firefox и Opera выбор устройств осуществляется из выпадающего списка непосредственно при разрешении доступа.

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

Обрати внимание на пульсирующий кружок в иконке на закладке и значок камеры в правой части адресной строки:

RTCMediaConnection

RTCMediaConnection - объект, предназначенный для установления и передачи медиапотоков по сети между участниками. Кроме того, этот объект отвечает за формирование описания медиасессии (SDP), получение информации об ICE-кандидатах для прохождения через NAT или сетевые экраны (локальные и с помощью STUN) и взаимодействие с TURN-сервером. У каждого участника должно быть по одному RTCMediaConnection на каждое соединение. Медиапотоки передаются по шифрованному протоколу SRTP.

TURN-серверы

ICE-кандидаты бывают трех типов: host, srflx и relay. Host содержат информацию, полученную локально, srflx - то, как узел выглядит для внешнего сервера (STUN), и relay - информация для проксирования трафика через TURN-сервер. Если наш узел находится за NAT’ом, то host-кандидаты будут содержать локальные адреса и будут бесполезны, кандидаты srflx помогут только при определенных видах NAT и relay будут последней надеждой пропустить трафик через промежуточный сервер.

Пример ICE-кандидата типа host, с адресом 192.168.1.37 и портом udp/34022:

A=candidate:337499441 2 udp 2113937151 192.168.1.37 34022 typ host generation 0

Общий формат для задания STUN/TURN-серверов:

Var servers = { "iceServers": [ { "url": "stun:stun.stunprotocol.org:3478" }, { "url": "turn:user@host:port", "credential": "password" } ]};

Публичных STUN-серверов в интернете много. Большой список, например, есть . К сожалению, решают они слишком малую часть проблем. Публичных же TURN-серверов, в отличие от STUN, практически нет. Связано это с тем, что TURN-сервер пропускает через себя медиапотоки, которые могут значительно загружать и сетевой канал, и сам сервер. Поэтому самый простой способ подключиться к TURN-серверам - установить его самому (понятно, что потребуется публичный IP). Из всех серверов, на мой взгляд, наилучший rfc5766-turn-server . Под него есть даже готовый образ для Amazon EC2.

С TURN пока не все так хорошо, как хотелось бы, но идет активная разработка, и хочется надеяться, через какое-то время WebRTC если не сравняется со Skype по качеству прохождения через трансляцию адресов (NAT) и сетевые экраны, то по крайней мере заметно приблизится.

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


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

Модель offer-answer

Для установления и изменения медиапотоков используется модель offer/answer (предложение/ответ; описана в RFC3264) и протокол SDP (Session Description Protocol). Они же используются и протоколом SIP. В этой модели выделяется два агента: Offerer - тот, кто генерирует SDP-описание сессии для создания новой или модификации существующей (Offer SDP), и Answerer - тот, кто получает SDP-описание сессии от другого агента и отвечает ему собственным описанием сессии (Answer SDP). При этом в спецификации требуется наличие протокола более высокого уровня (например, SIP или собственного поверх веб-сокетов, как в нашем случае), отвечающего за передачу SDP между агентами.

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

  • Первый участник, инициирующий соединение, формирует Offer, в котором передает структуру данных SDP (этот же протокол для той же цели используется в SIP), описывающую возможные характеристики медиапотока, который он собирается начать передавать. Этот блок данных необходимо передать второму участнику. Второй участник формирует Answer, со своим SDP и пересылает его первому.
  • И первый и второй участники выполняют процедуру определения возможных ICE-кандидатов, с помощью которых к ним сможет передать медиапоток второй участник. По мере определения кандидатов информация о них должна передаваться другому участнику.

Формирование Offer

Для формирования Offer нам понадобятся две функции. Первая будет вызываться в случае его успешного формирования. Второй параметр метода createOffer() - callback-функция, вызываемая в случае ошибки при его выполнении (при условии, что локальный поток уже доступен).

Дополнительно понадобятся два обработчика событий: onicecandidate при определении нового ICE-кандидата и onaddstream при подключении медиапотока от дальней стороны. Вернемся к нашему файлу. Добавим в HTML после строк с элементами еще одну:

createOffer

И после строки с элементом (на будущее):


Также в начале JavaScript-кода объявим глобальную переменную для RTCPeerConnection:

Var pc1;

При вызове конструктора RTCPeerConnection необходимо указать STUN/TURN-серверы. Подробнее о них см. врезку; пока все участники находятся в одной сети, они не требуются.

Var servers = null;

Параметры для подготовки Offer SDP

Var offerConstraints = {};

Первый параметр метода createOffer() - callback-функция, вызываемая при успешном формировании Offer

Function pc1_createOffer_success(desc) { console.log("pc1_createOffer_success(): \ndesc.sdp:\n"+desc.sdp+"desc:", desc); pc1.setLocalDescription(desc); // Зададим RTCPeerConnection, сформированный Offer SDP методом setLocalDescription. // Когда дальняя сторона пришлет свой Answer SDP, его нужно будет задать методом setRemoteDescription // Пока вторая сторона не реализована, ничего не делаем // pc2_receivedOffer(desc); }

Второй параметр - callback-функция, которая будет вызвана в случае ошибки

Function pc1_createOffer_error(error){ console.log("pc1_createOffer_success_error(): error:", error); }

И объявим callback-функцию, которой будут передаваться ICE-кандидаты по мере их определения:

Function pc1_onicecandidate(event){ if (event.candidate) { console.log("pc1_onicecandidate():\n"+ event.candidate.candidate.replace("\r\n", ""), event.candidate); // Пока вторая сторона не реализована, ничего не делаем // pc2.addIceCandidate(new RTCIceCandidate(event.candidate)); } }

А также callback-функцию для добавления медиапотока от дальней стороны (на будущее, так как пока у нас только один RTCPeerConnection):

Function pc1_onaddstream(event) { console.log("pc_onaddstream()"); remoteVideo1.src = URL.createObjectURL(event.stream); }

При нажатии на кнопку «createOffer» создадим RTCPeerConnection, зададим методы onicecandidate и onaddstream и запросим формирование Offer SDP, вызвав метод createOffer():

Function createOffer_click() { console.log("createOffer_click()"); pc1 = new webkitRTCPeerConnection(servers); // Создаем RTCPeerConnection pc1.onicecandidate = pc1_onicecandidate; // Callback-функция для обработки ICE-кандидатов pc1.onaddstream = pc1_onaddstream; // Callback-функция, вызываемая при появлении медиапотока от дальней стороны. Пока что его нет pc1.addStream(localStream); // Передадим локальный медиапоток (предполагаем, что он уже получен) pc1.createOffer(// И собственно запрашиваем формирование Offer pc1_createOffer_success, pc1_createOffer_error, offerConstraints); }

Сохраним файл как rtctest2.html, выложим его на сервер, откроем в браузере и посмотрим в консоли, какие данные формируются во время его работы. Второе видео пока не появится, так как участник всего один. Напомним, SDP - описание параметров медиасессии, доступные кодеки, медиапотоки, а ICE-кандидаты - возможные варианты подключения к данному участнику.

Формирование Answer SDP и обмен ICE-кандидатами

И Offer SDP, и каждого из ICE-кандидатов необходимо передать другой стороне и там после их получения у RTCPeerConnection вызвать методы setRemoteDescription для Offer SDP и addIceCandidate для каждого ICE-кандидата, полученного от дальней стороны; аналогично в обратную сторону для Answer SDP и удаленных ICE-кандидатов. Сам Answer SDP формируется аналогично Offer; разница в том, что вызывается не метод createOffer, а метод createAnswer и перед этим RTCPeerConnection методом setRemoteDescription передается Offer SDP, полученный от вызывающей стороны.

Добавим еще один видеоэлемент в HTML:

И глобальную переменную для второго RTCPeerConnection под объявлением первой:

Var pc2;

Обработка Offer и Answer SDP

Формирование Answer SDP очень похоже на Offer. В callback-функции, вызываемой при успешном формировании Answer, аналогично Offer, отдадим локальное описание и передадим полученный Answer SDP первому участнику:

Function pc2_createAnswer_success(desc) { pc2.setLocalDescription(desc); console.log("pc2_createAnswer_success()", desc.sdp); pc1.setRemoteDescription(desc); }

Callback-функция, вызываемая в случае ошибки при формировании Answer, полностью аналогична Offer:

Function pc2_createAnswer_error(error) { console.log("pc2_createAnswer_error():", error); }

Параметры для формирования Answer SDP:

Var answerConstraints = { "mandatory": { "OfferToReceiveAudio":true, "OfferToReceiveVideo":true } };

При получении Offer вторым участником создадим RTCPeerConnection и сформируем Answer аналогично Offer:

Function pc2_receivedOffer(desc) { console.log("pc2_receiveOffer()", desc); // Создаем объект RTCPeerConnection для второго участника аналогично первому pc2 = new webkitRTCPeerConnection(servers); pc2.onicecandidate = pc2_onicecandidate; // Задаем обработчик события при появлении ICE-кандидата pc2.onaddstream = pc_onaddstream; // При появлении потока подключим его к HTML pc2.addStream(localStream); // Передадим локальный медиапоток (в нашем примере у второго участника он тот же, что и у первого) // Теперь, когда второй RTCPeerConnection готов, передадим ему полученный Offer SDP (первому мы передавали локальный поток) pc2.setRemoteDescription(new RTCSessionDescription(desc)); // Запросим у второго соединения формирование данных для сообщения Answer pc2.createAnswer(pc2_createAnswer_success, pc2_createAnswer_error, answerConstraints); }

Для того чтобы в рамках нашего примера передать Offer SDP от первого участника ко второму, раскомментируем в функции pc1createOffer success() строку вызова:

Pc2_receivedOffer(desc);

Чтобы реализовать обработку ICE-кандидатов, раскомментируем в обработчике события готовности ICE-кандидатов первого участника pc1_onicecandidate() его передачу второму:

Pc2.addIceCandidate(new RTCIceCandidate(event.candidate));

Обработчик события готовности ICE-кандидатов второго участника зеркально подобен первому:

Function pc2_onicecandidate(event) { if (event.candidate) { console.log("pc2_onicecandidate():", event.candidate.candidate); pc1.addIceCandidate(new RTCIceCandidate(event.candidate)); } }

Сallback-функцию для добавления медиапотока от первого участника:

Function pc2_onaddstream(event) { console.log("pc_onaddstream()"); remoteVideo2.src = URL.createObjectURL(event.stream); }

Завершение соединения

Добавим еще одну кнопку в HTML

Hang Up

И функцию для завершения соединения

Function btnHangupClick() { // Отключаем локальное видео от HTML-элементов , останавливаем локальный медиапоток, устанавливаем = null localVideo1.src = ""; localStream.stop(); localStream = null; // Для каждого из участников отключаем видео от HTML-элементов , закрываем соединение, устанавливаем указатель = null remoteVideo1.src = ""; pc1.close(); pc1 = null; remoteVideo2.src = ""; pc2.close(); pc2 = null; }

Сохраним как rtctest3.html, выложим на сервер и откроем в браузере. В этом примере реализована двусторонняя передача медиапотоков между двумя RTCPeerConnection в рамках одной закладки браузера. Чтобы организовать через сеть обмен Offer и Answer SDP, ICE-кандидатами между участниками и другой информацией, потребуется вместо прямого вызова процедур реализовать обмен между участниками с помощью какого-либо транспорта, в нашем случае - веб-сокетов.

Трансляция экрана

Функцией getUserMedia можно также захватить экран и транслировать как MediaStream, указав следующие параметры:

Var mediaStreamConstraints = { audio: false, video: { mandatory: { chromeMediaSource: "screen" }, optional: } };

Для успешного доступа к экрану должно выполняться несколько условий:

  • включить флаг снимка экрана в getUserMedia() в chrome://flags/,chrome://flags/;
  • исходный файл должен быть загружен по HTTPS (SSL origin);
  • аудиопоток не должен запрашиваться;
  • не должно выполняться несколько запросов в одной закладке браузера.
Библиотеки для WebRTC

Хотя WebRTC еще и не закончен, уже появилось несколько базирующихся на нем библиотек. JsSIP предназначена для создания браузерных софтфонов, работающих с SIP-коммутаторами, такими как Asterisk и Camalio. PeerJS упростит создание P2P-сетей для обмена данными, а Holla сократит объем разработки, необходимый для P2P-связи из браузеров.

Node.js и socket.io

Для того чтобы организовать обмен SDP и ICE-кандидатами между двумя RTCPeerConnection через сеть, используем Node.js с модулем socket.io.

Установка последней стабильной версии Node.js (для Debian/Ubuntu) описана

$ sudo apt-get install python-software-properties python g++ make $ sudo add-apt-repository ppa:chris-lea/node.js $ sudo apt-get update $ sudo apt-get install nodejs

Установка под другие операционные системы описана

Проверим:

$ echo "sys=require("util"); sys.puts("Test message");" > nodetest1.js $ nodejs nodetest1.js

С помощью npm (Node Package Manager) установим socket.io и дополнительный модуль express:

$ npm install socket.io express

Проверим, создав файл nodetest2.js для серверной части:

$ nano nodetest2.js var app = require("express")() , server = require("http").createServer(app) , io = require("socket.io").listen(server); server.listen(80); // Если порт 80 свободен app.get("/", function (req, res) { // При обращении к корневой странице res.sendfile(__dirname + "/nodetest2.html"); // отдадим HTML-файл }); io.sockets.on("connection", function (socket) { // При подключении socket.emit("server event", { hello: "world" }); // отправим сообщение socket.on("client event", function (data) { // и объявим обработчик события при поступлении сообщения от клиента console.log(data); }); });

И nodetest2.html для клиентской части:

$ nano nodetest2.html var socket = io.connect("/"); // URL сервера веб-сокетов (корневая страница сервера, с которого была загружена страница) socket.on("server event", function (data) { console.log(data); socket.emit("client event", { "name": "value" }); });

Запустим сервер:

$ sudo nodejs nodetest2.js

и откроем страницу http://localhost:80 (если запущен локально на 80-м порту) в браузере. Если все успешно, в консоли JavaScript браузера мы увидим обмен событиями между браузером и сервером при подключении.

Обмен информацией между RTCPeerConnection через веб-сокеты Клиентская часть

Сохраним наш основной пример (rtcdemo3.html) под новым именем rtcdemo4.html. Подключим в элементе библиотеку socket.io:

И в начале сценария JavaScript - подключение к веб-сокетам:

Var socket = io.connect("http://localhost");

Заменим прямой вызов функций другого участника отправкой ему сообщения через веб-сокеты:

Function createOffer_success(desc) { ... // pc2_receivedOffer(desc); socket.emit("offer", desc); ... } function pc2_createAnswer_success(desc) { ... // pc1.setRemoteDescription(desc); socket.emit("answer", desc); } function pc1_onicecandidate(event) { ... // pc2.addIceCandidate(new RTCIceCandidate(event.candidate)); socket.emit("ice1", event.candidate); ... } function pc2_onicecandidate(event) { ... // pc1.addIceCandidate(new RTCIceCandidate(event.candidate)); socket.emit("ice2", event.candidate); ... }

В функции hangup() вместо прямого вызова функций второго участника передадим сообщение через веб-сокеты:

Function btnHangupClick() { ... // remoteVideo2.src = ""; pc2.close(); pc2 = null; socket.emit("hangup", {}); }

И добавим обработчики получения сообщения:

Socket.on("offer", function (data) { console.log("socket.on("offer"):", data); pc2_receivedOffer(data); }); socket.on("answer", function (data) {е console.log("socket.on("answer"):", data); pc1.setRemoteDescription(new RTCSessionDescription(data)); }); socket.on("ice1", function (data) { console.log("socket.on("ice1"):", data); pc2.addIceCandidate(new RTCIceCandidate(data)); }); socket.on("ice2", function (data) { console.log("socket.on("ice2"):", data); pc1.addIceCandidate(new RTCIceCandidate(data)); }); socket.on("hangup", function (data) { console.log("socket.on("hangup"):", data); remoteVideo2.src = ""; pc2.close(); pc2 = null; });

Серверная часть

На серверной стороне сохраним файл nodetest2 под новым именем rtctest4.js и внутри функции io.sockets.on("connection", function (socket) { ... } добавим прием и отправку сообщений клиентов:

Socket.on("offer", function (data) { // При получении сообщения "offer", // так как клиентское соединение в данном примере всего одно, // отправим сообщение обратно через тот же сокет socket.emit("offer", data); // Если бы было необходимо переслать сообщение по всем соединениям, // кроме отправителя: // soket.broadcast.emit("offer", data); }); socket.on("answer", function (data) { socket.emit("answer", data); }); socket.on("ice1", function (data) { socket.emit("ice1", data); }); socket.on("ice2", function (data) { socket.emit("ice2", data); }); socket.on("hangup", function (data) { socket.emit("hangup", data); });

Кроме этого, изменим имя HTML-файла:

// res.sendfile(__dirname + "/nodetest2.html"); // Отдадим HTML-файл res.sendfile(__dirname + "/rtctest4.html");

Запуск сервера:

$ sudo nodejs nodetest2.js

Несмотря на то что код обоих клиентов выполняется в пределах одной и той же закладки браузера, все взаимодействие между участниками в нашем примере полностью осуществляется через сеть и «разнести» участников уже не требует особых сложностей. Впрочем, то, что мы делали, тоже было очень простым - эти технологии и хороши своей простотой в использовании. Пусть иногда и обманчивой. В частности, не будем забывать, что без STUN/TURN-серверов наш пример не сможет работать в присутствии трансляции адресов и сетевых экранов.

Заключение

Получившийся пример очень условен, но если немного универсализировать обработчики событий, чтобы они не различались у вызывающей и вызываемой стороны, вместо двух объектов pc1 и pc2 сделать массив RTCPeerConnection и реализовать динамическое создание и удаление элементов ,то получится вполне пригодный для использования видеочат. В этом уже нет особой специфики, связанной с WebRTC, и пример простейшего видеочата на несколько участников (как и тексты всех примеров статьи) есть на диске, идущем с журналом. Впрочем, и в интернете можно найти уже немало хороших примеров. В частности, при подготовке статьи использовались: simpl.info getUserMedia , simpl.info RTCPeerConnection ,WebRTC Reference App .

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

Стремление обеспечить максимально эффективную передачу потоковых данных между браузерами приводит к появлению всё новых и более совершенных технологий, но они же могут стать источником новых опасений для пользователей, высоко ценящих приватность и безопасность в интернете. Одной из таких технологий является Real-Time Communications или сокращенно , представляющая собой набор API -интерфейсов, используемых, в частности, для обеспечения голосовой и видеосвязи в браузерах.

В настоящее время поддерживают большинство популярных веб-обозревателей, включая Google Chrome , Mozilla Firefox , Opera и Microsoft Edge . Эта полезная во многих отношениях технология имеет, с другой стороны, существенный недостаток, поскольку делает потенциально видимым сайтами реальный IP -пользователя даже в случае использования последним VPN и других инструментов обеспечения приватности в глобальной сети. Не все, однако, сайты используют , но и не все браузеры позволяют его отключать, по крайней мере, через основные настройки. Ниже мы покажем, как отключить в популярных обозревателях, а пока давайте узнаем, как определить, использует ли эту технологию сайт.

Если у вас Google Chrome или иной браузер на базе Chromium (Opera, Yandex и т.д.) , откройте анализируемый веб-ресурс, а затем перейдите в новой вкладке по адресу chrome://webrtc-internals . Если сайт предпринял попытку установить -соединение, вы увидите такую картину, как на скриншоте (адрес сайта будет указан наверху) .

В противном случае страница будет выглядеть вот так:

Если у вас , так же откройте сайт и перейдите в новой вкладке по адресу about:webrtc . Использующий сайт отобразится в разделе «Статистика сессии» , иначе раздел будет пустым.

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

В качестве альтернативы можно воспользоваться расширением , установив его из Магазина дополнений Firefox . А еще лучше скачайте утилиту , запустите и отметьте в списке выведенные ею параметров опцию (расположена в ветке Media, Camera, Mic) .

С Google Chrome всё немного сложнее. В его скрытых настройках нет опции, которая позволяла бы отключать , но это можно попробовать сделать с помощью стороннего расширения SсriptSafe . Будучи установлен, плагин отключает скрипты, в том числе и , жаль вот только, что у способа есть недостаток, ведь никто не может гарантировать, что сайты после этого будут нормально работать. Этот же плагин можно использовать для отключения в Opera и (версии ищите в магазинах дополнений) .