Merge branch 'main' into main2

# Conflicts:
#	src/main/java/com/genersoft/iot/vmp/conf/UserSetting.java
#	src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/AckRequestProcessor.java
#	src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/response/cmd/BroadcastResponseMessageHandler.java
#	src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java
#	src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java
#	src/main/resources/all-application.yml
This commit is contained in:
648540858
2023-01-05 11:07:06 +08:00
15 changed files with 343 additions and 146 deletions

View File

@@ -83,4 +83,19 @@ public class AudioBroadcastManager {
return audioBroadcastCatch;
}
public List<AudioBroadcastCatch> get(String deviceId) {
List<AudioBroadcastCatch> audioBroadcastCatchList= new ArrayList<>();
if (SipUtils.isFrontEnd(deviceId)) {
audioBroadcastCatchList.add(data.get(deviceId));
}else {
for (String key : data.keySet()) {
if (key.startsWith(deviceId)) {
audioBroadcastCatchList.add(data.get(key));
}
}
}
return audioBroadcastCatchList;
}
}

View File

@@ -1,14 +1,10 @@
package com.genersoft.iot.vmp.gb28181.transmit.event.request;
import com.genersoft.iot.vmp.conf.SipConfig;
import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform;
import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommander;
import com.genersoft.iot.vmp.gb28181.transmit.SIPSender;
import com.genersoft.iot.vmp.gb28181.utils.SipUtils;
import gov.nist.javax.sip.SipProviderImpl;
import gov.nist.javax.sip.message.SIPRequest;
import gov.nist.javax.sip.message.SIPResponse;
import gov.nist.javax.sip.stack.SIPServerTransactionImpl;
import org.apache.commons.lang3.ArrayUtils;
import org.dom4j.Document;
import org.dom4j.DocumentException;
@@ -17,14 +13,14 @@ import org.dom4j.io.SAXReader;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.security.core.parameters.P;
import javax.sip.*;
import javax.sip.address.Address;
import javax.sip.address.AddressFactory;
import javax.sip.address.SipURI;
import javax.sip.header.*;
import javax.sip.header.ContentTypeHeader;
import javax.sip.header.ExpiresHeader;
import javax.sip.header.HeaderFactory;
import javax.sip.message.MessageFactory;
import javax.sip.message.Request;
import javax.sip.message.Response;
@@ -157,7 +153,10 @@ public abstract class SIPRequestProcessorParent {
responseAckExtraParam.content = sdp;
responseAckExtraParam.sipURI = sipURI;
return responseAck(request, Response.OK, null, responseAckExtraParam);
SIPResponse sipResponse = responseAck(request, Response.OK, null, responseAckExtraParam);
return sipResponse;
}
/**
@@ -190,7 +189,8 @@ public abstract class SIPRequestProcessorParent {
reader.setEncoding(charset);
// 对海康出现的未转义字符做处理。
String[] destStrArray = new String[]{"&lt;","&gt;","&amp;","&apos;","&quot;"};
char despChar = '&'; // 或许可扩展兼容其他字符
// 或许可扩展兼容其他字符
char despChar = '&';
byte destBye = (byte) despChar;
List<Byte> result = new ArrayList<>();
byte[] rawContent = request.getRawContent();
@@ -220,4 +220,5 @@ public abstract class SIPRequestProcessorParent {
return xml.getRootElement();
}
}

View File

@@ -1,24 +1,18 @@
package com.genersoft.iot.vmp.gb28181.transmit.event.request.impl;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.genersoft.iot.vmp.conf.DynamicTask;
import com.genersoft.iot.vmp.conf.exception.SsrcTransactionNotFoundException;
import com.genersoft.iot.vmp.gb28181.bean.AudioBroadcastCatch;
import com.genersoft.iot.vmp.gb28181.bean.Device;
import com.genersoft.iot.vmp.conf.UserSetting;
import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform;
import com.genersoft.iot.vmp.gb28181.bean.SendRtpItem;
import com.genersoft.iot.vmp.gb28181.session.AudioBroadcastManager;
import com.genersoft.iot.vmp.gb28181.transmit.SIPProcessorObserver;
import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommander;
import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform;
import com.genersoft.iot.vmp.gb28181.transmit.event.request.ISIPRequestProcessor;
import com.genersoft.iot.vmp.gb28181.transmit.event.request.SIPRequestProcessorParent;
import com.genersoft.iot.vmp.media.zlm.ZLMRTPServerFactory;
import com.genersoft.iot.vmp.media.zlm.ZlmHttpHookSubscribe;
import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
import com.genersoft.iot.vmp.service.IDeviceService;
import com.genersoft.iot.vmp.service.IMediaServerService;
import com.genersoft.iot.vmp.service.IPlayService;
import com.genersoft.iot.vmp.service.bean.RequestPushStreamMsg;
import com.genersoft.iot.vmp.service.redisMsg.RedisGbPlayMsgListener;
import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
@@ -29,15 +23,15 @@ import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.sip.InvalidArgumentException;
import javax.sip.RequestEvent;
import javax.sip.SipException;
import javax.sip.address.SipURI;
import javax.sip.header.CallIdHeader;
import javax.sip.header.FromHeader;
import javax.sip.header.HeaderAddress;
import javax.sip.header.ToHeader;
import java.text.ParseException;
import java.util.HashMap;
import java.util.Map;
/**
* SIP命令类型 ACK请求
@@ -46,7 +40,7 @@ import java.text.ParseException;
@Component
public class AckRequestProcessor extends SIPRequestProcessorParent implements InitializingBean, ISIPRequestProcessor {
private Logger logger = LoggerFactory.getLogger(AckRequestProcessor.class);
private final Logger logger = LoggerFactory.getLogger(AckRequestProcessor.class);
private final String method = "ACK";
@Autowired
@@ -73,32 +67,21 @@ public class AckRequestProcessor extends SIPRequestProcessorParent implements In
@Autowired
private IMediaServerService mediaServerService;
@Autowired
private ZlmHttpHookSubscribe subscribe;
@Autowired
private DynamicTask dynamicTask;
@Autowired
private ISIPCommander cmder;
@Autowired
private IDeviceService deviceService;
@Autowired
private ISIPCommanderForPlatform commanderForPlatform;
@Autowired
private AudioBroadcastManager audioBroadcastManager;
@Autowired
private RedisGbPlayMsgListener redisGbPlayMsgListener;
@Autowired
private UserSetting userSetting;
@Autowired
private IPlayService playService;
/**
* 处理 ACK请求
*
* @param evt
*/
@Override
public void process(RequestEvent evt) {
@@ -106,44 +89,45 @@ public class AckRequestProcessor extends SIPRequestProcessorParent implements In
String platformGbId = ((SipURI) ((HeaderAddress) evt.getRequest().getHeader(FromHeader.NAME)).getAddress().getURI()).getUser();
logger.info("[收到ACK] platformGbId->{}", platformGbId);
ParentPlatform parentPlatform = storager.queryParentPlatByServerGBId(platformGbId);
// 取消设置的超时任务
dynamicTask.stop(callIdHeader.getCallId());
String channelId = ((SipURI) ((HeaderAddress) evt.getRequest().getHeader(ToHeader.NAME)).getAddress().getURI()).getUser();
SendRtpItem sendRtpItem = redisCatchStorage.querySendRTPServer(null, null, null, callIdHeader.getCallId());
if (sendRtpItem == null) {
logger.warn("[收到ACK]:未找到通道({})的推流信息", channelId);
return;
}
String is_Udp = sendRtpItem.isTcp() ? "0" : "1";
MediaServerItem mediaInfo = mediaServerService.getOne(sendRtpItem.getMediaServerId());
logger.info("收到ACKrtp/{}开始向上级推流, 目标={}:{}SSRC={}, RTCP={}", sendRtpItem.getStreamId(),
sendRtpItem.getIp(), sendRtpItem.getPort(), sendRtpItem.getSsrc(), sendRtpItem.isRtcp());
if (mediaInfo == null) {
RequestPushStreamMsg requestPushStreamMsg = RequestPushStreamMsg.getInstance(
sendRtpItem.getMediaServerId(), sendRtpItem.getApp(), sendRtpItem.getStreamId(),
sendRtpItem.getIp(), sendRtpItem.getPort(), sendRtpItem.getSsrc(), sendRtpItem.isTcp(),
sendRtpItem.getLocalPort(), sendRtpItem.getPt(), sendRtpItem.isUsePs(), sendRtpItem.isOnlyAudio());
redisGbPlayMsgListener.sendMsgForStartSendRtpStream(sendRtpItem.getServerId(), requestPushStreamMsg, json -> {
startSendRtpStreamHand(evt, sendRtpItem, parentPlatform, json, callIdHeader);
});
}else {
JSONObject startSendRtpStreamResult = zlmrtpServerFactory.startSendRtp(mediaInfo, sendRtpItem);
if (startSendRtpStreamResult != null) {
startSendRtpStreamHand(evt, sendRtpItem, parentPlatform, startSendRtpStreamResult, callIdHeader);
if (userSetting.getPushStreamAfterAck()) {
ParentPlatform parentPlatform = storager.queryParentPlatByServerGBId(platformGbId);
// 取消设置的超时任务
dynamicTask.stop(callIdHeader.getCallId());
String channelId = ((SipURI) ((HeaderAddress) evt.getRequest().getHeader(ToHeader.NAME)).getAddress().getURI()).getUser();
SendRtpItem sendRtpItem = redisCatchStorage.querySendRTPServer(null, null, null, callIdHeader.getCallId());
if (sendRtpItem == null) {
logger.warn("[收到ACK]:未找到通道({})的推流信息", channelId);
return;
}
String is_Udp = sendRtpItem.isTcp() ? "0" : "1";
MediaServerItem mediaInfo = mediaServerService.getOne(sendRtpItem.getMediaServerId());
logger.info("收到ACKrtp/{}开始向上级推流, 目标={}:{}SSRC={}, RTCP={}", sendRtpItem.getStreamId(),
sendRtpItem.getIp(), sendRtpItem.getPort(), sendRtpItem.getSsrc(), sendRtpItem.isRtcp());
if (mediaInfo == null) {
RequestPushStreamMsg requestPushStreamMsg = RequestPushStreamMsg.getInstance(
sendRtpItem.getMediaServerId(), sendRtpItem.getApp(), sendRtpItem.getStreamId(),
sendRtpItem.getIp(), sendRtpItem.getPort(), sendRtpItem.getSsrc(), sendRtpItem.isTcp(),
sendRtpItem.getLocalPort(), sendRtpItem.getPt(), sendRtpItem.isUsePs(), sendRtpItem.isOnlyAudio());
redisGbPlayMsgListener.sendMsgForStartSendRtpStream(sendRtpItem.getServerId(), requestPushStreamMsg, json -> {
startSendRtpStreamHand(evt, sendRtpItem, parentPlatform, json, callIdHeader);
});
}else {
JSONObject startSendRtpStreamResult = zlmrtpServerFactory.startSendRtp(mediaInfo, sendRtpItem);
if (startSendRtpStreamResult != null) {
startSendRtpStreamHand(evt, sendRtpItem, parentPlatform, startSendRtpStreamResult, callIdHeader);
}
}
}
}
private void startSendRtpStreamHand(RequestEvent evt, SendRtpItem sendRtpItem, ParentPlatform parentPlatform,
JSONObject jsonObject, CallIdHeader callIdHeader) {
JSONObject jsonObject, Map<String, Object> param, CallIdHeader callIdHeader) {
if (jsonObject == null) {
logger.error("RTP推流失败: 请检查ZLM服务");
} else if (jsonObject.getInteger("code") == 0) {
logger.info("调用ZLM推流接口, 结果: {}", jsonObject);
logger.info("RTP推流成功[ {}/{} ]{}->{}:{}, " ,sendRtpItem.getApp(), sendRtpItem.getStreamId(), sendRtpItem.getIp(), sendRtpItem.getIp(), sendRtpItem.getPort());
logger.info("RTP推流成功[ {}/{} ]{}->{}:{}, " ,param.get("app"), param.get("stream"), jsonObject.getString("local_port"), param.get("dst_url"), param.get("dst_port"));
} else {
logger.error("RTP推流失败: {}, 参数:{}",jsonObject.getString("msg"), JSON.toJSONString(sendRtpItem));
logger.error("RTP推流失败: {}, 参数:{}",jsonObject.getString("msg"), JSON.toJSONString(param));
if (sendRtpItem.isOnlyAudio()) {
Device device = deviceService.getDevice(sendRtpItem.getDeviceId());
AudioBroadcastCatch audioBroadcastCatch = audioBroadcastManager.get(sendRtpItem.getDeviceId(), sendRtpItem.getChannelId());
@@ -152,17 +136,12 @@ public class AckRequestProcessor extends SIPRequestProcessorParent implements In
cmder.streamByeCmd(device, sendRtpItem.getChannelId(), audioBroadcastCatch.getSipTransactionInfo(), null);
} catch (SipException | ParseException | InvalidArgumentException |
SsrcTransactionNotFoundException e) {
logger.error("[命令发送失败] 停止语音喊话: {}", e.getMessage());
logger.error("[命令发送失败] 停止语音对讲: {}", e.getMessage());
}
}
}else {
// 向上级平台
try {
commanderForPlatform.streamByeCmd(parentPlatform, callIdHeader.getCallId());
} catch (SipException | InvalidArgumentException | ParseException e) {
logger.error("[命令发送失败] 国标级联 发送BYE: {}", e.getMessage());
}
}
}
}
}

