Commit 3291c4b2e67d510186ca5fbfac8ec5af1a9d4f16
1 parent
912c83df
修复多平台推流无人观看redis通知
Showing
8 changed files
with
186 additions
and
47 deletions
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/ByeRequestProcessor.java
| ... | ... | @@ -15,8 +15,11 @@ import com.genersoft.iot.vmp.gb28181.transmit.event.request.ISIPRequestProcessor |
| 15 | 15 | import com.genersoft.iot.vmp.gb28181.transmit.event.request.SIPRequestProcessorParent; |
| 16 | 16 | import com.genersoft.iot.vmp.media.zlm.ZLMServerFactory; |
| 17 | 17 | import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; |
| 18 | +import com.genersoft.iot.vmp.media.zlm.dto.StreamPushItem; | |
| 18 | 19 | import com.genersoft.iot.vmp.service.*; |
| 19 | 20 | import com.genersoft.iot.vmp.service.bean.MessageForPushChannel; |
| 21 | +import com.genersoft.iot.vmp.service.bean.RequestStopPushStreamMsg; | |
| 22 | +import com.genersoft.iot.vmp.service.redisMsg.RedisGbPlayMsgListener; | |
| 20 | 23 | import com.genersoft.iot.vmp.storager.IRedisCatchStorage; |
| 21 | 24 | import com.genersoft.iot.vmp.storager.IVideoManagerStorage; |
| 22 | 25 | import gov.nist.javax.sip.message.SIPRequest; |
| ... | ... | @@ -92,6 +95,12 @@ public class ByeRequestProcessor extends SIPRequestProcessorParent implements In |
| 92 | 95 | @Autowired |
| 93 | 96 | private UserSetting userSetting; |
| 94 | 97 | |
| 98 | + @Autowired | |
| 99 | + private IStreamPushService pushService; | |
| 100 | + | |
| 101 | + @Autowired | |
| 102 | + private RedisGbPlayMsgListener redisGbPlayMsgListener; | |
| 103 | + | |
| 95 | 104 | @Override |
| 96 | 105 | public void afterPropertiesSet() throws Exception { |
| 97 | 106 | // 添加消息处理的订阅 |
| ... | ... | @@ -124,58 +133,81 @@ public class ByeRequestProcessor extends SIPRequestProcessorParent implements In |
| 124 | 133 | param.put("stream",streamId); |
| 125 | 134 | param.put("ssrc",sendRtpItem.getSsrc()); |
| 126 | 135 | logger.info("[收到bye] 停止推流:{}, 媒体节点: {}", streamId, sendRtpItem.getMediaServerId()); |
| 127 | - MediaServerItem mediaInfo = mediaServerService.getOne(sendRtpItem.getMediaServerId()); | |
| 128 | - redisCatchStorage.deleteSendRTPServer(sendRtpItem.getPlatformId(), sendRtpItem.getChannelId(), | |
| 129 | - callIdHeader.getCallId(), null); | |
| 130 | - zlmServerFactory.stopSendRtpStream(mediaInfo, param); | |
| 131 | - if (userSetting.getUseCustomSsrcForParentInvite()) { | |
| 132 | - mediaServerService.releaseSsrc(mediaInfo.getId(), sendRtpItem.getSsrc()); | |
| 133 | - } | |
| 136 | + | |
| 134 | 137 | if (sendRtpItem.getPlayType().equals(InviteStreamType.PUSH)) { |
| 135 | - ParentPlatform platform = platformService.queryPlatformByServerGBId(sendRtpItem.getPlatformId()); | |
| 136 | - if (platform != null) { | |
| 137 | - MessageForPushChannel messageForPushChannel = MessageForPushChannel.getInstance(0, | |
| 138 | - sendRtpItem.getApp(), sendRtpItem.getStream(), sendRtpItem.getChannelId(), | |
| 139 | - sendRtpItem.getPlatformId(), platform.getName(), userSetting.getServerId(), sendRtpItem.getMediaServerId()); | |
| 140 | - messageForPushChannel.setPlatFormIndex(platform.getId()); | |
| 141 | - redisCatchStorage.sendPlatformStopPlayMsg(messageForPushChannel); | |
| 138 | + // 查询这路流是否是本平台的 | |
| 139 | + StreamPushItem push = pushService.getPush(sendRtpItem.getApp(), sendRtpItem.getStream()); | |
| 140 | + if (push!= null && !push.isSelf()) { | |
| 141 | + // 不是本平台的就发送redis消息让其他wvp停止发流 | |
| 142 | + ParentPlatform platform = platformService.queryPlatformByServerGBId(sendRtpItem.getPlatformId()); | |
| 143 | + if (platform != null) { | |
| 144 | + RequestStopPushStreamMsg streamMsg = RequestStopPushStreamMsg.getInstance(sendRtpItem, platform.getName(), platform.getId()); | |
| 145 | + redisGbPlayMsgListener.sendMsgForStopSendRtpStream(sendRtpItem.getServerId(), streamMsg); | |
| 146 | + } | |
| 142 | 147 | }else { |
| 143 | - logger.info("[上级平台停止观看] 未找到平台{}的信息,发送redis消息失败", sendRtpItem.getPlatformId()); | |
| 144 | - } | |
| 145 | - } | |
| 148 | + MediaServerItem mediaInfo = mediaServerService.getOne(sendRtpItem.getMediaServerId()); | |
| 149 | + redisCatchStorage.deleteSendRTPServer(sendRtpItem.getPlatformId(), sendRtpItem.getChannelId(), | |
| 150 | + callIdHeader.getCallId(), null); | |
| 151 | + zlmServerFactory.stopSendRtpStream(mediaInfo, param); | |
| 152 | + if (userSetting.getUseCustomSsrcForParentInvite()) { | |
| 153 | + mediaServerService.releaseSsrc(mediaInfo.getId(), sendRtpItem.getSsrc()); | |
| 154 | + } | |
| 146 | 155 | |
| 147 | - AudioBroadcastCatch audioBroadcastCatch = audioBroadcastManager.get(sendRtpItem.getDeviceId(), sendRtpItem.getChannelId()); | |
| 148 | - if (audioBroadcastCatch != null && audioBroadcastCatch.getSipTransactionInfo().getCallId().equals(callIdHeader.getCallId())) { | |
| 149 | - // 来自上级平台的停止对讲 | |
| 150 | - logger.info("[停止对讲] 来自上级,平台:{}, 通道:{}", sendRtpItem.getDeviceId(), sendRtpItem.getChannelId()); | |
| 151 | - audioBroadcastManager.del(sendRtpItem.getDeviceId(), sendRtpItem.getChannelId()); | |
| 156 | + ParentPlatform platform = platformService.queryPlatformByServerGBId(sendRtpItem.getPlatformId()); | |
| 157 | + if (platform != null) { | |
| 158 | + MessageForPushChannel messageForPushChannel = MessageForPushChannel.getInstance(0, | |
| 159 | + sendRtpItem.getApp(), sendRtpItem.getStream(), sendRtpItem.getChannelId(), | |
| 160 | + sendRtpItem.getPlatformId(), platform.getName(), userSetting.getServerId(), sendRtpItem.getMediaServerId()); | |
| 161 | + messageForPushChannel.setPlatFormIndex(platform.getId()); | |
| 162 | + redisCatchStorage.sendPlatformStopPlayMsg(messageForPushChannel); | |
| 163 | + }else { | |
| 164 | + logger.info("[上级平台停止观看] 未找到平台{}的信息,发送redis消息失败", sendRtpItem.getPlatformId()); | |
| 165 | + } | |
| 166 | + } | |
| 167 | + }else { | |
| 168 | + MediaServerItem mediaInfo = mediaServerService.getOne(sendRtpItem.getMediaServerId()); | |
| 169 | + redisCatchStorage.deleteSendRTPServer(sendRtpItem.getPlatformId(), sendRtpItem.getChannelId(), | |
| 170 | + callIdHeader.getCallId(), null); | |
| 171 | + zlmServerFactory.stopSendRtpStream(mediaInfo, param); | |
| 172 | + if (userSetting.getUseCustomSsrcForParentInvite()) { | |
| 173 | + mediaServerService.releaseSsrc(mediaInfo.getId(), sendRtpItem.getSsrc()); | |
| 174 | + } | |
| 152 | 175 | } |
| 176 | + MediaServerItem mediaInfo = mediaServerService.getOne(sendRtpItem.getMediaServerId()); | |
| 177 | + if (mediaInfo != null) { | |
| 178 | + AudioBroadcastCatch audioBroadcastCatch = audioBroadcastManager.get(sendRtpItem.getDeviceId(), sendRtpItem.getChannelId()); | |
| 179 | + if (audioBroadcastCatch != null && audioBroadcastCatch.getSipTransactionInfo().getCallId().equals(callIdHeader.getCallId())) { | |
| 180 | + // 来自上级平台的停止对讲 | |
| 181 | + logger.info("[停止对讲] 来自上级,平台:{}, 通道:{}", sendRtpItem.getDeviceId(), sendRtpItem.getChannelId()); | |
| 182 | + audioBroadcastManager.del(sendRtpItem.getDeviceId(), sendRtpItem.getChannelId()); | |
| 183 | + } | |
| 153 | 184 | |
| 154 | - int totalReaderCount = zlmServerFactory.totalReaderCount(mediaInfo, sendRtpItem.getApp(), streamId); | |
| 155 | - if (totalReaderCount <= 0) { | |
| 156 | - logger.info("[收到bye] {} 无其它观看者,通知设备停止推流", streamId); | |
| 157 | - if (sendRtpItem.getPlayType().equals(InviteStreamType.PLAY)) { | |
| 158 | - Device device = deviceService.getDevice(sendRtpItem.getDeviceId()); | |
| 159 | - if (device == null) { | |
| 160 | - logger.info("[收到bye] {} 通知设备停止推流时未找到设备信息", streamId); | |
| 161 | - } | |
| 162 | - try { | |
| 163 | - logger.info("[停止点播] {}/{}", sendRtpItem.getDeviceId(), sendRtpItem.getChannelId()); | |
| 164 | - cmder.streamByeCmd(device, sendRtpItem.getChannelId(), streamId, null); | |
| 165 | - } catch (InvalidArgumentException | ParseException | SipException | | |
| 166 | - SsrcTransactionNotFoundException e) { | |
| 167 | - logger.error("[收到bye] {} 无其它观看者,通知设备停止推流, 发送BYE失败 {}",streamId, e.getMessage()); | |
| 185 | + int totalReaderCount = zlmServerFactory.totalReaderCount(mediaInfo, sendRtpItem.getApp(), streamId); | |
| 186 | + if (totalReaderCount <= 0) { | |
| 187 | + logger.info("[收到bye] {} 无其它观看者,通知设备停止推流", streamId); | |
| 188 | + if (sendRtpItem.getPlayType().equals(InviteStreamType.PLAY)) { | |
| 189 | + Device device = deviceService.getDevice(sendRtpItem.getDeviceId()); | |
| 190 | + if (device == null) { | |
| 191 | + logger.info("[收到bye] {} 通知设备停止推流时未找到设备信息", streamId); | |
| 192 | + } | |
| 193 | + try { | |
| 194 | + logger.info("[停止点播] {}/{}", sendRtpItem.getDeviceId(), sendRtpItem.getChannelId()); | |
| 195 | + cmder.streamByeCmd(device, sendRtpItem.getChannelId(), streamId, null); | |
| 196 | + } catch (InvalidArgumentException | ParseException | SipException | | |
| 197 | + SsrcTransactionNotFoundException e) { | |
| 198 | + logger.error("[收到bye] {} 无其它观看者,通知设备停止推流, 发送BYE失败 {}",streamId, e.getMessage()); | |
| 199 | + } | |
| 168 | 200 | } |
| 169 | 201 | } |
| 170 | 202 | } |
| 171 | 203 | } |
| 172 | 204 | |
| 173 | - // 可能是设备发送的停止 | |
| 174 | - SsrcTransaction ssrcTransaction = streamSession.getSsrcTransactionByCallId(callIdHeader.getCallId()); | |
| 175 | - if (ssrcTransaction == null) { | |
| 176 | - return; | |
| 177 | - } | |
| 178 | - logger.info("[收到bye] 来自设备:{}, 通道已停止推流: {}", ssrcTransaction.getDeviceId(), ssrcTransaction.getChannelId()); | |
| 205 | + // 可能是设备发送的停止 | |
| 206 | + SsrcTransaction ssrcTransaction = streamSession.getSsrcTransactionByCallId(callIdHeader.getCallId()); | |
| 207 | + if (ssrcTransaction == null) { | |
| 208 | + return; | |
| 209 | + } | |
| 210 | + logger.info("[收到bye] 来自设备:{}, 通道已停止推流: {}", ssrcTransaction.getDeviceId(), ssrcTransaction.getChannelId()); | |
| 179 | 211 | |
| 180 | 212 | ParentPlatform platform = platformService.queryPlatformByServerGBId(ssrcTransaction.getDeviceId()); |
| 181 | 213 | if (platform != null ) { | ... | ... |
src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java
| ... | ... | @@ -579,7 +579,7 @@ public class ZLMHttpHookListener { |
| 579 | 579 | } |
| 580 | 580 | // 收到无人观看说明流也没有在往上级推送 |
| 581 | 581 | if (redisCatchStorage.isChannelSendingRTP(inviteInfo.getChannelId())) { |
| 582 | - List<SendRtpItem> sendRtpItems = redisCatchStorage.querySendRTPServerByChnnelId( | |
| 582 | + List<SendRtpItem> sendRtpItems = redisCatchStorage.querySendRTPServerByChannelId( | |
| 583 | 583 | inviteInfo.getChannelId()); |
| 584 | 584 | if (!sendRtpItems.isEmpty()) { |
| 585 | 585 | for (SendRtpItem sendRtpItem : sendRtpItems) { | ... | ... |
src/main/java/com/genersoft/iot/vmp/service/bean/RequestStopPushStreamMsg.java
0 → 100755
| 1 | +package com.genersoft.iot.vmp.service.bean; | |
| 2 | + | |
| 3 | +import com.genersoft.iot.vmp.gb28181.bean.SendRtpItem; | |
| 4 | + | |
| 5 | + | |
| 6 | +public class RequestStopPushStreamMsg { | |
| 7 | + | |
| 8 | + | |
| 9 | + private SendRtpItem sendRtpItem; | |
| 10 | + | |
| 11 | + | |
| 12 | + private String platformName; | |
| 13 | + | |
| 14 | + | |
| 15 | + private int platFormIndex; | |
| 16 | + | |
| 17 | + public SendRtpItem getSendRtpItem() { | |
| 18 | + return sendRtpItem; | |
| 19 | + } | |
| 20 | + | |
| 21 | + public void setSendRtpItem(SendRtpItem sendRtpItem) { | |
| 22 | + this.sendRtpItem = sendRtpItem; | |
| 23 | + } | |
| 24 | + | |
| 25 | + public String getPlatformName() { | |
| 26 | + return platformName; | |
| 27 | + } | |
| 28 | + | |
| 29 | + public void setPlatformName(String platformName) { | |
| 30 | + this.platformName = platformName; | |
| 31 | + } | |
| 32 | + | |
| 33 | + | |
| 34 | + public int getPlatFormIndex() { | |
| 35 | + return platFormIndex; | |
| 36 | + } | |
| 37 | + | |
| 38 | + public void setPlatFormIndex(int platFormIndex) { | |
| 39 | + this.platFormIndex = platFormIndex; | |
| 40 | + } | |
| 41 | + | |
| 42 | + public static RequestStopPushStreamMsg getInstance(SendRtpItem sendRtpItem, String platformName, int platFormIndex) { | |
| 43 | + RequestStopPushStreamMsg streamMsg = new RequestStopPushStreamMsg(); | |
| 44 | + streamMsg.setSendRtpItem(sendRtpItem); | |
| 45 | + streamMsg.setPlatformName(platformName); | |
| 46 | + streamMsg.setPlatFormIndex(platFormIndex); | |
| 47 | + return streamMsg; | |
| 48 | + } | |
| 49 | +} | ... | ... |
src/main/java/com/genersoft/iot/vmp/service/bean/WvpRedisMsgCmd.java
| ... | ... | @@ -6,7 +6,17 @@ package com.genersoft.iot.vmp.service.bean; |
| 6 | 6 | |
| 7 | 7 | public class WvpRedisMsgCmd { |
| 8 | 8 | |
| 9 | + /** | |
| 10 | + * 请求获取推流信息 | |
| 11 | + */ | |
| 9 | 12 | public static final String GET_SEND_ITEM = "GetSendItem"; |
| 13 | + /** | |
| 14 | + * 请求推流的请求 | |
| 15 | + */ | |
| 10 | 16 | public static final String REQUEST_PUSH_STREAM = "RequestPushStream"; |
| 17 | + /** | |
| 18 | + * 停止推流的请求 | |
| 19 | + */ | |
| 20 | + public static final String REQUEST_STOP_PUSH_STREAM = "RequestStopPushStream"; | |
| 11 | 21 | |
| 12 | 22 | } | ... | ... |
src/main/java/com/genersoft/iot/vmp/service/redisMsg/RedisGbPlayMsgListener.java
| ... | ... | @@ -133,7 +133,10 @@ public class RedisGbPlayMsgListener implements MessageListener { |
| 133 | 133 | case WvpRedisMsgCmd.REQUEST_PUSH_STREAM: |
| 134 | 134 | RequestPushStreamMsg param = JSON.to(RequestPushStreamMsg.class, wvpRedisMsg.getContent()); |
| 135 | 135 | requestPushStreamMsgHand(param, wvpRedisMsg.getFromId(), wvpRedisMsg.getSerial()); |
| 136 | - | |
| 136 | + break; | |
| 137 | + case WvpRedisMsgCmd.REQUEST_STOP_PUSH_STREAM: | |
| 138 | + RequestStopPushStreamMsg streamMsg = JSON.to(RequestStopPushStreamMsg.class, wvpRedisMsg.getContent()); | |
| 139 | + requestStopPushStreamMsgHand(streamMsg, wvpRedisMsg.getFromId(), wvpRedisMsg.getSerial()); | |
| 137 | 140 | break; |
| 138 | 141 | default: |
| 139 | 142 | break; |
| ... | ... | @@ -397,6 +400,19 @@ public class RedisGbPlayMsgListener implements MessageListener { |
| 397 | 400 | redisTemplate.convertAndSend(WVP_PUSH_STREAM_KEY, jsonObject); |
| 398 | 401 | } |
| 399 | 402 | |
| 403 | + /** | |
| 404 | + * 发送请求推流的消息 | |
| 405 | + */ | |
| 406 | + public void sendMsgForStopSendRtpStream(String serverId, RequestStopPushStreamMsg streamMsg) { | |
| 407 | + String key = UUID.randomUUID().toString(); | |
| 408 | + WvpRedisMsg redisMsg = WvpRedisMsg.getRequestInstance(userSetting.getServerId(), serverId, | |
| 409 | + WvpRedisMsgCmd.REQUEST_STOP_PUSH_STREAM, key, JSON.toJSONString(streamMsg)); | |
| 410 | + | |
| 411 | + JSONObject jsonObject = (JSONObject)JSON.toJSON(redisMsg); | |
| 412 | + logger.info("[REDIS 请求其他平台停止推流] {}: {}", serverId, jsonObject); | |
| 413 | + redisTemplate.convertAndSend(WVP_PUSH_STREAM_KEY, jsonObject); | |
| 414 | + } | |
| 415 | + | |
| 400 | 416 | private SendRtpItem querySendRTPServer(String platformGbId, String channelId, String streamId, String callId) { |
| 401 | 417 | if (platformGbId == null) { |
| 402 | 418 | platformGbId = "*"; |
| ... | ... | @@ -423,4 +439,36 @@ public class RedisGbPlayMsgListener implements MessageListener { |
| 423 | 439 | return null; |
| 424 | 440 | } |
| 425 | 441 | } |
| 442 | + | |
| 443 | + /** | |
| 444 | + * 处理收到的请求推流的请求 | |
| 445 | + */ | |
| 446 | + private void requestStopPushStreamMsgHand(RequestStopPushStreamMsg streamMsg, String fromId, String serial) { | |
| 447 | + SendRtpItem sendRtpItem = streamMsg.getSendRtpItem(); | |
| 448 | + if (sendRtpItem == null) { | |
| 449 | + logger.info("[REDIS 执行其他平台的请求停止推流] 失败: sendRtpItem为NULL"); | |
| 450 | + return; | |
| 451 | + } | |
| 452 | + MediaServerItem mediaInfo = mediaServerService.getOne(sendRtpItem.getMediaServerId()); | |
| 453 | + if (mediaInfo == null) { | |
| 454 | + // TODO 回复错误 | |
| 455 | + return; | |
| 456 | + } | |
| 457 | + Map<String, Object> param = new HashMap<>(); | |
| 458 | + param.put("vhost","__defaultVhost__"); | |
| 459 | + param.put("app",sendRtpItem.getApp()); | |
| 460 | + param.put("stream",sendRtpItem.getStream()); | |
| 461 | + param.put("ssrc", sendRtpItem.getSsrc()); | |
| 462 | + | |
| 463 | + if (zlmServerFactory.stopSendRtpStream(mediaInfo, param)) { | |
| 464 | + logger.info("[REDIS 执行其他平台的请求停止推流] 成功: {}/{}", sendRtpItem.getApp(), sendRtpItem.getStream()); | |
| 465 | + // 发送redis消息 | |
| 466 | + MessageForPushChannel messageForPushChannel = MessageForPushChannel.getInstance(0, | |
| 467 | + sendRtpItem.getApp(), sendRtpItem.getStream(), sendRtpItem.getChannelId(), | |
| 468 | + sendRtpItem.getPlatformId(), streamMsg.getPlatformName(), userSetting.getServerId(), sendRtpItem.getMediaServerId()); | |
| 469 | + messageForPushChannel.setPlatFormIndex(streamMsg.getPlatFormIndex()); | |
| 470 | + redisCatchStorage.sendPlatformStopPlayMsg(messageForPushChannel); | |
| 471 | + } | |
| 472 | + | |
| 473 | + } | |
| 426 | 474 | } | ... | ... |
src/main/java/com/genersoft/iot/vmp/service/redisMsg/RedisPushStreamCloseResponseListener.java
| ... | ... | @@ -73,7 +73,7 @@ public class RedisPushStreamCloseResponseListener implements MessageListener { |
| 73 | 73 | MessageForPushChannel pushChannel = JSON.parseObject(message.getBody(), MessageForPushChannel.class); |
| 74 | 74 | StreamPushItem push = streamPushService.getPush(pushChannel.getApp(), pushChannel.getStream()); |
| 75 | 75 | if (push != null) { |
| 76 | - List<SendRtpItem> sendRtpItems = redisCatchStorage.querySendRTPServerByChnnelId( | |
| 76 | + List<SendRtpItem> sendRtpItems = redisCatchStorage.querySendRTPServerByChannelId( | |
| 77 | 77 | push.getGbId()); |
| 78 | 78 | if (!sendRtpItems.isEmpty()) { |
| 79 | 79 | for (SendRtpItem sendRtpItem : sendRtpItems) { | ... | ... |
src/main/java/com/genersoft/iot/vmp/storager/IRedisCatchStorage.java
| ... | ... | @@ -181,7 +181,7 @@ public interface IRedisCatchStorage { |
| 181 | 181 | */ |
| 182 | 182 | void sendStreamPushRequestedMsgForStatus(); |
| 183 | 183 | |
| 184 | - List<SendRtpItem> querySendRTPServerByChnnelId(String channelId); | |
| 184 | + List<SendRtpItem> querySendRTPServerByChannelId(String channelId); | |
| 185 | 185 | |
| 186 | 186 | List<SendRtpItem> querySendRTPServerByStream(String stream); |
| 187 | 187 | ... | ... |
src/main/java/com/genersoft/iot/vmp/storager/impl/RedisCatchStorageImpl.java
| ... | ... | @@ -184,7 +184,7 @@ public class RedisCatchStorageImpl implements IRedisCatchStorage { |
| 184 | 184 | } |
| 185 | 185 | |
| 186 | 186 | @Override |
| 187 | - public List<SendRtpItem> querySendRTPServerByChnnelId(String channelId) { | |
| 187 | + public List<SendRtpItem> querySendRTPServerByChannelId(String channelId) { | |
| 188 | 188 | if (channelId == null) { |
| 189 | 189 | return null; |
| 190 | 190 | } | ... | ... |