Web Call Server поддерживает аудио и видеозвонки из браузера на SIP устройства, PBX серверы, SIP-GSM-шлюзы, VoIP конференции и другие устройства с поддержкой протокола SIP. Таким образом, веб-приложение в браузере может работать, как программный телефон с поддержкой протокола SIP, принимать и инициировать голосовые и видеозвонки.
Описание
Поддерживаемые платформы и браузеры
Chrome | Firefox | Safari 11 | Edge | |
---|---|---|---|---|
Windows | + | + | + | |
Mac OS | + | + | + | |
Android | + | + | ||
iOS | - | - | + |
Поддерживаемые протоколы
- WebRTC
- RTP
- SIP
Поддерживаемые кодеки
- H.264
- VP8
- G.711
- Speex
- G.729
- Opus
Поддерживаемые SIP функции
- DTMF
- Удержание звонка
- Перевод звонка
SIP функции управляются при помощи REST API.
Схема работы
1: SIP-сервер как прокси-сервер для передачи вызовов и RTP медиа
2: SIP-сервер только как сервер для передачи вызовов
- Браузер начинает звонок с помощью REST-вызова /call/startup
- WCS соединяется с SIP-сервером
- SIP-сервер соединяется с SIP-устройством, принимающим звонок
- Браузер и SIP-устройство обмениваются аудио- и видеопотоками
Последовательность выполнения операций (Call Flow)
Ниже описана последовательность вызовов при использовании примера Phone для создания звонка
1. Отправка REST-запроса /call/startup при помощи JavaScript API:
session.createCall(), call.call() code
var outCall = session.createCall({ callee: $("#callee").val(), visibleName: $("#sipLogin").val(), localVideoDisplay: localDisplay, remoteVideoDisplay: remoteDisplay, constraints: constraints, receiveAudio: true, receiveVideo: false ... }); outCall.call();
2. Установка соединения с SIP-сервером
3. Установка соединения с адресатом
4. Получение подтверждения от SIP-устройства
5. Получение подтверждения от SIP-сервера
6. Получение от сервера события, подтверждающего успешное соединение.
CallStatusEvent ESTABLISHED code
var outCall = session.createCall({ callee: $("#callee").val(), visibleName: $("#sipLogin").val(), localVideoDisplay: localDisplay, remoteVideoDisplay: remoteDisplay, constraints: constraints, receiveAudio: true, receiveVideo: false }).on(CALL_STATUS.RING, function(){ ... }).on(CALL_STATUS.ESTABLISHED, function(){ setStatus("#callStatus", CALL_STATUS.ESTABLISHED); $("#holdBtn").prop('disabled',false); onAnswerOutgoing(); }).on(CALL_STATUS.HOLD, function() { ... }).on(CALL_STATUS.FINISH, function(){ ... }).on(CALL_STATUS.FAILED, function(){ ... }); outCall.call();
7. Стороны звонка обмениваются аудио- и видеопотоками
8. Завершение звонка
call.hangup() code
function onConnected(session) { $("#connectBtn, #connectTokenBtn").text("Disconnect").off('click').click(function(){ $(this).prop('disabled', true); if (currentCall) { showOutgoing(); disableOutgoing(true); setStatus("#callStatus", ""); currentCall.hangup(); } session.disconnect(); }).prop('disabled', false); }
9. Отправка команды на SIP-сервер
10. Отправка команды на SIP-устройство
11. Получение подтверждения от SIP-устройства
12. Получение подтверждения от SIP-сервера
Исходящий звонок из браузера на SIP-устройство
1. Для тестирования используем:
- два SIP-аккаунта;
- веб-приложение Phone Video для совершения звонка;
- программный телефон для ответа на звонок.
2. Откройте веб-приложение Phone Video. Введите данные SIP-аккаунта, звонящего из браузера:
3. Запустите программный телефон, введите данные SIP-аккаунта, принимающего звонок:
4. Нажмите в браузере кнопку Connect, будет установлено соединение с сервером. Затем введите идентификатор SIP-аккаунта, принимающего звонок, и нажмите кнопку Call:
5. Примите звонок в программном телефоне, нажав кнопку ответа на звонок с использованием видео:
В отдельном окне отобразится видео, транслируемое из браузера:
6. В браузере также отобразится видео:
7. Для завершения звонка нажмите кнопку Hangup в браузере, либо кнопку завершения звонка в программном телефоне.
Прием входящего звонка с SIP-устройства в браузере
1. Для тестирования используем:
- два SIP-аккаунта;
- программный телефон для совершения звонка;
- веб-приложение Phone Video для ответа на звонок.
2. Откройте веб-приложение Phone Video. Введите данные SIP-аккаунта, принимающего звонок в браузере:
3. Запустите программный телефон, введите данные звонящего SIP-аккаунта:
4. Нажмите в браузере кнопку Connect, будет установлено соединение с сервером. В программном телефоне введите идентификатор SIP-аккаунта, принимающего звонок, и нажмите кнопку вызова:
5. Примите звонок в браузере, нажав кнопку Answer:
6. В браузере отобразится видео:
7. В отдельном окне программного телефона также отобразится видео, транслируемое из браузера:
8. Для завершения звонка нажмите кнопку Hangup в браузере, либо кнопку завершения звонка в программном телефоне
Управление камерой, микрофоном и устройствами вывода звука
Выбор и переключение устройств ввода и вывода
Как и при захвате видеопотока, при совершении звонка из браузера можно выбрать камеру, микрофон и (только в браузере Chrome) устройство вывода звука. Кроме того, устройства можно переключать во время звонка.
1. Выбор камеры, микрофона, устройства вывода звука code:
Flashphoner.getMediaDevices(null, true, MEDIA_DEVICE_KIND.ALL).then(function (list) { for (var type in list) { if (list.hasOwnProperty(type)) { list[type].forEach(function(device) { if (device.type == "mic") { ... } else if (device.type == "speaker") { ... } else if (device.type == "camera") { ... } }); } } ... }).catch(function (error) { $("#notifyFlash").text("Failed to get media devices "+error); });
2. Переключение устройства вывода звука во время звонка code:
$( "#speakerList" ).change(function() { if (currentCall) { currentCall.setAudioOutputId($(this).val()); } });
3. Переключение микрофона во время звонка code:
$("#switchMicBtn").click(function() { if (currentCall) { currentCall.switchMic().then(function(id) { $('#micList option:selected').prop('selected', false); $("#micList option[value='"+ id +"']").prop('selected', true); }).catch(function(e) { console.log("Error " + e); }); } }).prop('disabled', true);
4. Переключение камеры во время звонка code:
$("#switchCamBtn").click(function() { if (currentCall) { currentCall.switchCam().then(function(id) { $('#cameraList option:selected').prop('selected', false); $("#cameraList option[value='"+ id +"']").prop('selected', true); }).catch(function(e) { console.log("Error " + e); }); } }).prop('disabled', true);
Установка размера видео
При создании звонка, может быть указан размер исходящего видео
code:
function getConstraints() { var constraints = { ... video: { deviceId: {exact: $('#cameraList').find(":selected").val()}, width: parseInt($('#sendWidth').val()), height: parseInt($('#sendHeight').val()) } }; if (Browser.isSafariWebRTC() && Browser.isiOS() && Flashphoner.getMediaProviders()[0] === "WebRTC") { constraints.video.width = {min: parseInt($('#sendWidth').val()), max: 640}; constraints.video.height = {min: parseInt($('#sendHeight').val()), max: 480}; } return constraints; }
Отображение WebRTC-статистики
Во время SIP-звонка клиентское приложение получает WebRTC-статистику в соответствии со стандартом. Эта статистика может быть отображена в браузере, например:
Отметим, что в браузере Safari отображается только статистика аудио.
1. Отображение статистики во время звонка
call.getStats() code:
currentCall.getStats(function (stats) { if (stats && stats.outboundStream) { if (stats.outboundStream.videoStats) { $('#videoStatBytesSent').text(stats.outboundStream.videoStats.bytesSent); $('#videoStatPacketsSent').text(stats.outboundStream.videoStats.packetsSent); $('#videoStatFramesEncoded').text(stats.outboundStream.videoStats.framesEncoded); } else { ... } if (stats.outboundStream.audioStats) { $('#audioStatBytesSent').text(stats.outboundStream.audioStats.bytesSent); $('#audioStatPacketsSent').text(stats.outboundStream.audioStats.packetsSent); } else { ... } } });
Известные проблемы
1. Невозможно совершить SIP-звонок при некорректно заданных параметрах звонка SIP Login, SIP Authentification name
Симптомы: звонок не совершается, зависает в статусе PENDING
Решение: согласно стандарту, SIP Login и SIP Authentification name не должны содержать неэкранированных пробелов, спецсимволов и не должны заключаться в угловые скобки '<>'.
Например, такое заполнение полей не соответствует стандарту
sipLogin='Ralf C12441@host.com' sipAuthenticationName='Ralf C' sipPassword='demo' sipVisibleName='null'
а такое соответствует
sipLogin='Ralf_C12441' sipAuthenticationName='Ralf_C' sipPassword='demo' sipVisibleName='Ralf C'
2. Проблемы со звуком при звонках из браузера Edge.
Симптомы:
а) исходящий звук периодически то резко приглушается, то идет нормально.
б) входящий звук слышен, только если говорить в микрофон.
Решение:
Отключить для браузера Edge использование кодеков SILK и G.722 в SIP звонках.
3. Не работает переключение микрофона в браузере Safari.
Симптомы: не переключается микрофон при помощи метода switchMic() WCS WebSDK.
Решение: использовать другой браузер, поскольку Safari всегда использует микрофон sound input, выбранный в настройках звука системы sound menu (для входа необходимо зажать клавишу Option (Alt) и щелкнуть по иконке звука в меню). После выбора другого микрофона в sound menu требуется перезагрузка Mac.
Если не работает микрофон Logitech USB camera (когда выбран в sound input), может помочь изменение format / sample rate в Audio MIDI Setup и перезагрузка.
function getConstraints() { | |
var constraints = { | |
audio: {deviceId: {exact: $('#micList').find(":selected").val()}}, | |
video: { | |
deviceId: {exact: $('#cameraList').find(":selected").val()}, | |
width: parseInt($('#sendWidth').val()), | |
height: parseInt($('#sendHeight').val()) | |
} | |
}; | |
if (Browser.isSafariWebRTC() && Browser.isiOS() && Flashphoner.getMediaProviders()[0] === "WebRTC") { | |
constraints.video.width = {min: parseInt($('#sendWidth').val()), max: 640}; | |
constraints.video.height = {min: parseInt($('#sendHeight').val()), max: 480}; | |
} | |
return constraints; | |
} |