View File

@@ -1,6 +1,7 @@
package com.genersoft.iot.vmp.gb28181.transmit.event.request.impl;
import com.alibaba.fastjson2.JSONObject;
import com.genersoft.iot.vmp.common.VideoManagerConstants;
import com.genersoft.iot.vmp.conf.DynamicTask;
import com.genersoft.iot.vmp.conf.SipConfig;
import com.genersoft.iot.vmp.conf.UserSetting;
@@ -439,18 +440,23 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements
try {
// 超时未收到Ack应该回复bye,当前等待时间为10秒
dynamicTask.startDelay(callIdHeader.getCallId(), () -> {
logger.info("Ack 等待超时");
mediaServerService.releaseSsrc(mediaServerItemInUSe.getId(), sendRtpItem.getSsrc());
// 回复bye
try {
cmderFroPlatform.streamByeCmd(platform, callIdHeader.getCallId());
} catch (SipException | InvalidArgumentException | ParseException e) {
logger.error("[命令发送失败] 国标级联 发送BYE: {}", e.getMessage());
}
}, 60 * 1000);
responseSdpAck(request, content.toString(), platform);
if (userSetting.getPushStreamAfterAck()) {
dynamicTask.startDelay(callIdHeader.getCallId(), () -> {
logger.info("Ack 等待超时");
mediaServerService.releaseSsrc(mediaServerItemInUSe.getId(), sendRtpItem.getSsrc());
// 回复bye
try {
cmderFroPlatform.streamByeCmd(platform, callIdHeader.getCallId());
} catch (SipException | InvalidArgumentException | ParseException e) {
logger.error("[命令发送失败] 国标级联 发送BYE: {}", e.getMessage());
}
}, 60 * 1000);
}
SIPResponse sipResponse = responseSdpAck(request, content.toString(), platform);
if (!userSetting.getPushStreamAfterAck()) {
playService.startPushStream(sendRtpItem, sipResponse, platform, request.getCallIdHeader());
}
} catch (SipException e) {
e.printStackTrace();
} catch (InvalidArgumentException e) {
@@ -878,7 +884,11 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements
content.append("f=\r\n");
try {
return responseSdpAck(request, content.toString(), platform);
SIPResponse sipResponse = responseSdpAck(request, content.toString(), platform);
if (!userSetting.getPushStreamAfterAck()) {
playService.startPushStream(sendRtpItem, sipResponse, platform, request.getCallIdHeader());
}
return sipResponse;
} catch (SipException e) {
e.printStackTrace();
} catch (InvalidArgumentException e) {
@@ -905,11 +915,14 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements
}
if (device != null) {
logger.info("收到设备" + requesterId + "的语音广播Invite请求");
String key = VideoManagerConstants.BROADCAST_WAITE_INVITE + device.getDeviceId() + audioBroadcastCatch.getChannelId();
dynamicTask.stop(key);
try {
responseAck(request, Response.TRYING);
} catch (SipException | InvalidArgumentException | ParseException e) {
logger.error("[命令发送失败] invite BAD_REQUEST: {}", e.getMessage());
playService.stopAudioBroadcast(device.getDeviceId(), audioBroadcastCatch.getChannelId());
return;
}
String contentString = new String(request.getRawContent());
// jainSip不支持y=字段, 移除移除以解析。
@@ -964,11 +977,14 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements
responseAck(request, Response.UNSUPPORTED_MEDIA_TYPE); // 不支持的格式发415
} catch (SipException | InvalidArgumentException | ParseException e) {
logger.error("[命令发送失败] invite 不支持的媒体格式: {}", e.getMessage());
playService.stopAudioBroadcast(device.getDeviceId(), audioBroadcastCatch.getChannelId());
return;
}
return;
}
String addressStr = sdp.getOrigin().getAddress();
logger.info("设备{}请求语音流,地址:{}:{}ssrc{}", requesterId, addressStr, port, ssrc);
logger.info("设备{}请求语音流,地址:{}:{}ssrc{}, {}", requesterId, addressStr, port, ssrc,
mediaTransmissionTCP ? (tcpActive? "TCP主动":"TCP被动") : "UDP");
MediaServerItem mediaServerItem = playService.getNewMediaServerItem(device);
if (mediaServerItem == null) {
@@ -977,6 +993,7 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements
responseAck(request, Response.BUSY_HERE);
} catch (SipException | InvalidArgumentException | ParseException e) {
logger.error("[命令发送失败] invite 未找到可用的zlm: {}", e.getMessage());
playService.stopAudioBroadcast(device.getDeviceId(), audioBroadcastCatch.getChannelId());
}
return;
}
@@ -990,13 +1007,12 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements
responseAck(request, Response.BUSY_HERE);
} catch (SipException | InvalidArgumentException | ParseException e) {
logger.error("[命令发送失败] invite 服务器端口资源不足: {}", e.getMessage());
playService.stopAudioBroadcast(device.getDeviceId(), audioBroadcastCatch.getChannelId());
return;
}
return;
}
sendRtpItem.setTcp(mediaTransmissionTCP);
if (tcpActive != null) {
sendRtpItem.setTcpActive(tcpActive);
}
String app = "broadcast";
String stream = device.getDeviceId() + "_" + audioBroadcastCatch.getChannelId();
@@ -1011,6 +1027,11 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements
sendRtpItem.setUsePs(false);
sendRtpItem.setRtcp(false);
sendRtpItem.setOnlyAudio(true);
sendRtpItem.setTcp(mediaTransmissionTCP);
if (tcpActive != null) {
sendRtpItem.setTcpActive(tcpActive);
}
redisCatchStorage.updateSendRTPSever(sendRtpItem);
@@ -1023,11 +1044,13 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements
responseAck(request, Response.GONE);
} catch (SipException | InvalidArgumentException | ParseException e) {
logger.error("[命令发送失败] 语音通话 回复410失败 {}", e.getMessage());
return;
}
playService.stopAudioBroadcast(device.getDeviceId(), audioBroadcastCatch.getChannelId());
}
} catch (SdpException e) {
logger.error("[SDP解析异常]", e);
playService.stopAudioBroadcast(device.getDeviceId(), audioBroadcastCatch.getChannelId());
}
} else {
logger.warn("来自无效设备/平台的请求");
@@ -1084,6 +1107,11 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements
audioBroadcastCatch.setSipTransactionInfoByRequset(sipResponse);
audioBroadcastManager.update(audioBroadcastCatch);
// 开启发流大华在收到200OK后就会开始建立连接
if (!userSetting.getPushStreamAfterAck()) {
playService.startPushStream(sendRtpItem, sipResponse, parentPlatform, request.getCallIdHeader());
}
} catch (SipException | InvalidArgumentException | ParseException | SdpParseException e) {
logger.error("[命令发送失败] 语音喊话 回复200OKSDP: {}", e.getMessage());
}

