Создание видео чата в реальном времени на WebRTC и Twilio

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

Скорее всего, вы уже использовали эту технологию и даже не подозревали об этом. Если вы когда-нибудь использовали Facebook Messenger, WhatsApp или Snapchat видео или голосовые функции, вы неосознанно использовали WebRTC для общения с семьей и друзьями.

WebRTC и другие подобные веб-технологии меняют способы общения людей. Разработчики предоставляют расширенные коммуникации, которые легко интегрируются в любое приложение. Подобно тому, как Facebook, Snapchat, Tango и WhatsApp интегрируют аудио и видео в свои приложения.

Возможно вы удивитесь, но данный процесс довольно простой, быстрый и более рентабельный. Так как эта великая технология от Google с открытым исходным кодом, благодаря ей, вы можете создавать ваши приложения без затрат на лицензирование. Однако путь к созданию собственного решения может оказаться довольно сложным, если вы не знакомы с некоторыми общими компонентами которые необходимы в работе с WebRTC, такие как TURN/STUN, signaling, multipoint conferencing units (MCU) и так далее.

В нашей отрасли, есть свыше 20 платформ, таких как сервис (PaaS) поставщиков, предлагающих готовые решения WebRTC. После того как мы обрели большой опыт работы с этой технологией, у нас есть несколько любимых PaaS провайдеров, которые отлично работают с нашими клиентами. Чтобы сократить время разработки, мы сотрудничаем со многими поставщиками. Один из поставщиков - Twilio. В этой статье мы сосредоточим внимание на данной платформе.

Twilio Video

Twilio, предоставляют набор средств коммуникации с помощью простого API и SDK. Их решение позволяет разработчикам реализовать связь в реальном времени в своих приложениях. Новым продуктом от Twilio является программируемое видео, которое позволяет создавать HD многопартийные видео и аудио в области мобильных и веб-приложений. Twilio ветеран в индустрии WebRTC и расширяет свой текущий продукт Client Twilio, у которого уже есть некоторые компоненты работающие на основе WebRTC.

Создание видео чата

Для использования демонстрационного примера, вам понадобится учетная запись Twilio. Убедитесь, что вы выбрали “Programmable Video” в качестве первого сервиса который вы планируете использовать. После того как вы создали свой аккаунт, вам потребуется следующая информация для создания приложения:

Полномочия Описание
Twilio аккаунт SID Идентификатор вашего аккаунта - можете найти его в панели инструментов.
Twilio видео конфигурация SID Токен доступа - сгенерировать здесь.
Ключ API Используется для аутентификации - сгенерировать здесь.
Секретный ключ API Используется для аутентификации - сгенерировать здесь.

Мы также будем использовать Firebase как простой способ отслеживания доступных для чата пользователей. Firebase является сервисом Mobile Backend, который работает в качестве Backend вашего приложения, включая хранение данных, аутентификацию пользователей, статичный хостинг и многое другое.

Демо

Весь код данной статьи, доступен на GitHub, также вы можете посмотреть живую демонстрацию на Blacc Spot Media. В настоящее время WebRTC поддерживается только на компьютерах с браузерами Google Chrome, Mozilla Firefox и Opera:

PHP

Для того, чтобы получить доступ к платформе Twilio, вы должны сначала пройти проверку подлинности в системе. В этом примере мы используем PHP на стороне сервера. Twilio имеет широкий спектр серверных библиотек в соответствии с вашими предпочтениями. После проверки подлинности, передаем учетные данные, которые вы получили от вашего аккаунта Twilio.

// ДОБАВЛЕНИЕ БИБЛИОТЕКИ TWILIO
require_once('twilio/Services/Twilio.php');

// TWILIO ПОЛНОМОЧИЯ
$TWILIO_ACCOUNT_SID = 'your account sid here';
$TWILIO_CONFIGURATION_SID = 'your configuration sid here';
$TWILIO_API_KEY = 'your API key here';
$TWILIO_API_SECRET = 'your API secret here';

// СОЗДАНИЕ ТОКЕНА TWILIO
// $id will be the user name used to join the chat
$id = $_GET['id'];

$token = new Services_Twilio_AccessToken(
    $TWILIO_ACCOUNT_SID,
    $TWILIO_API_KEY,
    $TWILIO_API_SECRET,
    3600,
    $id
);

// ДОСТУП
$grant = new Services_Twilio_Auth_ConversationsGrant();
$grant->setConfigurationProfileSid($TWILIO_CONFIGURATION_SID);
$token->addGrant($grant);

