WebRTC - это бесплатный проект с открытым исходным кодом, который позволяет веб-браузерам и мобильным устройствам обеспечивать простую связь в реальном времени. Это означает, что функции приложения, такие как одноранговая видеоконференция, могут быть легко интегрированы в веб-страницу. Браузерный видеочат можно быстро спроектировать с помощью HTML и JavaScript, при этом не требуется никакого внутреннего кода.
Видеозвонок через WebRTC между двумя устройствами iOS с помощью веб-браузера Safari.
WebRTC позволяет пользователям передавать одноранговое аудио и видео в современных веб-браузерах. Этот снимок экрана сделан из видеозвонка WebRTC между двумя устройствами iOS с использованием веб-браузера Safari.
Сделать пользовательское устройство клиентом WebRTC так же просто, как инициализировать новый RTCPeerConnection (); объект в интерфейсном JavaScript. В настоящее время поддержка WebRTC поставляется с веб-браузерами, такими как Chrome, FireFox, Edge, Safari и Opera на рабочем столе, а также с родными веб-браузерами iOS и Android.
Видеочат установлен на двух или более клиентских устройствах по протоколу WebRTC. Соединение может быть выполнено с использованием одного из двух режимов. Первый режим одноранговый, то есть аудио и видео пакеты передаются напрямую от клиента к клиенту с UDP , Это работает до тех пор, пока обе машины имеют IP-адрес, доступный через общедоступный Интернет.
Полагаться на одноранговые соединения для видеочата в браузере нецелесообразно в производственных приложениях. Обычно для Интерактивного установления связи или инфраструктуры ICE не удается установить соединение между двумя пользователями, когда один или оба находятся за повышенной безопасностью ЛВС.
Чтобы смягчить это, вы можете установить Конфигурация RTC сначала попытаться выполнить одноранговое соединение, а затем вернуться к ретранслируемому соединению в случае сбоя однорангового соединения.
Если общедоступные IP-адреса недоступны, как, например, в корпоративных сетях WiFi, необходимо установить соединение WebRTC через TCP с использованием сервера TURN. Каркас ICE решит, нужно ли это, когда пользователи пытаются подключиться. Сервер TURN действует как ретранслятор для видео и аудио данных. Экземпляры TURN требуют пропускной способности и машинного времени - поэтому они не бесплатны, как потоковая передача в одноранговой сети.
Такой разработчик, как вы, может создать сервер TURN, используя решения с открытым исходным кодом и общий веб-хостинг. Вы также можете использовать провайдер TURN, как Xirsys , Помните, что использование стороннего поставщика TURN означает, что все аудио- и видеоданные проходят через их системы при передаче.
WebRTC исключает очень важный компонент из видеосвязи. Клиент должен использовать службу сигнализации для передачи сообщений своим партнерам или партнерам. Эти сообщения предназначены для таких событий, как:
Эти сообщения являются частью потока транзакций сигнализации, который описан в Документация Mozilla Developer Network для WebRTC , Эта диаграмма иллюстрирует все операции, которые должны выполняться для аудио или видео вызова WebRTC.
Сервер сигнализации WebRTC является абстрактной концепцией. Многие службы могут стать таким «сигнальным сервером», как WebSockets, Socket.IO или PubNub. Если вам нужно создать решение для этого, вы в конечном итоге спросите: строить или покупать?
PubNub позволяет такому разработчику, как вы, полностью и дешево внедрить управляемые событиями решения, такие как служба сигнализации WebRTC. Библиотека с открытым исходным кодом WebRTC, которая использует PubNub доступно на GitHub. Однако следующее решение PubNub работает даже быстрее, чем сборка с использованием WebRTC SDK.
PubNub похож на глобальный CDN для данных в реальном времени. Клиенты PubNub используют его IaaS для создания приложений чата в реальном времени, карт отслеживания местоположения в режиме реального времени, сигнализации устройств IoT и многого другого. Разработчики могут сосредоточиться на построении своего совместного общего опыта и оставить инфраструктуру для PubNub. Есть PubNub SDK для каждого языка программирования и устройства. Клиентские SDK обеспечивают надежные паб / суб соединения, доставку данных и управление сетью; все возможно в несколько строк кода.
Хотите включить видео- и аудиоконференции в реальном времени с WebRTC в свое веб-приложение? Это сообщество поддерживается Пакет WebRTC JS , который оборачивает PubNub JS SDK, ускорит ваш процесс разработки. Вы можете найти Пакет WebRTC JS на npm ,
Сообщество открытого исходного кода создало пакет WebRTC для простых вызовов 1: 1 с PubNub. Теперь вы можете предоставить своим пользователям одноранговый или ретранслированный видеочат WebRTC. Вы можете использовать свои собственные учетные данные STUN / TURN с тем же объектом конфигурации, который показан в MDN RTCC Конфигурационная документация (обратите внимание, что Safari нравится только массив URL-адресов).
Пакет WebRTC JS ссылка в этом посте с открытым исходным кодом и поддерживается сообществом.
Используйте на свой риск!
Плагин использует PubNub's Pub / Sub Messaging для Служба сигнализации WebRTC , Все рукопожатия, требуемые Поток транзакций сигнализации WebRTC находятся под прикрытием плагина, так что вы можете сосредоточиться на коде более высокого уровня вашего приложения.
Список «онлайн-пользователей» в пользовательском интерфейсе обновляется в режиме реального времени с использованием PubNub Presence. Для того, чтобы это работало в вашем приложении, вам нужно включить Присутствие в Панель управления PubNub Admin , Для набора демонстрационных ключей, созданного при создании учетной записи, по умолчанию отключено присутствие. Вы должны включить его для набора ключей API.
Плагин доступен на NPM:
npm установить pubnub-js-webrtc
Попробуйте пример приложения WebRTC в JS WebRTC Пакет GitHub Репозиторий ,
Исходный код примера приложения находится в папке примера .
Теперь вы можете создать собственное полнофункциональное приложение чата WebRTC с PubNub!
В этом уроке мы будем использовать простой старый JavaScript, HTML и CSS. Если вы хотите использовать современный интерфейс (например, Вью , реагировать , или же угловатый ), чтобы создать приложение чата, проверьте Страница учебных пособий PubNub или PubNub Чат Ресурсный Центр ,
Вы можете использовать HTML а также CSS в моем примере проекта. Скопируйте эти файлы в папку вашего проекта.
Это делает очень общий пользовательский интерфейс приложения чата. В примере приложения есть только 1 глобальный чат и нет личных чатов 1: 1, хотя их легко реализовать. Убедитесь, что вы также копируете изображения png из пример к вашему проекту.
Откройте index.html в вашем любимом текстовом редакторе. Замените теги сценария под тегом body вашего HTML-файла этими двумя сценариями CDN. Оставьте третий тег script, который ссылается на app.js. Мы напишем этот файл вместе.
<script src = "https://cdn.pubnub.com/sdk/javascript/pubnub.4.21.7.js"> </ script> <script src = "https://cdn.jsdelivr.net/npm/pubnub -js-webrtc@latest/dist/pubnub-js-webrtc.js "> </ скрипт>
Следующим шагом будет создание вашего собственного файла app.js в том же каталоге, что и ваш файл index.html. Причина, по которой нам нужно создать новый app.js, заключается в том, что скрипт в моем примере использует Xirsys , Моя личная учетная запись подключена к моему серверу функций PubNub. Вам нужно будет создать свой собственный сервер и учетную запись, если вы хотите использовать TURN-провайдера, такого как Xirsys. Мой следующий пост будет содержать учебник по созданию приложений WebRTC с TURN.
Скрипт app.js, который мы напишем вместе, будет использовать только бесплатные одноранговые WebRTC-соединения. Если вы попытаетесь сделать видеозвонок с 2 устройствами в одной локальной сети, ваше приложение будет работать. Нет уверенности в том, что соединение видеовызова может быть установлено с клиентами в отдельных сетях (из-за безопасности NAT).
Сначала мы сделаем ссылки на все элементы DOM из файла index.html. Как только мы можем ссылаться на них в нашем коде JavaScript, мы можем манипулировать ими программно.
const chatInterface = document.getElementById ('chat-interface'); const myVideoSample = document.getElementById ('my-video-sample'); const myVideo = document.getElementById ('my-video'); const remoteVideo = document.getElementById ('remote-video'); const videoModal = document.getElementById ('video-modal'); const closeVideoButton = document.getElementById ('close-video'); const brokenMyVideo = document.getElementById ('broken-my-video'); const brokenSampleVideo = document.getElementById ('broken-sample-video'); const usernameModal = document.getElementById ('username-input-modal'); const usernameInput = document.getElementById ('username-input'); const joinButton = document.getElementById ('кнопка соединения); const callConfirmModal = document.getElementById ('call-verify-modal'); const callConfirmUsername = document.getElementById ('call-verify-username'); const yesCallButton = document.getElementById ('yes-call'); const noCallButton = document.getElementById ('no-call'); constcomingCallModal = document.getElementById ('coming-call-modal '); const callFromSpan = document.getElementById ('call-from'); const acceptCallButton = document.getElementById ('accept-call'); const rejectCallButton = document.getElementById ('reject-call'); const onlineList = document.getElementById ('онлайн-список'); const chat = document.getElementById ('chat'); const log = document.getElementById ('log'); const messageInput = document.getElementById ('message-input'); const submit = document.getElementById ('submit');
Далее мы добавим некоторые переменные, которые содержат имя класса CSS, глобальную информацию о приложении и информацию о конфигурации WebRTC.
const hide = 'hide'; // Канал PubNub для отправки / получения сообщений глобального чата // также используется для присутствия пользователя с помощью PubNub Presence const globalChannel = 'global-channel'; пусть webRtcPhone; пусть пабнуб; // Словарь конфигурации RTCC из браузера WebRTC API // Добавьте сюда информацию о сервере STUN и TURN для вызова WebRTC const rtcConfig = {}; пусть имя пользователя; // Имя пользователя в приложении let myAudioVideoStream; // Локальный аудио и видео поток let noVideoTimeout; // Используется для проверки успешности подключения к видео const noVideoTimeoutMS = 5000; // Ошибка предупреждения, если видео не удается подключиться
Теперь мы рассмотрим обязательный клиентский код для функциональности пакета WebRTC.
// Инициировать аудио и видео поток на этом клиенте getLocalStream (). Then ((localMediaStream) => {myAudioVideoStream = localMediaStream; myVideoSample.srcObject = myAudioVideoStream; myVideo.srcObject = myAudioVideoStream;}) {catchVideo (}) .classList.add (hide); myVideoSample.classList.add (hide); brokenMyVideo.classList.remove (hide); brokenSampleVideo.classList.remove (hide);}); // Запрашиваем у пользователя ввод имени пользователя getLocalUserName (). Then ((myUsername) => {username = myUsername; usernameModal.classList.add (hide); initWebRtcApp ();}); // Отправить сообщение чата, когда нажата клавиша Enter. MessageInput.addEventListener ('keydown', (event) => {if (event.keyCode === 13 &&! Event.shiftKey) {event.preventDefault (); sendMessage () ; вернуть; } }); // Отправка сообщения чата при нажатии кнопки отправки submit.addEventListener ('click', sendMessage); const closeVideoEventHandler = (event) => {videoModal.classList.add (скрыть); chatInterface.classList.remove (скрыть); clearTimeout (noVideoTimeout); webRtcPhone.disconnect (); // отключаем текущий телефонный звонок} // Регистрируем обработчик события отключения при нажатии кнопки закрытия видео closeVideoButton.addEventListener ('click', closeVideoEventHandler);
Новый код, который мы только что добавили:
Далее мы собираемся добавить код инициализации для части WebRTC веб-приложения.
const initWebRtcApp = () => {// Событие объекта телефона WebRTC, когда видео удаленного партнера становится доступным. const onPeerStream = (webRTCTrackEvent) => {console.log («Доступен одноранговый поток аудио / видео»); const peerStream = webRTCTrackEvent.streams [0]; window.peerStream = peerStream; remoteVideo.srcObject = peerStream; }; // Событие объекта телефона WebRTC, когда удаленный узел пытается вам позвонить. const onIncomingCall = (fromUuid, callResponseCallback) => {let username = document.getElementById (fromUuid) .children [1] .innerText; comingCall (username) .then ((acceptCall) => {if (acceptCall) {// Завершить уже открытый вызов перед открытием нового webRtcPhone.disconnect (); videoModal.classList.remove (hide); chatInterface.classList.add (скрыть); noVideoTimeout = setTimeout (noVideo, noVideoTimeoutMS);} callResponseCallback ({acceptCall});}); }; // Событие объекта телефона WebRTC, когда удаленный узел отвечает на ваш запрос вызова. const onCallResponse = (acceptCall) => {console.log («Ответ на вызов:», acceptCall? «принято»: «отклонено»); if (acceptCall) {videoModal.classList.remove (hide); chatInterface.classList.add (скрыть); noVideoTimeout = setTimeout (noVideo, noVideoTimeoutMS); }}; // Событие объекта телефона WebRTC для случая, когда звонок отключается или время ожидания. const onDisconnect = () => {console.log ('Вызов отключен'); videoModal.classList.add (скрыть); chatInterface.classList.remove (скрыть); clearTimeout (noVideoTimeout); }; // Выводит список онлайн-пользователей в пользовательском интерфейсе и регистрирует метод вызова в событии click // Когда пользователь щелкает имя партнера в онлайн-списке, приложение вызывает этого пользователя. const addToOnlineUserList = (оккупант) => {const userId = оккупант.uuid; const name = оккупант. ��остояние? оккупант.стате.имя: ноль; if (! name) return; const userListDomElement = createUserListItem (userId, name); const УжеInList = document.getElementById (userId); const isMe = pubnub.getUUID () === userId; if (readyInList) {removeFromOnlineUserList (оккупант.uuid); } if (isMe) {return; } onlineList.appendChild (userListDomElement); userListDomElement.addEventListener ('click', (событие) => {const userToCall = userId; verifyCall (name) .then ((yesDoCall) => {if (yesDoCall) {webRtcPhone.callUser (userToCall, {myStream: myAudioVideoStream)} }});}); } const removeFromOnlineUserList = (uuid) => {const div = document.getElementById (uuid); if (div) div.remove (); }; pubnub = новый PubNub ({publishKey: '_YOUR_PUBNUB_PUBLISH_API_KEY_HERE_', subscribeKey: '_YOUR_PUBNUB_SUBSCRIBE_API_KEY_HERE_'}); // Этот слушатель PubNub поддерживает текстовый чат и онлайн-список пользователей. pubnub.addListener ({message: function (event) {// Рендеринг сообщения глобального чата в пользовательском интерфейсе if (event.channel === globalChannel) {renderMessage (event);}}, status: function (statusEvent) {if ( statusEvent.category === "PNConnectedCategory") {pubnub.setState ({состояние: {имя: имя пользователя}, каналы: [globalChannel], uuid: pubnub.getUUID ()}); pubnub.hereNow ({каналы: [globalChannel] , includeUUIDs: true, includeState: true}, (status, response) => {response.channels [globalChannel] .occupants .forEach (addToOnlineUserList);});}}, присутствие: (status, response) => {if ( status.error) {console.error (status.error);} еще if (status.channel === globalChannel) {if (status.action === "join") {addToOnlineUserList (status, response);} еще if (status.action === "state-change") {addToOnlineUserList (status, response);} еще if (status.action === "уйти") {removeFromOnlineUserList (status.uuid);} еще if (status.action === "timeout") {removeFromOnlineUserList (response.uuid);}}}}); pubnub.subscribe ({channel: [globalChannel], withPresence: true}); window.ismyuuid = pubnub.getUUID (); // Отключаем PubNub перед тем, как пользователь уходит со страницы window.onbeforeunload = (событие) => {pubnub.unsubscribe ({channel: [globalChannel]}); }; // Конфигурация объекта телефона WebRTC. let config = {rtcConfig, ignoreNonTurn: false, myStream: myAudioVideoStream, onPeerStream, // требуется onIncomingCall, // требуется onCallResponse, // требуется onDisconnect, // требуется pubnub // требуется}; webRtcPhone = новый WebRtcPhone (config); };
Код, который мы только что добавили в app.js, выполняется после того, как пользователь вводит свое «имя пользователя», и это:
Прежде чем продолжить, важно отметить, что нам нужно вставить наши бесплатные ключи API PubNub в эту функцию. Мы можем получить несколько вечно свободных ключей, используя форму регистрации ниже. Эти ключи бесплатны до 1 миллиона транзакций в месяц, что отлично подходит для любителей или профессиональных проверенных приложений.
Вы можете вставить свои клиентские ключи API Pub / Sub в файл app.js в объекте инициализации PubNub, как вы могли видеть в предыдущем фрагменте кода.
pubnub = новый PubNub ({publishKey: '_YOUR_PUBNUB_PUBLISH_API_KEY_HERE_', subscribeKey: '_YOUR_PUBNUB_SUBSCRIBE_API_KEY_HERE_'});
Нам нужно включить функцию присутствия PubNub на панели администратора PubNub. При создании набора ключей PubNub функция присутствия для ключа по умолчанию отключена. Мы можем включить его для ключа, перейдя в Панель управления PubNub Admin и нажав тумблер.
Пример приложения использует присутствие, чтобы показать, какие пользователи находятся в сети в приложении. Мы используем UUID пользователя PubNub для хранения уникальных ссылок на каждого пользователя в приложении. Когда мы выполняем операцию видеозвонка WebRTC, мы используем UUID, чтобы оба пользователя могли отображать соответствующее имя пользователя в своем пользовательском интерфейсе.
Далее нам понадобятся некоторые служебные методы для выполнения определенных функций пользовательского интерфейса. Они не характерны для всех приложений WebRTC, они предназначены только для запуска этого конкретного пользовательского интерфейса, который я разработал. Добавьте этот код в конец файла app.js.
// = - = - = - = - = - = - = - = - = - = - = - = - = - = - = - = - = - = - = - = - = - = - = - = - = - = - = - = - = - = - = - = - = - = - = - = - = - = - = // Функции визуализации пользовательского интерфейса // = - = - = - = - = - = - = - = - = - = - = - = - = - = - = - = - = - = - = - = - = - = - = - = - = - = - = - = - = - = - = - = - = - = - = - = - = - = - = функция renderMessage (сообщение) {const messageDomNode = createMessageHTML (сообщение); log.append (messageDomNode); // Сортировка сообщений в журнале чата на основе их временного маркера (значение идентификатора DOM) sortNodeChildren (log, 'id'); chat.scrollTop = chat.scrollHeight; } function messagesCall (name) {return new Promise ((resol) => {acceptCallButton.onclick = function () {comingCallModal.classList.add (hide); resol (true);} rejectCallButton.onclick = function () {comingCallModal. classList.add (hide); resol (false);} callFromSpan.innerHTML = name ;comingCallModal.classList.remove (hide);}); } function verifyCall (name) {вернуть новое Promise ((resol) => {yesCallButton.onclick = function () {callConfirmModal.classList.add (hide); resol (true);} noCallButton.onclick = function () {callConfirmModal. classList.add (hide); resol (false);} callConfirmUsername.innerHTML = name; callConfirmModal.classList.remove (hide);}); } function getLocalUserName () {return new Promise ((resol) => {usernameInput.focus (); usernameInput.value = ''; usernameInput.addEventListener ('keyup', (event) => {const nameLength = usernameInput.value. length; if (nameLength> 0) {joinButton.classList.remove ('disabled');} else {joinButton.classList.add ('disabled');} if (event.keyCode === 13 && nameLength> 0) { resolve (usernameInput.value);}}); joinButton.addEventListener ('click', (event) => {const nameLength = usernameInput.value.length; if (nameLength> 0) {resol (usernameInput.value);}} );}); } function getLocalStream () {вернуть новое Promise ((разрешить, отклонить) => {navigator.mediaDevices .getUserMedia ({audio: true, video: true}) .then ((avStream) => {resol (avStream);}) .catch ((err) => {alert ('Невозможно получить доступ к локальной камере или микрофону.'); console.error (err); reject ();});}); } function createUserListItem (userId, name) {const div = document.createElement ('div'); div.id = userId; const img = document.createElement ('img'); img.src = './phone.png'; const span = document.createElement ('span'); span.innerHTML = name; div.appendChild (IMG); div.appendChild (диапазон); вернуть div; } function createMessageHTML (messageEvent) {const text = messageEvent.message.text; const jsTime = parseInt (messageEvent.timetoken.substring (0,13)); const dateString = новая дата (jsTime) .toLocaleString (); const senderUuid = messageEvent.publisher; const senderName = senderUuid === pubnub.getUUID ()? имя пользователя: document.getElementById (senderUuid) .children [1] .innerText; const div = document.createElement ('div'); const b = document.createElement ('b'); div.id = messageEvent.timetoken; b.innerHTML = `$ {senderName} ($ {dateString}):`; div.appendChild (б); div.innerHTML + = текст; вернуть div; } // = - = - = - = - = - = - = - = - = - = - = - = - = - = - = - = - = - = - = - = - = - = - = - = - = - = - = - = - = - = - = - = - = - = - = - = - = - = - = // Функции утилит // = - = - = - = - = - = - = - = - = - = - = - = - = - = - = - = - = - = - = - = - = - = - = - = - = - = - = - = - = - = - = - = - = - = - = - = - = - = - = function sendMessage () {const messageToSend = messageInput.value.replace (/ \ r? \ n | \ r / g, ''); const trimmed = messageToSend.replace (/ (\ s) / g, ''); if (trimmed.length> 0) {pubnub.publish ({channel: globalChannel, message: {text: messageToSend}}); } messageInput.value = ''; } // Сортирует одноуровневые элементы HTML на основе значения атрибута function sortNodeChildren (parent, attribute) {const length = parent.children.length; for (пусть i = 0; i <длина-1; i ++) {if (parent.children [i + 1] [attribute] <parent.children [i] [attribute]) {parent.children [i + 1]. parentNode .insertBefore (parent.children [i + 1], parent.children [i]); я = -1; }}} function noVideo () {const message = 'Не установлено одноранговое соединение. \ n' + 'Попробуйте добавить сервер TURN в конфигурацию WebRTC.'; if (remoteVideo.paused) {alert (message); closeVideoEventHandler (); }}
Нам нужны стили CSS в нашем приложении для приятного и приятного пользовательского интерфейса. Файл index.html уже имеет ссылку на файл style.css, поэтому добавьте его в ту же папку. файл style.css для этого WebRTC приложение доступно в репозитории GitHub.
Готово! Теперь вы можете развернуть ваши статические интерфейсные веб-файлы на платформе веб-хостинга, такой как WordPress или Страницы GitHub , Ваше приложение чата WebRTC будет доступно для использования любому человеку в мире. Код совместим с мобильными устройствами. Это означает, что новейшие веб-браузеры на iOS и Android смогут запускать приложение для видео лицом к лицу!
Нет. Это проект с открытым исходным кодом, поддерживаемый сообществом. Если у вас есть вопросы или вам нужна помощь, обратитесь к [email protected] , Если вы хотите сообщить об ошибке, сделайте это на Страница GitHub Issues ,
Нет. PubNub очень хорошо сочетается с WebRTC в качестве службы сигнализации. Это означает, что PubNub передает события от клиента к клиенту с помощью обмена сообщениями Pub / Sub. Эти события включают в себя:
Групповые вызовы могут развиваться с помощью WebRTC и PubNub, однако текущий пакет PubNub JS WebRTC может подключить только 2 пользователя в частном вызове. Сообщество может разработать эту функцию в будущем, но на данный момент нет никаких планов развития.
Пакет PubNub JS WebRTC является проектом с открытым исходным кодом, поддерживаемым сообществом. Это означает, что лучшее место для сообщения об ошибках - это страница GitHub Issues для репозитория кода. Сообщество будет заниматься исправлением ошибки по желанию, поэтому нет гарантии, что исправление будет сделано. Если вы хотите предоставить исправление кода, подключите репозиторий GitHub к своей учетной записи GitHub, отправьте исправления и сделайте запрос на извлечение (процесс задокументирован на GitHub).
Для большего количества примеров, проверьте Страница учебных пособий PubNub , Если вам нравится этот плагин, вам нужна помощь или вы хотите создать нечто подобное, обратитесь к [email protected] , Мы хотим услышать ваше мнение!
Copyleft © 2017 . www.flashphone.ru