Делаем видео-чат в веб-браузере с минимумом трудозатрат

23db3b4a409415d68b111d6a15530d05.pngДля реализации функционала видео-чата в браузере существует две наиболее подходящие из технологии — WebRTC и Flash. Каждая из технологий обладает рядом своих особенностей, например, во Flash можно использовать видео кодеки H.264 или Sorenson, а в WebRTC на текущий момент доступен VP8, что делает два этих подхода плохо совместимыми друг с другом (перекодирование видео на лету — это очень затратная операция), к тому же видео-чат лучше делать peer-to-peer по возможности, стоит ли говорить, что соединить Flash и WebRTC напрямую не выйдет. В нашем примере мы рассмотрим вариант видео-звонка звонка из WebRTC в WebRTC, с помощью платформы VoxImplant. В целом, можно сделать выбор конкретного варианта, вплоть до динамического выбора технологии в зависимости от того кому звоним. Подробности, как обычно, под катом.Создание приложения, пользователей, сценария и настройкаДля начала нам потребуется аккаунт разработчика VoxImplant (регистрация тут), после входа в панель управления VoxImplant в разделе Applications создаем новое приложение и называем его videochat. Чтобы организовать простой видео-чат нам потребуется хотя бы 2 пользователя — testuser1 и testuser2, создаем их в разделе Users и привязываем к приложению, используя кнопку Assign applications (аналогично можно уже созданных юзеров привязать к приложению во время редактирования приложения). При звонке от пользователя к пользователю все равно вызывается сценарий обработки звонка, который пишутся на Javascript и выполняется движком VoxEngine. Создаем в разделе Scenarios новый сценарий, назовем его User2User, при использовании режима peer-to-peer сценарий будет выглядеть следующим образом: VoxEngine.forwardCallToUserDirect (); Если в будущем захочется гонять видео через сервер (принудительно), то можно использовать VoxEngine.forwardCallToUser (null, true); , но в этом случае звонки будут стоить денег.Если необходимо управлять сигнализацией, чтобы, например, завершить звонок в какой-то момент со стороны сервера, то можно вместо хелпера forwardCallToUserDirect использовать следующий сценарий:

var call1, call2;

VoxEngine.addEventListener (AppEvents.CallAlerting, function (e) { call1 = e.call; call2 = VoxEngine.callUserDirect (e.call, e.destination, e.displayName, e.headers); call2.addEventListener (CallEvents.Connected, handleCallConnected); });

