Commit 4604aaea99925415db8d9efe1d7e68d6f59e93c8
1 parent
3571ca27
优化语音对讲支持根据设备设置释放收到ACK后开始发流
Showing
9 changed files
with
128 additions
and
101 deletions
src/main/java/com/genersoft/iot/vmp/conf/UserSetting.java
| ... | ... | @@ -47,8 +47,6 @@ public class UserSetting { |
| 47 | 47 | |
| 48 | 48 | private Boolean syncChannelOnDeviceOnline = Boolean.FALSE; |
| 49 | 49 | |
| 50 | - private Boolean pushStreamAfterAck = Boolean.FALSE; | |
| 51 | - | |
| 52 | 50 | private Boolean sipLog = Boolean.FALSE; |
| 53 | 51 | private Boolean sqlLog = Boolean.FALSE; |
| 54 | 52 | private Boolean sendToPlatformsWhenIdLost = Boolean.FALSE; |
| ... | ... | @@ -234,14 +232,6 @@ public class UserSetting { |
| 234 | 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 | 235 | public Boolean getSipUseSourceIpAsRemoteAddress() { |
| 246 | 236 | return sipUseSourceIpAsRemoteAddress; |
| 247 | 237 | } | ... | ... |
src/main/java/com/genersoft/iot/vmp/gb28181/bean/Device.java
| ... | ... | @@ -188,8 +188,8 @@ public class Device { |
| 188 | 188 | @Schema(description = "设备注册的事务信息") |
| 189 | 189 | private SipTransactionInfo sipTransactionInfo; |
| 190 | 190 | |
| 191 | - | |
| 192 | - | |
| 191 | + @Schema(description = "控制语音对讲流程,释放收到ACK后发流") | |
| 192 | + private boolean broadcastPushAfterAck; | |
| 193 | 193 | |
| 194 | 194 | public String getDeviceId() { |
| 195 | 195 | return deviceId; |
| ... | ... | @@ -465,4 +465,11 @@ public class Device { |
| 465 | 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 | 3 | import com.alibaba.fastjson2.JSONObject; |
| 4 | 4 | import com.genersoft.iot.vmp.conf.DynamicTask; |
| 5 | 5 | import com.genersoft.iot.vmp.conf.UserSetting; |
| 6 | +import com.genersoft.iot.vmp.gb28181.bean.Device; | |
| 6 | 7 | import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform; |
| 7 | 8 | import com.genersoft.iot.vmp.gb28181.bean.SendRtpItem; |
| 8 | 9 | import com.genersoft.iot.vmp.gb28181.transmit.SIPProcessorObserver; |
| ... | ... | @@ -10,9 +11,8 @@ import com.genersoft.iot.vmp.gb28181.transmit.event.request.ISIPRequestProcessor |
| 10 | 11 | import com.genersoft.iot.vmp.gb28181.transmit.event.request.SIPRequestProcessorParent; |
| 11 | 12 | import com.genersoft.iot.vmp.media.zlm.ZLMRTPServerFactory; |
| 12 | 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 | 14 | import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; |
| 15 | +import com.genersoft.iot.vmp.service.IDeviceService; | |
| 16 | 16 | import com.genersoft.iot.vmp.service.IMediaServerService; |
| 17 | 17 | import com.genersoft.iot.vmp.service.IPlayService; |
| 18 | 18 | import com.genersoft.iot.vmp.service.bean.RequestPushStreamMsg; |
| ... | ... | @@ -63,6 +63,9 @@ public class AckRequestProcessor extends SIPRequestProcessorParent implements In |
| 63 | 63 | private IVideoManagerStorage storager; |
| 64 | 64 | |
| 65 | 65 | @Autowired |
| 66 | + private IDeviceService deviceService; | |
| 67 | + | |
| 68 | + @Autowired | |
| 66 | 69 | private ZLMRTPServerFactory zlmrtpServerFactory; |
| 67 | 70 | |
| 68 | 71 | @Autowired |
| ... | ... | @@ -87,40 +90,23 @@ public class AckRequestProcessor extends SIPRequestProcessorParent implements In |
| 87 | 90 | @Override |
| 88 | 91 | public void process(RequestEvent evt) { |
| 89 | 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 | 110 | if (mediaInfo == null) { |
| 125 | 111 | RequestPushStreamMsg requestPushStreamMsg = RequestPushStreamMsg.getInstance( |
| 126 | 112 | sendRtpItem.getMediaServerId(), sendRtpItem.getApp(), sendRtpItem.getStream(), |
| ... | ... | @@ -130,30 +116,75 @@ public class AckRequestProcessor extends SIPRequestProcessorParent implements In |
| 130 | 116 | playService.startSendRtpStreamHand(sendRtpItem, parentPlatform, json, param, callIdHeader); |
| 131 | 117 | }); |
| 132 | 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 | 120 | if (startSendRtpStreamResult != null) { |
| 153 | 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 | 427 | |
| 428 | 428 | try { |
| 429 | 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 | 442 | } catch (SipException | InvalidArgumentException | ParseException e) { |
| 448 | 443 | logger.error("[命令发送失败] 国标级联 回复SdpAck", e); |
| 449 | 444 | } |
| ... | ... | @@ -650,7 +645,6 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements |
| 650 | 645 | if (response != null) { |
| 651 | 646 | sendRtpItem.setToTag(response.getToTag()); |
| 652 | 647 | } |
| 653 | - | |
| 654 | 648 | redisCatchStorage.updateSendRTPSever(sendRtpItem); |
| 655 | 649 | |
| 656 | 650 | } else { |
| ... | ... | @@ -888,16 +882,8 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements |
| 888 | 882 | content.append("f=\r\n"); |
| 889 | 883 | |
| 890 | 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 | 887 | logger.error("未处理的异常 ", e); |
| 902 | 888 | } |
| 903 | 889 | return null; |
| ... | ... | @@ -1132,7 +1118,7 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements |
| 1132 | 1118 | audioBroadcastManager.update(audioBroadcastCatch); |
| 1133 | 1119 | |
| 1134 | 1120 | // 开启发流,大华在收到200OK后就会开始建立连接 |
| 1135 | - if (!userSetting.getPushStreamAfterAck()) { | |
| 1121 | + if (!device.isBroadcastPushAfterAck()) { | |
| 1136 | 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 | 64 | |
| 65 | 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 | 68 | JSONObject jsonObject, Map<String, Object> param, CallIdHeader callIdHeader); |
| 69 | 69 | |
| 70 | 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 | 1481 | } |
| 1482 | 1482 | |
| 1483 | 1483 | @Override |
| 1484 | - public void startSendRtpStreamHand(SendRtpItem sendRtpItem, ParentPlatform parentPlatform, | |
| 1484 | + public void startSendRtpStreamHand(SendRtpItem sendRtpItem, Object correlationInfo, | |
| 1485 | 1485 | JSONObject jsonObject, Map<String, Object> param, CallIdHeader callIdHeader) { |
| 1486 | 1486 | if (jsonObject == null) { |
| 1487 | 1487 | logger.error("RTP推流失败: 请检查ZLM服务"); |
| ... | ... | @@ -1504,10 +1504,13 @@ public class PlayServiceImpl implements IPlayService { |
| 1504 | 1504 | } |
| 1505 | 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 | 43 | "on_line," + |
| 44 | 44 | "media_server_id," + |
| 45 | 45 | "switch_primary_sub_stream," + |
| 46 | + "broadcast_push_after_ack," + | |
| 46 | 47 | "(SELECT count(0) FROM wvp_device_channel WHERE device_id=wvp_device.device_id) as channel_count "+ |
| 47 | 48 | " FROM wvp_device WHERE device_id = #{deviceId}") |
| 48 | 49 | Device getDeviceByDeviceId(String deviceId); |
| ... | ... | @@ -73,6 +74,7 @@ public interface DeviceMapper { |
| 73 | 74 | "subscribe_cycle_for_alarm,"+ |
| 74 | 75 | "ssrc_check,"+ |
| 75 | 76 | "as_message_channel,"+ |
| 77 | + "broadcast_push_after_ack,"+ | |
| 76 | 78 | "geo_coord_sys,"+ |
| 77 | 79 | "on_line"+ |
| 78 | 80 | ") VALUES (" + |
| ... | ... | @@ -101,6 +103,7 @@ public interface DeviceMapper { |
| 101 | 103 | "#{subscribeCycleForAlarm}," + |
| 102 | 104 | "#{ssrcCheck}," + |
| 103 | 105 | "#{asMessageChannel}," + |
| 106 | + "#{broadcastPushAfterAck}," + | |
| 104 | 107 | "#{geoCoordSys}," + |
| 105 | 108 | "#{onLine}" + |
| 106 | 109 | ")") |
| ... | ... | @@ -155,6 +158,7 @@ public interface DeviceMapper { |
| 155 | 158 | "subscribe_cycle_for_alarm,"+ |
| 156 | 159 | "ssrc_check,"+ |
| 157 | 160 | "as_message_channel,"+ |
| 161 | + "broadcast_push_after_ack,"+ | |
| 158 | 162 | "geo_coord_sys,"+ |
| 159 | 163 | "on_line,"+ |
| 160 | 164 | "media_server_id,"+ |
| ... | ... | @@ -196,6 +200,7 @@ public interface DeviceMapper { |
| 196 | 200 | "subscribe_cycle_for_alarm,"+ |
| 197 | 201 | "ssrc_check,"+ |
| 198 | 202 | "as_message_channel,"+ |
| 203 | + "broadcast_push_after_ack,"+ | |
| 199 | 204 | "geo_coord_sys,"+ |
| 200 | 205 | "on_line"+ |
| 201 | 206 | " FROM wvp_device WHERE on_line = true") |
| ... | ... | @@ -226,6 +231,7 @@ public interface DeviceMapper { |
| 226 | 231 | "subscribe_cycle_for_alarm,"+ |
| 227 | 232 | "ssrc_check,"+ |
| 228 | 233 | "as_message_channel,"+ |
| 234 | + "broadcast_push_after_ack,"+ | |
| 229 | 235 | "geo_coord_sys,"+ |
| 230 | 236 | "on_line"+ |
| 231 | 237 | " FROM wvp_device WHERE ip = #{host} AND port=#{port}") |
| ... | ... | @@ -247,6 +253,7 @@ public interface DeviceMapper { |
| 247 | 253 | "<if test=\"subscribeCycleForAlarm != null\">, subscribe_cycle_for_alarm=#{subscribeCycleForAlarm}</if>" + |
| 248 | 254 | "<if test=\"ssrcCheck != null\">, ssrc_check=#{ssrcCheck}</if>" + |
| 249 | 255 | "<if test=\"asMessageChannel != null\">, as_message_channel=#{asMessageChannel}</if>" + |
| 256 | + "<if test=\"broadcastPushAfterAck != null\">, broadcast_push_after_ack=#{broadcastPushAfterAck}</if>" + | |
| 250 | 257 | "<if test=\"geoCoordSys != null\">, geo_coord_sys=#{geoCoordSys}</if>" + |
| 251 | 258 | "<if test=\"switchPrimarySubStream != null\">, switch_primary_sub_stream=#{switchPrimarySubStream}</if>" + |
| 252 | 259 | "<if test=\"mediaServerId != null\">, media_server_id=#{mediaServerId}</if>" + |
| ... | ... | @@ -264,6 +271,7 @@ public interface DeviceMapper { |
| 264 | 271 | "charset,"+ |
| 265 | 272 | "ssrc_check,"+ |
| 266 | 273 | "as_message_channel,"+ |
| 274 | + "broadcastPushAfterAck,"+ | |
| 267 | 275 | "geo_coord_sys,"+ |
| 268 | 276 | "on_line,"+ |
| 269 | 277 | "media_server_id,"+ |
| ... | ... | @@ -278,6 +286,7 @@ public interface DeviceMapper { |
| 278 | 286 | "#{charset}," + |
| 279 | 287 | "#{ssrcCheck}," + |
| 280 | 288 | "#{asMessageChannel}," + |
| 289 | + "#{broadcastPushAfterAck}," + | |
| 281 | 290 | "#{geoCoordSys}," + |
| 282 | 291 | "#{onLine}," + |
| 283 | 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 | 70 | <el-form-item label="其他选项"> |
| 71 | 71 | <el-checkbox label="SSRC校验" v-model="form.ssrcCheck" style="float: left"></el-checkbox> |
| 72 | 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 | 74 | </el-form-item> |
| 74 | 75 | <el-form-item> |
| 75 | 76 | <div style="float: right;"> | ... | ... |