Технологіям для дзвінків з браузера вже багато років: 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 - перше знайомство

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-елементу

Третій параметр - 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: [Email protected]: 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 після рядків з елементами

І після рядка з елементом


Також на початку 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

Для того щоб в рамках нашого прикладу передати Offer SDP від ​​першого учасника до другого, раскомментіруем в функції pc1 createOffer 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

І функцію для завершення з'єднання

Function btnHangupClick () (// Відключаємо локальне відео від HTML-елементів

Збережемо як 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

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

$ 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 відбудеться переворот не тільки в нашому уявленні про голосового і відеозв'язку, а й в тому, як ми сприймаємо інтернет в цілому. WebRTC позиціонується не тільки як технологія для дзвінків з браузера в браузер, а й як технологія комунікацій реального часу. Спільний перегляд, яку ми розібрали, лише невелика частина можливих варіантів його використання. Вже є приклади трансляції екрана (скріншарінга), і спільної роботи, і навіть P2P-мережу доставки контенту на основі браузерів за допомогою RTCDataChannel.

Мета цієї статті - на демонстраційному зразку пирингового відеочату (p2p відеочату) ознайомитися з його структурою та принципом роботи. Для цієї мети скористаємося многопользовательским демонстраційними зразками пирингового відеочату webrtc.io-demo. Його можна завантажити за посиланням: https://github.com/webRTC/webrtc.io-demo/tree/master/site.

Необхідно відзначити, що GitHub - це сайт або веб-сервіс для спільної розробки Web-проектів. На ньому розробники можуть розміщувати коди своїх розробок, обговорювати їх і спілкуватися один з одним. Крім того, деякі великі IT-компанії розміщують свої офіційні репозиторії на цьому сайті. Сервіс є безкоштовним для проектів з відкритим вихідним кодом. GitHub - це сховище бібліотек відкритого, вільного вихідного коду.

Отже, скачаний з GitHub демонстраційний зразок пирингового відеочату, розмістимо на диску C персонального комп'ютера в створеній директорії для нашого застосування "webrtc_demo".


Мал. 1

Як випливає зі структури (рис.1) пірінговий відчути складається з клієнтського script.js і серверного server.js скриптів, реалізованих на мові програмування JavaScript. Скрипт (бібліотека) webrtc.io.js (CLIENT) - забезпечує організацію комунікацій в реальному часі між браузерами по тимчасовій схемі: "клієнт-клієнт", а webrtc.io.js (CLIENT) і webrtc.io.js (SERVER), використовуючи протокол WebSocket, забезпечують дуплексний зв'язок між браузером і веб-сервером по архітектурі "клієнт-сервер".

Скрипт webrtc.io.js (SERVER) входить в бібліотеку webrtc.io і знаходиться в директорії node_modules \ webrtc.io \ lib. Інтерфейс відеочату index.html реалізований на HTML5 та CSS3. Вміст файлів програми webrtc_demo можна подивитися одним з html-редакторів, наприклад "Notepad ++".

Принцип роботи відеочату будемо перевіряти в файлової системиПК. Для запуску сервера (server.js) на ПК необхідно встановити середу виконання node.js. Node.js дозволяє запускати JavaScript-код поза браузера. Завантажити node.js можна за посиланням: http://nodejs.org/ (версія v0.10.13 на 15.07.13). на головній сторінцісайту node.org клацаємо на кнопці download і переходимо на http://nodejs.org/download/. для користувачів windowsспочатку викачуємо win.installer (.msi), потім запускаємо win.installer (.msi) на ПК, і встановлюємо nodejs і "npm package manager" в директорію Program Files.




Мал. 2

Таким чином, node.js складається з середовища розробки та виконання JavaScript коду, а також з набору внутрішніх модулів, які можна встановити за допомогою менеджера або диспетчера пакетів npm.

Для установки модулів необхідно в командному рядку з директорії додатку (наприклад, "webrtc_demo") виконати команду: npm install імя_модуля. В процесі установки модулів npm-менеджер створює папку node_modules в директорії, з якої була виконана установка. В процесі роботи nodejs автоматично підключає модулі з директорії node_modules.

Отже, після установки node.js, відкриваємо командний рядок і оновимо модуль express в папці node_modules директорії webrtc_demo за допомогою менеджера пакетів npm:

C: \ webrtc_demo> npm install express

Модуль express - це веб-фреймворк для node.js або веб-платформа для розробки додатків. Щоб мати глобальний доступ до express, можна встановити його таким чином: npm install -g express.

Потім оновимо модуль webrtc.io:

C: \ webrtc_demo> npm install webrtc.io

Потім в командному рядку запускаємо сервер: server.js:

C: \ webrtc_demo> node server.js


Мал. 3

Все, сервер працює успішно (рисунок 3). Тепер за допомогою веб-браузера можна звернутися до сервера по ip-адресою і завантажити веб-сторінку index.html, з якої веб-браузер буде витягувати код клієнтського скрипта - script.js і код скрипта webrtc.io.js, і виконувати їх. Для роботи пирингового відеочату (для установки з'єднання між двома браузерами) необхідно з двох браузерів, що підтримують webrtc, звернутися по ip-адресою до сигнального сервера, що працює на node.js.

В результаті відкриється інтерфейс клієнтської частини комунікаційного додатки (відеочату) із запитом на дозвіл доступу до камери і мікрофону (рис. 4).



Мал. 4

Після клацання на кнопці "Дозволити" підключаються камера і мікрофон для мультимедійне спілкування. Крім того, через інтерфейс відеочату можна спілкуватися текстовими даними (рис. 5).



Мал. 5

Необхідно відмітити, що . Сервер є сигнальним, і в основному призначений для установки з'єднання між браузерами користувачів. Для роботи серверного скрипта server.js, що забезпечує WebRTC-сигналізацію, використовується Node.js.

Преамбула. P2P відчутина базі WebRTC- це альтернатива Skype і інших засобів зв'язку. Основними елементами p2p відеочату на базі WebRTC є браузері контактний сервер. P2P відеочати - це пирингові відеочати, в яких сервер не приймає участі в передачі інформаційних потоків. Інформація передається безпосередньо між браузерами користувачів (пиринге) без будь-яких додаткових програм. Крім браузерів в p2p відео чатах використовуються контактні сервери, які призначені для реєстрації користувачів, зберігання даних про них і забезпечення комутації між користувачами. Браузери, які підтримують новітні технології WebRTC і HTML5, забезпечують передачу миттєвих текстових повідомлень і файлів, а також забезпечують голосове і відео спілкування в IP мережах.

Отже, чати, веб чати, голосові і відеочати в веб інтерфейсі, IMS, VoIP - це сервіси, які забезпечують комунікації в режимі онлайн через складові мережі з пакетною комутацією. Як правило, комунікаційні сервіси вимагають або установки клієнтських додатків на призначені для користувача пристрої (ПК, смартфони і т.д.), або установки плагінів і розширень в браузери. Сервіси мають свої комунікаційні мережі, більшість з яких побудовані по архітектурі "клієнт-сервер".

Комунікаційні сервіси є додатками, за винятком IMS, в яких канали передачі голосу, відео, даних і тексту не інтегровані. У мережах кожного сервісу застосовуються. Необхідно відзначити, що зазначені програми не можуть одночасно працювати в декількох комунікаційних мережах, тобто додатки, як правило, не можуть взаємодіяти між собою, в результаті чого для кожної комунікаційної мережі необхідно встановлювати окремий додаток.

Проблему інтеграції комунікаційних послуг реального часу (чат, телефонії, відеоконференції), тобто інтеграцію каналів передачі голосу, відео, даних і доступ до них за допомогою однієї програми (браузера) можна вирішити в тимчасових або p2p відео чатах(Пірінгових, point - to - point) на основі протоколу WebRTC. По суті, браузер, що підтримує WebRTC, стає єдиним інтерфейсом для всіх призначених для користувача пристроїв (ПК, смартфонів, Айпад, IP-телефонів, мобільних телефоніві т.д.), які працюють з комунікаційними сервісами.

Саме WebRTC забезпечує реалізацію в браузері всіх технологій, що забезпечують комунікації реального часу. Суть p2p відеочатів полягає в тому, що мультимедійні та текстові дані передаються безпосередньо між браузерами користувачів (віддаленими пиринге) без участі сервера і додаткових програм. Таким чином, браузери не тільки забезпечують доступ практично до всіх інформаційних ресурсів Інтернет, які зберігаються на серверах, а й стають єдиним способом доступу до всіх комунікаційних послуг реального часу і до поштових послуг (голосової пошти, електронній пошті, SMS і т.д.)

Сервери (контактні сервери) p2p відеочатів призначені тільки для реєстрації користувачів, зберігання даних про користувачів і установки з'єднання (комутації) між браузерами користувачів. Перші p2p відеочати були реалізовані із застосуванням flash технологій. Flash p2p відеочати застосовуються, наприклад, в соціальних мережах. Flash p2p відеочати не забезпечують високу якість передачі мультимедійних даних. Крім того, для виведення голосу і відео потоку з мікрофона і відеокамери в p2p flash чатах необхідна установка flash плагінав веб-браузер.

Але до телекомунікаційних сервісів нового покоління відносяться веб-комунікації, Які для спілкування через Інтернет використовують лише браузериі контактні сервери, що підтримують протоколи WebRTCі специфікацію HTML5. Будь-яке призначене для користувача пристрій (ПК, iPad, смартфони і т.д.), забезпечене таким браузером, може забезпечити якісні голосові і відеодзвінки, а також передачу миттєвих текстових повідомлень і файлів.

Отже, новою технологією веб-комунікацій (p2p чатів, відеочатів) є протокол WebRTC. WebRTC спільно з HTML5, CSS3 і JavaScript дозволяють створювати різні веб додатки. WebRT призначений для організації веб-комунікацій (пірінгових мереж) в реальному часі по тимчасовій архітектурі. P2P чати на основі WebRTC забезпечують передачу файлів, а також текстові, голосові та відео спілкування користувачів через Інтернет з використанням тільки веб-браузерів без застосування зовнішніх доповнень і плагінів в браузері.

В p2p чатах сервер використовується тільки для установки p2p з'єднання між двома браузерами. Для створення клієнтської частини p2p чату на базі протоколу WebRTC використовують HTML5, CSS3 і JavaScript. Клієнтську програму взаємодіє з браузерами через API WebRTC.

WebRTC реалізуються трьома JavaScript API:

  • RTCPeerConnection;
  • MediaStream (getUserMedia);
  • RTCDataChannel.

Браузери передають мультимедійні дані по протоколу SRTP, який працює поверх UDP. Оскільки NAT створює проблеми для браузерів (клієнтів), що знаходяться за маршрутизаторами NAT, які використовують p2p з'єднання через мережу Інтернет, то для обходу NAT трансляторів використовується STUN. STUN - це клієнт-серверний протокол, який працює поверх транспортного протоколу UDP. В p2p чатах, як правило, застосовується публічний STUN-сервер, а отримана з нього інформація використовується для UDP-з'єднання між двома браузерами, якщо вони знаходяться за NAT.

Приклади реалізації WebRTC додатків (p2p чатів, голосових і відео веб чатів):
1. P2P відчути Bistri (one-click video chat, p2p чат), виконаний на основі WebRTC, можна відкрити на Bistri. Bistri працює в браузері без установки додаткових програм і плагінів. Суть роботи полягає в наступному: відкрийте p2p відчути по вказаним посиланням, після реєстрації в розпочатому інтерфейсі запросіть партнерів, потім зі списку peer-клієнтів виберіть того партнера, який знаходиться в мережі і клацніть на кнопці "відеодзвінок".

В результаті MediaStream (getUserMedia) виконає захоплення мікрофона веб-камери, а сервер виконає обмін сигнальними повідомленнями з обраним партнером. Після обміну сигнальними повідомленнями PeerConnection API створює канали для передачі голосового і відео потоків. Крім того, Bistri здійснює передачу миттєвих текстових повідомлень і файлів. На рис. 1 представлений скріншот інтерфейсу p2p відеочату Bistri.


Мал. 1. P2P відчути Bistri

2. Twelephone (p2p відчути, p2p чат, SIP Twelephone) - це клієнтську програмупобудовано на базі HTML5 і WebRTC, яке дозволяє здійснювати голосові і відеодзвінки, а також здійснювати передачу миттєвих текстових повідомлень, тобто Twelephone включає тестовий p2p чат, відеочат і SIP Twelephone. Необхідно відзначити, що Twelephone підтримує протокол SIP і тепер можна здійснювати і приймати голосові і відеодзвінки з SIP-телефонів, використовуючи свій аккаунт в Twitter, як номер телефону. Крім того, текстові повідомлення можна вводити голосом через мікрофон, а програма розпізнавання голосу вводить текст в рядок "Send a message".

Twelephone - це веб телефонія, яка функціонує на основі браузера Google Chrome, Починаючи з версії 25, без додаткового програмного забезпечення. Twelephone був розроблений Chris Matthieu. Серверна частина Twelephone побудована на основі Node.js. Сервер (контактний сервер) використовується тільки для установки p2p з'єднання між двома браузерами або WebRTC клієнтами. Додаток Twelephone не має власних коштів авторизації, а орієнтоване на підключення до аккаунту ( облікового запису) В Twitter.

На рис. 2 представлений скріншот інтерфейсу p2p відеочату Twelephone.



Мал. 2. P2P Twelephone

3. Груповий p2p відчути Conversat.io побудований на основі новітніх технологій WebRTC і HTML5. Відчути Conversat розроблений на основі бібліотеки SimpleWebRTC і призначений для спілкування до 6 peer-клієнтів в одній кімнаті (для спілкування вкажіть назву спільної кімнати для peer-клієнтів в рядку "Name the conversation"). P2P відчути Conversat надає комунікаційні послуги користувачам без реєстрації на контактному сервері. На рис. 3 представлений скріншот інтерфейсу p2p відеочату Conversat.



Мал. 3. Груповий P2P відчути Conversat.io

Для участі в P2P чатах на базі WebRTC необхідно щоб у користувачів був встановлений браузер, що підтримує протокол WebRTC і специфікацію HTML5. В даний час браузери Google Chrome, починаючи з версії 25, і Mozilla Firefox Nightly підтримують протокол WebRTC і специфікацію HTML5. WebRTC додатки за якістю передачі зображення і звуку перевершують Flash додатки.

Більшість матеріалу по WebRTCзосереджено на прикладному рівні написання коду і не сприяє розумінню технології. Спробуємо заглибитися і дізнатися як відбувається з'єднання, що таке дескриптор сесії і кандидати, для чого потрібні STUNі TURNсервера.

WebRTC

Вступ

WebRTC - технологія, орієнтована на браузери, яка дозволяє з'єднати два клієнта для відео-передачі даних. Основні особливості - внутрішня підтримка браузерами (не потрібні сторонні впроваджуються технології типу adobe flash ) І здатність з'єднувати клієнтів без використання додаткових серверів - з'єднання peer-to-peer(Далі, p2p).

встановити з'єднання p2p- досить важке завдання, так як комп'ютери не завжди володіють публічними IPадресами, тобто адресами в інтернеті. Через невеликої кількості IPv4адрес (і для цілей безпеки) був розроблений механізм NAT, Який дозволяє створювати приватні мережі, наприклад, для домашнього використання. Багато домашні роутери зараз підтримують NATі завдяки цьому всі домашні пристрої мають вихід в інтернет, хоча провайдери інтернету зазвичай надають один IPадреса. публічні IPадреси - унікальні в інтернеті, а приватні немає. Тому з'єднатися p2p- важко.

Для того, щоб зрозуміти це краще, розглянемо три ситуації: обидва вузла знаходяться в одній мережі (Малюнок 1), Обидва вузла знаходяться в різних мережах (один в приватній, інший в публічній) (Малюнок 2)і обидва вузла знаходяться в різних приватних мережах з однаковими IPадресами (Малюнок 3).

Малюнок 1: Обидва вузла в одній мережі

Малюнок 2: Вузли в різних мережах (один в приватній, інший в публічній)

Малюнок 3: Вузли в різних приватних мережах, але з чисельно рівними адресами

На малюнках вище перша буква в дво-символьних позначеннях означає тип вузла (p = peer, R = router). На першому малюнку ситуація сприятлива: вузли в своїй мережі цілком ідентифікуються мережевими IPадресами і тому можуть підключатися один до одного безпосередньо. На другому малюнку маємо дві різні мережі, у яких схожі нумерації вузлів. Тут з'являються маршрутизатори (роутери), у яких є два мережевих інтерфейсу - всередині своєї мережі і поза своєї мережі. Тому у них два IPадреси. Звичайні вузли мають тільки один інтерфейс, через який вони можуть спілкуватися лише в своїй мережі. Якщо вони передають дані комусь поза своєї мережі, то тільки за допомогою NATвсередині маршрутизатора (роутера) і тому видимі для інших під IPадресою роутера - це їх зовнішній IPадреса. Таким чином, у вузла p1є внутрішній IP = 192.168.0.200 і зовнішній IP = 10.50.200.5 , Причому остання адреса буде зовнішнім також і для всіх інших вузлів в його мережі. Схожа ситуація і для вузла p2. Тому їх зв'язок неможлива, якщо використовувати тільки їх внутрішні (свої) IPадреси. Можна скористатися зовнішніми адресами, тобто адресами роутерів, але, так як у всіх вузлів в одній приватній мережі один і той же зовнішній адресу, то це досить важко. Це проблема вирішується за допомогою механізму NAT

Що ж буде, якщо ми все-таки вирішимо з'єднати вузли через їх внутрішні адреси? Дані не вийдуть за межі мережі. Для посилення ефекту можна уявити ситуацію, зображену на останньому малюнку - у обох вузлів збігаються внутрішні адреси. Якщо вони будуть використовувати їх для комунікації, то кожен вузол буде спілкуватися з самим собою.

WebRTCуспішно справляється з такими проблемами, використовуючи протокол ICE, Який, правда, вимагає використання додаткових серверів ( STUN, TURN). Про все це нижче.

Дві фази WebRTC

Щоб з'єднати два вузла через протокол WebRTC(або просто RTC, Якщо зв'язуються два iPhone'A) необхідно провести якісь попередні дії для встановлення з'єднання. Це перша фаза - щоб установити. Друга фаза - передача відео-даних.

Відразу варто сказати, що, хоч технологія WebRTCв своїй роботі використовує безліч різних способів комунікації ( TCPі UDP) І має гнучке переключення між ними, ця технологія не має протоколу для передачі даних про з'єднання. Тож не дивно, адже підключити два вузла p2pне так-то просто. Тому необхідно мати певний додатковийспосіб передачі даних, ніяк не пов'язаний з WebRTC. Це може бути сокетних передача, протокол HTTP, Це може бути навіть протокол SMTPабо Пошта Росії. Цей механізм передачі початковихданих називається сигнальним. Передавати потрібно не так багато інформації. Всі дані передаються у вигляді тексту і діляться на два типи - SDPі Ice Candidate. Перший тип використовується для встановлення логічного з'єднання, а другий для фізичного. Детально про все це пізніше, а поки лише важливо пам'ятати, що WebRTCдасть нам якусь інформацію, яку потрібно буде передати іншим сайтом. Як тільки ми передамо всю потрібну інформацію, вузли зможуть з'єднатися і більше наша допомога потрібна не буде. Таким чином, сигнальний механізм, який ми повинні реалізувати окремо, буде використовуватися тільки при підключенні, А при передачі відео-даних використовуватися не буде.

Отже, розглянемо першу фазу - фазу встановлення з'єднання. Вона складається з декількох пунктів. Розглянемо цю фазу спочатку для вузла, який ініціює з'єднання, а потім для очікує.

  • Ініціатор (той, хто телефонує - caller):
    1. Пропозиція почати відео-передачу даних (createOffer)
    2. отримання свого SDP SDP)
    3. отримання своїх Ice candidate Ice candidate)
  • Дзвінок дзвінка ( callee):
    1. Отримання локального (свого) медіа потоку і установка його для передачі (getUserMediaStream)
    2. Отримання пропозиції почати відео-передачу даних і створення відповіді (createAnswer)
    3. отримання свого SDPоб'єкта і передача його через сигнальний механізм ( SDP)
    4. отримання своїх Ice candidateоб'єктів і передача їх через сигнальний механізм ( Ice candidate)
    5. Отримання віддаленого (чужого) медіа потоку і відображення його на екрані (onAddStream)