View File

@@ -1,5 +1,7 @@
package com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.response.cmd;
import com.genersoft.iot.vmp.common.VideoManagerConstants;
import com.genersoft.iot.vmp.conf.DynamicTask;
import com.genersoft.iot.vmp.gb28181.bean.AudioBroadcastCatch;
import com.genersoft.iot.vmp.gb28181.bean.AudioBroadcastCatchStatus;
import com.genersoft.iot.vmp.gb28181.bean.Device;
@@ -9,6 +11,7 @@ import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder;
import com.genersoft.iot.vmp.gb28181.transmit.event.request.SIPRequestProcessorParent;
import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.IMessageHandler;
import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.response.ResponseMessageHandler;
import com.genersoft.iot.vmp.service.IPlayService;
import gov.nist.javax.sip.message.SIPRequest;
import org.dom4j.Element;
import org.slf4j.Logger;
@@ -35,11 +38,14 @@ public class BroadcastResponseMessageHandler extends SIPRequestProcessorParent i
private ResponseMessageHandler responseMessageHandler;
@Autowired
private DeferredResultHolder deferredResultHolder;
private DynamicTask dynamicTask;
@Autowired
private AudioBroadcastManager audioBroadcastManager;
@Autowired
private IPlayService playService;
@Override
public void afterPropertiesSet() throws Exception {
responseMessageHandler.addHandler(cmdType, this);
@@ -47,6 +53,8 @@ public class BroadcastResponseMessageHandler extends SIPRequestProcessorParent i
@Override
public void handForDevice(RequestEvent evt, Device device, Element rootElement) {
SIPRequest request = (SIPRequest) evt.getRequest();
try {
String channelId = getText(rootElement, "DeviceID");
if (!audioBroadcastManager.exit(device.getDeviceId(), channelId)) {
@@ -55,12 +63,23 @@ public class BroadcastResponseMessageHandler extends SIPRequestProcessorParent i
return;
}
String result = getText(rootElement, "Result");
logger.info("收到语音广播回复 {}{}/{}", result, device.getDeviceId(), channelId );
AudioBroadcastCatch audioBroadcastCatch = audioBroadcastManager.get(device.getDeviceId(), channelId);
audioBroadcastCatch.setStatus(AudioBroadcastCatchStatus.WaiteInvite);
audioBroadcastManager.update(audioBroadcastCatch);
logger.info("[语音广播]回复{}, {}/{}", result, device.getDeviceId(), channelId );
// 回复200 OK
responseAck((SIPRequest) evt.getRequest(), Response.OK);
responseAck(request, Response.OK);
if (result.equalsIgnoreCase("OK")) {
AudioBroadcastCatch audioBroadcastCatch = audioBroadcastManager.get(device.getDeviceId(), channelId);
audioBroadcastCatch.setStatus(AudioBroadcastCatchStatus.WaiteInvite);
audioBroadcastManager.update(audioBroadcastCatch);
// 等待invite消息 超时则结束
String key = VideoManagerConstants.BROADCAST_WAITE_INVITE + device.getDeviceId() + channelId;
dynamicTask.startDelay(key, ()->{
logger.info("[语音广播]等待invite消息超时{}/{}", device.getDeviceId(), channelId);
playService.stopAudioBroadcast(device.getDeviceId(), channelId);
}, 2000);
}else {
playService.stopAudioBroadcast(device.getDeviceId(), channelId);
}
} catch (ParseException | SipException | InvalidArgumentException e) {
logger.error("[命令发送失败] 国标级联 语音喊话: {}", e.getMessage());
}

View File

@@ -35,6 +35,7 @@ import java.util.concurrent.ConcurrentLinkedQueue;
public class CatalogResponseMessageHandler extends SIPRequestProcessorParent implements InitializingBean, IMessageHandler {
private Logger logger = LoggerFactory.getLogger(CatalogResponseMessageHandler.class);
private final String cmdType = "Catalog";
@Autowired