Commit becea82736dcfc833d1d68021fc3baf1e23acc36

Authored by 648540858
2 parents 4604aaea 733a11f2

Merge branch 'wvp-28181-2.0' into main-dev

# Conflicts:
#	src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommanderFroPlatform.java
#	src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/AckRequestProcessor.java
#	src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/InviteRequestProcessor.java
#	src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java
#	src/main/java/com/genersoft/iot/vmp/service/impl/MediaServerServiceImpl.java
#	src/main/java/com/genersoft/iot/vmp/service/impl/PlatformServiceImpl.java
#	src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java
#	src/main/java/com/genersoft/iot/vmp/service/redisMsg/RedisPushStreamCloseResponseListener.java
Showing 18 changed files with 393 additions and 107 deletions
src/main/java/com/genersoft/iot/vmp/common/VideoManagerConstants.java
... ... @@ -158,6 +158,7 @@ public class VideoManagerConstants {
158 158  
159 159 public static final String WVP_STREAM_GB_ID_PREFIX = "memberNo_";
160 160 public static final String WVP_STREAM_GPS_MSG_PREFIX = "WVP_STREAM_GPS_MSG_";
  161 + public static final String WVP_OTHER_SEND_RTP_INFO = "VMP_OTHER_SEND_RTP_INFO_";
161 162  
162 163 /**
163 164 * Redis Const
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommanderFroPlatform.java
... ... @@ -18,6 +18,7 @@ import com.genersoft.iot.vmp.media.zlm.ZLMRTPServerFactory;
18 18 import com.genersoft.iot.vmp.media.zlm.ZlmHttpHookSubscribe;
19 19 import com.genersoft.iot.vmp.media.zlm.dto.HookSubscribeFactory;
20 20 import com.genersoft.iot.vmp.media.zlm.dto.HookSubscribeForStreamChange;
  21 +import com.genersoft.iot.vmp.media.zlm.ZLMServerFactory;
21 22 import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
22 23 import com.genersoft.iot.vmp.media.zlm.dto.hook.HookParam;
23 24 import com.genersoft.iot.vmp.service.IMediaServerService;
... ... @@ -68,7 +69,7 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform {
68 69 private SipSubscribe sipSubscribe;
69 70  
70 71 @Autowired
71   - private ZLMRTPServerFactory zlmrtpServerFactory;
  72 + private ZLMServerFactory ZLMServerFactory;
72 73  
73 74 @Autowired
74 75 private SipLayer sipLayer;
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/AckRequestProcessor.java
... ... @@ -9,7 +9,7 @@ import com.genersoft.iot.vmp.gb28181.bean.SendRtpItem;
9 9 import com.genersoft.iot.vmp.gb28181.transmit.SIPProcessorObserver;
10 10 import com.genersoft.iot.vmp.gb28181.transmit.event.request.ISIPRequestProcessor;
11 11 import com.genersoft.iot.vmp.gb28181.transmit.event.request.SIPRequestProcessorParent;
12   -import com.genersoft.iot.vmp.media.zlm.ZLMRTPServerFactory;
  12 +import com.genersoft.iot.vmp.media.zlm.ZLMServerFactory;
13 13 import com.genersoft.iot.vmp.media.zlm.ZlmHttpHookSubscribe;
14 14 import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
15 15 import com.genersoft.iot.vmp.service.IDeviceService;
... ... @@ -66,7 +66,7 @@ public class AckRequestProcessor extends SIPRequestProcessorParent implements In
66 66 private IDeviceService deviceService;
67 67  
68 68 @Autowired
69   - private ZLMRTPServerFactory zlmrtpServerFactory;
  69 + private ZLMServerFactory ZLMServerFactory;
70 70  
71 71 @Autowired
72 72 private ZlmHttpHookSubscribe hookSubscribe;
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/ByeRequestProcessor.java
... ... @@ -13,7 +13,7 @@ import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommander;
13 13 import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform;
14 14 import com.genersoft.iot.vmp.gb28181.transmit.event.request.ISIPRequestProcessor;
15 15 import com.genersoft.iot.vmp.gb28181.transmit.event.request.SIPRequestProcessorParent;
16   -import com.genersoft.iot.vmp.media.zlm.ZLMRTPServerFactory;
  16 +import com.genersoft.iot.vmp.media.zlm.ZLMServerFactory;
17 17 import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
18 18 import com.genersoft.iot.vmp.service.*;
19 19 import com.genersoft.iot.vmp.service.bean.MessageForPushChannel;
... ... @@ -72,7 +72,7 @@ public class ByeRequestProcessor extends SIPRequestProcessorParent implements In
72 72 private IVideoManagerStorage storager;
73 73  
74 74 @Autowired
75   - private ZLMRTPServerFactory zlmrtpServerFactory;
  75 + private ZLMServerFactory ZLMServerFactory;
76 76  
77 77 @Autowired
78 78 private SSRCFactory ssrcFactory;
... ... @@ -125,7 +125,7 @@ public class ByeRequestProcessor extends SIPRequestProcessorParent implements In
125 125 MediaServerItem mediaInfo = mediaServerService.getOne(sendRtpItem.getMediaServerId());
126 126 redisCatchStorage.deleteSendRTPServer(sendRtpItem.getPlatformId(), sendRtpItem.getChannelId(),
127 127 callIdHeader.getCallId(), null);
128   - zlmrtpServerFactory.stopSendRtpStream(mediaInfo, param);
  128 + ZLMServerFactory.stopSendRtpStream(mediaInfo, param);
129 129 if (sendRtpItem.getPlayType().equals(InviteStreamType.PUSH)) {
130 130 ParentPlatform platform = platformService.queryPlatformByServerGBId(sendRtpItem.getPlatformId());
131 131 if (platform != null) {
... ... @@ -139,7 +139,7 @@ public class ByeRequestProcessor extends SIPRequestProcessorParent implements In
139 139 }
140 140 }
141 141  
142   - int totalReaderCount = zlmrtpServerFactory.totalReaderCount(mediaInfo, sendRtpItem.getApp(), streamId);
  142 + int totalReaderCount = ZLMServerFactory.totalReaderCount(mediaInfo, sendRtpItem.getApp(), streamId);
143 143 if (totalReaderCount <= 0) {
144 144 logger.info("[收到bye] {} 无其它观看者,通知设备停止推流", streamId);
145 145 if (sendRtpItem.getPlayType().equals(InviteStreamType.PLAY)) {
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/InviteRequestProcessor.java
... ... @@ -20,6 +20,7 @@ import com.genersoft.iot.vmp.gb28181.utils.SipUtils;
20 20 import com.genersoft.iot.vmp.media.zlm.ZLMMediaListManager;
21 21 import com.genersoft.iot.vmp.media.zlm.ZLMRESTfulUtils;
22 22 import com.genersoft.iot.vmp.media.zlm.ZLMRTPServerFactory;
  23 +import com.genersoft.iot.vmp.media.zlm.ZLMServerFactory;
23 24 import com.genersoft.iot.vmp.media.zlm.ZlmHttpHookSubscribe;
24 25 import com.genersoft.iot.vmp.media.zlm.dto.*;
25 26 import com.genersoft.iot.vmp.media.zlm.dto.hook.OnStreamChangedHookParam;
... ... @@ -102,7 +103,7 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements
102 103 private AudioBroadcastManager audioBroadcastManager;
103 104  
104 105 @Autowired
105   - private ZLMRTPServerFactory zlmrtpServerFactory;
  106 + private ZLMServerFactory ZLMServerFactory;
106 107  
107 108 @Autowired
108 109 private IMediaServerService mediaServerService;
... ... @@ -374,7 +375,7 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements
374 375 streamTypeStr = "UDP";
375 376 }
376 377 logger.info("[上级Invite] {}, 平台:{}, 通道:{}, 收流地址:{}:{},收流方式:{}, ssrc:{}", sessionName, username, channelId, addressStr, port, streamTypeStr, ssrc);
377   - SendRtpItem sendRtpItem = zlmrtpServerFactory.createSendRtpItem(mediaServerItem, addressStr, port, ssrc, requesterId,
  378 + SendRtpItem sendRtpItem = ZLMServerFactory.createSendRtpItem(mediaServerItem, addressStr, port, ssrc, requesterId,
378 379 device.getDeviceId(), channelId, mediaTransmissionTCP, platform.isRtcp());
379 380  
380 381 if (tcpActive != null) {
... ... @@ -577,10 +578,10 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements
577 578 CallIdHeader callIdHeader, MediaServerItem mediaServerItem,
578 579 int port, Boolean tcpActive, boolean mediaTransmissionTCP,
579 580 String channelId, String addressStr, String ssrc, String requesterId) {
580   - Boolean streamReady = zlmrtpServerFactory.isStreamReady(mediaServerItem, gbStream.getApp(), gbStream.getStream());
  581 + Boolean streamReady = ZLMServerFactory.isStreamReady(mediaServerItem, gbStream.getApp(), gbStream.getStream());
581 582 if (streamReady != null && streamReady) {
582 583 // 自平台内容
583   - SendRtpItem sendRtpItem = zlmrtpServerFactory.createSendRtpItem(mediaServerItem, addressStr, port, ssrc, requesterId,
  584 + SendRtpItem sendRtpItem = ZLMServerFactory.createSendRtpItem(mediaServerItem, addressStr, port, ssrc, requesterId,
584 585 gbStream.getApp(), gbStream.getStream(), channelId, mediaTransmissionTCP, platform.isRtcp());
585 586  
586 587 if (sendRtpItem == null) {
... ... @@ -617,10 +618,10 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements
617 618 String channelId, String addressStr, String ssrc, String requesterId) {
618 619 // 推流
619 620 if (streamPushItem.isSelf()) {
620   - Boolean streamReady = zlmrtpServerFactory.isStreamReady(mediaServerItem, gbStream.getApp(), gbStream.getStream());
  621 + Boolean streamReady = ZLMServerFactory.isStreamReady(mediaServerItem, gbStream.getApp(), gbStream.getStream());
621 622 if (streamReady != null && streamReady) {
622 623 // 自平台内容
623   - SendRtpItem sendRtpItem = zlmrtpServerFactory.createSendRtpItem(mediaServerItem, addressStr, port, ssrc, requesterId,
  624 + SendRtpItem sendRtpItem = ZLMServerFactory.createSendRtpItem(mediaServerItem, addressStr, port, ssrc, requesterId,
624 625 gbStream.getApp(), gbStream.getStream(), channelId, mediaTransmissionTCP, platform.isRtcp());
625 626  
626 627 if (sendRtpItem == null) {
... ... @@ -735,7 +736,7 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements
735 736 mediaListManager.addChannelOnlineEventLister(gbStream.getApp(), gbStream.getStream(), (app, stream, serverId) -> {
736 737 dynamicTask.stop(callIdHeader.getCallId());
737 738 if (serverId.equals(userSetting.getServerId())) {
738   - SendRtpItem sendRtpItem = zlmrtpServerFactory.createSendRtpItem(mediaServerItem, addressStr, finalPort, ssrc, requesterId,
  739 + SendRtpItem sendRtpItem = ZLMServerFactory.createSendRtpItem(mediaServerItem, addressStr, finalPort, ssrc, requesterId,
739 740 app, stream, channelId, mediaTransmissionTCP, platform.isRtcp());
740 741  
741 742 if (sendRtpItem == null) {
... ...
src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java
... ... @@ -454,33 +454,35 @@ public class ZLMHttpHookListener {
454 454 GbStream gbStream = storager.getGbStream(param.getApp(), param.getStream());
455 455 if (gbStream != null) {
456 456 // eventPublisher.catalogEventPublishForStream(null, gbStream, CatalogEvent.OFF);
457   - }
458   - zlmMediaListManager.removeMedia(param.getApp(), param.getStream());
459   - }
460   - GbStream gbStream = storager.getGbStream(param.getApp(), param.getStream());
461   - if (gbStream != null) {
462   - eventPublisher.catalogEventPublishForStream(null, gbStream, param.isRegist() ? CatalogEvent.ON : CatalogEvent.OFF);
463 457 }
464   - if (type != null) {
465   - // 发送流变化redis消息
466   - JSONObject jsonObject = new JSONObject();
467   - jsonObject.put("serverId", userSetting.getServerId());
468   - jsonObject.put("app", param.getApp());
469   - jsonObject.put("stream", param.getStream());
470   - jsonObject.put("register", param.isRegist());
471   - jsonObject.put("mediaServerId", param.getMediaServerId());
472   - redisCatchStorage.sendStreamChangeMsg(type, jsonObject);
  458 + zlmMediaListManager.removeMedia(param.getApp(), param.getStream());
  459 + }
  460 + GbStream gbStream = storager.getGbStream(param.getApp(), param.getStream());
  461 + if (gbStream != null) {
  462 + if (userSetting.isUsePushingAsStatus()) {
  463 + eventPublisher.catalogEventPublishForStream(null, gbStream, param.isRegist()?CatalogEvent.ON:CatalogEvent.OFF);
473 464 }
474 465 }
  466 + if (type != null) {
  467 + // 发送流变化redis消息
  468 + JSONObject jsonObject = new JSONObject();
  469 + jsonObject.put("serverId", userSetting.getServerId());
  470 + jsonObject.put("app", param.getApp());
  471 + jsonObject.put("stream", param.getStream());
  472 + jsonObject.put("register", param.isRegist());
  473 + jsonObject.put("mediaServerId", param.getMediaServerId());
  474 + redisCatchStorage.sendStreamChangeMsg(type, jsonObject);
  475 + }
475 476 }
476   - if (!param.isRegist()) {
477   - List<SendRtpItem> sendRtpItems = redisCatchStorage.querySendRTPServerByStream(param.getStream());
478   - if (sendRtpItems.size() > 0) {
479   - for (SendRtpItem sendRtpItem : sendRtpItems) {
480   - if (sendRtpItem != null && sendRtpItem.getApp().equals(param.getApp())) {
481   - String platformId = sendRtpItem.getPlatformId();
482   - ParentPlatform platform = storager.queryParentPlatByServerGBId(platformId);
483   - Device device = deviceService.getDevice(platformId);
  477 + }
  478 + if (!param.isRegist()) {
  479 + List<SendRtpItem> sendRtpItems = redisCatchStorage.querySendRTPServerByStream(param.getStream());
  480 + if (sendRtpItems.size() > 0) {
  481 + for (SendRtpItem sendRtpItem : sendRtpItems) {
  482 + if (sendRtpItem != null && sendRtpItem.getApp().equals(param.getApp())) {
  483 + String platformId = sendRtpItem.getPlatformId();
  484 + ParentPlatform platform = storager.queryParentPlatByServerGBId(platformId);
  485 + Device device = deviceService.getDevice(platformId);
484 486  
485 487 try {
486 488 if (platform != null) {
... ...
src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaListManager.java
... ... @@ -61,7 +61,7 @@ public class ZLMMediaListManager {
61 61 private UserSetting userSetting;
62 62  
63 63 @Autowired
64   - private ZLMRTPServerFactory zlmrtpServerFactory;
  64 + private ZLMServerFactory ZLMServerFactory;
65 65  
66 66 @Autowired
67 67 private IMediaServerService mediaServerService;
... ... @@ -97,7 +97,7 @@ public class ZLMMediaListManager {
97 97 public void sendStreamEvent(String app, String stream, String mediaServerId) {
98 98 MediaServerItem mediaServerItem = mediaServerService.getOne(mediaServerId);
99 99 // 查看推流状态
100   - Boolean streamReady = zlmrtpServerFactory.isStreamReady(mediaServerItem, app, stream);
  100 + Boolean streamReady = ZLMServerFactory.isStreamReady(mediaServerItem, app, stream);
101 101 if (streamReady != null && streamReady) {
102 102 ChannelOnlineEvent channelOnlineEventLister = getChannelOnlineEventLister(app, stream);
103 103 if (channelOnlineEventLister != null) {
... ...
src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRTPServerFactory.java renamed to src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMServerFactory.java
... ... @@ -15,7 +15,7 @@ import java.util.HashMap;
15 15 import java.util.Map;
16 16  
17 17 @Component
18   -public class ZLMRTPServerFactory {
  18 +public class ZLMServerFactory {
19 19  
20 20 private Logger logger = LoggerFactory.getLogger("ZLMRTPServerFactory");
21 21  
... ...
src/main/java/com/genersoft/iot/vmp/service/impl/MediaServerServiceImpl.java
... ... @@ -87,7 +87,7 @@ public class MediaServerServiceImpl implements IMediaServerService {
87 87  
88 88  
89 89 @Autowired
90   - private ZLMRTPServerFactory zlmrtpServerFactory;
  90 + private ZLMServerFactory ZLMServerFactory;
91 91  
92 92 @Autowired
93 93 private EventPublisher publisher;
... ... @@ -201,7 +201,7 @@ public class MediaServerServiceImpl implements IMediaServerService {
201 201 if (mediaServerItem == null) {
202 202 return;
203 203 }
204   - zlmrtpServerFactory.closeRtpServer(mediaServerItem, streamId);
  204 + ZLMServerFactory.closeRtpServer(mediaServerItem, streamId);
205 205 }
206 206  
207 207 @Override
... ... @@ -210,7 +210,7 @@ public class MediaServerServiceImpl implements IMediaServerService {
210 210 callback.run(false);
211 211 return;
212 212 }
213   - zlmrtpServerFactory.closeRtpServer(mediaServerItem, streamId, callback);
  213 + ZLMServerFactory.closeRtpServer(mediaServerItem, streamId, callback);
214 214 }
215 215  
216 216 @Override
... ... @@ -221,7 +221,7 @@ public class MediaServerServiceImpl implements IMediaServerService {
221 221  
222 222 @Override
223 223 public Boolean updateRtpServerSSRC(MediaServerItem mediaServerItem, String streamId, String ssrc) {
224   - return zlmrtpServerFactory.updateRtpServerSSRC(mediaServerItem, streamId, ssrc);
  224 + return ZLMServerFactory.updateRtpServerSSRC(mediaServerItem, streamId, ssrc);
225 225 }
226 226  
227 227 @Override
... ...
src/main/java/com/genersoft/iot/vmp/service/impl/PlatformServiceImpl.java
... ... @@ -14,6 +14,7 @@ import com.genersoft.iot.vmp.media.zlm.ZLMRTPServerFactory;
14 14 import com.genersoft.iot.vmp.media.zlm.ZlmHttpHookSubscribe;
15 15 import com.genersoft.iot.vmp.media.zlm.dto.HookSubscribeFactory;
16 16 import com.genersoft.iot.vmp.media.zlm.dto.HookSubscribeForStreamChange;
  17 +import com.genersoft.iot.vmp.media.zlm.ZLMServerFactory;
17 18 import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
18 19 import com.genersoft.iot.vmp.media.zlm.dto.hook.OnStreamChangedHookParam;
19 20 import com.genersoft.iot.vmp.service.IInviteStreamService;
... ... @@ -83,7 +84,7 @@ public class PlatformServiceImpl implements IPlatformService {
83 84 private DynamicTask dynamicTask;
84 85  
85 86 @Autowired
86   - private ZLMRTPServerFactory zlmrtpServerFactory;
  87 + private ZLMServerFactory ZLMServerFactory;
87 88  
88 89 @Autowired
89 90 private SubscribeHolder subscribeHolder;
... ... @@ -364,7 +365,7 @@ public class PlatformServiceImpl implements IPlatformService {
364 365 param.put("vhost", "__defaultVhost__");
365 366 param.put("app", sendRtpItem.getApp());
366 367 param.put("stream", sendRtpItem.getStream());
367   - zlmrtpServerFactory.stopSendRtpStream(mediaInfo, param);
  368 + ZLMServerFactory.stopSendRtpStream(mediaInfo, param);
368 369 }
369 370 }
370 371 }
... ...
src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java
... ... @@ -20,6 +20,11 @@ import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform;
20 20 import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander;
21 21 import com.genersoft.iot.vmp.gb28181.utils.SipUtils;
22 22 import com.genersoft.iot.vmp.media.zlm.*;
  23 +import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommanderFroPlatform;
  24 +import com.genersoft.iot.vmp.media.zlm.AssistRESTfulUtils;
  25 +import com.genersoft.iot.vmp.media.zlm.ZLMRESTfulUtils;
  26 +import com.genersoft.iot.vmp.media.zlm.ZLMServerFactory;
  27 +import com.genersoft.iot.vmp.media.zlm.ZlmHttpHookSubscribe;
23 28 import com.genersoft.iot.vmp.media.zlm.dto.HookSubscribeFactory;
24 29 import com.genersoft.iot.vmp.media.zlm.dto.HookSubscribeForStreamChange;
25 30 import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
... ... @@ -96,6 +101,9 @@ public class PlayServiceImpl implements IPlayService {
96 101 private ZLMRESTfulUtils zlmresTfulUtils;
97 102  
98 103 @Autowired
  104 + private ZLMServerFactory ZLMServerFactory;
  105 +
  106 + @Autowired
99 107 private AssistRESTfulUtils assistRESTfulUtils;
100 108  
101 109 @Autowired
... ... @@ -167,7 +175,7 @@ public class PlayServiceImpl implements IPlayService {
167 175 String mediaServerId = streamInfo.getMediaServerId();
168 176 MediaServerItem mediaInfo = mediaServerService.getOne(mediaServerId);
169 177  
170   - Boolean ready = zlmrtpServerFactory.isStreamReady(mediaInfo, "rtp", streamId);
  178 + Boolean ready = ZLMServerFactory.isStreamReady(mediaInfo, "rtp", streamId);
171 179 if (ready != null && ready) {
172 180 callback.run(InviteErrorCode.SUCCESS.getCode(), InviteErrorCode.SUCCESS.getMsg(), streamInfo);
173 181 inviteStreamService.call(InviteSessionType.PLAY, device.getDeviceId(), channelId, null,
... ... @@ -183,12 +191,11 @@ public class PlayServiceImpl implements IPlayService {
183 191 }
184 192 }
185 193 }
186   -
187 194 String streamId = null;
188 195 if (mediaServerItem.isRtpEnable()) {
189 196 streamId = String.format("%s_%s", device.getDeviceId(), channelId);
190 197 }
191   - SSRCInfo ssrcInfo = mediaServerService.openRTPServer(mediaServerItem, streamId, null, device.isSsrcCheck(), false, 0, false, false, device.getStreamModeForParam());
  198 + SSRCInfo ssrcInfo = mediaServerService.openRTPServer(mediaServerItem, streamId, null, device.isSsrcCheck(), false, 0, false, device.getStreamModeForParam());
192 199 if (ssrcInfo == null) {
193 200 callback.run(InviteErrorCode.ERROR_FOR_RESOURCE_EXHAUSTION.getCode(), InviteErrorCode.ERROR_FOR_RESOURCE_EXHAUSTION.getMsg(), null);
194 201 inviteStreamService.call(InviteSessionType.PLAY, device.getDeviceId(), channelId, null,
... ...
src/main/java/com/genersoft/iot/vmp/service/redisMsg/RedisGbPlayMsgListener.java
... ... @@ -6,7 +6,7 @@ import com.genersoft.iot.vmp.common.VideoManagerConstants;
6 6 import com.genersoft.iot.vmp.conf.DynamicTask;
7 7 import com.genersoft.iot.vmp.conf.UserSetting;
8 8 import com.genersoft.iot.vmp.gb28181.bean.SendRtpItem;
9   -import com.genersoft.iot.vmp.media.zlm.ZLMRTPServerFactory;
  9 +import com.genersoft.iot.vmp.media.zlm.ZLMServerFactory;
10 10 import com.genersoft.iot.vmp.media.zlm.ZlmHttpHookSubscribe;
11 11 import com.genersoft.iot.vmp.media.zlm.dto.HookSubscribeFactory;
12 12 import com.genersoft.iot.vmp.media.zlm.dto.HookSubscribeForStreamChange;
... ... @@ -72,7 +72,7 @@ public class RedisGbPlayMsgListener implements MessageListener {
72 72 private RedisTemplate<Object, Object> redisTemplate;
73 73  
74 74 @Autowired
75   - private ZLMRTPServerFactory zlmrtpServerFactory;
  75 + private ZLMServerFactory ZLMServerFactory;
76 76  
77 77 @Autowired
78 78 private IMediaServerService mediaServerService;
... ... @@ -230,7 +230,7 @@ public class RedisGbPlayMsgListener implements MessageListener {
230 230 param.put("pt", requestPushStreamMsg.getPt());
231 231 param.put("use_ps", requestPushStreamMsg.isPs() ? "1" : "0");
232 232 param.put("only_audio", requestPushStreamMsg.isOnlyAudio() ? "1" : "0");
233   - JSONObject jsonObject = zlmrtpServerFactory.startSendRtpStream(mediaInfo, param);
  233 + JSONObject jsonObject = ZLMServerFactory.startSendRtpStream(mediaInfo, param);
234 234 // 回复消息
235 235 responsePushStream(jsonObject, fromId, serial);
236 236 }
... ... @@ -267,7 +267,7 @@ public class RedisGbPlayMsgListener implements MessageListener {
267 267 return;
268 268 }
269 269 // 确定流是否在线
270   - Boolean streamReady = zlmrtpServerFactory.isStreamReady(mediaServerItem, content.getApp(), content.getStream());
  270 + Boolean streamReady = ZLMServerFactory.isStreamReady(mediaServerItem, content.getApp(), content.getStream());
271 271 if (streamReady != null && streamReady) {
272 272 logger.info("[回复推流信息] {}/{}", content.getApp(), content.getStream());
273 273 responseSendItem(mediaServerItem, content, toId, serial);
... ... @@ -311,7 +311,7 @@ public class RedisGbPlayMsgListener implements MessageListener {
311 311 * 将获取到的sendItem发送出去
312 312 */
313 313 private void responseSendItem(MediaServerItem mediaServerItem, RequestSendItemMsg content, String toId, String serial) {
314   - SendRtpItem sendRtpItem = zlmrtpServerFactory.createSendRtpItem(mediaServerItem, content.getIp(),
  314 + SendRtpItem sendRtpItem = ZLMServerFactory.createSendRtpItem(mediaServerItem, content.getIp(),
315 315 content.getPort(), content.getSsrc(), content.getPlatformId(),
316 316 content.getApp(), content.getStream(), content.getChannelId(),
317 317 content.getTcp(), content.getRtcp());
... ...
src/main/java/com/genersoft/iot/vmp/service/redisMsg/RedisPushStreamCloseResponseListener.java
... ... @@ -6,7 +6,7 @@ import com.genersoft.iot.vmp.gb28181.bean.InviteStreamType;
6 6 import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform;
7 7 import com.genersoft.iot.vmp.gb28181.bean.SendRtpItem;
8 8 import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform;
9   -import com.genersoft.iot.vmp.media.zlm.ZLMRTPServerFactory;
  9 +import com.genersoft.iot.vmp.media.zlm.ZLMServerFactory;
10 10 import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
11 11 import com.genersoft.iot.vmp.media.zlm.dto.StreamPushItem;
12 12 import com.genersoft.iot.vmp.service.IMediaServerService;
... ... @@ -58,7 +58,7 @@ public class RedisPushStreamCloseResponseListener implements MessageListener {
58 58 private IMediaServerService mediaServerService;
59 59  
60 60 @Autowired
61   - private ZLMRTPServerFactory zlmrtpServerFactory;
  61 + private ZLMServerFactory ZLMServerFactory;
62 62  
63 63  
64 64 private Map<String, PushStreamResponseEvent> responseEvents = new ConcurrentHashMap<>();
... ...
src/main/java/com/genersoft/iot/vmp/storager/impl/RedisCatchStorageImpl.java
... ... @@ -304,7 +304,7 @@ public class RedisCatchStorageImpl implements IRedisCatchStorage {
304 304 @Override
305 305 public void sendStreamChangeMsg(String type, JSONObject jsonObject) {
306 306 String key = VideoManagerConstants.WVP_MSG_STREAM_CHANGE_PREFIX + type;
307   - logger.info("[redis 流变化事件] {}: {}", key, jsonObject.toString());
  307 + logger.info("[redis 流变化事件] 发送 {}: {}", key, jsonObject.toString());
308 308 redisTemplate.convertAndSend(key, jsonObject);
309 309 }
310 310  
... ... @@ -540,14 +540,14 @@ public class RedisCatchStorageImpl implements IRedisCatchStorage {
540 540 @Override
541 541 public void sendMobilePositionMsg(JSONObject jsonObject) {
542 542 String key = VideoManagerConstants.VM_MSG_SUBSCRIBE_MOBILE_POSITION;
543   - logger.info("[redis发送通知] 移动位置 {}: {}", key, jsonObject.toString());
  543 + logger.info("[redis发送通知] 发送 移动位置 {}: {}", key, jsonObject.toString());
544 544 redisTemplate.convertAndSend(key, jsonObject);
545 545 }
546 546  
547 547 @Override
548 548 public void sendStreamPushRequestedMsg(MessageForPushChannel msg) {
549 549 String key = VideoManagerConstants.VM_MSG_STREAM_PUSH_REQUESTED;
550   - logger.info("[redis发送通知] 推流被请求 {}: {}/{}", key, msg.getApp(), msg.getStream());
  550 + logger.info("[redis发送通知] 发送 推流被请求 {}: {}/{}", key, msg.getApp(), msg.getStream());
551 551 redisTemplate.convertAndSend(key, JSON.toJSON(msg));
552 552 }
553 553  
... ... @@ -555,7 +555,7 @@ public class RedisCatchStorageImpl implements IRedisCatchStorage {
555 555 public void sendAlarmMsg(AlarmChannelMessage msg) {
556 556 // 此消息用于对接第三方服务下级来的消息内容
557 557 String key = VideoManagerConstants.VM_MSG_SUBSCRIBE_ALARM;
558   - logger.info("[redis发送通知] 报警{}: {}", key, JSON.toJSON(msg));
  558 + logger.info("[redis发送通知] 发送 报警{}: {}", key, JSON.toJSON(msg));
559 559 redisTemplate.convertAndSend(key, JSON.toJSON(msg));
560 560 }
561 561  
... ... @@ -568,7 +568,7 @@ public class RedisCatchStorageImpl implements IRedisCatchStorage {
568 568 @Override
569 569 public void sendStreamPushRequestedMsgForStatus() {
570 570 String key = VideoManagerConstants.VM_MSG_GET_ALL_ONLINE_REQUESTED;
571   - logger.info("[redis通知]获取所有推流设备的状态");
  571 + logger.info("[redis通知] 发送 获取所有推流设备的状态");
572 572 JSONObject jsonObject = new JSONObject();
573 573 jsonObject.put(key, key);
574 574 redisTemplate.convertAndSend(key, jsonObject);
... ... @@ -596,6 +596,7 @@ public class RedisCatchStorageImpl implements IRedisCatchStorage {
596 596 @Override
597 597 public void sendDeviceOrChannelStatus(String deviceId, String channelId, boolean online) {
598 598 String key = VideoManagerConstants.VM_MSG_SUBSCRIBE_DEVICE_STATUS;
  599 + logger.info("[redis通知] 发送 推送设备/通道状态, {}/{}-{}", deviceId, channelId, online);
599 600 StringBuilder msg = new StringBuilder();
600 601 msg.append(deviceId);
601 602 if (channelId != null) {
... ... @@ -626,14 +627,14 @@ public class RedisCatchStorageImpl implements IRedisCatchStorage {
626 627 @Override
627 628 public void sendPlatformStartPlayMsg(MessageForPushChannel msg) {
628 629 String key = VideoManagerConstants.VM_MSG_STREAM_START_PLAY_NOTIFY;
629   - logger.info("[redis发送通知] 推流被上级平台观看 {}: {}/{}->{}", key, msg.getApp(), msg.getStream(), msg.getPlatFormId());
  630 + logger.info("[redis发送通知] 发送 推流被上级平台观看 {}: {}/{}->{}", key, msg.getApp(), msg.getStream(), msg.getPlatFormId());
630 631 redisTemplate.convertAndSend(key, JSON.toJSON(msg));
631 632 }
632 633  
633 634 @Override
634 635 public void sendPlatformStopPlayMsg(MessageForPushChannel msg) {
635 636 String key = VideoManagerConstants.VM_MSG_STREAM_STOP_PLAY_NOTIFY;
636   - logger.info("[redis发送通知] 上级平台停止观看 {}: {}/{}->{}", key, msg.getApp(), msg.getStream(), msg.getPlatFormId());
  637 + logger.info("[redis发送通知] 发送 上级平台停止观看 {}: {}/{}->{}", key, msg.getApp(), msg.getStream(), msg.getPlatFormId());
637 638 redisTemplate.convertAndSend(key, JSON.toJSON(msg));
638 639 }
639 640 }
... ...
src/main/java/com/genersoft/iot/vmp/vmanager/bean/OtherRtpSendInfo.java 0 → 100644
  1 +package com.genersoft.iot.vmp.vmanager.bean;
  2 +
  3 +public class OtherRtpSendInfo {
  4 +
  5 + /**
  6 + * 发流IP
  7 + */
  8 + private String ip;
  9 +
  10 + /**
  11 + * 发流端口
  12 + */
  13 + private int port;
  14 +
  15 + /**
  16 + * 收流IP
  17 + */
  18 + private String receiveIp;
  19 +
  20 + /**
  21 + * 收流端口
  22 + */
  23 + private int receivePort;
  24 +
  25 + /**
  26 + * 会话ID
  27 + */
  28 + private String callId;
  29 +
  30 + /**
  31 + * 流ID
  32 + */
  33 + private String stream;
  34 +
  35 + /**
  36 + * 推流应用名
  37 + */
  38 + private String pushApp;
  39 +
  40 + /**
  41 + * 推流流ID
  42 + */
  43 + private String pushStream;
  44 +
  45 + /**
  46 + * 推流SSRC
  47 + */
  48 + private String pushSSRC;
  49 +
  50 +
  51 +
  52 + public String getIp() {
  53 + return ip;
  54 + }
  55 +
  56 + public void setIp(String ip) {
  57 + this.ip = ip;
  58 + }
  59 +
  60 + public int getPort() {
  61 + return port;
  62 + }
  63 +
  64 + public void setPort(int port) {
  65 + this.port = port;
  66 + }
  67 +
  68 + public String getReceiveIp() {
  69 + return receiveIp;
  70 + }
  71 +
  72 + public void setReceiveIp(String receiveIp) {
  73 + this.receiveIp = receiveIp;
  74 + }
  75 +
  76 + public int getReceivePort() {
  77 + return receivePort;
  78 + }
  79 +
  80 + public void setReceivePort(int receivePort) {
  81 + this.receivePort = receivePort;
  82 + }
  83 +
  84 + public String getCallId() {
  85 + return callId;
  86 + }
  87 +
  88 + public void setCallId(String callId) {
  89 + this.callId = callId;
  90 + }
  91 +
  92 + public String getStream() {
  93 + return stream;
  94 + }
  95 +
  96 + public void setStream(String stream) {
  97 + this.stream = stream;
  98 + }
  99 +
  100 + public String getPushApp() {
  101 + return pushApp;
  102 + }
  103 +
  104 + public void setPushApp(String pushApp) {
  105 + this.pushApp = pushApp;
  106 + }
  107 +
  108 + public String getPushStream() {
  109 + return pushStream;
  110 + }
  111 +
  112 + public void setPushStream(String pushStream) {
  113 + this.pushStream = pushStream;
  114 + }
  115 +
  116 + public String getPushSSRC() {
  117 + return pushSSRC;
  118 + }
  119 +
  120 + public void setPushSSRC(String pushSSRC) {
  121 + this.pushSSRC = pushSSRC;
  122 + }
  123 +
  124 + @Override
  125 + public String toString() {
  126 + return "OtherRtpSendInfo{" +
  127 + "ip='" + ip + '\'' +
  128 + ", port=" + port +
  129 + ", receiveIp='" + receiveIp + '\'' +
  130 + ", receivePort=" + receivePort +
  131 + ", callId='" + callId + '\'' +
  132 + ", stream='" + stream + '\'' +
  133 + '}';
  134 + }
  135 +}
... ...
src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/playback/PlaybackController.java
... ... @@ -11,7 +11,7 @@ import com.genersoft.iot.vmp.gb28181.bean.Device;
11 11 import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder;
12 12 import com.genersoft.iot.vmp.gb28181.transmit.callback.RequestMessage;
13 13 import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander;
14   -import com.genersoft.iot.vmp.media.zlm.ZLMRTPServerFactory;
  14 +import com.genersoft.iot.vmp.media.zlm.ZLMServerFactory;
15 15 import com.genersoft.iot.vmp.service.IInviteStreamService;
16 16 import com.genersoft.iot.vmp.service.IPlayService;
17 17 import com.genersoft.iot.vmp.service.bean.InviteErrorCode;
... ... @@ -54,7 +54,7 @@ public class PlaybackController {
54 54 private SIPCommander cmder;
55 55  
56 56 @Autowired
57   - private ZLMRTPServerFactory zlmrtpServerFactory;
  57 + private ZLMServerFactory ZLMServerFactory;
58 58  
59 59 @Autowired
60 60 private IVideoManagerStorage storager;
... ...
src/main/java/com/genersoft/iot/vmp/vmanager/rtp/RtpController.java
1 1 package com.genersoft.iot.vmp.vmanager.rtp;
2 2  
  3 +import com.alibaba.fastjson2.JSONObject;
  4 +import com.genersoft.iot.vmp.common.VideoManagerConstants;
  5 +import com.genersoft.iot.vmp.conf.DynamicTask;
3 6 import com.genersoft.iot.vmp.conf.SipConfig;
4 7 import com.genersoft.iot.vmp.conf.UserSetting;
5 8 import com.genersoft.iot.vmp.conf.VersionInfo;
6 9 import com.genersoft.iot.vmp.conf.exception.ControllerException;
7   -import com.genersoft.iot.vmp.gb28181.bean.SendRtpItem;
  10 +import com.genersoft.iot.vmp.media.zlm.SendRtpPortManager;
  11 +import com.genersoft.iot.vmp.media.zlm.ZLMServerFactory;
8 12 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;
9 15 import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
10   -import com.genersoft.iot.vmp.service.*;
  16 +import com.genersoft.iot.vmp.media.zlm.dto.hook.OnRtpServerTimeoutHookParam;
  17 +import com.genersoft.iot.vmp.service.IDeviceChannelService;
  18 +import com.genersoft.iot.vmp.service.IDeviceService;
  19 +import com.genersoft.iot.vmp.service.IMediaServerService;
11 20 import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
12 21 import com.genersoft.iot.vmp.vmanager.bean.ErrorCode;
  22 +import com.genersoft.iot.vmp.vmanager.bean.OtherRtpSendInfo;
13 23 import io.swagger.v3.oas.annotations.Operation;
14 24 import io.swagger.v3.oas.annotations.Parameter;
15 25 import io.swagger.v3.oas.annotations.tags.Tag;
  26 +import okhttp3.OkHttpClient;
  27 +import okhttp3.Request;
  28 +import org.slf4j.Logger;
  29 +import org.slf4j.LoggerFactory;
16 30 import org.springframework.beans.factory.annotation.Autowired;
17 31 import org.springframework.beans.factory.annotation.Value;
  32 +import org.springframework.data.redis.core.RedisTemplate;
18 33 import org.springframework.web.bind.annotation.GetMapping;
19 34 import org.springframework.web.bind.annotation.RequestMapping;
20 35 import org.springframework.web.bind.annotation.ResponseBody;
21 36 import org.springframework.web.bind.annotation.RestController;
22 37  
  38 +import java.io.IOException;
  39 +import java.util.HashMap;
  40 +import java.util.Map;
  41 +import java.util.concurrent.TimeUnit;
  42 +
23 43 @SuppressWarnings("rawtypes")
24 44 @Tag(name = "第三方服务对接")
25 45  
... ... @@ -28,7 +48,15 @@ import org.springframework.web.bind.annotation.RestController;
28 48 public class RtpController {
29 49  
30 50 @Autowired
31   - private ZlmHttpHookSubscribe zlmHttpHookSubscribe;
  51 + private ZLMServerFactory zlmServerFactory;
  52 +
  53 + @Autowired
  54 + private SendRtpPortManager sendRtpPortManager;
  55 +
  56 + private final static Logger logger = LoggerFactory.getLogger(RtpController.class);
  57 +
  58 + @Autowired
  59 + private ZlmHttpHookSubscribe hookSubscribe;
32 60  
33 61 @Autowired
34 62 private IMediaServerService mediaServerService;
... ... @@ -49,11 +77,11 @@ public class RtpController {
49 77 private IDeviceChannelService channelService;
50 78  
51 79 @Autowired
52   - private IStreamPushService pushService;
  80 + private DynamicTask dynamicTask;
53 81  
54 82  
55 83 @Autowired
56   - private IStreamProxyService proxyService;
  84 + private RedisTemplate<Object, Object> redisTemplate;
57 85  
58 86  
59 87 @Value("${server.port}")
... ... @@ -73,12 +101,67 @@ public class RtpController {
73 101 @Parameter(name = "stream", description = "形成的流的ID", required = true)
74 102 @Parameter(name = "tcpMode", description = "收流模式, 0为UDP, 1为TCP被动", required = true)
75 103 @Parameter(name = "callBack", description = "回调地址,如果收流超时会通道回调通知,回调为get请求,参数为callId", required = true)
76   - public SendRtpItem openRtpServer(Boolean isSend, String ssrc, String callId, String stream, Integer tcpMode, String callBack) {
77   - MediaServerItem mediaServerItem = mediaServerService.getMediaServerForMinimumLoad(null);
  104 + public OtherRtpSendInfo openRtpServer(Boolean isSend, String ssrc, String callId, String stream, Integer tcpMode, String callBack) {
  105 +
  106 + logger.info("[第三方服务对接->开启收流和获取发流信息] isSend->{}, ssrc->{}, callId->{}, stream->{}, tcpMode->{}, callBack->{}",
  107 + isSend, ssrc, callId, stream, tcpMode==0?"UDP":"TCP被动", callBack);
  108 +
  109 + MediaServerItem mediaServerItem = mediaServerService.getDefaultMediaServer();
78 110 if (mediaServerItem == null) {
79 111 throw new ControllerException(ErrorCode.ERROR100.getCode(),"没有可用的MediaServer");
80 112 }
81   - return null;
  113 + if (stream == null) {
  114 + throw new ControllerException(ErrorCode.ERROR100.getCode(),"stream参数不可为空");
  115 + }
  116 + if (isSend != null && isSend && callId == null) {
  117 + throw new ControllerException(ErrorCode.ERROR100.getCode(),"isSend为true时,CallID不能为空");
  118 + }
  119 + int ssrcInt = 0;
  120 + if (ssrc != null) {
  121 + try {
  122 + ssrcInt = Integer.parseInt(ssrc);
  123 + }catch (NumberFormatException e) {
  124 + throw new ControllerException(ErrorCode.ERROR100.getCode(),"ssrc格式错误");
  125 + }
  126 +
  127 + }
  128 + int localPort = zlmServerFactory.createRTPServer(mediaServerItem, stream, ssrcInt, null, false, tcpMode);
  129 + // 注册回调如果rtp收流超时则通过回调发送通知
  130 + if (callBack != null) {
  131 + HookSubscribeForRtpServerTimeout hookSubscribeForRtpServerTimeout = HookSubscribeFactory.on_rtp_server_timeout(ssrc, null, mediaServerItem.getId());
  132 + // 订阅 zlm启动事件, 新的zlm也会从这里进入系统
  133 + hookSubscribe.addSubscribe(hookSubscribeForRtpServerTimeout,
  134 + (mediaServerItemInUse, hookParam)->{
  135 + OnRtpServerTimeoutHookParam serverTimeoutHookParam = (OnRtpServerTimeoutHookParam) hookParam;
  136 + if (stream.equals(serverTimeoutHookParam.getStream_id())) {
  137 + logger.info("[开启收流和获取发流信息] 等待收流超时 callId->{}, 发送回调", callId);
  138 + OkHttpClient.Builder httpClientBuilder = new OkHttpClient.Builder();
  139 + OkHttpClient client = httpClientBuilder.build();
  140 + String url = callBack + "?callId=" + callId;
  141 + Request request = new Request.Builder().get().url(url).build();
  142 + try {
  143 + client.newCall(request).execute();
  144 + } catch (IOException e) {
  145 + logger.error("[开启收流和获取发流信息] 等待收流超时 callId->{}, 发送回调失败", callId, e);
  146 + }
  147 + }
  148 + });
  149 + }
  150 + String key = VideoManagerConstants.WVP_OTHER_SEND_RTP_INFO + userSetting.getServerId() + callId;
  151 + OtherRtpSendInfo otherRtpSendInfo = new OtherRtpSendInfo();
  152 + otherRtpSendInfo.setReceiveIp(mediaServerItem.getSdpIp());
  153 + otherRtpSendInfo.setReceivePort(localPort);
  154 + otherRtpSendInfo.setCallId(callId);
  155 + otherRtpSendInfo.setStream(stream);
  156 + if (isSend != null && isSend) {
  157 + int port = sendRtpPortManager.getNextPort(mediaServerItem.getId());
  158 + otherRtpSendInfo.setIp(mediaServerItem.getSdpIp());
  159 + otherRtpSendInfo.setPort(port);
  160 + logger.info("[开启收流和获取发流信息] 结果,callId->{}, {}", callId, otherRtpSendInfo);
  161 + }
  162 + // 将信息写入redis中,以备后用
  163 + redisTemplate.opsForValue().set(key, otherRtpSendInfo, 300, TimeUnit.SECONDS);
  164 + return otherRtpSendInfo;
82 165 }
83 166  
84 167 @GetMapping(value = "/receive/close")
... ... @@ -86,7 +169,9 @@ public class RtpController {
86 169 @Operation(summary = "关闭收流")
87 170 @Parameter(name = "stream", description = "流的ID", required = true)
88 171 public void closeRtpServer(String stream) {
89   -
  172 + logger.info("[第三方服务对接->关闭收流] stream->{}", stream);
  173 + MediaServerItem mediaServerItem = mediaServerService.getDefaultMediaServer();
  174 + zlmServerFactory.closeRtpServer(mediaServerItem,stream);
90 175 }
91 176  
92 177 @GetMapping(value = "/send/start")
... ... @@ -99,9 +184,44 @@ public class RtpController {
99 184 @Parameter(name = "stream", description = "待发送流Id", required = true)
100 185 @Parameter(name = "callId", description = "整个过程的唯一标识,不传则使用随机端口发流", required = true)
101 186 @Parameter(name = "onlyAudio", description = "是否只有音频", required = true)
  187 + @Parameter(name = "isUdp", description = "是否为UDP", required = true)
102 188 @Parameter(name = "streamType", description = "流类型,1为es流,2为ps流, 默认es流", required = false)
103   - public void sendRTP(String ssrc, String ip, Integer port, String app, String stream, String callId, Boolean onlyAudio, Integer streamType) {
104   -
  189 + public void sendRTP(String ssrc, String ip, Integer port, String app, String stream, String callId, Boolean onlyAudio, Boolean isUdp, Integer streamType) {
  190 + logger.info("[第三方服务对接->发送流] ssrc->{}, ip->{}, port->{}, app->{}, stream->{}, callId->{}, onlyAudio->{}, streamType->{}",
  191 + ssrc, ip, port, app, stream, callId, onlyAudio, streamType == 1? "ES":"PS");
  192 + MediaServerItem mediaServerItem = mediaServerService.getDefaultMediaServer();
  193 + String key = VideoManagerConstants.WVP_OTHER_SEND_RTP_INFO + userSetting.getServerId() + callId;
  194 + OtherRtpSendInfo sendInfo = (OtherRtpSendInfo)redisTemplate.opsForValue().get(key);
  195 + if (sendInfo == null) {
  196 + sendInfo = new OtherRtpSendInfo();
  197 + }
  198 + sendInfo.setPushApp(app);
  199 + sendInfo.setPushStream(stream);
  200 + sendInfo.setPushSSRC(ssrc);
  201 +
  202 + Map<String, Object> param = new HashMap<>(12);
  203 + param.put("vhost","__defaultVhost__");
  204 + param.put("app",app);
  205 + param.put("stream",stream);
  206 + param.put("ssrc", ssrc);
  207 +
  208 + param.put("dst_url",ip);
  209 + param.put("dst_port", port);
  210 + String is_Udp = isUdp ? "1" : "0";
  211 + param.put("is_udp", is_Udp);
  212 + param.put("src_port", sendInfo.getPort());
  213 + param.put("use_ps", streamType==2 ? "1" : "0");
  214 + param.put("only_audio", onlyAudio ? "1" : "0");
  215 +
  216 + JSONObject jsonObject = zlmServerFactory.startSendRtpStream(mediaServerItem, param);
  217 + if (jsonObject.getInteger("code") == 0) {
  218 + logger.info("[第三方服务对接->发送流] 发流成功,callId->{}", callId);
  219 + redisTemplate.opsForValue().set(key, sendInfo);
  220 + }else {
  221 + redisTemplate.delete(key);
  222 + logger.info("[第三方服务对接->发送流] 发流失败,callId->{}, {}", callId, jsonObject.getString("msg"));
  223 + throw new ControllerException(ErrorCode.ERROR100.getCode(), "[发流失败] " + jsonObject.getString("msg"));
  224 + }
105 225 }
106 226  
107 227  
... ... @@ -111,7 +231,25 @@ public class RtpController {
111 231 @Operation(summary = "关闭发送流")
112 232 @Parameter(name = "callId", description = "整个过程的唯一标识,不传则使用随机端口发流", required = true)
113 233 public void closeSendRTP(String callId) {
114   -
  234 + logger.info("[第三方服务对接->关闭发送流] callId->{}", callId);
  235 + String key = VideoManagerConstants.WVP_OTHER_SEND_RTP_INFO + userSetting.getServerId() + callId;
  236 + OtherRtpSendInfo sendInfo = (OtherRtpSendInfo)redisTemplate.opsForValue().get(key);
  237 + if (sendInfo == null){
  238 + throw new ControllerException(ErrorCode.ERROR100.getCode(), "未开启发流");
  239 + }
  240 + Map<String, Object> param = new HashMap<>();
  241 + param.put("vhost","__defaultVhost__");
  242 + param.put("app",sendInfo.getPushApp());
  243 + param.put("stream",sendInfo.getPushStream());
  244 + param.put("ssrc",sendInfo.getPushSSRC());
  245 + MediaServerItem mediaServerItem = mediaServerService.getDefaultMediaServer();
  246 + Boolean result = zlmServerFactory.stopSendRtpStream(mediaServerItem, param);
  247 + if (!result) {
  248 + logger.info("[第三方服务对接->关闭发送流] 失败 callId->{}", callId);
  249 + throw new ControllerException(ErrorCode.ERROR100.getCode(), "停止发流失败");
  250 + }else {
  251 + logger.info("[第三方服务对接->关闭发送流] 成功 callId->{}", callId);
  252 + }
115 253 }
116 254  
117 255 }
... ...
web_src/src/components/dialog/catalogEdit.vue
... ... @@ -12,15 +12,6 @@
12 12 >
13 13 <div id="shared" style="margin-top: 1rem;margin-right: 100px;">
14 14 <el-form ref="form" :rules="rules" :model="form" label-width="140px" >
15   -<!-- <el-form-item >-->
16   -<!-- 建议的类型:-->
17   -<!-- <br/>-->
18   -<!-- &emsp;&emsp;行政区划(可选2位/4位/6位/8位/10位数字,例如:130432,表示河北省邯郸市广平县)-->
19   -<!-- <br/>-->
20   -<!-- &emsp;&emsp;业务分组(第11、12、13位215,例如:34020000002150000001)-->
21   -<!-- <br/>-->
22   -<!-- &emsp;&emsp;虚拟组织(第11、12、13位216,例如:34020000002160000001)-->
23   -<!-- </el-form-item>-->
24 15 <el-form-item label="节点编号" prop="id" >
25 16 <el-input v-model="form.id" :disabled="isEdit" clearable></el-input>
26 17 </el-form-item>
... ... @@ -63,7 +54,11 @@ export default {
63 54 return callback(new Error('行政区划编号必须为2/4/6/8位'));
64 55 }
65 56 if (this.form.parentId !== this.platformDeviceId && this.form.parentId.length >= value.trim().length) {
66   - return callback(new Error('行政区划编号长度应该每次两位递增'));
  57 + if (this.form.parentId.length === 20) {
  58 + return callback(new Error('业务分组/虚拟组织下不可创建行政区划'));
  59 + }else {
  60 + return callback(new Error('行政区划编号长度应该每次两位递增'));
  61 + }
67 62 }
68 63 }else {
69 64 if (value.trim().length !== 20) {
... ... @@ -122,27 +117,31 @@ export default {
122 117 this.level = level;
123 118 },
124 119 onSubmit: function () {
125   - console.log("onSubmit");
126   - console.log(this.form);
127   - this.$axios({
128   - method:"post",
129   - url:`/api/platform/catalog/${!this.isEdit? "add":"edit"}`,
130   - data: this.form
131   - }).then((res)=> {
132   - if (res.data.code === 0) {
133   - if (this.submitCallback)this.submitCallback(this.form)
134   - }else {
135   - this.$message({
136   - showClose: true,
137   - message: res.data.msg,
138   - type: "error",
  120 + this.$refs["form"].validate((valid) => {
  121 + if (valid) {
  122 + this.$axios({
  123 + method:"post",
  124 + url:`/api/platform/catalog/${!this.isEdit? "add":"edit"}`,
  125 + data: this.form
  126 + }).then((res)=> {
  127 + if (res.data.code === 0) {
  128 + if (this.submitCallback)this.submitCallback(this.form)
  129 + }else {
  130 + this.$message({
  131 + showClose: true,
  132 + message: res.data.msg,
  133 + type: "error",
  134 + });
  135 + }
  136 + this.close();
  137 + })
  138 + .catch((error)=> {
  139 + console.log(error);
139 140 });
140   - }
141   - this.close();
142   - })
143   - .catch((error)=> {
144   - console.log(error);
145   - });
  141 + } else {
  142 + return false;
  143 + }
  144 + });
146 145 },
147 146 close: function () {
148 147 this.isEdit = false;
... ...