Відмінність лише в другому пункті.

Незважаючи на гадану заплутаність кроків тут їх насправді три: відправка свого медіа потоку (п.1), установка параметрів з'єднання (пп.2-4), отримання чужого медіа потоку (п.5). Найскладніший - другий крок, тому що він складається з двох частин: встановлення фізичногоі логічногоз'єднання. перша вказує шлях, За яким повинні йти пакети, щоб дійти від одного вузла мережі до іншого. друга вказує параметри відео / аудіо- яке використовувати якість, які використовувати кодеки.

подумки етап createOfferабо createAnswerслід з'єднати з етапами передачі SDPі Ice candidateоб'єктів.

Основні сутності

Медіа потоки (MediaStream)

Основний сутністю є медіа потік, тобто потік відео та аудіо даних, картинка і звук. Медіа потоки бувають двох типів - локальні і віддалені. Локальний отримує дані від пристроїв входу (камера, мікрофон), а віддалений по мережі. Таким чином у кожного вузла є і локальний, і віддалений потік. В WebRTCдля потоків існує інтерфейс MediaStreamі також існує підінтерфейсів LocalMediaStreamспеціально для локального потоку. В JavaScriptможна зіткнутися тільки з першим, а якщо використовувати libjingle, То можна зіткнутися і з другим.

