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 | 87 | public List<AudioBroadcastCatch> get(String deviceId) { |
| 88 | 88 | List<AudioBroadcastCatch> audioBroadcastCatchList= new ArrayList<>(); |
| 89 | 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 | 93 | }else { |
| 92 | 94 | for (String key : data.keySet()) { |
| 93 | 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 | 2 | |
| 3 | 3 | import com.genersoft.iot.vmp.common.StreamInfo; |
| 4 | 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 | 6 | import com.genersoft.iot.vmp.gb28181.session.AudioBroadcastManager; |
| 10 | 7 | import com.genersoft.iot.vmp.gb28181.session.VideoStreamSessionManager; |
| 11 | 8 | import com.genersoft.iot.vmp.gb28181.transmit.SIPProcessorObserver; |
| 12 | 9 | import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommander; |
| 10 | +import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform; | |
| 13 | 11 | import com.genersoft.iot.vmp.gb28181.transmit.event.request.ISIPRequestProcessor; |
| 14 | 12 | import com.genersoft.iot.vmp.gb28181.transmit.event.request.SIPRequestProcessorParent; |
| 15 | 13 | import com.genersoft.iot.vmp.media.zlm.ZLMRTPServerFactory; |
| ... | ... | @@ -37,6 +35,7 @@ import javax.sip.header.ToHeader; |
| 37 | 35 | import javax.sip.message.Response; |
| 38 | 36 | import java.text.ParseException; |
| 39 | 37 | import java.util.HashMap; |
| 38 | +import java.util.List; | |
| 40 | 39 | import java.util.Map; |
| 41 | 40 | |
| 42 | 41 | /** |
| ... | ... | @@ -52,6 +51,9 @@ public class ByeRequestProcessor extends SIPRequestProcessorParent implements In |
| 52 | 51 | private ISIPCommander cmder; |
| 53 | 52 | |
| 54 | 53 | @Autowired |
| 54 | + private ISIPCommanderForPlatform commanderForPlatform; | |
| 55 | + | |
| 56 | + @Autowired | |
| 55 | 57 | private IRedisCatchStorage redisCatchStorage; |
| 56 | 58 | |
| 57 | 59 | @Autowired |
| ... | ... | @@ -204,12 +206,86 @@ public class ByeRequestProcessor extends SIPRequestProcessorParent implements In |
| 204 | 206 | case broadcast: |
| 205 | 207 | String deviceId = ssrcTransaction.getDeviceId(); |
| 206 | 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 | 284 | break; |
| 209 | 285 | default: |
| 210 | 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 | 195 | List<AudioBroadcastCatch> audioBroadcastCatches = audioBroadcastManager.get(deviceId); |
| 196 | 196 | if (audioBroadcastCatches.size() > 0) { |
| 197 | 197 | for (AudioBroadcastCatch audioBroadcastCatch : audioBroadcastCatches) { |
| 198 | + | |
| 198 | 199 | SendRtpItem sendRtpItem = redisCatchStorage.querySendRTPServer(deviceId, audioBroadcastCatch.getChannelId(), null, null); |
| 199 | 200 | if (sendRtpItem != null) { |
| 200 | 201 | redisCatchStorage.deleteSendRTPServer(deviceId, sendRtpItem.getChannelId(), null, null); | ... | ... |
web_src/src/components/dialog/devicePlayer.vue
| ... | ... | @@ -301,8 +301,8 @@ |
| 301 | 301 | <el-tab-pane label="语音对讲" name="broadcast"> |
| 302 | 302 | <div style="padding: 0 10px"> |
| 303 | 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 | 306 | </div> |
| 307 | 307 | <div class="trank" style="text-align: center;"> |
| 308 | 308 | <el-button @click="broadcastStatusClick()" :type="getBroadcastStatus()" :disabled="broadcastStatus === -2" | ... | ... |