echo json_encode(array(
    'id'    => $id,
    'token' => $token->toJWT(),
));

HTML

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

<div class="m-content">
    <h1>Quick Start Your WebRTC Project with Twilio</h1>
    <div class="start">
        <input type="text" id="id" name="id" value="" placeholder="Enter your name to join the chat" />
        <button id="start">Join Chat Room</button>
        <button id="disconnect" class="b-disconnect hide">Disconnect from Chat</button>
        <div class="status">
            <strong>MY STATUS:</strong> <span id="status">DISCONNECTED</span>
        </div>
    </div>
    <div class="local">
        <div id="lstream"></div>
    </div>
    <div class="remote">
        <div id="rstream"></div>
    </div>
    <div class="users-list"></div>
    <div class="logs"></div>
</div>
<script src="https://code.jquery.com/jquery-1.9.1.min.js"></script>
<script src="https://media.twiliocdn.com/sdk/js/common/v0.1/twilio-common.min.js"></script>
<script src="https://media.twiliocdn.com/sdk/js/conversations/v0.13/twilio-conversations.min.js"></script>
<script src="https://cdn.firebase.com/js/client/2.4.0/firebase.js"></script>
<script src="/app.js"></script>

JavaScript

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

if (!navigator.webkitGetUserMedia && !navigator.mozGetUserMedia) {
    tlog('You are using a browser that is not WebRTC compatible, please use Google Chrome or Mozilla Firefox', true);
}

Мы используем функцию под названием tlog() для отправки сообщений о состоянии к пользователю. Мы посылаем HTML строку msg вместе с параметром e со значением true.

function tlog(msg, e) {
  if (e) {
    $('.logs').append('<div class="log error">' + msg + '</div>');
  } else {
    $('.logs').append('<div class="log">' + msg + '</div>');
  }
}

После того, когда мы определили что пользователь подключился с помощью подходящего браузера, мы воспользуемся jQuery, для обработки события нажатия, когда пользователь готов присоединиться к чату. Мы направим Ajax запрос со стороны сервера со сгенерированным файлом token.php который содержит id пользователя для подключения к чату. Данный запрос вы можете наблюдать на сайте http://www.brille.ua/.

В нашем демонстрационном примере мы используем текстовое поле для ввода имени пользователя. После того, как мы получили токен, мы передаем его вместе с Twilio.AccessManager, чтобы создать новый Twilio.Conversations.Client, который будет прослушивать события с помощью Promise.

$('#start').on('click', function() {
  if ($('#id').val() == '') {
    tlog('Please enter a name to join the chat', true);
  } else {
    id = $('#id').val().replace(/\s+/g, '');
    $.ajax({
      type: 'POST',
      url: 'token.php',
      data: {
        id: $('#id').val()
      },
      dataType: "json",
      success: function(data) {

        var accessManager = new Twilio.AccessManager(data.token);
        conversationsClient = new Twilio.Conversations.Client(accessManager);
        conversationsClient.listen().then(clientConnected, function(e) {
          tlog('Could not connect to Twilio: ' + e.message, true);
        });
      }
    });
  }
});

После успешного соединения и ответа от Twilio.Conversations.Client, мы вызываем функцию clientConnected() вместе с firebaseConnect(). Вам нужно будет добавить Firebase URL с вашего аккаунта для сохранения всех доступных пользователей. Мы также добавим несколько слушателей событий для Firebase, которые будут отслеживать подключения и выход из чата.

function clientConnected() {
  firebaseConnect();
  $('#id, #start').hide();
  $('#disconnect').fadeIn();
  $('#status').css({ 'color': '#5E9F21' }).text('CONNECTED');
  tlog('You have succussfully connected to this Twilio chat room as <strong>' + id + '</strong>.');
  if (!lmedia) {
    startConversation();
  };
  conversationInvite();
}

function firebaseConnect(){
  var fburl = '...add your firebase url here...';
  firebase = new Firebase(fburl + '/users');
  var uid = firebase.push(id);
  fid = uid.toString();

  new Firebase(fid)
    .onDisconnect()
    .remove();

  firebase.on('child_added', function(child) {
    addParticipant(child);
  });

  firebase.on('child_removed', function(child) {
    $('.' + child.val()).remove();
  });
}

function addParticipant(child) {
  if (child.val() != id) {
    var markup = '<div class="user ' + child.val() + '"><span>'
               + child.val() + '</span><button class="b-connect" id="'
               + child.val() + '">Call Now</button></div>';
    $('.users-list').append(markup);
  }
}