В WebRTCіснує досить заплутана ієрархія всередині потоку. Кожен потік може складатися з декількох медіа доріжок ( MediaTrack), Які в свою чергу можуть складатися з декількох медіа каналів ( MediaChannel). Та й самих медіа потоків може бути теж декілька.

Розглянемо все по порядку. Для цього будемо тримати в умі деякий приклад. Припустимо, що ми хочемо передавати не тільки відео себе, але і відео нашого столу, на якому лежить листок паперу, на якому ми збираємося щось писати. Нам знадобиться два відео (ми + стіл) і одне аудіо (ми). Ясно, що ми і стіл варто розділити на різні потоки, тому що ці дані, напевно, слабо залежать одна від одної. Тому у нас буде два MediaStream'A - один для нас і один для столу. Перший буде містити і відео, і аудіо дані, а другий - тільки відео (Малюнок 4).

Малюнок 4: Два різних медіа потоку. Один для нас, один для нашого столу

Відразу ясно, що медіа потік як мінімум повинен включати в себе можливість утримувати дані різних типів- відео та аудіо. Це враховано в технології і тому кожен тип даних реалізується через медіа доріжку MediaTrack. У медіа доріжки є спеціальне властивість kind, Яке і визначає, що перед нами - відео або аудіо (Малюнок 5)

