Commit 455e58f866d7f538422f50362137d9759dc58768
1 parent
6b1d9662
优化合并对讲broadcast级联模式
Showing
4 changed files
with
88 additions
and
9 deletions
src/main/java/com/genersoft/iot/vmp/gb28181/session/AudioBroadcastManager.java
| @@ -87,7 +87,9 @@ public class AudioBroadcastManager { | @@ -87,7 +87,9 @@ public class AudioBroadcastManager { | ||
| 87 | public List<AudioBroadcastCatch> get(String deviceId) { | 87 | public List<AudioBroadcastCatch> get(String deviceId) { |
| 88 | List<AudioBroadcastCatch> audioBroadcastCatchList= new ArrayList<>(); | 88 | List<AudioBroadcastCatch> audioBroadcastCatchList= new ArrayList<>(); |
| 89 | if (SipUtils.isFrontEnd(deviceId)) { | 89 | if (SipUtils.isFrontEnd(deviceId)) { |
| 90 | - audioBroadcastCatchList.add(data.get(deviceId)); | 90 | + if (data.get(deviceId) != null) { |
| 91 | + audioBroadcastCatchList.add(data.get(deviceId)); | ||
| 92 | + } | ||
| 91 | }else { | 93 | }else { |
| 92 | for (String key : data.keySet()) { | 94 | for (String key : data.keySet()) { |
| 93 | if (key.startsWith(deviceId)) { | 95 | if (key.startsWith(deviceId)) { |
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/ByeRequestProcessor.java
| @@ -2,14 +2,12 @@ package com.genersoft.iot.vmp.gb28181.transmit.event.request.impl; | @@ -2,14 +2,12 @@ package com.genersoft.iot.vmp.gb28181.transmit.event.request.impl; | ||
| 2 | 2 | ||
| 3 | import com.genersoft.iot.vmp.common.StreamInfo; | 3 | import com.genersoft.iot.vmp.common.StreamInfo; |
| 4 | import com.genersoft.iot.vmp.conf.exception.SsrcTransactionNotFoundException; | 4 | import com.genersoft.iot.vmp.conf.exception.SsrcTransactionNotFoundException; |
| 5 | -import com.genersoft.iot.vmp.gb28181.bean.Device; | ||
| 6 | -import com.genersoft.iot.vmp.gb28181.bean.InviteStreamType; | ||
| 7 | -import com.genersoft.iot.vmp.gb28181.bean.SendRtpItem; | ||
| 8 | -import com.genersoft.iot.vmp.gb28181.bean.SsrcTransaction; | 5 | +import com.genersoft.iot.vmp.gb28181.bean.*; |
| 9 | import com.genersoft.iot.vmp.gb28181.session.AudioBroadcastManager; | 6 | import com.genersoft.iot.vmp.gb28181.session.AudioBroadcastManager; |
| 10 | import com.genersoft.iot.vmp.gb28181.session.VideoStreamSessionManager; | 7 | import com.genersoft.iot.vmp.gb28181.session.VideoStreamSessionManager; |
| 11 | import com.genersoft.iot.vmp.gb28181.transmit.SIPProcessorObserver; | 8 | import com.genersoft.iot.vmp.gb28181.transmit.SIPProcessorObserver; |
| 12 | import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommander; | 9 | import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommander; |
| 10 | +import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform; | ||
| 13 | import com.genersoft.iot.vmp.gb28181.transmit.event.request.ISIPRequestProcessor; | 11 | import com.genersoft.iot.vmp.gb28181.transmit.event.request.ISIPRequestProcessor; |
| 14 | import com.genersoft.iot.vmp.gb28181.transmit.event.request.SIPRequestProcessorParent; | 12 | import com.genersoft.iot.vmp.gb28181.transmit.event.request.SIPRequestProcessorParent; |
| 15 | import com.genersoft.iot.vmp.media.zlm.ZLMRTPServerFactory; | 13 | import com.genersoft.iot.vmp.media.zlm.ZLMRTPServerFactory; |
| @@ -37,6 +35,7 @@ import javax.sip.header.ToHeader; | @@ -37,6 +35,7 @@ import javax.sip.header.ToHeader; | ||
| 37 | import javax.sip.message.Response; | 35 | import javax.sip.message.Response; |
| 38 | import java.text.ParseException; | 36 | import java.text.ParseException; |
| 39 | import java.util.HashMap; | 37 | import java.util.HashMap; |
| 38 | +import java.util.List; | ||
| 40 | import java.util.Map; | 39 | import java.util.Map; |
| 41 | 40 | ||
| 42 | /** | 41 | /** |
| @@ -52,6 +51,9 @@ public class ByeRequestProcessor extends SIPRequestProcessorParent implements In | @@ -52,6 +51,9 @@ public class ByeRequestProcessor extends SIPRequestProcessorParent implements In | ||
| 52 | private ISIPCommander cmder; | 51 | private ISIPCommander cmder; |
| 53 | 52 | ||
| 54 | @Autowired | 53 | @Autowired |
| 54 | + private ISIPCommanderForPlatform commanderForPlatform; | ||
| 55 | + | ||
| 56 | + @Autowired | ||
| 55 | private IRedisCatchStorage redisCatchStorage; | 57 | private IRedisCatchStorage redisCatchStorage; |
| 56 | 58 | ||
| 57 | @Autowired | 59 | @Autowired |
| @@ -204,12 +206,86 @@ public class ByeRequestProcessor extends SIPRequestProcessorParent implements In | @@ -204,12 +206,86 @@ public class ByeRequestProcessor extends SIPRequestProcessorParent implements In | ||
| 204 | case broadcast: | 206 | case broadcast: |
| 205 | String deviceId = ssrcTransaction.getDeviceId(); | 207 | String deviceId = ssrcTransaction.getDeviceId(); |
| 206 | String channelId1 = ssrcTransaction.getChannelId(); | 208 | String channelId1 = ssrcTransaction.getChannelId(); |
| 207 | - // 如果是 | 209 | + |
| 210 | + Device deviceFromTransaction = storager.queryVideoDevice(deviceId); | ||
| 211 | + if (deviceFromTransaction == null) { | ||
| 212 | + ParentPlatform parentPlatform = storager.queryParentPlatByServerGBId(deviceId); | ||
| 213 | + if (parentPlatform != null) { | ||
| 214 | + // 来自上级平台的停止对讲 | ||
| 215 | + // 释放ssrc | ||
| 216 | + MediaServerItem mediaServerItemFromTransaction = mediaServerService.getOne(ssrcTransaction.getMediaServerId()); | ||
| 217 | + if (mediaServerItemFromTransaction != null) { | ||
| 218 | + mediaServerService.releaseSsrc(mediaServerItemFromTransaction.getId(), ssrcTransaction.getSsrc()); | ||
| 219 | + } | ||
| 220 | + streamSession.remove(ssrcTransaction.getDeviceId(), ssrcTransaction.getChannelId(), ssrcTransaction.getStream()); | ||
| 221 | + } | ||
| 222 | + }else { | ||
| 223 | + // 来自设备的停止对讲 | ||
| 224 | + // 如果是来自设备,则听停止推流。 来自上级则停止收流 | ||
| 225 | + AudioBroadcastCatch audioBroadcastCatch = audioBroadcastManager.get(deviceId, channelId1); | ||
| 226 | + if (audioBroadcastCatch != null) { | ||
| 227 | + // | ||
| 228 | + SendRtpItem sendRtpItemForBroadcast = redisCatchStorage.querySendRTPServer(deviceId, channelId1, | ||
| 229 | + audioBroadcastCatch.getStream(), audioBroadcastCatch.getSipTransactionInfo().getCallId()); | ||
| 230 | + if (sendRtpItemForBroadcast != null) { | ||
| 231 | + MediaServerItem mediaServerItemForBroadcast = mediaServerService.getOne(sendRtpItem.getMediaServerId()); | ||
| 232 | + if (mediaServerItemForBroadcast == null) { | ||
| 233 | + return; | ||
| 234 | + } | ||
| 235 | + | ||
| 236 | + Boolean ready = zlmrtpServerFactory.isStreamReady(mediaServerItem, sendRtpItem.getApp(), audioBroadcastCatch.getStream()); | ||
| 237 | + if (ready) { | ||
| 238 | + Map<String, Object> param = new HashMap<>(); | ||
| 239 | + param.put("vhost","__defaultVhost__"); | ||
| 240 | + param.put("app",sendRtpItem.getApp()); | ||
| 241 | + param.put("stream",audioBroadcastCatch.getStream()); | ||
| 242 | + param.put("ssrc",sendRtpItem.getSsrc()); | ||
| 243 | + logger.info("[收到bye] 停止推流:{}", audioBroadcastCatch.getStream()); | ||
| 244 | + MediaServerItem mediaInfo = mediaServerService.getOne(sendRtpItem.getMediaServerId()); | ||
| 245 | + redisCatchStorage.deleteSendRTPServer(sendRtpItem.getPlatformId(), sendRtpItem.getChannelId(), request.getCallIdHeader().getCallId(), null); | ||
| 246 | + zlmrtpServerFactory.stopSendRtpStream(mediaInfo, param); | ||
| 247 | + } | ||
| 248 | + if (audioBroadcastCatch.isFromPlatform()) { | ||
| 249 | + // 上级也正在点播。 向上级回复bye | ||
| 250 | + List<SsrcTransaction> ssrcTransactions = streamSession.getSsrcTransactionForAll(null, channelId1, null, null); | ||
| 251 | + if (ssrcTransactions.size() > 0) { | ||
| 252 | + for (SsrcTransaction transaction : ssrcTransactions) { | ||
| 253 | + if (transaction.getType().equals(VideoStreamSessionManager.SessionType.broadcast)) { | ||
| 254 | + ParentPlatform parentPlatform = storager.queryParentPlatByServerGBId(transaction.getDeviceId()); | ||
| 255 | + if (parentPlatform != null) { | ||
| 256 | + try { | ||
| 257 | + commanderForPlatform.streamByeCmd(parentPlatform, channelId1, transaction.getStream(), transaction.getCallId(), eventResult -> { | ||
| 258 | + streamSession.remove(transaction.getDeviceId(), transaction.getChannelId(), transaction.getStream()); | ||
| 259 | + }); | ||
| 260 | + } catch (InvalidArgumentException | SipException | ParseException | | ||
| 261 | + SsrcTransactionNotFoundException e) { | ||
| 262 | + logger.error("[命令发送失败] 向{}发送bye失败", transaction.getDeviceId()); | ||
| 263 | + } | ||
| 264 | + // 释放ssrc | ||
| 265 | + MediaServerItem mediaServerItemFromTransaction = mediaServerService.getOne(transaction.getMediaServerId()); | ||
| 266 | + if (mediaServerItemFromTransaction != null) { | ||
| 267 | + mediaServerService.releaseSsrc(mediaServerItemFromTransaction.getId(), transaction.getSsrc()); | ||
| 268 | + } | ||
| 269 | + streamSession.remove(transaction.getDeviceId(), transaction.getChannelId(), transaction.getStream()); | ||
| 270 | + } | ||
| 271 | + } | ||
| 272 | + } | ||
| 273 | + } | ||
| 274 | + | ||
| 275 | + } | ||
| 276 | + redisCatchStorage.deleteSendRTPServer(deviceId, channelId1, | ||
| 277 | + audioBroadcastCatch.getStream(), audioBroadcastCatch.getSipTransactionInfo().getCallId()); | ||
| 278 | + | ||
| 279 | + } | ||
| 280 | + | ||
| 281 | + audioBroadcastManager.del(deviceId, channelId1); | ||
| 282 | + } | ||
| 283 | + } | ||
| 208 | break; | 284 | break; |
| 209 | default: | 285 | default: |
| 210 | break; | 286 | break; |
| 211 | } | 287 | } |
| 212 | - streamSession.remove(device.getDeviceId(), channelId, ssrcTransaction.getStream()); | 288 | + |
| 213 | } | 289 | } |
| 214 | } | 290 | } |
| 215 | } | 291 | } |
src/main/java/com/genersoft/iot/vmp/service/impl/DeviceServiceImpl.java
| @@ -195,6 +195,7 @@ public class DeviceServiceImpl implements IDeviceService { | @@ -195,6 +195,7 @@ public class DeviceServiceImpl implements IDeviceService { | ||
| 195 | List<AudioBroadcastCatch> audioBroadcastCatches = audioBroadcastManager.get(deviceId); | 195 | List<AudioBroadcastCatch> audioBroadcastCatches = audioBroadcastManager.get(deviceId); |
| 196 | if (audioBroadcastCatches.size() > 0) { | 196 | if (audioBroadcastCatches.size() > 0) { |
| 197 | for (AudioBroadcastCatch audioBroadcastCatch : audioBroadcastCatches) { | 197 | for (AudioBroadcastCatch audioBroadcastCatch : audioBroadcastCatches) { |
| 198 | + | ||
| 198 | SendRtpItem sendRtpItem = redisCatchStorage.querySendRTPServer(deviceId, audioBroadcastCatch.getChannelId(), null, null); | 199 | SendRtpItem sendRtpItem = redisCatchStorage.querySendRTPServer(deviceId, audioBroadcastCatch.getChannelId(), null, null); |
| 199 | if (sendRtpItem != null) { | 200 | if (sendRtpItem != null) { |
| 200 | redisCatchStorage.deleteSendRTPServer(deviceId, sendRtpItem.getChannelId(), null, null); | 201 | redisCatchStorage.deleteSendRTPServer(deviceId, sendRtpItem.getChannelId(), null, null); |
web_src/src/components/dialog/devicePlayer.vue
| @@ -301,8 +301,8 @@ | @@ -301,8 +301,8 @@ | ||
| 301 | <el-tab-pane label="语音对讲" name="broadcast"> | 301 | <el-tab-pane label="语音对讲" name="broadcast"> |
| 302 | <div style="padding: 0 10px"> | 302 | <div style="padding: 0 10px"> |
| 303 | <el-switch v-model="broadcastMode" :disabled="broadcastStatus !== -1" active-color="#409EFF" | 303 | <el-switch v-model="broadcastMode" :disabled="broadcastStatus !== -1" active-color="#409EFF" |
| 304 | - active-text="喊话" | ||
| 305 | - inactive-text="对讲"></el-switch> | 304 | + active-text="喊话(Broadcast)" |
| 305 | + inactive-text="对讲(Talk)"></el-switch> | ||
| 306 | </div> | 306 | </div> |
| 307 | <div class="trank" style="text-align: center;"> | 307 | <div class="trank" style="text-align: center;"> |
| 308 | <el-button @click="broadcastStatusClick()" :type="getBroadcastStatus()" :disabled="broadcastStatus === -2" | 308 | <el-button @click="broadcastStatusClick()" :type="getBroadcastStatus()" :disabled="broadcastStatus === -2" |