Настало время магии WebRTC! Мы получаем доступ к микрофону и камере, при помощи вызова Twilio.Conversations.LocalMedia() и присоединяем поток к HTML-элементу. Обратите внимание: Вам нужно будет разрешить доступ к микрофону и камере.

function startConversation() {
  lmedia = new Twilio.Conversations.LocalMedia();
  Twilio.Conversations.getUserMedia().then(function(mediaStream) {
    lmedia.addStream(mediaStream);
    lmedia.attach('#lstream');
  }, function(e) {
    tlog('We were unable to access your Camera and Microphone.');
  });
}

Далее мы добавляем слушатель событий для входящих приглашений от других пользователей в чате. Мы добавили invite.accept().then(conversationStarted), чтобы разрешить автоматическое соединение. Обратите внимание: Вам нужно будет разрешить доступ к камере и микрофону для каждого дополнительного пользователя.

function conversationInvite() {
  conversationsClient.on('invite', function(invite) {
    invite.accept().then(conversationStarted);
    tlog('You have a incoming invite from: ' + invite.from + '');
  });
}

После того, как вы присоединились к чату, вы увидите кнопку Call Now, расположенную возле каждого пользователя, который доступен для общения в чате. Нажмите на кнопку, чтобы подключиться к пользователю.

Мы будем передавать поток как options.localMedia, пользователю которого приглашаем в чат.

$(document).on('click', '.b-connect', function() {
    var user = $(this).attr('id');
    var options = {};
    options.localMedia = lmedia;
    conversationsClient
      .inviteToConversation(user, options)
      .then(conversationStarted, function(error) {
        tlog('We were unable to create the chat conversation with that user, try another online user.', true);
      });
});

После принятия входящего приглашения, происходит подключение к чату.

function conversationStarted(convo) {
  conversation = convo;
  tlog('We are waiting on your friend to connect...');
  participantConnected();
  participantDisconnected();
}

Далее добавляем функцию participantConnected() при помощи обработчика событий для всех участников, подключенных к разговору. По мере подключения пользователя, добавляем свои media используя participant.media.attach('#rstream').

function participantConnected() {
  conversation.on('participantConnected', function(participant) {
    new Firebase(fid).remove();
    participant.media.attach('#rstream');
    tlog('You are connected with: <strong>' + participant.identity + '</strong>');
  });
}

И наконец, мы добавим обработчик событий для каждого участника, для определения выхода из чата, в функции participantDisconnected(). Это позволяет отслеживать выход из чата и удалять пользователей.

function participantDisconnected() {
  conversation.on('participantDisconnected', function(participant) {
    if (!disconnected) {
      var uid = firebase.push(id);
      fid = uid.toString();
      new Firebase(fid).onDisconnect().remove();
    }

    $('.' + participant.identity).remove();
    tlog('<strong>' + participant.identity + '</strong> has disconnected from this chat.');
    $('.users-list').empty();

    if (firebase) {
      firebase.once('child_added', function(child) {
        addParticipant(child);
      });
    }
  });
}

Мы предлагаем пользователям возможность ручного отключения от чата и сброса в состояние по умолчанию. Очищаем доступность пользователей из Firebase, так что другие пользователи не смогут подключиться, пока пользователь не станет онлайн. Далее мы останавливаем поток разговора и прекращаем доступ к микрофону и камере.

$('#disconnect').on('click', function() {
  new Firebase(fid).remove();
  firebase.off();
  firebase = null;
  disconnected = true;
  $('#disconnect').hide();
  $('#start, #id').fadeIn();
  $('#status').css({
    'color': ''
  }).text('DISCONNETED');
  $('.users-list').empty();
  stopConversation();
});

function stopConversation() {
  if (conversation) {
    conversation.disconnect();
    conversationsClient = null;
    conversation = null;
    lmedia.stop();
    lmedia = null;
    tlog('You have successfully disconnected from this chat conversation, start another one now.');
  } else {
    lmedia.stop();
    lmedia = null;
    tlog('Please rejoin the chatroom to start a conversation.');
  }
}

 

Перевод статьи Create a Real-Time Video Chat Room with WebRTC & Twilio

Тэги: ajaxchatwebrtc

Вход

Уважаемый пользователь! Мы обнаружили, что вы используете AdBlock и вынуждены скрыть часть материалов на нашем сайте. Siteacademy существует и развивается за счет доходов от рекламы. Просим внести наш сайт в список исключений или отключить Блокировщик рекламы на нашем сайте.