...
Для этого WCS должен быть настроен на прием звонков от АТС при помощи SIP транков. Затем WCS ждет входящих звонков от АТС. После того, как звонок установлен, из этого звонка создается поток и ретранслируется на указанный RTMP сервер. Кр=огда Когда звонок завершится, поток также завершается.
...
Настройка WCS
На стороне WCS, в файле flashphoner.properties должен быть установлен следующий параметр
...
Code Block | ||||
---|---|---|---|---|
| ||||
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 OK
- sdpParams - параметры, подставляемые в SDP для управления битрейтом и пропускной способностью канала передачи медиаданных звонка
WCS поддерживает TCP и UDP транспорт для SIP звонков и прослушивает порт, заданный в localPort, как по TCP, так и по UDP.
По умолчанию, имя RTMP потока будет сформировано как rtmp_0123456, где 0123456 - вызываемый номер. Для того, чтобы удалить префикс rtmp_, необходимо указать следующую настройку в файле flashphoner.properties properties
Code Block | ||
---|---|---|
| ||
rtmp_transponder_stream_name_prefix= |
...
3. Отправьте запрос /call/inject_stream/startup для перенаправления в звонок потока из файла на диске WCS
4. Содержимое файла играет на стороне программного телефона
...
5. Отправьте запрос /call/inject_stream/terminate, чтобы остановить проигрывание файла
Реализация собственного обработчика входящих SIP сообщений
В некоторых случаях, необходима дополнительная обработка входящих SIP сообщений. Для этого должен быть разработан собственный Java класс, реализующий интерфейс ISipMessageListener
, который будет перехватывать входящие SIP сообщения и обрабатывать их.
Рассмотрим пример, который добавляет порт в Request URI входящего INVITE запроса, если порт не указан. Исходный текст класса:
Code Block | ||||||
---|---|---|---|---|---|---|
| ||||||
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());
}
}
}
}
} |
Создадим на сервере структуру каталогов
Code Block | ||||
---|---|---|---|---|
| ||||
mkdir -p com/customListener |
Копируем исходный текст класса в созданный каталог и компилируем его
Code Block | ||||
---|---|---|---|---|
| ||||
javac -cp "/usr/local/FlashphonerWebCallServer/lib/*" ./com/customListener/customSipMessageListener.java |
Упаковываем скомпилированный класс в jar файл
Code Block | ||||
---|---|---|---|---|
| ||||
jar cf customSipMessageListener.jar com/customListener/customSipMessageListener.class |
Копируем jar файл в каталог сервера
Code Block | ||||
---|---|---|---|---|
| ||||
cp customSipMessageListener.jar /usr/local/FlashphonerWebCallServer/lib |
В файле flashphoner.properties необходимо указать созданный класс в настройке
Code Block | ||||
---|---|---|---|---|
| ||||
sip_msg_listener=com.customListener.customSipMessageListener |
и перезапустить сервер.
Запись потока входящего SIP звонка
Потоки, полученные из входящих SIP-звонков, могут быть записаны на сервере. Для того, чтобы записывать все входящие звонки, необходимо указать следующие настройки в файле flashphoner.properties:
Code Block | ||
---|---|---|
| ||
sip_record_stream=true |
Чтобы записать поток отдельного звонка, необходимо использовать соответствующий REST запрос.
Обратите внимание, что входящие звонки не будут записываться, если активна настройка
Code Block | ||
---|---|---|
| ||
sip_single_route_only=true |
Известные проблемы
1. В RTMP потоке, ретранслированном из входящего звонка, может наблюдаться рассинхронизация
Симптомы: рассинхронизация в потоке звонка при воспроизведении с RTMP сервера
Решение:
a) выставить настройку
Code Block | ||
---|---|---|
| ||
sip_force_rtcp_feedback=true |
b) свести к минимум либо исключить потери на канале между АТС и сервером