Малюнок 5: Медіа потоки складаються з медіа доріжок

Як буде все відбуватися в програмі? Ми створимо два медіа потоку. Потім створимо дві відео доріжки і одну аудіо доріжку. Отримаємо доступ до камер і мікрофону. Зазначимо кожній доріжці який пристрій використовувати. Додамо відео і аудіо доріжку в перший медіа потік і відео доріжку від іншої камери в другій медіа потік.

Але як ми помітний медіа потоки з яким ведеться розмова? Для цього кожен медіа потік має властивість label- мітка потоку, його назва (Малюнок 6). Таке ж властивість мають і медіа доріжки. Хоча на перший погляд здається, що відео від звуку можна відрізнити і іншими способами.

Малюнок 6: Медіа потоки і доріжки ідентифікуються мітками

Так, а якщо медіа доріжки можна ідентифікувати через мітку, то навіщо нам для нашого прикладу використовувати два медіа потоку, замість одного? Адже можна передавати один медіа потік, а доріжки використовувати в ньому різні. Ми дійшли до важливого властивості медіа потоків - вони синхронізуютьмедіа доріжки. Різні медіа потоки не синхронізуються між собою, але всередині кожного медіа потоку все доріжки відтворюються одночасно.

Таким чином, якщо ми хочемо, щоб наші слова, наші емоції на обличчі і наш листочок паперу відтворювалися одночасно, то варто використовувати один медіа потік. Якщо це не так важливо, то вигідніше використовувати різні потоки - картинка буде більш гладкою.

