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,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;"> |