Commit 6b1d966255db75070f42b1e6a430ddff4299b248
1 parent
4362a5b4
优化合并对讲broadcast级联模式
Showing
9 changed files
with
127 additions
and
91 deletions
pom.xml
| @@ -6,7 +6,7 @@ | @@ -6,7 +6,7 @@ | ||
| 6 | <parent> | 6 | <parent> |
| 7 | <groupId>org.springframework.boot</groupId> | 7 | <groupId>org.springframework.boot</groupId> |
| 8 | <artifactId>spring-boot-starter-parent</artifactId> | 8 | <artifactId>spring-boot-starter-parent</artifactId> |
| 9 | - <version>2.7.2</version> | 9 | + <version>2.7.9</version> |
| 10 | </parent> | 10 | </parent> |
| 11 | 11 | ||
| 12 | <groupId>com.genersoft</groupId> | 12 | <groupId>com.genersoft</groupId> |
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommanderFroPlatform.java
| @@ -790,11 +790,11 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform { | @@ -790,11 +790,11 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform { | ||
| 790 | content.append("t=0 0\r\n"); | 790 | content.append("t=0 0\r\n"); |
| 791 | 791 | ||
| 792 | if ("TCP-PASSIVE".equalsIgnoreCase(userSetting.getBroadcastForPlatform())) { | 792 | if ("TCP-PASSIVE".equalsIgnoreCase(userSetting.getBroadcastForPlatform())) { |
| 793 | - content.append("m=video " + ssrcInfo.getPort() + " TCP/RTP/AVP 8 96\r\n"); | 793 | + content.append("m=audio " + ssrcInfo.getPort() + " TCP/RTP/AVP 8 96\r\n"); |
| 794 | } else if ("TCP-ACTIVE".equalsIgnoreCase(userSetting.getBroadcastForPlatform())) { | 794 | } else if ("TCP-ACTIVE".equalsIgnoreCase(userSetting.getBroadcastForPlatform())) { |
| 795 | - content.append("m=video " + ssrcInfo.getPort() + " TCP/RTP/AVP 8 96\r\n"); | 795 | + content.append("m=audio " + ssrcInfo.getPort() + " TCP/RTP/AVP 8 96\r\n"); |
| 796 | } else if ("UDP".equalsIgnoreCase(userSetting.getBroadcastForPlatform())) { | 796 | } else if ("UDP".equalsIgnoreCase(userSetting.getBroadcastForPlatform())) { |
| 797 | - content.append("m=video " + ssrcInfo.getPort() + " RTP/AVP 8 96\r\n"); | 797 | + content.append("m=audio " + ssrcInfo.getPort() + " RTP/AVP 8 96\r\n"); |
| 798 | } | 798 | } |
| 799 | 799 | ||
| 800 | content.append("a=recvonly\r\n"); | 800 | content.append("a=recvonly\r\n"); |
| @@ -817,12 +817,12 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform { | @@ -817,12 +817,12 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform { | ||
| 817 | sipSender.transmitRequest(sipLayer.getLocalIp(platform.getDeviceIp()), request, (e -> { | 817 | sipSender.transmitRequest(sipLayer.getLocalIp(platform.getDeviceIp()), request, (e -> { |
| 818 | streamSession.remove(platform.getServerGBId(), channelId, ssrcInfo.getStream()); | 818 | streamSession.remove(platform.getServerGBId(), channelId, ssrcInfo.getStream()); |
| 819 | mediaServerService.releaseSsrc(mediaServerItem.getId(), ssrcInfo.getSsrc()); | 819 | mediaServerService.releaseSsrc(mediaServerItem.getId(), ssrcInfo.getSsrc()); |
| 820 | + subscribe.removeSubscribe(hookSubscribe); | ||
| 820 | errorEvent.response(e); | 821 | errorEvent.response(e); |
| 821 | }), e -> { | 822 | }), e -> { |
| 822 | - // 这里为例避免一个通道的点播只有一个callID这个参数使用一个固定值 | ||
| 823 | ResponseEvent responseEvent = (ResponseEvent) e.event; | 823 | ResponseEvent responseEvent = (ResponseEvent) e.event; |
| 824 | SIPResponse response = (SIPResponse) responseEvent.getResponse(); | 824 | SIPResponse response = (SIPResponse) responseEvent.getResponse(); |
| 825 | - streamSession.put(platform.getServerGBId(), channelId, callIdHeader.getCallId(), stream, ssrcInfo.getSsrc(), mediaServerItem.getId(), response, VideoStreamSessionManager.SessionType.play); | 825 | + streamSession.put(platform.getServerGBId(), channelId, callIdHeader.getCallId(), stream, ssrcInfo.getSsrc(), mediaServerItem.getId(), response, VideoStreamSessionManager.SessionType.broadcast); |
| 826 | okEvent.response(e); | 826 | okEvent.response(e); |
| 827 | }); | 827 | }); |
| 828 | } | 828 | } |
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/AckRequestProcessor.java
| @@ -102,7 +102,7 @@ public class AckRequestProcessor extends SIPRequestProcessorParent implements In | @@ -102,7 +102,7 @@ public class AckRequestProcessor extends SIPRequestProcessorParent implements In | ||
| 102 | } | 102 | } |
| 103 | String isUdp = sendRtpItem.isTcp() ? "0" : "1"; | 103 | String isUdp = sendRtpItem.isTcp() ? "0" : "1"; |
| 104 | MediaServerItem mediaInfo = mediaServerService.getOne(sendRtpItem.getMediaServerId()); | 104 | MediaServerItem mediaInfo = mediaServerService.getOne(sendRtpItem.getMediaServerId()); |
| 105 | - logger.info("收到ACK,rtp/{}开始向上级推流, 目标={}:{},SSRC={}, RTCP={}", sendRtpItem.getStream(), | 105 | + logger.info("收到ACK,rtp/{}开始级推流, 目标={}:{},SSRC={}, RTCP={}", sendRtpItem.getStream(), |
| 106 | sendRtpItem.getIp(), sendRtpItem.getPort(), sendRtpItem.getSsrc(), sendRtpItem.isRtcp()); | 106 | sendRtpItem.getIp(), sendRtpItem.getPort(), sendRtpItem.getSsrc(), sendRtpItem.isRtcp()); |
| 107 | Map<String, Object> param = new HashMap<>(12); | 107 | Map<String, Object> param = new HashMap<>(12); |
| 108 | param.put("vhost","__defaultVhost__"); | 108 | param.put("vhost","__defaultVhost__"); |
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/ByeRequestProcessor.java
| @@ -2,7 +2,10 @@ package com.genersoft.iot.vmp.gb28181.transmit.event.request.impl; | @@ -2,7 +2,10 @@ 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.*; | 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; | ||
| 6 | import com.genersoft.iot.vmp.gb28181.session.AudioBroadcastManager; | 9 | import com.genersoft.iot.vmp.gb28181.session.AudioBroadcastManager; |
| 7 | import com.genersoft.iot.vmp.gb28181.session.VideoStreamSessionManager; | 10 | import com.genersoft.iot.vmp.gb28181.session.VideoStreamSessionManager; |
| 8 | import com.genersoft.iot.vmp.gb28181.transmit.SIPProcessorObserver; | 11 | import com.genersoft.iot.vmp.gb28181.transmit.SIPProcessorObserver; |
| @@ -24,9 +27,10 @@ import org.springframework.beans.factory.InitializingBean; | @@ -24,9 +27,10 @@ import org.springframework.beans.factory.InitializingBean; | ||
| 24 | import org.springframework.beans.factory.annotation.Autowired; | 27 | import org.springframework.beans.factory.annotation.Autowired; |
| 25 | import org.springframework.stereotype.Component; | 28 | import org.springframework.stereotype.Component; |
| 26 | 29 | ||
| 27 | -import javax.sip.*; | 30 | +import javax.sip.InvalidArgumentException; |
| 31 | +import javax.sip.RequestEvent; | ||
| 32 | +import javax.sip.SipException; | ||
| 28 | import javax.sip.address.SipURI; | 33 | import javax.sip.address.SipURI; |
| 29 | -import javax.sip.header.CallIdHeader; | ||
| 30 | import javax.sip.header.FromHeader; | 34 | import javax.sip.header.FromHeader; |
| 31 | import javax.sip.header.HeaderAddress; | 35 | import javax.sip.header.HeaderAddress; |
| 32 | import javax.sip.header.ToHeader; | 36 | import javax.sip.header.ToHeader; |
| @@ -87,13 +91,15 @@ public class ByeRequestProcessor extends SIPRequestProcessorParent implements In | @@ -87,13 +91,15 @@ public class ByeRequestProcessor extends SIPRequestProcessorParent implements In | ||
| 87 | @Override | 91 | @Override |
| 88 | public void process(RequestEvent evt) { | 92 | public void process(RequestEvent evt) { |
| 89 | 93 | ||
| 94 | + // TODO 此处需要重构 | ||
| 95 | + SIPRequest request =(SIPRequest) evt.getRequest(); | ||
| 90 | try { | 96 | try { |
| 91 | - responseAck((SIPRequest) evt.getRequest(), Response.OK); | 97 | + responseAck(request, Response.OK); |
| 92 | } catch (SipException | InvalidArgumentException | ParseException e) { | 98 | } catch (SipException | InvalidArgumentException | ParseException e) { |
| 93 | logger.error("[回复BYE信息失败],{}", e.getMessage()); | 99 | logger.error("[回复BYE信息失败],{}", e.getMessage()); |
| 94 | } | 100 | } |
| 95 | - CallIdHeader callIdHeader = (CallIdHeader)evt.getRequest().getHeader(CallIdHeader.NAME); | ||
| 96 | - SendRtpItem sendRtpItem = redisCatchStorage.querySendRTPServer(null, null, null, callIdHeader.getCallId()); | 101 | + |
| 102 | + SendRtpItem sendRtpItem = redisCatchStorage.querySendRTPServer(null, null, null, request.getCallIdHeader().getCallId()); | ||
| 97 | 103 | ||
| 98 | if (sendRtpItem != null){ | 104 | if (sendRtpItem != null){ |
| 99 | logger.info("[收到bye] {}/{}", sendRtpItem.getPlatformId(), sendRtpItem.getChannelId()); | 105 | logger.info("[收到bye] {}/{}", sendRtpItem.getPlatformId(), sendRtpItem.getChannelId()); |
| @@ -115,7 +121,7 @@ public class ByeRequestProcessor extends SIPRequestProcessorParent implements In | @@ -115,7 +121,7 @@ public class ByeRequestProcessor extends SIPRequestProcessorParent implements In | ||
| 115 | param.put("ssrc",sendRtpItem.getSsrc()); | 121 | param.put("ssrc",sendRtpItem.getSsrc()); |
| 116 | logger.info("[收到bye] 停止推流:{}", streamId); | 122 | logger.info("[收到bye] 停止推流:{}", streamId); |
| 117 | MediaServerItem mediaInfo = mediaServerService.getOne(sendRtpItem.getMediaServerId()); | 123 | MediaServerItem mediaInfo = mediaServerService.getOne(sendRtpItem.getMediaServerId()); |
| 118 | - redisCatchStorage.deleteSendRTPServer(sendRtpItem.getPlatformId(), sendRtpItem.getChannelId(), callIdHeader.getCallId(), null); | 124 | + redisCatchStorage.deleteSendRTPServer(sendRtpItem.getPlatformId(), sendRtpItem.getChannelId(), request.getCallIdHeader().getCallId(), null); |
| 119 | zlmrtpServerFactory.stopSendRtpStream(mediaInfo, param); | 125 | zlmrtpServerFactory.stopSendRtpStream(mediaInfo, param); |
| 120 | 126 | ||
| 121 | int totalReaderCount = zlmrtpServerFactory.totalReaderCount(mediaInfo, sendRtpItem.getApp(), streamId); | 127 | int totalReaderCount = zlmrtpServerFactory.totalReaderCount(mediaInfo, sendRtpItem.getApp(), streamId); |
| @@ -159,7 +165,7 @@ public class ByeRequestProcessor extends SIPRequestProcessorParent implements In | @@ -159,7 +165,7 @@ public class ByeRequestProcessor extends SIPRequestProcessorParent implements In | ||
| 159 | } | 165 | } |
| 160 | SsrcTransaction ssrcTransactionForPlay = streamSession.getSsrcTransaction(device.getDeviceId(), channelId, "play", null); | 166 | SsrcTransaction ssrcTransactionForPlay = streamSession.getSsrcTransaction(device.getDeviceId(), channelId, "play", null); |
| 161 | if (ssrcTransactionForPlay != null){ | 167 | if (ssrcTransactionForPlay != null){ |
| 162 | - if (ssrcTransactionForPlay.getCallId().equals(callIdHeader.getCallId())){ | 168 | + if (ssrcTransactionForPlay.getCallId().equals(request.getCallIdHeader().getCallId())){ |
| 163 | // 释放ssrc | 169 | // 释放ssrc |
| 164 | MediaServerItem mediaServerItem = mediaServerService.getOne(ssrcTransactionForPlay.getMediaServerId()); | 170 | MediaServerItem mediaServerItem = mediaServerService.getOne(ssrcTransactionForPlay.getMediaServerId()); |
| 165 | if (mediaServerItem != null) { | 171 | if (mediaServerItem != null) { |
| @@ -168,7 +174,7 @@ public class ByeRequestProcessor extends SIPRequestProcessorParent implements In | @@ -168,7 +174,7 @@ public class ByeRequestProcessor extends SIPRequestProcessorParent implements In | ||
| 168 | streamSession.remove(device.getDeviceId(), channelId, ssrcTransactionForPlay.getStream()); | 174 | streamSession.remove(device.getDeviceId(), channelId, ssrcTransactionForPlay.getStream()); |
| 169 | } | 175 | } |
| 170 | } | 176 | } |
| 171 | - SsrcTransaction ssrcTransactionForPlayBack = streamSession.getSsrcTransaction(device.getDeviceId(), channelId, callIdHeader.getCallId(), null); | 177 | + SsrcTransaction ssrcTransactionForPlayBack = streamSession.getSsrcTransaction(device.getDeviceId(), channelId, request.getCallIdHeader().getCallId(), null); |
| 172 | if (ssrcTransactionForPlayBack != null) { | 178 | if (ssrcTransactionForPlayBack != null) { |
| 173 | // 释放ssrc | 179 | // 释放ssrc |
| 174 | MediaServerItem mediaServerItem = mediaServerService.getOne(ssrcTransactionForPlayBack.getMediaServerId()); | 180 | MediaServerItem mediaServerItem = mediaServerService.getOne(ssrcTransactionForPlayBack.getMediaServerId()); |
| @@ -178,5 +184,32 @@ public class ByeRequestProcessor extends SIPRequestProcessorParent implements In | @@ -178,5 +184,32 @@ public class ByeRequestProcessor extends SIPRequestProcessorParent implements In | ||
| 178 | streamSession.remove(device.getDeviceId(), channelId, ssrcTransactionForPlayBack.getStream()); | 184 | streamSession.remove(device.getDeviceId(), channelId, ssrcTransactionForPlayBack.getStream()); |
| 179 | } | 185 | } |
| 180 | } | 186 | } |
| 187 | + SsrcTransaction ssrcTransaction = streamSession.getSsrcTransaction(null, null, request.getCallIdHeader().getCallId(), null); | ||
| 188 | + if (ssrcTransaction != null) { | ||
| 189 | + // 释放ssrc | ||
| 190 | + MediaServerItem mediaServerItem = mediaServerService.getOne(ssrcTransaction.getMediaServerId()); | ||
| 191 | + if (mediaServerItem != null) { | ||
| 192 | + mediaServerService.releaseSsrc(mediaServerItem.getId(), ssrcTransaction.getSsrc()); | ||
| 193 | + } | ||
| 194 | + | ||
| 195 | + switch (ssrcTransaction.getType()) { | ||
| 196 | +// case play: | ||
| 197 | +// break; | ||
| 198 | +// case talk: | ||
| 199 | +// break; | ||
| 200 | +// case playback: | ||
| 201 | +// break; | ||
| 202 | +// case download: | ||
| 203 | +// break; | ||
| 204 | + case broadcast: | ||
| 205 | + String deviceId = ssrcTransaction.getDeviceId(); | ||
| 206 | + String channelId1 = ssrcTransaction.getChannelId(); | ||
| 207 | + // 如果是 | ||
| 208 | + break; | ||
| 209 | + default: | ||
| 210 | + break; | ||
| 211 | + } | ||
| 212 | + streamSession.remove(device.getDeviceId(), channelId, ssrcTransaction.getStream()); | ||
| 213 | + } | ||
| 181 | } | 214 | } |
| 182 | } | 215 | } |
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/BroadcastNotifyMessageHandler.java
| @@ -102,6 +102,7 @@ public class BroadcastNotifyMessageHandler extends SIPRequestProcessorParent imp | @@ -102,6 +102,7 @@ public class BroadcastNotifyMessageHandler extends SIPRequestProcessorParent imp | ||
| 102 | 102 | ||
| 103 | DeviceChannel deviceChannel = storage.queryChannelInParentPlatform(platform.getServerGBId(), targetId); | 103 | DeviceChannel deviceChannel = storage.queryChannelInParentPlatform(platform.getServerGBId(), targetId); |
| 104 | if (deviceChannel == null) { | 104 | if (deviceChannel == null) { |
| 105 | + logger.warn("[国标级联 语音喊话] 未找到通道 platform: {}, channel: {}", platform.getServerGBId(), targetId); | ||
| 105 | responseAck(request, Response.NOT_FOUND, "TargetID not found"); | 106 | responseAck(request, Response.NOT_FOUND, "TargetID not found"); |
| 106 | return; | 107 | return; |
| 107 | } | 108 | } |
| @@ -123,6 +124,7 @@ public class BroadcastNotifyMessageHandler extends SIPRequestProcessorParent imp | @@ -123,6 +124,7 @@ public class BroadcastNotifyMessageHandler extends SIPRequestProcessorParent imp | ||
| 123 | commanderForPlatform.broadcastResultCmd(platform, deviceChannel, sn, true, eventResult->{ | 124 | commanderForPlatform.broadcastResultCmd(platform, deviceChannel, sn, true, eventResult->{ |
| 124 | logger.info("[国标级联] 语音喊话 回复失败 platform: {}, 错误:{}/{}", platform.getServerGBId(), eventResult.statusCode, eventResult.msg); | 125 | logger.info("[国标级联] 语音喊话 回复失败 platform: {}, 错误:{}/{}", platform.getServerGBId(), eventResult.statusCode, eventResult.msg); |
| 125 | }, eventResult->{ | 126 | }, eventResult->{ |
| 127 | + | ||
| 126 | // 消息发送成功, 向上级发送invite,获取推流 | 128 | // 消息发送成功, 向上级发送invite,获取推流 |
| 127 | try { | 129 | try { |
| 128 | platformService.broadcastInvite(platform, deviceChannel.getChannelId(), mediaServerForMinimumLoad, (mediaServerItem, response)->{ | 130 | platformService.broadcastInvite(platform, deviceChannel.getChannelId(), mediaServerForMinimumLoad, (mediaServerItem, response)->{ |
| @@ -132,7 +134,7 @@ public class BroadcastNotifyMessageHandler extends SIPRequestProcessorParent imp | @@ -132,7 +134,7 @@ public class BroadcastNotifyMessageHandler extends SIPRequestProcessorParent imp | ||
| 132 | AudioBroadcastCatch broadcastCatch = audioBroadcastManager.get(device.getDeviceId(), targetId); | 134 | AudioBroadcastCatch broadcastCatch = audioBroadcastManager.get(device.getDeviceId(), targetId); |
| 133 | if (broadcastCatch != null ) { | 135 | if (broadcastCatch != null ) { |
| 134 | if (playService.audioBroadcastInUse(device, targetId)) { | 136 | if (playService.audioBroadcastInUse(device, targetId)) { |
| 135 | - logger.info("[国标级联] 语音喊话 设备正正在使用中 platform: {}, channel: {}", | 137 | + logger.info("[国标级联] 语音喊话 设备正在使用中 platform: {}, channel: {}", |
| 136 | platform.getServerGBId(), deviceChannel.getChannelId()); | 138 | platform.getServerGBId(), deviceChannel.getChannelId()); |
| 137 | // 查看语音通道已经建立且已经占用 回复BYE | 139 | // 查看语音通道已经建立且已经占用 回复BYE |
| 138 | try { | 140 | try { |
src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRTPServerFactory.java
| @@ -259,11 +259,11 @@ public class ZLMRTPServerFactory { | @@ -259,11 +259,11 @@ public class ZLMRTPServerFactory { | ||
| 259 | // 订阅 zlm启动事件, 新的zlm也会从这里进入系统 | 259 | // 订阅 zlm启动事件, 新的zlm也会从这里进入系统 |
| 260 | hookSubscribe.addSubscribe(hookSubscribeForRtpServerTimeout, | 260 | hookSubscribe.addSubscribe(hookSubscribeForRtpServerTimeout, |
| 261 | (MediaServerItem mediaServerItem, JSONObject response)->{ | 261 | (MediaServerItem mediaServerItem, JSONObject response)->{ |
| 262 | - logger.info("[上级点播] {}->监听端口到期继续保持监听", ssrc); | 262 | + logger.info("[保持端口] {}->监听端口到期继续保持监听", ssrc); |
| 263 | keepPort(serverItem, ssrc); | 263 | keepPort(serverItem, ssrc); |
| 264 | }); | 264 | }); |
| 265 | } | 265 | } |
| 266 | - logger.info("[上级点播] {}->监听端口: {}", ssrc, localPort); | 266 | + logger.info("[保持端口] {}->监听端口: {}", ssrc, localPort); |
| 267 | return localPort; | 267 | return localPort; |
| 268 | } | 268 | } |
| 269 | 269 | ||
| @@ -271,7 +271,7 @@ public class ZLMRTPServerFactory { | @@ -271,7 +271,7 @@ public class ZLMRTPServerFactory { | ||
| 271 | * 释放保持的端口 | 271 | * 释放保持的端口 |
| 272 | */ | 272 | */ |
| 273 | public boolean releasePort(MediaServerItem serverItem, String ssrc) { | 273 | public boolean releasePort(MediaServerItem serverItem, String ssrc) { |
| 274 | - logger.info("[上级点播] {}->释放监听端口", ssrc); | 274 | + logger.info("[保持端口] {}->释放监听端口", ssrc); |
| 275 | boolean closeRTPServerResult = closeRtpServer(serverItem, ssrc); | 275 | boolean closeRTPServerResult = closeRtpServer(serverItem, ssrc); |
| 276 | HookSubscribeForRtpServerTimeout hookSubscribeForRtpServerTimeout = HookSubscribeFactory.on_rtp_server_timeout(ssrc, null, serverItem.getId()); | 276 | HookSubscribeForRtpServerTimeout hookSubscribeForRtpServerTimeout = HookSubscribeFactory.on_rtp_server_timeout(ssrc, null, serverItem.getId()); |
| 277 | // 订阅 zlm启动事件, 新的zlm也会从这里进入系统 | 277 | // 订阅 zlm启动事件, 新的zlm也会从这里进入系统 |
| @@ -357,7 +357,7 @@ public class ZLMRTPServerFactory { | @@ -357,7 +357,7 @@ public class ZLMRTPServerFactory { | ||
| 357 | 357 | ||
| 358 | public JSONObject startSendRtp(MediaServerItem mediaInfo, SendRtpItem sendRtpItem) { | 358 | public JSONObject startSendRtp(MediaServerItem mediaInfo, SendRtpItem sendRtpItem) { |
| 359 | String is_Udp = sendRtpItem.isTcp() ? "0" : "1"; | 359 | String is_Udp = sendRtpItem.isTcp() ? "0" : "1"; |
| 360 | - logger.info("rtp/{}开始向上级推流, 目标={}:{},SSRC={}", sendRtpItem.getStream(), sendRtpItem.getIp(), sendRtpItem.getPort(), sendRtpItem.getSsrc()); | 360 | + logger.info("rtp/{}开始推流, 目标={}:{},SSRC={}", sendRtpItem.getStream(), sendRtpItem.getIp(), sendRtpItem.getPort(), sendRtpItem.getSsrc()); |
| 361 | Map<String, Object> param = new HashMap<>(12); | 361 | Map<String, Object> param = new HashMap<>(12); |
| 362 | param.put("vhost","__defaultVhost__"); | 362 | param.put("vhost","__defaultVhost__"); |
| 363 | param.put("app",sendRtpItem.getApp()); | 363 | param.put("app",sendRtpItem.getApp()); |
src/main/java/com/genersoft/iot/vmp/service/impl/PlatformServiceImpl.java
| @@ -373,7 +373,7 @@ public class PlatformServiceImpl implements IPlatformService { | @@ -373,7 +373,7 @@ public class PlatformServiceImpl implements IPlatformService { | ||
| 373 | errorEvent.response(new SipSubscribe.EventResult(-1, "端口监听失败")); | 373 | errorEvent.response(new SipSubscribe.EventResult(-1, "端口监听失败")); |
| 374 | return; | 374 | return; |
| 375 | } | 375 | } |
| 376 | - logger.info("[国标级联] 发起语音喊话 deviceId: {}, channelId: {},收流端口: {}, 收流模式:{}, SSRC: {}, SSRC校验:{}", | 376 | + logger.info("[国标级联] 语音喊话,发起Invite消息 deviceId: {}, channelId: {},收流端口: {}, 收流模式:{}, SSRC: {}, SSRC校验:{}", |
| 377 | platform.getServerGBId(), channelId, ssrcInfo.getPort(), userSetting.getBroadcastForPlatform(), ssrcInfo.getSsrc(), ssrcCheck); | 377 | platform.getServerGBId(), channelId, ssrcInfo.getPort(), userSetting.getBroadcastForPlatform(), ssrcInfo.getSsrc(), ssrcCheck); |
| 378 | 378 | ||
| 379 | String timeOutTaskKey = UUID.randomUUID().toString(); | 379 | String timeOutTaskKey = UUID.randomUUID().toString(); |
| @@ -396,6 +396,7 @@ public class PlatformServiceImpl implements IPlatformService { | @@ -396,6 +396,7 @@ public class PlatformServiceImpl implements IPlatformService { | ||
| 396 | } | 396 | } |
| 397 | }, userSetting.getPlayTimeout()); | 397 | }, userSetting.getPlayTimeout()); |
| 398 | commanderForPlatform.broadcastInviteCmd(platform, channelId, mediaServerItem, ssrcInfo, (mediaServerItemForInvite, response)->{ | 398 | commanderForPlatform.broadcastInviteCmd(platform, channelId, mediaServerItem, ssrcInfo, (mediaServerItemForInvite, response)->{ |
| 399 | + logger.info("[国标级联] 发起语音喊话 收到上级推流 deviceId: {}, channelId: {}", platform.getServerGBId(), channelId); | ||
| 399 | dynamicTask.stop(timeOutTaskKey); | 400 | dynamicTask.stop(timeOutTaskKey); |
| 400 | // hook响应 | 401 | // hook响应 |
| 401 | playService.onPublishHandlerForPlay(mediaServerItemForInvite, response, platform.getServerGBId(), channelId); | 402 | playService.onPublishHandlerForPlay(mediaServerItemForInvite, response, platform.getServerGBId(), channelId); |
src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java
| @@ -1183,7 +1183,7 @@ public class PlayServiceImpl implements IPlayService { | @@ -1183,7 +1183,7 @@ public class PlayServiceImpl implements IPlayService { | ||
| 1183 | 1183 | ||
| 1184 | String is_Udp = sendRtpItem.isTcp() ? "0" : "1"; | 1184 | String is_Udp = sendRtpItem.isTcp() ? "0" : "1"; |
| 1185 | MediaServerItem mediaInfo = mediaServerService.getOne(sendRtpItem.getMediaServerId()); | 1185 | MediaServerItem mediaInfo = mediaServerService.getOne(sendRtpItem.getMediaServerId()); |
| 1186 | - logger.info("收到ACK,rtp/{}开始向上级推流, 目标={}:{},SSRC={}, RTCP={}", sendRtpItem.getStream(), | 1186 | + logger.info("收到ACK,rtp/{}开始推流, 目标={}:{},SSRC={}, RTCP={}", sendRtpItem.getStream(), |
| 1187 | sendRtpItem.getIp(), sendRtpItem.getPort(), sendRtpItem.getSsrc(), sendRtpItem.isRtcp()); | 1187 | sendRtpItem.getIp(), sendRtpItem.getPort(), sendRtpItem.getSsrc(), sendRtpItem.isRtcp()); |
| 1188 | Map<String, Object> param = new HashMap<>(12); | 1188 | Map<String, Object> param = new HashMap<>(12); |
| 1189 | param.put("vhost", "__defaultVhost__"); | 1189 | param.put("vhost", "__defaultVhost__"); |
web_src/src/components/dialog/devicePlayer.vue
| @@ -181,7 +181,7 @@ | @@ -181,7 +181,7 @@ | ||
| 181 | style="font-size: 1.875rem;"></i></div> | 181 | style="font-size: 1.875rem;"></i></div> |
| 182 | <div style="position: absolute; left: 7.25rem; top: 3.25rem; font-size: 1.875rem;" | 182 | <div style="position: absolute; left: 7.25rem; top: 3.25rem; font-size: 1.875rem;" |
| 183 | @mousedown="ptzCamera('zoomout')" @mouseup="ptzCamera('stop')"><i | 183 | @mousedown="ptzCamera('zoomout')" @mouseup="ptzCamera('stop')"><i |
| 184 | - class="el-icon-zoom-out control-zoom-btn"></i></div> | 184 | + class="el-icon-zoom-out control-zoom-btn"></i></div> |
| 185 | <div class="contro-speed" style="position: absolute; left: 4px; top: 7rem; width: 9rem;"> | 185 | <div class="contro-speed" style="position: absolute; left: 4px; top: 7rem; width: 9rem;"> |
| 186 | <el-slider v-model="controSpeed" :max="255"></el-slider> | 186 | <el-slider v-model="controSpeed" :max="255"></el-slider> |
| 187 | </div> | 187 | </div> |
| @@ -300,7 +300,8 @@ | @@ -300,7 +300,8 @@ | ||
| 300 | </el-tab-pane> | 300 | </el-tab-pane> |
| 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" active-text="喊话" | 303 | + <el-switch v-model="broadcastMode" :disabled="broadcastStatus !== -1" active-color="#409EFF" |
| 304 | + active-text="喊话" | ||
| 304 | inactive-text="对讲"></el-switch> | 305 | inactive-text="对讲"></el-switch> |
| 305 | </div> | 306 | </div> |
| 306 | <div class="trank" style="text-align: center;"> | 307 | <div class="trank" style="text-align: center;"> |
| @@ -565,20 +566,20 @@ export default { | @@ -565,20 +566,20 @@ export default { | ||
| 565 | this.tracks = [] | 566 | this.tracks = [] |
| 566 | let _this = this; | 567 | let _this = this; |
| 567 | this.$copyText(data).then( | 568 | this.$copyText(data).then( |
| 568 | - function (e) { | ||
| 569 | - _this.$message({ | ||
| 570 | - showClose: true, | ||
| 571 | - message: '复制成功', | ||
| 572 | - type: 'success' | ||
| 573 | - }); | ||
| 574 | - }, | ||
| 575 | - function (e) { | ||
| 576 | - _this.$message({ | ||
| 577 | - showClose: true, | ||
| 578 | - message: '复制失败,请手动复制', | ||
| 579 | - type: 'error' | ||
| 580 | - }); | ||
| 581 | - } | 569 | + function (e) { |
| 570 | + _this.$message({ | ||
| 571 | + showClose: true, | ||
| 572 | + message: '复制成功', | ||
| 573 | + type: 'success' | ||
| 574 | + }); | ||
| 575 | + }, | ||
| 576 | + function (e) { | ||
| 577 | + _this.$message({ | ||
| 578 | + showClose: true, | ||
| 579 | + message: '复制失败,请手动复制', | ||
| 580 | + type: 'error' | ||
| 581 | + }); | ||
| 582 | + } | ||
| 582 | ); | 583 | ); |
| 583 | }, | 584 | }, |
| 584 | ptzCamera: function (command) { | 585 | ptzCamera: function (command) { |
| @@ -654,55 +655,54 @@ export default { | @@ -654,55 +655,54 @@ export default { | ||
| 654 | this.$axios({ | 655 | this.$axios({ |
| 655 | method: 'get', | 656 | method: 'get', |
| 656 | url: '/api/play/broadcast/' + this.deviceId + '/' + this.channelId + "?timeout=30&broadcastMode=" + this.broadcastMode | 657 | url: '/api/play/broadcast/' + this.deviceId + '/' + this.channelId + "?timeout=30&broadcastMode=" + this.broadcastMode |
| 657 | - }).then( (res)=> { | 658 | + }).then((res) => { |
| 658 | if (res.data.code === 0) { | 659 | if (res.data.code === 0) { |
| 659 | let streamInfo = res.data.data.streamInfo; | 660 | let streamInfo = res.data.data.streamInfo; |
| 660 | if (document.location.protocol.includes("https")) { | 661 | if (document.location.protocol.includes("https")) { |
| 661 | this.startBroadcast(streamInfo.rtcs) | 662 | this.startBroadcast(streamInfo.rtcs) |
| 662 | - }else { | 663 | + } else { |
| 663 | this.startBroadcast(streamInfo.rtc) | 664 | this.startBroadcast(streamInfo.rtc) |
| 664 | } | 665 | } |
| 665 | - | ||
| 666 | - }else { | ||
| 667 | - this.$message({ | ||
| 668 | - showClose: true, | ||
| 669 | - message: res.data.msg, | ||
| 670 | - type: "error", | ||
| 671 | - }); | ||
| 672 | - } | ||
| 673 | - }); | ||
| 674 | - }else if (this.broadcastStatus === 1) { | ||
| 675 | - this.broadcastStatus = -1; | ||
| 676 | - this.broadcastRtc.close() | ||
| 677 | - } | ||
| 678 | - }, | ||
| 679 | - startBroadcast(url){ | ||
| 680 | - // 获取推流鉴权Key | ||
| 681 | - this.$axios({ | ||
| 682 | - method: 'post', | ||
| 683 | - url: '/api/user/userInfo', | ||
| 684 | - }).then( (res)=> { | ||
| 685 | - if (res.data.code !== 0) { | ||
| 686 | - this.$message({ | ||
| 687 | - showClose: true, | ||
| 688 | - message: "获取推流鉴权Key失败", | ||
| 689 | - type: "error", | ||
| 690 | - }); | ||
| 691 | - this.broadcastStatus = -1; | ||
| 692 | - }else { | ||
| 693 | - let pushKey = res.data.data.pushKey; | ||
| 694 | - // 获取推流鉴权KEY | ||
| 695 | - url += "&sign=" + crypto.createHash('md5').update(pushKey, "utf8").digest('hex') | ||
| 696 | - console.log("开始语音喊话: " + url) | ||
| 697 | - this.broadcastRtc = new ZLMRTCClient.Endpoint({ | ||
| 698 | - debug: true, // 是否打印日志 | ||
| 699 | - zlmsdpUrl: url, //流地址 | ||
| 700 | - simulecast: false, | ||
| 701 | - useCamera: false, | ||
| 702 | - audioEnable: true, | ||
| 703 | - videoEnable: false, | ||
| 704 | - recvOnly: false, | ||
| 705 | - }) | 666 | + } else { |
| 667 | + this.$message({ | ||
| 668 | + showClose: true, | ||
| 669 | + message: res.data.msg, | ||
| 670 | + type: "error", | ||
| 671 | + }); | ||
| 672 | + } | ||
| 673 | + }); | ||
| 674 | + } else if (this.broadcastStatus === 1) { | ||
| 675 | + this.broadcastStatus = -1; | ||
| 676 | + this.broadcastRtc.close() | ||
| 677 | + } | ||
| 678 | + }, | ||
| 679 | + startBroadcast(url) { | ||
| 680 | + // 获取推流鉴权Key | ||
| 681 | + this.$axios({ | ||
| 682 | + method: 'post', | ||
| 683 | + url: '/api/user/userInfo', | ||
| 684 | + }).then((res) => { | ||
| 685 | + if (res.data.code !== 0) { | ||
| 686 | + this.$message({ | ||
| 687 | + showClose: true, | ||
| 688 | + message: "获取推流鉴权Key失败", | ||
| 689 | + type: "error", | ||
| 690 | + }); | ||
| 691 | + this.broadcastStatus = -1; | ||
| 692 | + } else { | ||
| 693 | + let pushKey = res.data.data.pushKey; | ||
| 694 | + // 获取推流鉴权KEY | ||
| 695 | + url += "&sign=" + crypto.createHash('md5').update(pushKey, "utf8").digest('hex') | ||
| 696 | + console.log("开始语音喊话: " + url) | ||
| 697 | + this.broadcastRtc = new ZLMRTCClient.Endpoint({ | ||
| 698 | + debug: true, // 是否打印日志 | ||
| 699 | + zlmsdpUrl: url, //流地址 | ||
| 700 | + simulecast: false, | ||
| 701 | + useCamera: false, | ||
| 702 | + audioEnable: true, | ||
| 703 | + videoEnable: false, | ||
| 704 | + recvOnly: false, | ||
| 705 | + }) | ||
| 706 | 706 | ||
| 707 | // webrtcPlayer.on(ZLMRTCClient.Events.WEBRTC_ON_REMOTE_STREAMS,(e)=>{//获取到了远端流,可以播放 | 707 | // webrtcPlayer.on(ZLMRTCClient.Events.WEBRTC_ON_REMOTE_STREAMS,(e)=>{//获取到了远端流,可以播放 |
| 708 | // console.error('播放成功',e.streams) | 708 | // console.error('播放成功',e.streams) |
| @@ -715,15 +715,15 @@ export default { | @@ -715,15 +715,15 @@ export default { | ||
| 715 | // // this.eventcallbacK("LOCAL STREAM", "获取到了本地流") | 715 | // // this.eventcallbacK("LOCAL STREAM", "获取到了本地流") |
| 716 | // }); | 716 | // }); |
| 717 | 717 | ||
| 718 | - this.broadcastRtc.on(ZLMRTCClient.Events.WEBRTC_NOT_SUPPORT,(e)=>{// 获取到了本地流 | ||
| 719 | - console.error('不支持webrtc',e) | ||
| 720 | - this.$message({ | ||
| 721 | - showClose: true, | ||
| 722 | - message: '不支持webrtc, 无法进行语音喊话', | ||
| 723 | - type: 'error' | ||
| 724 | - }); | ||
| 725 | - this.broadcastStatus = -1; | ||
| 726 | - }); | 718 | + this.broadcastRtc.on(ZLMRTCClient.Events.WEBRTC_NOT_SUPPORT, (e) => {// 获取到了本地流 |
| 719 | + console.error('不支持webrtc', e) | ||
| 720 | + this.$message({ | ||
| 721 | + showClose: true, | ||
| 722 | + message: '不支持webrtc, 无法进行语音喊话', | ||
| 723 | + type: 'error' | ||
| 724 | + }); | ||
| 725 | + this.broadcastStatus = -1; | ||
| 726 | + }); | ||
| 727 | 727 | ||
| 728 | this.broadcastRtc.on(ZLMRTCClient.Events.WEBRTC_ICE_CANDIDATE_ERROR, (e) => {// ICE 协商出错 | 728 | this.broadcastRtc.on(ZLMRTCClient.Events.WEBRTC_ICE_CANDIDATE_ERROR, (e) => {// ICE 协商出错 |
| 729 | console.error('ICE 协商出错') | 729 | console.error('ICE 协商出错') |