function handleCallConnected (e) { call1.answerDirect (call2); // Тут можно, например, разъединить звонок через какое-то время setTimeout (VoxEngine.terminate, 5000); } После создания сценария нам нужно привязать его к приложению через правило (Rule) — идем в раздел Applications и редактируем наше приложение, в табе Rules создаем новое правило (Add rule). Назвать можно как угодно, например, Intercom, в Pattern указывается регулярное выражение — правило срабатывает если номер соот-вует этому выражению, оставляем .* и перетаскиваем наш сценарий User2User из Available в Assigned и сохраняем правило. Сохраняем приложение, остается только сделать клиент с помощью VoxImplant Web SDK.

Создание веб-клиента Для клиента потребуется только файл voximplant.min.js, который лежит на cdn, а также базовое понимание как устроено Web SDK. Чтобы все выглядело все более-менее прилично можно использовать Bootstrap. Не вижу смысла вываливать сюда весь код из HTML-файла, разберем только основные моменты, а более глубоко разобраться всегда можно, скачав файлы с нашей странички на GitHub. // Подключаем SDK

// Создаем инстанс VoxImplant var voxAPI = VoxImplant.getInstance (); // Вешаем обработчики событий voxAPI.addEventListener (VoxImplant.Events.SDKReady, onSdkReady); voxAPI.addEventListener (VoxImplant.Events.ConnectionEstablished, onConnectionEstablished); voxAPI.addEventListener (VoxImplant.Events.ConnectionFailed, onConnectionFailed); voxAPI.addEventListener (VoxImplant.Events.ConnectionClosed, onConnectionClosed); voxAPI.addEventListener (VoxImplant.Events.AuthResult, onAuthResult); voxAPI.addEventListener (VoxImplant.Events.IncomingCall, onIncomingCall); voxAPI.addEventListener (VoxImplant.Events.MicAccessResult, onMicAccessResult);

// Инициализуем SDK try { voxAPI.init ({ useRTCOnly: true, // используем WebRTC принудительно micRequired: true, // запрос доступа к микрофону/камере до подключения к VoxImplant videoSupport: true, // включить поддержку видео }); } catch (e) { // если браузер не поддерживает WebRTC выводим какое-нибудь сообщение if (e.message == «NO_WEBRTC_SUPPORT») alert («WebRTC support isn’t available»); }

// Теперь можно пользоваться SDK — подключаемся function onSdkReady (){ voxAPI.connect (); // после вызова появится диалог доступа к камере/микрофону }

// Обрабатываем function onMicAccessResult (e) { if (e.result) { // разрешили доступ к камере/микрофону

} else { // запретили доступ к камере/микрофону } }

// Установили соединение с VoxImplant function onConnectionEstablished () { // Можно авторизоваться — тут надо показать диалог для ввода данных, а потом вызвать следующую функцию // Замените application_user, application_name, account_name и application_user_password на ваши данные для тестирования voxAPI.login (application_user+»@»+application_name+».»+account_name+».voximplant.com», application_user_password); }

// Не смогли подключиться к VoxImplant function onConnectionFailed () { // Или веб-сокеты не подключились или UDP закрыто }

// Закрылось соединение function onConnectionClosed () { // Можно вызвать connect по новой для переподключения }

function onAuthResult (e) { if (e.result) { // авторизовались — теперь можно звонить или принимать звонки } else { // ошибка авторизации, можно посмотреть e.code, чтобы понять что не так } }

var currentCall = null; // текущий звонок

// Входящий звонок function onIncomingCall (e) { currentCall = e.call; // Вешаем обработчики currentCall.addEventListener (VoxImplant.CallEvents.Connected, onCallConnected); currentCall.addEventListener (VoxImplant.CallEvents.Disconnected, onCallDisconnected); currentCall.addEventListener (VoxImplant.CallEvents.Failed, onCallFailed); // Отвечаем на звонок автоматически. В нормальном приложении лучше показать инфо о входящем звонке и дать возможность принять или отбить. currentCall.answer (); }

// Функция для исходящего звонка function createCall () { // application_username — имя юзера, которому звонит (по видео) currentCall = voxAPI.call (application_username, true); // Вешаем обработчики currentCall.addEventListener (VoxImplant.CallEvents.Connected, onCallConnected); currentCall.addEventListener (VoxImplant.CallEvents.Disconnected, onCallDisconnected); currentCall.addEventListener (VoxImplant.CallEvents.Failed, onCallFailed); }

// Звонок соединился function onCallConnected (e) { // Включаем отправку видео и показываем входящее видео voxAPI.sendVideo (true); currentCall.showRemoteVideo (true); }

// Звонок завершился function onCallDisconnected (e) { currentCall = null; }

// Ошибка при звонке function onCallFailed (e) { // Код ошибки e.code, описание ошибки e.reason } Вот собственно все основные функции и эвенты, которые нам нужны. Естественно, это голый JS, к этому нужно прикрутить стили и верстку. Вариант, который мы выложили на GitHub выглядит так: 2ed5ddfe27de4fe7843573557083e07f.png

54de2b51255b40f088f6f539df8c1473.png

9558715bd2c341e0ab9be24676f065c9.png

В случае если нужна поддержка и Flash и WebRTC придется переключать клиентское приложение в соответствующий режим, потому что видео-звонки WebRTC<>Flash мы реализовывать не стали. Надеемся, что в ближайшем будущем поддержка WebRTC появится в IE12, а за ним и в Safari. Если у вам нужен вариант «звонок с сайта оператору», то можно сделать 2 операторских приложения, одно с использованием WebRTC, другое с использованием Flash, и направлять звонки с сайта в зависимости от того какой режим SDK включится у посетителя сайта или на одного или на другого оператора.

Файлы проекта на GitHub

© Habrahabr.ru