Якщо якусь доріжку необхідно відключати під час передачі, то можна скористатися властивістю enabledмедіа доріжки.

Насамкінець варто подумати про стерео звук. Як відомо стерео звук - це два різних звуки. І передавати їх треба теж окремо. Для цього використовуються канали MediaChannel. Медіа доріжка звуку може мати багато каналів (наприклад, 6, якщо потрібен звук 5 + 1). Всередині медіа доріжки канали, зрозуміло теж синхронізовані. Для відео зазвичай використовується тільки один канал, але можуть використовуватися і кілька, наприклад, для накладення реклами.

Резюмуючи: ми використовуємо медіа потік для передачі відео і аудіо даних. Усередині кожного медіа потоку дані синхронізовані. Ми можемо використовувати кілька медіа потоків, якщо синхронізація нам не потрібна. Усередині кожного медіа потоку є медіа доріжки двох видів - для відео і для аудіо. Доріжок зазвичай не більше двох, але може бути і більше, якщо потрібно передавати кілька різних відео (співрозмовника і його столу). Кожна доріжка може складатися з декількох каналів, що використовується зазвичай тільки для стерео звуку.

У найпростішій ситуації відеочату у нас буде один локальний медіа потік, який буде складатися з двох доріжок - відео доріжки і аудіо доріжки, кожна з яких буде складатися з одного основного каналу. Відео доріжка відповідає за камеру, аудіо доріжка - за мікрофон, а медіа потік - це контейнер їх обох.

Дескриптор сесії (SDP)

У різних комп'ютерів завжди будуть різні камери, мікрофони, відеокарти та інше обладнання. Існує безліч параметрів, якими вони володіють. Все це необхідно скоординувати для медіа передачі даних між двома вузлами мережі. WebRTCробить це автоматично і створює спеціальний об'єкт - дескриптор сесії SDP. Передайте цей об'єкт іншого вузла, і можна передавати медіа дані. Тільки зв'язку з іншим вузлом поки немає.

Для цього використовується будь-який сигнальний механізм. SDPможна передати хоч через сокети, хоч людиною (повідомити його іншим сайтом по телефону), хоч Поштою Росії. Все дуже просто - Вам дадуть вже готовий SDPі його потрібно переслати. А при отриманні на іншій стороні - передати у відомство WebRTC. Дескриптор сесії зберігається у вигляді тексту і його можна змінити в своїх додатках, але, як правило, це не потрібно. Як приклад, при з'єднанні десктоп↔телефон іноді потрібно примусово вибирати потрібний аудіо кодек.

Зазвичай під час активного з'єднання необхідно вказувати якусь адресу, наприклад URL. Тут в цьому немає необхідності, так як через сигнальний механізм Ви самі відправите дані за призначенням. Щоб вказати WebRTC, Що ми хочемо встановити p2pз'єднання потрібно викликати функцію createOffer. Після виклику цієї функції і вказівки їй спеціального callback'A буде створено SDPоб'єкт і переданий в цей же callback. Все, що від Вас потрібно - передати цей об'єкт по мережі іншого вузла (співрозмовника). Після цього на іншому кінці через сигнальний механізм прийдуть дані, а саме цей SDPоб'єкт. Цей дескриптор сесії для цього вузла чужий і тому несе корисну інформацію. Отримання цього об'єкта - сигнал до початку з'єднання. Тому Ви повинні погодитися на це і викликати функцію createAnswer. Вона - повний аналог createOffer. Знову в Ваш callbackпередадуть локальний дескриптор сесії і його потрібно буде передати по сигнальному механізму назад.

Варто відзначити, що викликати функцію createAnswer можна тільки після отримання чужого SDPоб'єкта. Чому? Тому що локальний SDPоб'єкт, який буде генеруватися при виклику createAnswer, повинен спиратися на віддалений SDPоб'єкт. Тільки в такому випадку можливо скоординувати свої настройки відео з настройками співрозмовника. Також не варто викликати createAnswer і createOffer до отримання локального медіа потоку - їм буде нічого писати в SDPоб'єкт.

Так як в WebRTCє можливість редагування SDPоб'єкта, то після отримання локального дескриптора його потрібно встановити. Це може здатися трохи дивним, що потрібно передавати WebRTCто, що вона сама нам дала, але такий протокол. Коли переходите дескриптора його потрібно теж встановити. Тому Ви повинні на одному вузлі встановити два дескриптора - свій і чужий (тобто локальний і віддалений).

після такого рукостисканнявузли знають про побажання один одного. Наприклад, якщо вузол 1 підтримує кодеки Aі B, А вузол 2 підтримує кодеки Bі C, То, так як кожен вузол знає свій і чужий дескриптори, обидва вузла виберуть кодек B(Малюнок 7). Логіка з'єднання тепер встановлена, і можна передавати медіа потоки, але є інша проблема - вузли і раніше пов'язані лише сигнальним механізмом.


Малюнок 7: Узгодження кодеків

Кандидати (Ice candidate)

технологія WebRTCнамагається заплутати нас своєю новою методологією. При установці з'єднання не вказується адреса того вузла, з яким потрібно з'єднатися. встановлюється спочатку логічнез'єднання, а не фізичне, Хоча завжди робилося навпаки. Але це не здасться дивним, якщо не забувати, що ми використовуємо сторонній сигнальний механізм.

Отже, з'єднання вже встановлено (логічне з'єднання), але поки немає шляху, по якому вузли мережі можуть передавати дані. Тут не все так просто, але почнемо з простого. Нехай вузли знаходяться в одній приватній мережі. Як ми вже знаємо, вони можуть легко з'єднуватися один з одним за своїми внутрішніми IPадресами (або можливо, з якихось інших, якщо використовується не TCP / IP).

