Commit 4604aaea99925415db8d9efe1d7e68d6f59e93c8

Authored by 648540858
1 parent 3571ca27

优化语音对讲支持根据设备设置释放收到ACK后开始发流

src/main/java/com/genersoft/iot/vmp/conf/UserSetting.java
@@ -47,8 +47,6 @@ public class UserSetting { @@ -47,8 +47,6 @@ public class UserSetting {
47 47
48 private Boolean syncChannelOnDeviceOnline = Boolean.FALSE; 48 private Boolean syncChannelOnDeviceOnline = Boolean.FALSE;
49 49
50 - private Boolean pushStreamAfterAck = Boolean.FALSE;  
51 -  
52 private Boolean sipLog = Boolean.FALSE; 50 private Boolean sipLog = Boolean.FALSE;
53 private Boolean sqlLog = Boolean.FALSE; 51 private Boolean sqlLog = Boolean.FALSE;
54 private Boolean sendToPlatformsWhenIdLost = Boolean.FALSE; 52 private Boolean sendToPlatformsWhenIdLost = Boolean.FALSE;
@@ -234,14 +232,6 @@ public class UserSetting { @@ -234,14 +232,6 @@ public class UserSetting {
234 this.broadcastForPlatform = broadcastForPlatform; 232 this.broadcastForPlatform = broadcastForPlatform;
235 } 233 }
236 234
237 - public Boolean getPushStreamAfterAck() {  
238 - return pushStreamAfterAck;  
239 - }  
240 -  
241 - public void setPushStreamAfterAck(Boolean pushStreamAfterAck) {  
242 - this.pushStreamAfterAck = pushStreamAfterAck;  
243 - }  
244 -  
245 public Boolean getSipUseSourceIpAsRemoteAddress() { 235 public Boolean getSipUseSourceIpAsRemoteAddress() {
246 return sipUseSourceIpAsRemoteAddress; 236 return sipUseSourceIpAsRemoteAddress;
247 } 237 }
src/main/java/com/genersoft/iot/vmp/gb28181/bean/Device.java
@@ -188,8 +188,8 @@ public class Device { @@ -188,8 +188,8 @@ public class Device {
188 @Schema(description = "设备注册的事务信息") 188 @Schema(description = "设备注册的事务信息")
189 private SipTransactionInfo sipTransactionInfo; 189 private SipTransactionInfo sipTransactionInfo;
190 190
191 -  
192 - 191 + @Schema(description = "控制语音对讲流程,释放收到ACK后发流")
  192 + private boolean broadcastPushAfterAck;
193 193
194 public String getDeviceId() { 194 public String getDeviceId() {
195 return deviceId; 195 return deviceId;
@@ -465,4 +465,11 @@ public class Device { @@ -465,4 +465,11 @@ public class Device {
465 /*======================设备主子码流逻辑END=========================*/ 465 /*======================设备主子码流逻辑END=========================*/
466 466
467 467
  468 + public boolean isBroadcastPushAfterAck() {
  469 + return broadcastPushAfterAck;
  470 + }
  471 +
  472 + public void setBroadcastPushAfterAck(boolean broadcastPushAfterAck) {
  473 + this.broadcastPushAfterAck = broadcastPushAfterAck;
  474 + }
468 } 475 }
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/AckRequestProcessor.java
@@ -3,6 +3,7 @@ package com.genersoft.iot.vmp.gb28181.transmit.event.request.impl; @@ -3,6 +3,7 @@ package com.genersoft.iot.vmp.gb28181.transmit.event.request.impl;
3 import com.alibaba.fastjson2.JSONObject; 3 import com.alibaba.fastjson2.JSONObject;
4 import com.genersoft.iot.vmp.conf.DynamicTask; 4 import com.genersoft.iot.vmp.conf.DynamicTask;
5 import com.genersoft.iot.vmp.conf.UserSetting; 5 import com.genersoft.iot.vmp.conf.UserSetting;
  6 +import com.genersoft.iot.vmp.gb28181.bean.Device;
6 import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform; 7 import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform;
7 import com.genersoft.iot.vmp.gb28181.bean.SendRtpItem; 8 import com.genersoft.iot.vmp.gb28181.bean.SendRtpItem;
8 import com.genersoft.iot.vmp.gb28181.transmit.SIPProcessorObserver; 9 import com.genersoft.iot.vmp.gb28181.transmit.SIPProcessorObserver;
@@ -10,9 +11,8 @@ import com.genersoft.iot.vmp.gb28181.transmit.event.request.ISIPRequestProcessor @@ -10,9 +11,8 @@ import com.genersoft.iot.vmp.gb28181.transmit.event.request.ISIPRequestProcessor
10 import com.genersoft.iot.vmp.gb28181.transmit.event.request.SIPRequestProcessorParent; 11 import com.genersoft.iot.vmp.gb28181.transmit.event.request.SIPRequestProcessorParent;
11 import com.genersoft.iot.vmp.media.zlm.ZLMRTPServerFactory; 12 import com.genersoft.iot.vmp.media.zlm.ZLMRTPServerFactory;
12 import com.genersoft.iot.vmp.media.zlm.ZlmHttpHookSubscribe; 13 import com.genersoft.iot.vmp.media.zlm.ZlmHttpHookSubscribe;
13 -import com.genersoft.iot.vmp.media.zlm.dto.HookSubscribeFactory;  
14 -import com.genersoft.iot.vmp.media.zlm.dto.HookSubscribeForRtpServerTimeout;  
15 import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; 14 import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
  15 +import com.genersoft.iot.vmp.service.IDeviceService;
16 import com.genersoft.iot.vmp.service.IMediaServerService; 16 import com.genersoft.iot.vmp.service.IMediaServerService;
17 import com.genersoft.iot.vmp.service.IPlayService; 17 import com.genersoft.iot.vmp.service.IPlayService;
18 import com.genersoft.iot.vmp.service.bean.RequestPushStreamMsg; 18 import com.genersoft.iot.vmp.service.bean.RequestPushStreamMsg;
@@ -63,6 +63,9 @@ public class AckRequestProcessor extends SIPRequestProcessorParent implements In @@ -63,6 +63,9 @@ public class AckRequestProcessor extends SIPRequestProcessorParent implements In
63 private IVideoManagerStorage storager; 63 private IVideoManagerStorage storager;
64 64
65 @Autowired 65 @Autowired
  66 + private IDeviceService deviceService;
  67 +
  68 + @Autowired
66 private ZLMRTPServerFactory zlmrtpServerFactory; 69 private ZLMRTPServerFactory zlmrtpServerFactory;
67 70
68 @Autowired 71 @Autowired
@@ -87,40 +90,23 @@ public class AckRequestProcessor extends SIPRequestProcessorParent implements In @@ -87,40 +90,23 @@ public class AckRequestProcessor extends SIPRequestProcessorParent implements In
87 @Override 90 @Override
88 public void process(RequestEvent evt) { 91 public void process(RequestEvent evt) {
89 CallIdHeader callIdHeader = (CallIdHeader)evt.getRequest().getHeader(CallIdHeader.NAME); 92 CallIdHeader callIdHeader = (CallIdHeader)evt.getRequest().getHeader(CallIdHeader.NAME);
90 -  
91 - String platformGbId = ((SipURI) ((HeaderAddress) evt.getRequest().getHeader(FromHeader.NAME)).getAddress().getURI()).getUser();  
92 - logger.info("[收到ACK]: platformGbId->{}", platformGbId);  
93 - if (userSetting.getPushStreamAfterAck()) {  
94 - ParentPlatform parentPlatform = storager.queryParentPlatByServerGBId(platformGbId);  
95 - // 取消设置的超时任务  
96 - dynamicTask.stop(callIdHeader.getCallId());  
97 - String channelId = ((SipURI) ((HeaderAddress) evt.getRequest().getHeader(ToHeader.NAME)).getAddress().getURI()).getUser();  
98 - SendRtpItem sendRtpItem = redisCatchStorage.querySendRTPServer(null, null, null, callIdHeader.getCallId());  
99 - if (sendRtpItem == null) {  
100 - logger.warn("[收到ACK]:未找到通道({})的推流信息", channelId);  
101 - return;  
102 - }  
103 - String isUdp = sendRtpItem.isTcp() ? "0" : "1";  
104 - MediaServerItem mediaInfo = mediaServerService.getOne(sendRtpItem.getMediaServerId());  
105 - logger.info("收到ACK,rtp/{}开始级推流, 目标={}:{},SSRC={}, RTCP={}", sendRtpItem.getStream(),  
106 - sendRtpItem.getIp(), sendRtpItem.getPort(), sendRtpItem.getSsrc(), sendRtpItem.isRtcp());  
107 - Map<String, Object> param = new HashMap<>(12);  
108 - param.put("vhost","__defaultVhost__");  
109 - param.put("app",sendRtpItem.getApp());  
110 - param.put("stream",sendRtpItem.getStream());  
111 - param.put("ssrc", sendRtpItem.getSsrc());  
112 - param.put("dst_url",sendRtpItem.getIp());  
113 - param.put("dst_port", sendRtpItem.getPort());  
114 - param.put("src_port", sendRtpItem.getLocalPort());  
115 - param.put("pt", sendRtpItem.getPt());  
116 - param.put("use_ps", sendRtpItem.isUsePs() ? "1" : "0");  
117 - param.put("only_audio", sendRtpItem.isOnlyAudio() ? "1" : "0");  
118 - param.put("is_udp", isUdp);  
119 - if (!sendRtpItem.isTcp()) {  
120 - // udp模式下开启rtcp保活  
121 - param.put("udp_rtcp_timeout", sendRtpItem.isRtcp()? "1":"0");  
122 - }  
123 - 93 + String fromUserId = ((SipURI) ((HeaderAddress) evt.getRequest().getHeader(FromHeader.NAME)).getAddress().getURI()).getUser();
  94 + String toUserId = ((SipURI) ((HeaderAddress) evt.getRequest().getHeader(ToHeader.NAME)).getAddress().getURI()).getUser();
  95 + logger.info("[收到ACK]: 来自->{}", fromUserId);
  96 + SendRtpItem sendRtpItem = redisCatchStorage.querySendRTPServer(null, null, null, callIdHeader.getCallId());
  97 + if (sendRtpItem == null) {
  98 + logger.warn("[收到ACK]:未找到来自{},目标为({})的推流信息",fromUserId, toUserId);
  99 + return;
  100 + }
  101 + logger.info("[收到ACK]:rtp/{}开始级推流, 目标={}:{},SSRC={}, RTCP={}", sendRtpItem.getStream(),
  102 + sendRtpItem.getIp(), sendRtpItem.getPort(), sendRtpItem.getSsrc(), sendRtpItem.isRtcp());
  103 + // 取消设置的超时任务
  104 + dynamicTask.stop(callIdHeader.getCallId());
  105 + MediaServerItem mediaInfo = mediaServerService.getOne(sendRtpItem.getMediaServerId());
  106 + ParentPlatform parentPlatform = storager.queryParentPlatByServerGBId(fromUserId);
  107 +
  108 + if (parentPlatform != null) {
  109 + Map<String, Object> param = getSendRtpParam(sendRtpItem);
124 if (mediaInfo == null) { 110 if (mediaInfo == null) {
125 RequestPushStreamMsg requestPushStreamMsg = RequestPushStreamMsg.getInstance( 111 RequestPushStreamMsg requestPushStreamMsg = RequestPushStreamMsg.getInstance(
126 sendRtpItem.getMediaServerId(), sendRtpItem.getApp(), sendRtpItem.getStream(), 112 sendRtpItem.getMediaServerId(), sendRtpItem.getApp(), sendRtpItem.getStream(),
@@ -130,30 +116,75 @@ public class AckRequestProcessor extends SIPRequestProcessorParent implements In @@ -130,30 +116,75 @@ public class AckRequestProcessor extends SIPRequestProcessorParent implements In
130 playService.startSendRtpStreamHand(sendRtpItem, parentPlatform, json, param, callIdHeader); 116 playService.startSendRtpStreamHand(sendRtpItem, parentPlatform, json, param, callIdHeader);
131 }); 117 });
132 } else { 118 } else {
133 - // 如果是非严格模式,需要关闭端口占用  
134 - JSONObject startSendRtpStreamResult = null;  
135 - if (sendRtpItem.getLocalPort() != 0) {  
136 - if (sendRtpItem.isTcpActive()) {  
137 - startSendRtpStreamResult = zlmrtpServerFactory.startSendRtpPassive(mediaInfo, param);  
138 - }else {  
139 - param.put("dst_url", sendRtpItem.getIp());  
140 - param.put("dst_port", sendRtpItem.getPort());  
141 - startSendRtpStreamResult = zlmrtpServerFactory.startSendRtpStream(mediaInfo, param);  
142 - }  
143 - }else {  
144 - if (sendRtpItem.isTcpActive()) {  
145 - startSendRtpStreamResult = zlmrtpServerFactory.startSendRtpPassive(mediaInfo, param);  
146 - }else {  
147 - param.put("dst_url", sendRtpItem.getIp());  
148 - param.put("dst_port", sendRtpItem.getPort());  
149 - startSendRtpStreamResult = zlmrtpServerFactory.startSendRtpStream(mediaInfo, param);  
150 - }  
151 - } 119 + JSONObject startSendRtpStreamResult = sendRtp(sendRtpItem, mediaInfo, param);
152 if (startSendRtpStreamResult != null) { 120 if (startSendRtpStreamResult != null) {
153 playService.startSendRtpStreamHand(sendRtpItem, parentPlatform, startSendRtpStreamResult, param, callIdHeader); 121 playService.startSendRtpStreamHand(sendRtpItem, parentPlatform, startSendRtpStreamResult, param, callIdHeader);
154 } 122 }
155 } 123 }
  124 + }else {
  125 + Device device = deviceService.getDevice(fromUserId);
  126 + if (device == null) {
  127 + logger.warn("[收到ACK]:来自{},目标为({})的推流信息为找到流体服务[{}]信息",fromUserId, toUserId, sendRtpItem.getMediaServerId());
  128 + return;
  129 + }
  130 + // 设置为收到ACK后发送语音的设备已经在发送200OK开始发流了
  131 + if (!device.isBroadcastPushAfterAck()) {
  132 + return;
  133 + }
  134 + if (mediaInfo == null) {
  135 + logger.warn("[收到ACK]:来自{},目标为({})的推流信息为找到流体服务[{}]信息",fromUserId, toUserId, sendRtpItem.getMediaServerId());
  136 + return;
  137 + }
  138 + Map<String, Object> param = getSendRtpParam(sendRtpItem);
  139 + JSONObject startSendRtpStreamResult = sendRtp(sendRtpItem, mediaInfo, param);
  140 + if (startSendRtpStreamResult != null) {
  141 + playService.startSendRtpStreamHand(sendRtpItem, device, startSendRtpStreamResult, param, callIdHeader);
  142 + }
  143 + }
  144 + }
  145 +
  146 + private Map<String, Object> getSendRtpParam(SendRtpItem sendRtpItem) {
  147 + String isUdp = sendRtpItem.isTcp() ? "0" : "1";
  148 + Map<String, Object> param = new HashMap<>(12);
  149 + param.put("vhost","__defaultVhost__");
  150 + param.put("app",sendRtpItem.getApp());
  151 + param.put("stream",sendRtpItem.getStream());
  152 + param.put("ssrc", sendRtpItem.getSsrc());
  153 + param.put("dst_url",sendRtpItem.getIp());
  154 + param.put("dst_port", sendRtpItem.getPort());
  155 + param.put("src_port", sendRtpItem.getLocalPort());
  156 + param.put("pt", sendRtpItem.getPt());
  157 + param.put("use_ps", sendRtpItem.isUsePs() ? "1" : "0");
  158 + param.put("only_audio", sendRtpItem.isOnlyAudio() ? "1" : "0");
  159 + param.put("is_udp", isUdp);
  160 + if (!sendRtpItem.isTcp()) {
  161 + // udp模式下开启rtcp保活
  162 + param.put("udp_rtcp_timeout", sendRtpItem.isRtcp()? "1":"0");
156 } 163 }
  164 + return param;
  165 + }
  166 +
  167 + private JSONObject sendRtp(SendRtpItem sendRtpItem, MediaServerItem mediaInfo, Map<String, Object> param){
  168 + JSONObject startSendRtpStreamResult = null;
  169 + if (sendRtpItem.getLocalPort() != 0) {
  170 + if (sendRtpItem.isTcpActive()) {
  171 + startSendRtpStreamResult = zlmrtpServerFactory.startSendRtpPassive(mediaInfo, param);
  172 + }else {
  173 + param.put("dst_url", sendRtpItem.getIp());
  174 + param.put("dst_port", sendRtpItem.getPort());
  175 + startSendRtpStreamResult = zlmrtpServerFactory.startSendRtpStream(mediaInfo, param);
  176 + }
  177 + }else {
  178 + if (sendRtpItem.isTcpActive()) {
  179 + startSendRtpStreamResult = zlmrtpServerFactory.startSendRtpPassive(mediaInfo, param);
  180 + }else {
  181 + param.put("dst_url", sendRtpItem.getIp());
  182 + param.put("dst_port", sendRtpItem.getPort());
  183 + startSendRtpStreamResult = zlmrtpServerFactory.startSendRtpStream(mediaInfo, param);
  184 + }
  185 + }
  186 + return startSendRtpStreamResult;
  187 +
157 } 188 }
158 189
159 } 190 }
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/InviteRequestProcessor.java
@@ -427,23 +427,18 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements @@ -427,23 +427,18 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements
427 427
428 try { 428 try {
429 // 超时未收到Ack应该回复bye,当前等待时间为10秒 429 // 超时未收到Ack应该回复bye,当前等待时间为10秒
430 - if (userSetting.getPushStreamAfterAck()) {  
431 - dynamicTask.startDelay(callIdHeader.getCallId(), () -> {  
432 - logger.info("Ack 等待超时");  
433 - mediaServerService.releaseSsrc(mediaServerItemInUSe.getId(), sendRtpItem.getSsrc());  
434 - // 回复bye  
435 - try {  
436 - cmderFroPlatform.streamByeCmd(platform, callIdHeader.getCallId());  
437 - } catch (SipException | InvalidArgumentException | ParseException e) {  
438 - logger.error("[命令发送失败] 国标级联 发送BYE: {}", e.getMessage());  
439 - }  
440 - }, 60 * 1000);  
441 - } 430 + dynamicTask.startDelay(callIdHeader.getCallId(), () -> {
  431 + logger.info("Ack 等待超时");
  432 + mediaServerService.releaseSsrc(mediaServerItemInUSe.getId(), sendRtpItem.getSsrc());
  433 + // 回复bye
  434 + try {
  435 + cmderFroPlatform.streamByeCmd(platform, callIdHeader.getCallId());
  436 + } catch (SipException | InvalidArgumentException | ParseException e) {
  437 + logger.error("[命令发送失败] 国标级联 发送BYE: {}", e.getMessage());
  438 + }
  439 + }, 60 * 1000);
442 440
443 - SIPResponse sipResponse = responseSdpAck(request, content.toString(), platform);  
444 - if (!userSetting.getPushStreamAfterAck()) {  
445 - playService.startPushStream(sendRtpItem, sipResponse, platform, request.getCallIdHeader());  
446 - } 441 + responseSdpAck(request, content.toString(), platform);
447 } catch (SipException | InvalidArgumentException | ParseException e) { 442 } catch (SipException | InvalidArgumentException | ParseException e) {
448 logger.error("[命令发送失败] 国标级联 回复SdpAck", e); 443 logger.error("[命令发送失败] 国标级联 回复SdpAck", e);
449 } 444 }
@@ -650,7 +645,6 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements @@ -650,7 +645,6 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements
650 if (response != null) { 645 if (response != null) {
651 sendRtpItem.setToTag(response.getToTag()); 646 sendRtpItem.setToTag(response.getToTag());
652 } 647 }
653 -  
654 redisCatchStorage.updateSendRTPSever(sendRtpItem); 648 redisCatchStorage.updateSendRTPSever(sendRtpItem);
655 649
656 } else { 650 } else {
@@ -888,16 +882,8 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements @@ -888,16 +882,8 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements
888 content.append("f=\r\n"); 882 content.append("f=\r\n");
889 883
890 try { 884 try {
891 - SIPResponse sipResponse = responseSdpAck(request, content.toString(), platform);  
892 - if (!userSetting.getPushStreamAfterAck()) {  
893 - playService.startPushStream(sendRtpItem, sipResponse, platform, request.getCallIdHeader());  
894 - }  
895 - return sipResponse;  
896 - } catch (SipException e) {  
897 - logger.error("未处理的异常 ", e);  
898 - } catch (InvalidArgumentException e) {  
899 - logger.error("未处理的异常 ", e);  
900 - } catch (ParseException e) { 885 + return responseSdpAck(request, content.toString(), platform);
  886 + } catch (SipException | InvalidArgumentException | ParseException e) {
901 logger.error("未处理的异常 ", e); 887 logger.error("未处理的异常 ", e);
902 } 888 }
903 return null; 889 return null;
@@ -1132,7 +1118,7 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements @@ -1132,7 +1118,7 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements
1132 audioBroadcastManager.update(audioBroadcastCatch); 1118 audioBroadcastManager.update(audioBroadcastCatch);
1133 1119
1134 // 开启发流,大华在收到200OK后就会开始建立连接 1120 // 开启发流,大华在收到200OK后就会开始建立连接
1135 - if (!userSetting.getPushStreamAfterAck()) { 1121 + if (!device.isBroadcastPushAfterAck()) {
1136 playService.startPushStream(sendRtpItem, sipResponse, parentPlatform, request.getCallIdHeader()); 1122 playService.startPushStream(sendRtpItem, sipResponse, parentPlatform, request.getCallIdHeader());
1137 } 1123 }
1138 1124
src/main/java/com/genersoft/iot/vmp/service/IPlayService.java
@@ -64,7 +64,7 @@ public interface IPlayService { @@ -64,7 +64,7 @@ public interface IPlayService {
64 64
65 void startPushStream(SendRtpItem sendRtpItem, SIPResponse sipResponse, ParentPlatform platform, CallIdHeader callIdHeader); 65 void startPushStream(SendRtpItem sendRtpItem, SIPResponse sipResponse, ParentPlatform platform, CallIdHeader callIdHeader);
66 66
67 - void startSendRtpStreamHand(SendRtpItem sendRtpItem, ParentPlatform parentPlatform, 67 + void startSendRtpStreamHand(SendRtpItem sendRtpItem, Object correlationInfo,
68 JSONObject jsonObject, Map<String, Object> param, CallIdHeader callIdHeader); 68 JSONObject jsonObject, Map<String, Object> param, CallIdHeader callIdHeader);
69 69
70 void talkCmd(Device device, String channelId, MediaServerItem mediaServerItem, String stream, AudioBroadcastEvent event); 70 void talkCmd(Device device, String channelId, MediaServerItem mediaServerItem, String stream, AudioBroadcastEvent event);
src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java
@@ -1481,7 +1481,7 @@ public class PlayServiceImpl implements IPlayService { @@ -1481,7 +1481,7 @@ public class PlayServiceImpl implements IPlayService {
1481 } 1481 }
1482 1482
1483 @Override 1483 @Override
1484 - public void startSendRtpStreamHand(SendRtpItem sendRtpItem, ParentPlatform parentPlatform, 1484 + public void startSendRtpStreamHand(SendRtpItem sendRtpItem, Object correlationInfo,
1485 JSONObject jsonObject, Map<String, Object> param, CallIdHeader callIdHeader) { 1485 JSONObject jsonObject, Map<String, Object> param, CallIdHeader callIdHeader) {
1486 if (jsonObject == null) { 1486 if (jsonObject == null) {
1487 logger.error("RTP推流失败: 请检查ZLM服务"); 1487 logger.error("RTP推流失败: 请检查ZLM服务");
@@ -1504,10 +1504,13 @@ public class PlayServiceImpl implements IPlayService { @@ -1504,10 +1504,13 @@ public class PlayServiceImpl implements IPlayService {
1504 } 1504 }
1505 } else { 1505 } else {
1506 // 向上级平台 1506 // 向上级平台
1507 - try {  
1508 - commanderForPlatform.streamByeCmd(parentPlatform, callIdHeader.getCallId());  
1509 - } catch (SipException | InvalidArgumentException | ParseException e) {  
1510 - logger.error("[命令发送失败] 国标级联 发送BYE: {}", e.getMessage()); 1507 + if (correlationInfo instanceof ParentPlatform) {
  1508 + try {
  1509 + ParentPlatform parentPlatform = (ParentPlatform)correlationInfo;
  1510 + commanderForPlatform.streamByeCmd(parentPlatform, callIdHeader.getCallId());
  1511 + } catch (SipException | InvalidArgumentException | ParseException e) {
  1512 + logger.error("[命令发送失败] 国标级联 发送BYE: {}", e.getMessage());
  1513 + }
1511 } 1514 }
1512 } 1515 }
1513 } 1516 }
src/main/java/com/genersoft/iot/vmp/storager/dao/DeviceMapper.java
@@ -43,6 +43,7 @@ public interface DeviceMapper { @@ -43,6 +43,7 @@ public interface DeviceMapper {
43 "on_line," + 43 "on_line," +
44 "media_server_id," + 44 "media_server_id," +
45 "switch_primary_sub_stream," + 45 "switch_primary_sub_stream," +
  46 + "broadcast_push_after_ack," +
46 "(SELECT count(0) FROM wvp_device_channel WHERE device_id=wvp_device.device_id) as channel_count "+ 47 "(SELECT count(0) FROM wvp_device_channel WHERE device_id=wvp_device.device_id) as channel_count "+
47 " FROM wvp_device WHERE device_id = #{deviceId}") 48 " FROM wvp_device WHERE device_id = #{deviceId}")
48 Device getDeviceByDeviceId(String deviceId); 49 Device getDeviceByDeviceId(String deviceId);
@@ -73,6 +74,7 @@ public interface DeviceMapper { @@ -73,6 +74,7 @@ public interface DeviceMapper {
73 "subscribe_cycle_for_alarm,"+ 74 "subscribe_cycle_for_alarm,"+
74 "ssrc_check,"+ 75 "ssrc_check,"+
75 "as_message_channel,"+ 76 "as_message_channel,"+
  77 + "broadcast_push_after_ack,"+
76 "geo_coord_sys,"+ 78 "geo_coord_sys,"+
77 "on_line"+ 79 "on_line"+
78 ") VALUES (" + 80 ") VALUES (" +
@@ -101,6 +103,7 @@ public interface DeviceMapper { @@ -101,6 +103,7 @@ public interface DeviceMapper {
101 "#{subscribeCycleForAlarm}," + 103 "#{subscribeCycleForAlarm}," +
102 "#{ssrcCheck}," + 104 "#{ssrcCheck}," +
103 "#{asMessageChannel}," + 105 "#{asMessageChannel}," +
  106 + "#{broadcastPushAfterAck}," +
104 "#{geoCoordSys}," + 107 "#{geoCoordSys}," +
105 "#{onLine}" + 108 "#{onLine}" +
106 ")") 109 ")")
@@ -155,6 +158,7 @@ public interface DeviceMapper { @@ -155,6 +158,7 @@ public interface DeviceMapper {
155 "subscribe_cycle_for_alarm,"+ 158 "subscribe_cycle_for_alarm,"+
156 "ssrc_check,"+ 159 "ssrc_check,"+
157 "as_message_channel,"+ 160 "as_message_channel,"+
  161 + "broadcast_push_after_ack,"+
158 "geo_coord_sys,"+ 162 "geo_coord_sys,"+
159 "on_line,"+ 163 "on_line,"+
160 "media_server_id,"+ 164 "media_server_id,"+
@@ -196,6 +200,7 @@ public interface DeviceMapper { @@ -196,6 +200,7 @@ public interface DeviceMapper {
196 "subscribe_cycle_for_alarm,"+ 200 "subscribe_cycle_for_alarm,"+
197 "ssrc_check,"+ 201 "ssrc_check,"+
198 "as_message_channel,"+ 202 "as_message_channel,"+
  203 + "broadcast_push_after_ack,"+
199 "geo_coord_sys,"+ 204 "geo_coord_sys,"+
200 "on_line"+ 205 "on_line"+
201 " FROM wvp_device WHERE on_line = true") 206 " FROM wvp_device WHERE on_line = true")
@@ -226,6 +231,7 @@ public interface DeviceMapper { @@ -226,6 +231,7 @@ public interface DeviceMapper {
226 "subscribe_cycle_for_alarm,"+ 231 "subscribe_cycle_for_alarm,"+
227 "ssrc_check,"+ 232 "ssrc_check,"+
228 "as_message_channel,"+ 233 "as_message_channel,"+
  234 + "broadcast_push_after_ack,"+
229 "geo_coord_sys,"+ 235 "geo_coord_sys,"+
230 "on_line"+ 236 "on_line"+
231 " FROM wvp_device WHERE ip = #{host} AND port=#{port}") 237 " FROM wvp_device WHERE ip = #{host} AND port=#{port}")
@@ -247,6 +253,7 @@ public interface DeviceMapper { @@ -247,6 +253,7 @@ public interface DeviceMapper {
247 "<if test=\"subscribeCycleForAlarm != null\">, subscribe_cycle_for_alarm=#{subscribeCycleForAlarm}</if>" + 253 "<if test=\"subscribeCycleForAlarm != null\">, subscribe_cycle_for_alarm=#{subscribeCycleForAlarm}</if>" +
248 "<if test=\"ssrcCheck != null\">, ssrc_check=#{ssrcCheck}</if>" + 254 "<if test=\"ssrcCheck != null\">, ssrc_check=#{ssrcCheck}</if>" +
249 "<if test=\"asMessageChannel != null\">, as_message_channel=#{asMessageChannel}</if>" + 255 "<if test=\"asMessageChannel != null\">, as_message_channel=#{asMessageChannel}</if>" +
  256 + "<if test=\"broadcastPushAfterAck != null\">, broadcast_push_after_ack=#{broadcastPushAfterAck}</if>" +
250 "<if test=\"geoCoordSys != null\">, geo_coord_sys=#{geoCoordSys}</if>" + 257 "<if test=\"geoCoordSys != null\">, geo_coord_sys=#{geoCoordSys}</if>" +
251 "<if test=\"switchPrimarySubStream != null\">, switch_primary_sub_stream=#{switchPrimarySubStream}</if>" + 258 "<if test=\"switchPrimarySubStream != null\">, switch_primary_sub_stream=#{switchPrimarySubStream}</if>" +
252 "<if test=\"mediaServerId != null\">, media_server_id=#{mediaServerId}</if>" + 259 "<if test=\"mediaServerId != null\">, media_server_id=#{mediaServerId}</if>" +
@@ -264,6 +271,7 @@ public interface DeviceMapper { @@ -264,6 +271,7 @@ public interface DeviceMapper {
264 "charset,"+ 271 "charset,"+
265 "ssrc_check,"+ 272 "ssrc_check,"+
266 "as_message_channel,"+ 273 "as_message_channel,"+
  274 + "broadcastPushAfterAck,"+
267 "geo_coord_sys,"+ 275 "geo_coord_sys,"+
268 "on_line,"+ 276 "on_line,"+
269 "media_server_id,"+ 277 "media_server_id,"+
@@ -278,6 +286,7 @@ public interface DeviceMapper { @@ -278,6 +286,7 @@ public interface DeviceMapper {
278 "#{charset}," + 286 "#{charset}," +
279 "#{ssrcCheck}," + 287 "#{ssrcCheck}," +
280 "#{asMessageChannel}," + 288 "#{asMessageChannel}," +
  289 + "#{broadcastPushAfterAck}," +
281 "#{geoCoordSys}," + 290 "#{geoCoordSys}," +
282 "#{onLine}," + 291 "#{onLine}," +
283 "#{mediaServerId}," + 292 "#{mediaServerId}," +
src/main/resources/local.jks 0 → 100644
No preview for this file type
web_src/src/components/dialog/deviceEdit.vue
@@ -70,6 +70,7 @@ @@ -70,6 +70,7 @@
70 <el-form-item label="其他选项"> 70 <el-form-item label="其他选项">
71 <el-checkbox label="SSRC校验" v-model="form.ssrcCheck" style="float: left"></el-checkbox> 71 <el-checkbox label="SSRC校验" v-model="form.ssrcCheck" style="float: left"></el-checkbox>
72 <el-checkbox label="作为消息通道" v-model="form.asMessageChannel" style="float: left"></el-checkbox> 72 <el-checkbox label="作为消息通道" v-model="form.asMessageChannel" style="float: left"></el-checkbox>
  73 + <el-checkbox label="收到ACK后发流" v-model="form.broadcastPushAfterAck" style="float: left"></el-checkbox>
73 </el-form-item> 74 </el-form-item>
74 <el-form-item> 75 <el-form-item>
75 <div style="float: right;"> 76 <div style="float: right;">