...
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) свести к минимум либо исключить потери на канале между АТС и сервером