через деякі callbackWebRTCповідомляє нам Ice candidateоб'єкти. Вони теж приходять в текстовій формі і також, як з дескрипторами сесії, їх потрібно просто переслати через сигнальний механізм. Якщо дескриптор сесії містив інформацію про наших установках на рівні камери і мікрофона, то кандидати містять інформацію про наш розташуванні в мережі. Передайте їх іншим сайтом, і той зможе фізично з'єднатися з нами, а так як у нього вже є і дескриптор сесії, то і логічно зможе з'єднатися і дані «потечуть». Якщо він не забуде відправити нам і свій об'єкт кандидата, тобто інформацію про те, де знаходиться він сам в мережі, то і ми зможемо з ним з'єднатися. Зауважимо тут ще одна відмінність від класичного клієнт-серверної взаємодії. Спілкування з HTTP сервером відбувається за схемою запит-відповідь, клієнт відправляє дані на сервер, той обробляє їх і шле по адресою, вказаною в пакеті запиту. В WebRTCнеобхідно знати дві адресиі з'єднувати їх з двох сторін.

Різниця від дескрипторів сесії полягає в тому, що встановлювати потрібно тільки віддалених кандидатів. Редагування тут заборонено і не може принести ніякої користі. У деяких реалізаціях WebRTCкандидатів необхідно встановлювати тільки після установки дескрипторів сесії.

А чому дескриптор сесії був один, а кандидатів може бути багато? Тому що розташування в мережі може визначатися не тільки своїм внутрішнім IPадресою, але також і зовнішнім адресою маршрутизатора, і не обов'язково одного, а також адресами TURNсерверів. Залишок параграфа буде присвячений детальному розгляду кандидатів і тому, як з'єднувати вузли з різних приватних мереж.

Отже, два вузла знаходяться в одній мережі (Малюнок 8). Як їх ідентифікувати? За допомогою IPадрес. Більше ніяк. Правда, ще можна використовувати різні транспорти ( TCPі UDP) І різні порти. Це і є та інформація, яка міститься в об'єкті кандидата - IP, PORT, TRANSPORTі якась інша. Нехай, для прикладу, використовується UDPтранспорт і 531 порт.

Малюнок 8: Два вузла знаходяться в одній мережі

Тоді, якщо ми знаходимося в вузлі p1, то WebRTCпередасть нам такий об'єкт кандидата - . Тут наводиться не точна формат, а лише схема. Якщо ми в вузлі p2, То кандидат такий - . Через сигнальний механізм p1отримає кандидата p2(Тобто розташування вузла p2, А саме його IPі PORT). Після чого p1може з'єднатися з p2безпосередньо. Більш правильно, p1буде посилати дані на адресу 10.50.150.3:531 в надії, що вони дійдуть до p2. Не важливо, чи належить ця адреса вузла p2або якогось посередника. Важливо лише те, що через цю адресу дані будуть надсилатися і можуть досягти p2.

Поки вузли в одній мережі - все просто і легко - кожен вузол має тільки один об'єкт кандидата (завжди мається на увазі свій, тобто своє розташування в мережі). Але кандидатів стане набагато більше, коли вузли будуть знаходиться в різнихмережах.

Перейдемо до більш складному випадку. Один вузол буде знаходитися за роутером (точніше, за NAT), а другий вузол буде знаходитися в одній мережі з цим роутером (наприклад, в інтернеті) (Малюнок 9).

Малюнок 9: Один вузол за NAT, іншої немає

Цей випадок має приватне рішення проблеми, яке ми зараз і розглянемо. Домашній роутер зазвичай містить таблицю NAT. Це спеціальних механізм, розроблений для того, щоб вузли усередині приватній мережі роутера змогли звертатися, наприклад, до веб-сайтам.

Припустимо, що веб-сервер з'єднаний з інтернетом безпосередньо, тобто має публічним IP* Адреса. Нехай це буде вузол p2. вузол p1(Веб-клієнт) шле запит на адресу 10.50.200.10 . Спочатку дані потрапляють на роутер r1, А точніше на його внутрішнійінтерфейс 192.168.0.1 . Після чого, роутер запам'ятовує адресу джерела (адреса p1) І заносить його в спеціальну таблицю NAT, Потім змінює адресу джерела на свій ( p1 r1). Далі, за своїм зовнішньомуінтерфейсу роутер пересилає дані безпосередньо на веб-сервер p2. Веб-сервер обробляє дані, генерує відповідь і відправляє назад. відправляє роутера r1, Так як саме він стоїть в зворотній адресі (роутер підмінив адреса на свій). Роутер отримує дані, дивиться в таблицю NATі пересилає дані вузлу p1. Роутер виступає тут як посередник.

А що якщо кілька вузлів з внутрішньої мережі одночасно звертаються до зовнішньої мережі? Як роутер зрозуміє кому відправляти відповідь назад? Ця проблема вирішується за допомогою портів. Коли роутер підміняє адресу вузла на свій, він також підміняє і порт. Якщо два вузла звертаються до інтернету, то роутер підміняє їх порти джерел на різні. Тоді, коли пакет з веб-сервера прийде назад до роутера, то роутер зрозуміє по порту, кому призначений даний пакет. Приклад нижче.

Повернемося до технології WebRTC, А точніше, до її частини, яка використовує ICEпротокол (звідси і Iceкандидати). вузол p2має одного кандидата (своє розташування в мережі - 10.50.200.10 ), А вузол p1, Який знаходиться за роутером з NAT, матиме двох кандидатів - локального ( 192.168.0.200 ) І кандидата роутера ( 10.50.200.5 ). Перший не знадобиться, але він, тим не менш, генерується, так як WebRTCще нічого не знає про віддалений хост - він може перебувати в тій же мережі, а може і ні. Другий кандидат стане в нагоді, і, як ми вже знаємо, важливу роль буде грати порт (щоб пройти через NAT).

Запис в таблиці NATгенерується тільки коли дані виходять з внутрішньої мережі. Тому вузол p1повинен першим передати дані і тільки після цього дані вузла p2зможуть дістатися до вузла p1.

На практиці обидва вузлазнаходитимуться за NAT. Щоб створити запис в таблиці NATкожного роутера, вузли повинні щось відправити віддаленого вузла, але на цей раз ні перший не може дістатися до другого, ні навпаки. Це пов'язано з тим, що вузли не знають своїх зовнішніх IPадрес, а відправляти дані на внутрішні адреси безглуздо.

