Ретрансляция входящего SIP звонка в поток¶
Описание¶
WCS 5.2 может принять входящий звонок от АТС и опубликовать поток этого звонка как RTMP на указанный сервер (например, на Wowza). Кроме того, другой поток, опубликованный на сервере или захваченный по VOD из файла в локальном или сетевом хранилище может быть перенаправлен в звонок, в этом случае звонящий увидит и услышит этот поток.
Для этого WCS должен быть настроен на прием звонков от АТС при помощи SIP транков. Затем WCS ждет входящих звонков от АТС. После того, как звонок установлен, из этого звонка создается поток и ретранслируется на указанный RTMP сервер. Когда звонок завершится, поток также завершается.
Схема работы¶
- Абонент звонит на номер, для которого настроен SIP транк
- АТС перенаправляет звонок на WCS для приема
- WCS получает медиапоток от звонящего абонента
- WCS соединяется с RTMP сервером
- WCS публикует медиапоток на RTMP сервер
Настройка¶
Настройка WCS¶
На стороне WCS, в файле flashphoner.properties должен быть установлен следующий параметр
Кроме того, в файле /usr/local/FlashphonerWebCallServer/conf/sip_trunk.yml
должен быть настроен SIP транк:
trunks:
pbx_t0:
localPort: 40000
proxyIp: pbx_address
remotePort: 5060
url: rtmp://rtmp_server:1935/live
visibleName: CUSTOM_NAME
sdp: |
v=0
o=10009 2469 1555 IN IP4 0.0.0.0
c=IN IP4 0.0.0.0
t=0 0
m=audio 7270 RTP/AVP 96
a=rtpmap:96 opus/48000/2
a=recvonly
m=video 9202 RTP/AVP 96
a=rtpmap:96 H264/90000
a=fmtp:96 profile-level-id=42801F
a=recvonly
sdpParams:
- b=AS:2000
- b=RS:50
- b=RR:100
Здесь
pbx_t0
– наименование SIP транкаlocalPort
– порт для приема SIP звонковproxyIp
– адрес АТСremotePort
– порт АТС для регистрации на ней как принимающего звонкиurl
– URL RTMP сервера для публикации потокаvisibleName
- имя для отображения стороне, совершающей звонок, передается на АТС при регистрацииsdp
– SDP для отправки АТС в ответе 200 OKsdpParams
- параметры, подставляемые в SDP для управления битрейтом и пропускной способностью канала передачи медиаданных звонка
WCS поддерживает TCP и UDP транспорт для SIP звонков и прослушивает порт, заданный в localPort
, как по TCP, так и по UDP.
По умолчанию, имя RTMP потока будет сформировано как rtmp_0123456
, где 0123456
- вызываемый номер. Для того, чтобы удалить префикс rtmp_
, необходимо указать следующую настройку в файле flashphoner.properties
Настройка АТС¶
На стороне АТС, должен быть настроен SIP транк для перенаправления звонков WCS серверу. Звонки должны перенаправляться на порт, указанный в файле /usr/local/FlashphonerWebCallServer/conf/sip_trunk.yml
(40000 в приведенном примере).
Например, АТС OpenSIPS может быть настроена следующим образом:
route{
...
#WCS Sip trunk routing, 00 prefix + XX for server number (e.g. WCS1 => 01) + X for trunk number
if ($rU =~ "^00050[0-9]+$") {
# WCS5 address and port
rewritehostport("192.168.1.5:40000");
route(relay);
}
}
Тестирование¶
-
Для теста возьмем:
- WCS сервер
- АТС
- Программный телефон для установки звонка
- RTMP сервер
- VLC для воспроизведения RTMP потока
-
Откройте программный телефон, зарегистрируйтесь на АТС, сделайте видеозвонок на номер, определенный при настройке SIP транка на АТС, например
001201234
-
Откройте в VLC поток
rtmp://rtmp_server:1935/live/rtmp_001201234
-
Отправьте запрос
/call/inject_stream/startup
для перенаправления в звонок потока из файла на диске WCS
-
Содержимое файла играет на стороне программного телефона
-
Отправьте запрос
/call/inject\_stream/terminate
, чтобы остановить проигрывание файла
Реализация собственного обработчика входящих SIP сообщений¶
В некоторых случаях, необходима дополнительная обработка входящих SIP сообщений. Для этого должен быть разработан собственный Java класс, реализующий интерфейс ISipMessageListener
, который будет перехватывать входящие SIP сообщения и обрабатывать их.
Рассмотрим пример, который добавляет порт в Request URI
входящего INVITE запроса, если порт не указан. Исходный текст класса:
customSipMessageListener.java
package com.customListener;
import com.flashphoner.sdk.sip.ISipMessageListener;
import com.flashphoner.server.client.IClient;
import gov.nist.javax.sip.address.Authority;
import gov.nist.javax.sip.address.SipUri;
import gov.nist.javax.sip.message.SIPMessage;
import gov.nist.javax.sip.message.SIPRequest;
import gov.nist.javax.sip.stack.MessageChannel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.sip.message.Request;
public class customSipMessageListener implements ISipMessageListener {
private static Logger log = LoggerFactory.getLogger("customSipMessageListener");
@Override
public void processMessage(SIPMessage sipMessage, IClient client, MessageChannel channel) {
if (sipMessage instanceof SIPRequest) {
SIPRequest request = (SIPRequest) sipMessage;
String method = request.getRequestLine().getMethod();
if (Request.INVITE.equals(method)) {
Authority authority = ((SipUri)request.getRequestURI()).getAuthority();
int port = authority.getPort();
if (port <= 0) {
if (log.isDebugEnabled()) {
log.debug("Inject port " + channel.getPort());
}
authority.setPort(channel.getPort());
}
}
}
}
}
Создадим на сервере структуру каталогов
Копируем исходный текст класса в созданный каталог и компилируем его
javac -cp "/usr/local/FlashphonerWebCallServer/lib/*" ./com/customListener/customSipMessageListener.java
Упаковываем скомпилированный класс в jar файл
Копируем jar файл в каталог сервера
В файле flashphoner.properties необходимо указать созданный класс в настройке
и перезапустить сервер.
Запись потока входящего SIP звонка¶
Потоки, полученные из входящих SIP-звонков, могут быть записаны на сервере. Для того, чтобы записывать все входящие звонки, необходимо указать следующие настройки в файле flashphoner.properties
:
Чтобы записать поток отдельного звонка, необходимо использовать соответствующий REST запрос.
Известные проблемы¶
1. В RTMP потоке, ретранслированном из входящего звонка, может наблюдаться рассинхронизация¶
Симптомы
Рассинхронизация в потоке звонка при воспроизведении с RTMP сервера