Table of Contents |
---|
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 для создания звонка
...
session.createCall(), call.call() code
Code Block | ||||
---|---|---|---|---|
| ||||
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
Code Block | ||||
---|---|---|---|---|
| ||||
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
Code Block | ||||
---|---|---|---|---|
| ||||
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. В отдельном окне программного телефона также отобразится видео, транслируемое из браузера:
...
Управление камерой, микрофоном и устройствами вывода звука
Выбор и переключение устройств ввода и вывода
Как и при захвате видеопотока, при совершении звонка из браузера можно выбрать камеру, микрофон и (только в браузере Chrome) устройство вывода звука. Кроме того, устройства можно переключать во время звонка.
1. Выбор камеры, микрофона, устройства вывода звука code:
Code Block | ||||
---|---|---|---|---|
| ||||
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:
Code Block | ||||
---|---|---|---|---|
| ||||
$( "#speakerList" ).change(function() {
if (currentCall) {
currentCall.setAudioOutputId($(this).val());
}
}); |
3. Переключение микрофона во время звонка code:
Code Block | ||||
---|---|---|---|---|
| ||||
$("#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:
Code Block | ||||
---|---|---|---|---|
| ||||
$("#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:
Code Block | ||||
---|---|---|---|---|
| ||||
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;
} |
Совершение звонка без микрофона и камеры
В некоторых случаях, когда звонок не предполагает двухсторонней коммуникации, например, при звонке на голосовое меню, можно позвонить, не используя микрофон и камеру.
Для этого необходимо отключить таймер активности RTP настройкой в файле flashphoner.properties
Code Block | ||||
---|---|---|---|---|
| ||||
rtp_activity_detecting=false |
и отключить аудио и видео в настройке граничных параметров исходящего звонка в браузерах Chrome, Safari, MS Edge:
Code Block | ||||
---|---|---|---|---|
| ||||
var constraints = {
audio: false,
video: false
};
var outCall = session.createCall({
callee: $("#callee").val(),
visibleName: $("#sipLogin").val(),
constraints: constraints,
...
}) |
В браузере Firefox необходимо создать пустой аудиопоток:
Code Block | ||||
---|---|---|---|---|
| ||||
var constraints = {
audio: false,
video: false
};
if(Browser.isFirefox()) {
var audioContext = new AudioContext();
var emptyAudioStream = audioContext.createMediaStreamDestination().stream;
constraints.customStream = emptyAudioStream;
}
var outCall = session.createCall({
callee: $("#callee").val(),
visibleName: $("#sipLogin").val(),
constraints: constraints,
...
}) |
Отображение WebRTC-статистики
Во время SIP-звонка клиентское приложение получает WebRTC-статистику в соответствии со стандартом. Эта статистика может быть отображена в браузере, например:
Отметим, что в браузере Safari отображается только статистика аудио.
1. Отображение статистики во время звонка
call.getStats() code:
Code Block | ||||
---|---|---|---|---|
| ||||
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 {
...
}
}
}); |
Настройка используемых кодеков
WCS указывает поддерживаемые кодеки в INVITE SDP согласно следующим параметрам в файле flashphoner.properties.
1. В INVITE SDP включаются кодеки, указанные параметром codecs
, по умолчанию
Code Block | ||||
---|---|---|---|---|
| ||||
codecs=opus,alaw,ulaw,g729,speex16,g722,mpeg4-generic,telephone-event,h264,vp8,flv,mpv |
2. Из INVITE SDP исключаются кодеки, указанные параметром codecs_exclude_sip
, по умолчанию
Code Block | ||||
---|---|---|---|---|
| ||||
codecs_exclude_sip=mpeg4-generic,flv,mpv |
3. Из INVITE SDP исключаются кодеки, указанные браузером, если установлен параметр
Code Block | ||||
---|---|---|---|---|
| ||||
allow_outside_codecs=false |
4. Из INVITE SDP исключаются кодеки, указанные параметром stripCodecs
в клиентском приложении, например:
Code Block | ||||
---|---|---|---|---|
| ||||
var outCall = session.createCall({
callee: $("#callee").val(),
...
stripCodecs: "SILK,G722"
...
});
outCall.call(); |
Передача дополнительных параметров в SDP в запросе INVITE и ответе 200 OK
При создании звонка при помощи JavaScript API могут быть определены дополнительные параметры для управления пропускной способностью канала через SDP для исходящих (в запросе INVITE)
Code Block | ||||
---|---|---|---|---|
| ||||
var sdpAttributes = ["b=AS:3000","b=TIAS:2500000","b=RS:1000","b=RR:3000"];
var outCall = session.createCall({
sipSDP: sdpAttributes,
...
}); |
и входящих звонков (в ответе 200 OK)
Code Block | ||||
---|---|---|---|---|
| ||||
var sdpAttributes = ["b=AS:3000","b=TIAS:2500000","b=RS:1000","b=RR:3000"];
inCall.answer({
sipSDP: sdpAttributes,
...
}); |
Эти параметры проставляются в SDP после connection information ("c=IN IP4 <WCS IP>") и до time description ("t=0 0"):
Code Block | ||||
---|---|---|---|---|
| ||||
v=0
o=Flashphoner 0 1541068898263 IN IP4 192.168.1.5
s=Flashphoner/1.0
c=IN IP4 192.168.1.5
b=AS:3000
b=TIAS:2500000
b=RS:1000
b=RR:3000
t=0 0
m=audio |
Известные проблемы
1. Невозможно совершить SIP-звонок при некорректно заданных параметрах звонка SIP Login, SIP Authentification name
Симптомы: звонок не совершается, зависает в статусе PENDING
Решение: согласно стандарту, SIP Login и SIP Authentification name не должны содержать неэкранированных пробелов, спецсимволов и не должны заключаться в угловые скобки '<>'.
Например, такое заполнение полей не соответствует стандарту
Code Block | ||||
---|---|---|---|---|
| ||||
sipLogin='Ralf C12441@host.com'
sipAuthenticationName='Ralf C'
sipPassword='demo'
sipVisibleName='null'
|
а такое соответствует
Code Block | ||||
---|---|---|---|---|
| ||||
sipLogin='Ralf_C12441'
sipAuthenticationName='Ralf_C'
sipPassword='demo'
sipVisibleName='Ralf C'
|
2. Проблемы со звуком при звонках из браузера Edge.
Симптомы:
а) исходящий звук периодически то резко приглушается, то идет нормально.
б) входящий звук слышен, только если говорить в микрофон.
Решение:
Отключить для браузера Edge использование кодеков SILK и G.722 в SIP звонках при помощи опции stripCodecs:
Code Block | ||||
---|---|---|---|---|
| ||||
var outCall = session.createCall({
callee: $("#callee").val(),
visibleName: $("#sipLogin").val(),
localVideoDisplay: localDisplay,
remoteVideoDisplay: remoteDisplay,
constraints: constraints,
receiveAudio: true,
receiveVideo: false,
stripCodecs: "SILK,G722"
...
});
outCall.call(); |
или при помощи настройки
Code Block | ||
---|---|---|
| ||
codecs_exclude_sip=g722,mpeg4-generic,flv,mpv |
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 и перезагрузка.
4. Не устанавливается исходящий видеозвонок из браузера, если размер INVITE SDP превышает размер MTU
Симптомы: при попытке установить исходящий видеозвонок SIP-сторона возвращает 408 Request timeout, аудиозвонки при этом устанавливаются успешно
Решение: уменьшить количество кодеков в INVITE SDP таким образом, чтобы SDP укладывалось в размер пакета, определенный MTU (как правило, 1500 байт), при помощи настроек
Code Block | ||
---|---|---|
| ||
codecs_exclude_sip=mpeg4-generic,flv,mpv,opus,ulaw,h264,g722,g729
allow_outside_codecs=false |
Следует оставить только те кодеки, которые поддерживаются обеими сторонами звонка, в данном случае это VP8 и PCMA (alaw).
Include Page | ||||
---|---|---|---|---|
|