Однак, якщо зовнішні адреси відомі, то з'єднання буде легко встановлено. Якщо перший вузол відішле дані на роутер другого вузла, то роутер їх проігнорує, так як його таблиця NATпоки порожня. Однак в роутері першого вузла в таблиці NATз'явилася потрібна запис. Якщо тепер другий вузол відправить дані на роутер першого вузла, то роутер їх успішно передасть першому вузлу. Тепер і таблиця NATдругого роутера має потрібні дані.

Проблема в тому, що, щоб дізнатися своєї зовнішній IPадреса, потрібен вузол знаходиться в загальної мережі. Для вирішення такої проблеми використовуються додаткові сервери, які підключені до інтернету безпосередньо. З їх допомогою також створюються заповітні записи в таблиці NAT.

STUN і TURN сервера

при ініціалізації WebRTCнеобхідно вказати доступні STUNі TURNсервера, які ми в подальшому будемо називати ICEсерверами. Якщо серверу не будуть вказані, то з'єднатися зможуть тільки вузли в одній мережі (підключення до неї без NAT). Відразу варто відзначити, що для 3g-мереж обов'язково використання TURNсерверів.

STUN сервер- це просто сервер в інтернеті, який повертає зворотну адресу, тобто адресу вузла відправника. Вузол, що знаходить за роутером, звертається до STUNсервера, щоб пройти через NAT. Пакет, що прийшов до STUNсервера, містить адресу джерела - адреса роутера, тобто зовнішній адресу нашого вузла. Ця адреса STUNсервер і відправляє назад. Таким чином, вузол отримує свій зовнішній IPадреса і порт, через який він доступний з мережі. далі, WebRTCза допомогою цієї адреси створює додаткового кандидата (зовнішній адресу роутера і порт). Тепер в таблиці NATроутера є запис, яка пропускає до нашого вузла пакети, відправлені на роутер за потрібною порту.

Розглянемо цей процес на прикладі.

Приклад (робота STUN сервера)

STUNсервер будемо позначати через s1. Роутер, як і раніше, через r1, А вузол - через p1. Також необхідно буде стежити за таблицею NAT- її позначимо як r1_nat. Причому в цій таблиці зазвичай міститься багато записів від різний вузлів підмережі - вони приводитися не будуть.

Отже, на початку маємо порожню таблицю r1_nat.

Таблиця 2: Заголовок пакета

вузол p1відправляє цей пакет роутера r1(Не важливо яким чином, в різних подсетях можуть бути використані різні технології). Роутера необхідно зробити підміну адреси джерела Src IP, Так як вказаний в пакеті адреса свідомо не підійде для зовнішньої підмережі, більш того, адреси з такого діапазону зарезервовані, і жоден адреса в інтернеті не має такої адреси. Роутер робить підміну в пакеті і створює новий записв своїй таблиці r1_nat. Для цього йому потрібно придумати номер порту. Нагадаємо, що, так як кілька вузлів всередині підмережі можуть звертатися до зовнішньої мережі, то в таблиці NATповинна зберігатися додаткова інформація, Щоб роутер зміг визначити, кому з цих кількох вузлів призначається зворотний пакет від сервера. Нехай роутер придумав порт 888 .

Змінений заголовок пакета:

Таблиця 4: Таблиця NAT поповнилася новим записом

тут IPадреса і порт для підмережі абсолютно такі ж, як у вихідного пакета. Справді, при зворотному передачі ми повинні мати спосіб повністю їх відновити. IPадреса для зовнішньої мережі - це адреса роутера, а порт змінився на придуманий роутером.

Справжній порт, на який вузол p1приймає підключення - це, зрозуміло, 35777 , Але сервер шле дані на фіктивнийпорт 888 , Який буде змінений роутером на справжній 35777 .

Отже, роутер підмінив адресу і порт джерела в заголовку пакета і додав запис в таблицю NAT. Тепер пакет відправляється по мережі серверу, тобто вузлу s1. На вході, s1має такий пакет:

Src IP Src PORT Dest IP Dest PORT
10.50.200.5 888 12.62.100.200 6000

Таблиця 5: STUN сервер отримав пакет

Разом, STUNсервер знає, що йому прийшов пакет від адреси 10.50.200.5:888 . Тепер цю адресу сервер відправляє назад. Тут варто зупинитися і ще раз подивитися, що ми тільки що розглядали. Таблиці, наведені вище - це шматочок з заголовкапакету, зовсім не з його вмісту. Про вміст ми не говорили, тому що це не настільки важливо - воно якось описується в протоколі STUN. Тепер же ми будемо розглядати крім заголовка ще і вміст. Воно буде простим і містити адресу роутера - 10.50.200.5:888 , Хоча взяли ми його з заголовкапакету. Таке робиться не часто, зазвичай протоколам не важлива інформація про адреси вузлів, важливо лише, щоб пакети доставлялися за призначенням. Тут же ми розглядаємо протокол, який встановлює шлях між двома вузлами.

Отже, тепер у нас з'являється другий пакет, який йде в зворотному напрямку:

Таблиця 7: STUN сервер відправляє пакет з таким вмістом

Далі, пакет подорожує по мережі, поки не виявиться на зовнішньому інтерфейсі роутера r1. Роутер розуміє, що пакет призначений не йому. Як він це розуміє? Це можна дізнатися тільки по порту. порт 888 він не використовує для своїх особистих цілей, а використовує для механізму NAT. Тому в цю таблицю роутер і дивиться. Дивиться на стовпець External PORTі шукає рядок, яка співпаде з Dest PORTз пакету, що прийшов, тобто 888 .

Internal IP Internal PORT External IP External PORT
192.168.0.200 35777 10.50.200.5 888

Таблиця 8: Таблиця NAT

Нам пощастило, такий рядок існує. Якби не пощастило, то пакет б просто відкинути. Тепер потрібно зрозуміти, кому з вузлів підмережі треба відправляти цей пакет. Не варто поспішати, давайте знову згадаємо про важливість портів в цьому механізмі. Одночасно два вузла в підмережі могли б відправляти запити в зовнішню мережу. Тоді, якщо для першого вузла роутер придумав порт 888 , То для другого він би придумав порт 889 . Припустимо, що так і сталося, то є таблиця r1_natвиглядає так:

Таблиця 10: Роутер підміняє адресу приймача

