Захват потока с SIP-звонка¶
Описание¶
WCS может выступать в качестве WebRTC-SIP шлюза. При этом аудио- и видеопоток SIP-звонка, произведенного через WCS, может быть захвачен и воспроизведен в браузере, либо ретранслирован на другой сервер.
Типичный сценарий использования¶
- Между WCS и SIP-устройством (SIP MCU, сервер конференций или SIP-софтфон) установлен видеозвонок
- WCS получает аудио и видео данные с этого SIP-устройства
- Полученный аудио и видео трафик WCS-сервер перенаправляет на RTMP-сервер или другое устройство, способное принять и обработать RTMP-поток
Поддерживаемые протоколы¶
- WebRTC
- RTMP
- SIP
Поддерживаемые кодеки для SIP¶
- Видеокодеки: H.264, VP8
- Аудиокодеки: G.711, Speex, Opus
Поддерживаемые кодеки для RTMP¶
- Видеокодеки: H.264
- Аудиокодеки: AAC, G.711, Speex
Поддерживаемые кодеки для WebRTC¶
- Video: H.264, VP8
- Audio: Opus, G.711
REST API¶
Захват и ретрансляция SIP-звонков управляется при помощи REST API вызовов.
REST-запрос должен быть HTTP/HTTPS POST запросом в таком виде:
- HTTP:
http://sip-as-rtmp.flashphoner.com:8081/rest-api/call/startup
- HTTPS:
https://sip-as-rtmp.flashphoner.com:8444/rest-api/call/startup
Здесь:
sip-as-rtmp.flashphoner.com
- адрес WCS-сервера8081
- стандартный REST / HTTP порт WCS-сервера8444
- стандартный HTTPS портrest-api
- обязательная часть URL/call/startup
- используемый REST-метод
Общие правила¶
- Каждый SIP-звонок при создании может быть ассоциирован только с одним RTMP-потоком. В случае, если инициируется новый SIP-звонок с тем же RTMP URL и именем потока, как у существующего звонка, этот второй звонок будет отклонен сервером с HTTP статусом
409 Conflict
. Однако, при ретрансляции звонка в RTMP-поток при помощи REST-запроса/push/startup
, количество RTMP-потоков, создаваемых из одного звонка, не ограничивается. - SIP Call ID звонка должен быть уникальным. Попытка инициировать новый SIP-звонок с уже существующим Call ID будет отклонена WCS-сервером с HTTP статусом
409 Conflict
.
REST-методы¶
/call/startup¶
Начать SIP звонок
Request example¶
POST /rest-api/call/startup HTTP/1.1
Host: localhost:8081
Content-Type: application/json
{
"callId":"123456711",
"callee":"10000",
"toStream":"stream1",
"rtmpUrl":"rtmp://localhost:1935/live/",
"rtmpStream":"rtmp_stream1",
"hasAudio":true,
"hasVideo":true,
"sipLogin":"10009",
"sipAuthenticationName":"10009",
"sipPassword":"1234",
"sipDomain":"226.226.225.226",
"sipOutboundProxy":"226.226.225.226",
"sipPort":"5060",
"appKey":"defaultApp",
"sipRegisterRequired":false
}
Response example¶
Return codes¶
Code | Reason |
---|---|
200 | OK |
409 | Conflict |
/call/find¶
Найти SIP звонок по указанным критериям
Request example¶
POST /rest-api/call/find HTTP/1.1
Host: localhost:8081
Content-Type: application/json
{
"callId": "R08NQya-5NMe5v7q-JNkboaS-CGMlFi"
}
Response example¶
HTTP/1.1 200 OK
Access-Control-Allow-Origin: *
Content-Type: application/json
[
{
"custom": {},
"nodeId": null,
"appKey": null,
"sessionId": null,
"callId": "R08NQya-5NMe5v7q-JNkboaS-CGMlFi",
"parentCallId": null,
"incoming": false,
"status": "ESTABLISHED",
"sipStatus": 200,
"rtmpUrl": null,
"rtmpStream": null,
"streamName": null,
"rtmpStreamStatus": null,
"caller": "001",
"callee": "002",
"hasAudio": true,
"hasVideo": false,
"sdp": ...,
"visibleName": "001",
"inviteParameters": null,
"mediaProvider": "Flash",
"sipMessageRaw": null,
"isMsrp": false,
"target": null,
"holdForTransfer": false
}
]
Return codes¶
Code | Reason |
---|---|
200 | OK |
404 | Not found |
/call/find_all¶
Найти все SIP звонки
Request example¶
Response example¶
HTTP/1.1 200 OK
Access-Control-Allow-Origin: *
Content-Type: application/json
[
{
"custom": {},
"nodeId": null,
"appKey": null,
"sessionId": null,
"callId": "R08NQya-5NMe5v7q-JNkboaS-CGMlFi",
"parentCallId": null,
"incoming": false,
"status": "ESTABLISHED",
"sipStatus": 200,
"rtmpUrl": null,
"rtmpStream": null,
"streamName": null,
"rtmpStreamStatus": null,
"caller": "001",
"callee": "002",
"hasAudio": true,
"hasVideo": false,
"sdp": ...,
"visibleName": "001",
"inviteParameters": null,
"mediaProvider": "Flash",
"sipMessageRaw": null,
"isMsrp": false,
"target": null,
"holdForTransfer": false
},
...
]
Return codes¶
Code | Reason |
---|---|
200 | OK |
404 | Not found |
/call/terminate¶
Завершить SIP звонок
Request example¶
POST /rest-api/call/terminate HTTP/1.1
Host: localhost:8081
Content-Type: application/json
{
"callId":"123456711"
}
Response example¶
Return codes¶
Code | Reason |
---|---|
200 | OK |
404 | Not found |
/call/send_dtmf¶
Отправить сигнал DTMF в SIP звонок
Request example¶
POST /rest-api/call/terminate HTTP/1.1
Host: localhost:8081
Content-Type: application/json
{
"callId":"123456711",
"dtmf":"9",
"type":"RFC2833"
}
Response example¶
Return codes¶
Code | Reason |
---|---|
200 | OK |
404 | Not found |
Параметры¶
Параметр | Описание | Пример |
---|---|---|
callId | Уникальный идентификатор звонка |
Xq2tlLcX89tTjaji
|
callee | Вызываемый абонент |
10001
|
toStream | Имя потока, который будет опубликован на WCS сервере из SIP звонка |
call_stream1
|
rtmpUrl | Входной URL RTMP сервера для публикации потока звонка |
rtmp://rtmp-server.flashphoner.com:1935/live
|
rtmpStream | Имя потока на RTMP сервере (stream key) |
streamName2
|
hasAudio |
Если true , SDP будет иметь sendrecv параметр в аудио части. Если false , то recvonly
|
true
|
hasVideo |
Если true , SDP будет иметь sendrecv параметр в видео части. Если false , то recvonly
|
true
|
status | Статус звонка на WCS-сервере |
ESTABLISHED
|
sipStatus | Соответствующий статус звонка на SIP стороне |
200
|
rtmpStreamStatus |
Статус RTMP-потока:
RTMP_STREAM_WAIT - RTMP-stream is initializingRTMP_STREAM_ACTIVE - RTMP-stream has initialized and connection is establishedRTMP_CONNECTION_LOST - RTMP-connection is lostRTMP_CONNECTION_FAILED - RTMP-connection was not established |
RTMP_STREAM_ACTIVE
|
caller | Вызывающий абонент | |
visibleName | Отображаемое имя вызывающего абонента |
SDP параметры recvonly
и sendrecv
¶
Существует два основных режима для SIP звонков, созданных по REST API:
-
sendrecv
v=0 o=Flashphoner 0 1437391553771 IN IP4 sip.flashphoner.com s=Flashphoner/1.0 c=IN IP4 sip.flashphoner.com t=0 0 m=audio 31022 RTP/AVP 8 0 c=IN IP4 46.101.139.106 a=rtpmap:8 pcma/8000 a=rtpmap:0 pcmu/8000 a=ptime:20 a=rtcp:31023 IN IP4 sip.flashphoner.com a=sendrecv a=ssrc:1478013757 cname:rtp/audio/Xq2tlLcX89tTjaji m=video 31024 RTP/AVP 112 113 c=IN IP4 sip.flashphoner.com a=rtpmap:112 H264/90000 a=fmtp:112 packetization-mode=1; profile-level-id=420020 a=rtpmap:113 H264/90000 a=fmtp:113 packetization-mode=0; profile-level-id=420020 a=rtcp-fb:* ccm fir a=rtcp-fb:* nack a=rtcp-fb:* nack pli a=rtcp:31025 IN IP4 sip.flashphoner.com a=sendrecv a=ssrc:979076678 cname:rtp/video/Xq2tlLcX89tTjaji
-
recvonly
- SIP call parameters
- SDP
v=0 o=Flashphoner 0 1437391553771 IN IP4 sip.flashphoner.com s=Flashphoner/1.0 c=IN IP4 sip.flashphoner.com t=0 0 m=audio 31022 RTP/AVP 8 0 c=IN IP4 46.101.139.106 a=rtpmap:8 pcma/8000 a=rtpmap:0 pcmu/8000 a=ptime:20 a=rtcp:31023 IN IP4 sip.flashphoner.com a=recvonly a=ssrc:1478013757 cname:rtp/audio/Xq2tlLcX89tTjaji m=video 31024 RTP/AVP 112 113 c=IN IP4 sip.flashphoner.com a=rtpmap:112 H264/90000 a=fmtp:112 packetization-mode=1; profile-level-id=420020 a=rtpmap:113 H264/90000 a=fmtp:113 packetization-mode=0; profile-level-id=420020 a=rtcp-fb:* ccm fir a=rtcp-fb:* nack a=rtcp-fb:* nack pli a=rtcp:31025 IN IP4 sip.flashphoner.com a=recvonly a=ssrc:979076678 cname:rtp/video/Xq2tlLcX89tTjaji
В обоих случаях WCS не отправляет RTP аудио и видео трафик, т.к. инициатором звонка выступает REST-клиент, который не является источником аудио и видео потоков.
При этом WCS может явно указать в SDP, что с его стороны не будет аудио и видео трафика (режим recvonly
).
Если ваше SIP-устройство - это софтфон или другой SIP-телефон, он скорее всего будет сбрасывать звонок (в режиме sendrecv
) примерно в течение минуты после установки соединения. Это происходит из-за отсутствия RTP-трафика со стороны WCS.
Некоторые софтфоны корректно поддерживают режим recvonly
, например MicroSIP. В других софтфонах, таких как Bria, таймер проверки RTP-активности может быть увеличен, для того чтобы получить большую длительность звонка в режиме sendrecv
.
Если ваше SIP-устройство - это MCU или сервер SIP-конференций, скорее всего оно корректно отработает режим recvonly
, и звонок сможет быть установлен на длительное время.
Дополнительная информация по статусам звонка¶
WCS использует внутреннее приложение callApp
для передачи промежуточных статусов на бэкенд сервер.
Примеры¶
TRYING
, RTMP_STREAM_WAIT
{
"nodeId" : "w9NiNKZCtjK6C4vz1zVnzGWBJGkA2Cke@192.168.88.101",
"appKey" : "callApp",
"sessionId" : "127.0.0.1:1403649870519623722",
"callId" : "Xq2tlLcX89tTjaji_3",
"incoming" : false,
"status" : "TRYING",
"sipStatus" : 100,
"rtmpUrl" : "rtmp://rtmp.flashphoner.com:1935/live",
"rtmpStream" : "streamName2",
"rtmpStreamStatus" : "RTMP_STREAM_WAIT",
"caller" : "3000",
"callee" : "3002",
"hasAudio" : true,
"hasVideo" : true,
"visibleName" : "3000",
"mediaProvider" : "Flash",
"isMsrp" : false
}
ESTABLISHED
, RTMP_STREAM_ACTIVE
{
"nodeId" : "w9NiNKZCtjK6C4vz1zVnzGWBJGkA2Cke@192.168.88.101",
"appKey" : "callApp",
"sessionId" : "127.0.0.1:1403649870519623722",
"callId" : "Xq2tlLcX89tTjaji_3",
"incoming" : false,
"status" : "ESTABLISHED",
"sipStatus" : 200,
"rtmpUrl" : "rtmp.flashphoner.com:1935/live",
"rtmpStream" : "streamName2",
"rtmpStreamStatus" : "RTMP_STREAM_ACTIVE",
"caller" : "3000",
"callee" : "3002",
"hasAudio" : true,
"hasVideo" : true,
"visibleName" : "3000",
"mediaProvider" : "Flash",
"isMsrp" : false
}
ESTABLISHED
, RTMP_CONNECTION_LOST
{
"nodeId" : "w9NiNKZCtjK6C4vz1zVnzGWBJGkA2Cke@192.168.88.101",
"appKey" : "callApp",
"sessionId" : "127.0.0.1:1403649870519623722",
"callId" : "Xq2tlLcX89tTjaji_3",
"incoming" : false,
"status" : "ESTABLISHED",
"sipStatus" : 200,
"rtmpUrl" : "rtmp.flashphoner.com:1935/live",
"rtmpStream" : "streamName2",
"rtmpStreamStatus" : "RTMP_CONNECTION_LOST",
"caller" : "3000",
"callee" : "3002",
"hasAudio" : true,
"hasVideo" : true,
"visibleName" : "3000",
"mediaProvider" : "Flash",
"isMsrp" : false
}
Это уведомления, которые передаются встроенному или внешнему бэкенд серверу через внутренний REST-интерфейс. См. раздел REST hooks, чтобы получить больше информации о внутренних REST-приложениях. Кроме этого, может быть создано стороннее web-приложение, которое будет получать уведомления с WCS-сервера.
Известные проблемы¶
1. Поток SIP звонка может играть неплавно как HLS без транскодинга¶
Симптомы
При ретрансляции SIP как RTMP на серверы Wowza и получении потока с Wowza по HLS зритель наблюдает фризы, кратковременную рассинхронизацию.
Решение
Включить транскодинг на сервере, указав настройку в файле flashphoner.properties
2. Поток из аудио SIP звонка может не играть как WebRTC без указания соответствующих ограничений¶
Симптомы
При ретрансляции SIP as Stream поток аудиозвонка не воспроизводится по WebRTC в браузере
Решение
Поток аудиозвонка необходимо воспроизводить в браузере как аудиопоток, указав ограничение явным образом при создании потока в скрипте плеера, например
3. Параметры SIP Login
, SIP Authentification name
не должны содержать пробелов и спецсимволов¶
Симптомы
Звонок не совершается, при создании звонка при помощи REST API /call/startup
возвращается
HTTP/1.1 500 Internal Server Error
Access-Control-Allow-Origin: *
Content-Type: application/json
{
"error": "Internal Server Error",
"exception": "com.flashphoner.rest.server.exception.InternalErrorException",
"message": "SIP login or authentication name contains reserved symbols",
"path": "/rest-api/call/startup",
"status": 500,
"timestamp": 1559029484840
}
Решение
Согласно RFC 3621, SIP Login
и SIP Authentification name
не должны содержать неэкранированных пробелов, спецсимволов и не должны заключаться в угловые скобки <>
.
Например, такое заполнение полей не соответствует стандарту
sipLogin='Ralf C12441@host.com'
sipAuthenticationName='Ralf C'
sipPassword='demo'
sipVisibleName='null'
а такое соответствует
4. При ретрансляции видеозвонка в поток в некоторых случаях необходимо включить буферизацию RTP трафика¶
Симптомы
При видеозвонках на некоторые софтфоны заметна рассинхронизация между видео и аудио при проигрывании потока