Src IP Src PORT Dest IP Dest PORT
12.62.100.200 6000 192.168.0.200 35777

Таблиця 11: Роутер підмінив адреса приймача

Пакет успішно приходить до вузла p1і, подивившись на вміст пакета, вузол дізнається про свій зовнішній IPадресу, тобто про адресу роутера в зовнішній мережі. Також він знає і порт, який роутер пропускає через NAT.

Що ж далі? Яка від цього всього користь? Користь - це запис в таблиці r1_nat. Якщо тепер хто завгодно буде відправляти на роутер r1пакет з портом 888 , То роутер перенаправляє цей пакет вузлу p1. Таким чином, створився невеликий вузький прохід до захованих вузлу p1.

З прикладу вище можна отримати деяке уявлення про роботу NATі суті STUNсервера. Взагалі, механізм ICEі STUN / TURNсервера якраз і спрямовані на подолання обмежень NAT.

Між вузлом і сервером може стояти не один роутер, а кілька. В такому випадку вузол отримає адресу того роутера, який є першим виходить в ту ж мережу, що і сервер. Іншими словами, отримаємо адресу роутера, підключеного до STUNсервера. для p2pкомунікації це якраз те, що нам потрібно, якщо не забути той факт, що в кожному роутере додасться необхідна нам рядок в таблицю NAT. Тому зворотний шлях буде знову так само гладкий.

TURNсервер - це покращений STUNсервер. Звідси відразу слід витягти, що будь-який TURNсервер може працювати і як STUNсервер. Однак, є і переваги. якщо p2pкомунікація неможлива (як наприклад, в 3gмережах), то сервер переходить в режим ретранслятора ( relay), Тобто працює як посередник. Зрозуміло, ні про яке p2pтоді мова не йде, але за рамками механізму ICEвузли думають, що спілкуються безпосередньо.

У яких випадках необхідний TURNсервер? Чому не вистачає STUNсервера? Справа в тому, що існує кілька різновидів NAT. Вони однаково підміняють IPадреса і порт, однак до деяких з них вбудована додатковий захист від "фальсифікації". Наприклад, в симетричноютаблиці NATзберігаються ще 2 параметра - IPі порт віддаленого вузла. Пакет із зовнішньої мережі проходить через NATу внутрішню мережу тільки в тому випадку, якщо адреса і порт джерела збігаються з записаними в таблиці. Тому фокус зі STUNсервером не вдається - таблиця NATзберігає адресу і порт STUNсервера і, коли роутер отримує пакет від WebRTCспіврозмовника, він його відкидає, так як він "фальсифікований". Він прийшов не від STUNсервера.

Таким чином TURNсервер потрібен в тому випадку, коли обидва співрозмовники знаходяться за симетричним NAT(Кожен за своїм).

Коротке зведення

Нижче наведено деякі твердження про сутності WebRTC, Які необхідно завжди пам'ятати. Детально вони описані вище. Якщо якісь з тверджень Вам здадуться не до кінця ясними, перечитайте відповідні параграфи.

  • медіа потік
    • Відео та аудіо дані упаковуються в медіа потоки
    • Медіа потоки синхронізують медіа доріжки, з яких складаються
    • Різні медіа потоки не синхронізовані між собою
    • Медіа потоки можуть бути локальними і віддаленими, до локального зазвичай підключена камера і мікрофон, віддалені отримують дані з мережі в кодованому вигляді
    • Медіа доріжки бувають двох типів - для відео і для аудіо
    • Медіа доріжки мають можливість включення / вимикання
    • Медіа доріжки складаються з медіа каналів
    • Медіа доріжки синхронізують медіа канали, з яких складаються
    • Медіа потоки і медіа доріжки мають мітки, за якими їх можна розрізняти
  • дескриптор сесії
    • Дескриптор сесії використовується для логічного з'єднання двох вузлів мережі
    • Дескриптор сесії зберігає інформацію про доступні способикодування відео і аудіо даних
    • WebRTCвикористовує зовнішній сигнальний механізм - завдання пересилання дескрипторів сесії ( sdp) Лягає на додаток
    • Механізм логічного з'єднання складається з двох етапів - пропозиції ( offer) І відповіді ( answer)
    • Генерація дескриптора сесії неможлива без використання локального медіа потоку в разі пропозиції ( offer) І неможлива без використання віддаленого дескриптора сесії в разі відповіді ( answer)
    • Отриманий дескриптор треба віддати реалізації WebRTC, Причому неважливо, чи отримано цей дескриптор віддалено або ж локально від тієї ж реалізації WebRTC
    • Є можливість невеликої правки дескриптора сесії
  • кандидати
    • кандидат ( Ice candidate) - це адреса вузла в мережі
    • Адреса вузла може бути своїм, а може бути адресою роутера або TURNсервера
    • Кандидатів завжди багато
    • Кандидат складається з IPадреси, порту і типу транспорту ( TCPабо UDP)
    • Кандидати використовуються для встановлення фізичного з'єднання двох вузлів в мережі
    • Кандидатів також потрібно пересилати через сигнальний механізм
    • Кандидатів також потрібно передавати реалізації WebRTC, Однак тільки віддалених
    • У деяких реалізаціях WebRTCкандидатів можна передавати тільки після установки дескриптора сесії
  • STUN / TURN / ICE / NAT
    • NAT- механізм забезпечення доступу до зовнішньої мережі
    • Домашні роутери підтримують спеціальну таблицю NAT
    • Роутер підміняє адреси в пакетах - адреса джерела на свій, в разі, якщо пакет йде в зовнішню мережу, і адреса приймача на адресу вузла у внутрішній мережі, якщо пакет прийшов із зовнішньої мережі
    • Для забезпечення багатоканального доступу до зовнішньої мережі NATвикористовує порти
    • ICE- механізм обходу NAT
    • STUNі TURNсервера - сервера-помічники для обходу NAT
    • STUNсервер дозволяє створювати необхідні записи в таблиці NAT, А також повертає зовнішній адресу вузла
    • TURNсервер узагальнює STUNмеханізм і робить його працюючим завжди
    • У найгірших випадках TURNсервер використовується як посередник ( relay), тобто p2pперетворюється в клієнт-сервер-клієнтської зв'язок.

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 ще більше бізнес застосувань.