From 42901d03746d534d701ea3b8663e1c6d2c938c6d Mon Sep 17 00:00:00 2001 From: mrjackwang <30337754+mrjackwang@users.noreply.github.com> Date: 星期二, 15 三月 2022 10:28:23 +0800 Subject: [PATCH] Merge branch 'wvp-28181-2.0' into wvp-28181-2.0 --- src/main/java/com/genersoft/iot/vmp/gb28181/event/online/OnlineEventListener.java | 5 src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/playback/PlaybackController.java | 12 src/main/java/com/genersoft/iot/vmp/gb28181/bean/SubscribeInfo.java | 35 - src/main/java/com/genersoft/iot/vmp/service/bean/InviteTimeOutCallback.java | 6 src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java | 84 ++- src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRTPServerFactory.java | 8 src/main/java/com/genersoft/iot/vmp/storager/dao/PlatformChannelMapper.java | 4 src/main/java/com/genersoft/iot/vmp/gb28181/bean/SubscribeHolder.java | 12 src/main/java/com/genersoft/iot/vmp/web/gb28181/ApiStreamController.java | 2 src/main/java/com/genersoft/iot/vmp/conf/SipPlatformRunner.java | 7 src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/SubscribeRequestProcessor.java | 17 pom.xml | 10 src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/ISIPCommander.java | 9 web_src/src/components/dialog/chooseChannelForGb.vue | 4 src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/MessageRequestProcessor.java | 3 src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/playback/DownloadController.java | 14 src/main/java/com/genersoft/iot/vmp/storager/impl/RedisCatchStorageImpl.java | 145 +++--- src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/ByeRequestProcessor.java | 8 src/main/java/com/genersoft/iot/vmp/storager/IRedisCatchStorage.java | 22 src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/response/impl/RegisterResponseProcessor.java | 26 src/main/java/com/genersoft/iot/vmp/service/impl/MediaServerServiceImpl.java | 2 src/main/java/com/genersoft/iot/vmp/gb28181/bean/InviteStreamInfo.java | 61 ++ web_src/src/components/dialog/StreamProxyEdit.vue | 2 src/main/java/com/genersoft/iot/vmp/gb28181/event/subscribe/catalog/CatalogEventLister.java | 4 src/main/java/com/genersoft/iot/vmp/service/IPlayService.java | 12 src/main/java/com/genersoft/iot/vmp/service/bean/PlayBackResult.java | 6 src/main/java/com/genersoft/iot/vmp/gb28181/bean/ParentPlatform.java | 39 + src/main/java/com/genersoft/iot/vmp/gb28181/event/SipSubscribe.java | 10 src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java | 311 +++++++------- src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPProcessorObserver.java | 4 web_src/src/components/ParentPlatformList.vue | 26 + web_src/static/css/iconfont.css | 22 src/main/java/com/genersoft/iot/vmp/gb28181/bean/InviteStreamCallback.java | 5 src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/MediaStatusNotifyMessageHandler.java | 12 src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/AckRequestProcessor.java | 97 ++- src/main/java/com/genersoft/iot/vmp/storager/impl/VideoManagerStoragerImpl.java | 34 + web_src/src/components/dialog/chooseChannelForStream.vue | 4 src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/InviteRequestProcessor.java | 90 ++- web_src/static/css/iconfont.woff2 | 0 src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/platform/PlatformController.java | 16 src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java | 42 + src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommanderFroPlatform.java | 56 +- src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/play/PlayController.java | 4 DOCKERFILE | 2 src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/NotifyRequestProcessor.java | 1 src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/query/cmd/RecordInfoQueryMessageHandler.java | 2 src/main/java/com/genersoft/iot/vmp/storager/dao/DeviceChannelMapper.java | 10 47 files changed, 759 insertions(+), 548 deletions(-) diff --git a/DOCKERFILE b/DOCKERFILE index 96bc29b..6c4beb5 100644 --- a/DOCKERFILE +++ b/DOCKERFILE @@ -85,7 +85,7 @@ echo 'nohup /opt/media/MediaServer -d -m 3 &' >> run.sh && \ echo 'cd /opt/wvp' >> run.sh && \ echo 'if [${WVP_CONFIG}]; then' >> run.sh && \ - echo ' java -jar *.jar --spring.confi g.location=/opt/wvp/config/application.yml --media.record-assist-port=18081 ${WVP_CONFIG}' >> run.sh && \ + echo ' java -jar *.jar --spring.config.location=/opt/wvp/config/application.yml --media.record-assist-port=18081 ${WVP_CONFIG}' >> run.sh && \ echo 'else' >> run.sh && \ echo ' java -jar *.jar --spring.config.location=/opt/wvp/config/application.yml --media.record-assist-port=18081 --media.ip=127.0.0.1 --media.sdp-ip=${WVP_IP} --sip.ip=${WVP_IP} --media.stream-ip=${WVP_IP}' >> run.sh && \ echo 'fi' >> run.sh diff --git a/pom.xml b/pom.xml index 2dde4da..7ad53db 100644 --- a/pom.xml +++ b/pom.xml @@ -169,13 +169,6 @@ <version>1.2.73</version> </dependency> - <!--Guava鏄竴绉嶅熀浜庡紑婧愮殑Java搴�--> - <dependency> - <groupId>com.google.guava</groupId> - <artifactId>guava</artifactId> - <version>30.0-jre</version> - </dependency> - <!-- okhttp --> <dependency> <groupId>com.squareup.okhttp3</groupId> @@ -279,6 +272,9 @@ <plugin> <groupId>pl.project13.maven</groupId> <artifactId>git-commit-id-plugin</artifactId> + <configuration> + <offline>true</offline> + </configuration> </plugin> <plugin> diff --git a/src/main/java/com/genersoft/iot/vmp/conf/SipPlatformRunner.java b/src/main/java/com/genersoft/iot/vmp/conf/SipPlatformRunner.java index 4ebaf0b..7f9f847 100644 --- a/src/main/java/com/genersoft/iot/vmp/conf/SipPlatformRunner.java +++ b/src/main/java/com/genersoft/iot/vmp/conf/SipPlatformRunner.java @@ -60,12 +60,9 @@ // 鍙栨秷璁㈤槄 sipCommanderForPlatform.unregister(parentPlatform, null, (eventResult)->{ - ParentPlatform platform = storager.queryParentPlatByServerGBId(parentPlatform.getServerGBId()); - sipCommanderForPlatform.register(platform, null, null); + // 鍙戦�佸钩鍙版湭娉ㄥ唽娑堟伅 + publisher.platformNotRegisterEventPublish(parentPlatform.getServerGBId()); }); - - // 鍙戦�佸钩鍙版湭娉ㄥ唽娑堟伅 - publisher.platformNotRegisterEventPublish(parentPlatform.getServerGBId()); } } } diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/bean/InviteStreamCallback.java b/src/main/java/com/genersoft/iot/vmp/gb28181/bean/InviteStreamCallback.java new file mode 100644 index 0000000..42a0519 --- /dev/null +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/bean/InviteStreamCallback.java @@ -0,0 +1,5 @@ +package com.genersoft.iot.vmp.gb28181.bean; + +public interface InviteStreamCallback { + void call(InviteStreamInfo inviteStreamInfo); +} diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/bean/InviteStreamInfo.java b/src/main/java/com/genersoft/iot/vmp/gb28181/bean/InviteStreamInfo.java new file mode 100644 index 0000000..3f3c583 --- /dev/null +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/bean/InviteStreamInfo.java @@ -0,0 +1,61 @@ +package com.genersoft.iot.vmp.gb28181.bean; + +import com.alibaba.fastjson.JSONObject; +import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; + +public class InviteStreamInfo { + + public InviteStreamInfo(MediaServerItem mediaServerItem, JSONObject response, String callId, String app, String stream) { + this.mediaServerItem = mediaServerItem; + this.response = response; + this.callId = callId; + this.app = app; + this.stream = stream; + } + + private MediaServerItem mediaServerItem; + private JSONObject response; + private String callId; + private String app; + private String stream; + + public MediaServerItem getMediaServerItem() { + return mediaServerItem; + } + + public void setMediaServerItem(MediaServerItem mediaServerItem) { + this.mediaServerItem = mediaServerItem; + } + + public JSONObject getResponse() { + return response; + } + + public void setResponse(JSONObject response) { + this.response = response; + } + + public String getCallId() { + return callId; + } + + public void setCallId(String callId) { + this.callId = callId; + } + + public String getApp() { + return app; + } + + public void setApp(String app) { + this.app = app; + } + + public String getStream() { + return stream; + } + + public void setStream(String stream) { + this.stream = stream; + } +} diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/bean/ParentPlatform.java b/src/main/java/com/genersoft/iot/vmp/gb28181/bean/ParentPlatform.java index 0c06145..8df7939 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/bean/ParentPlatform.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/bean/ParentPlatform.java @@ -114,6 +114,21 @@ */ private String catalogId; + /** + * 宸茶璁㈤槄鐩綍淇℃伅 + */ + private boolean catalogSubscribe; + + /** + * 宸茶璁㈤槄鎶ヨ淇℃伅 + */ + private boolean alarmSubscribe; + + /** + * 宸茶璁㈤槄GPS淇℃伅 + */ + private boolean gpsSubscribe; + public Integer getId() { return id; } @@ -290,4 +305,28 @@ public void setCatalogId(String catalogId) { this.catalogId = catalogId; } + + public boolean isCatalogSubscribe() { + return catalogSubscribe; + } + + public void setCatalogSubscribe(boolean catalogSubscribe) { + this.catalogSubscribe = catalogSubscribe; + } + + public boolean isAlarmSubscribe() { + return alarmSubscribe; + } + + public void setAlarmSubscribe(boolean alarmSubscribe) { + this.alarmSubscribe = alarmSubscribe; + } + + public boolean isGpsSubscribe() { + return gpsSubscribe; + } + + public void setGpsSubscribe(boolean gpsSubscribe) { + this.gpsSubscribe = gpsSubscribe; + } } diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/bean/SubscribeHolder.java b/src/main/java/com/genersoft/iot/vmp/gb28181/bean/SubscribeHolder.java index a027486..287c2a0 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/bean/SubscribeHolder.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/bean/SubscribeHolder.java @@ -2,6 +2,8 @@ import org.springframework.stereotype.Component; +import java.util.ArrayList; +import java.util.List; import java.util.concurrent.ConcurrentHashMap; @Component @@ -34,4 +36,14 @@ public void removeMobilePositionSubscribe(String platformId) { mobilePositionMap.remove(platformId); } + + public List<String> getAllCatalogSubscribePlatform() { + List<String> platforms = new ArrayList<>(); + if(catalogMap.size() > 0) { + for (String key : catalogMap.keySet()) { + platforms.add(catalogMap.get(key).getId()); + } + } + return platforms; + } } diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/bean/SubscribeInfo.java b/src/main/java/com/genersoft/iot/vmp/gb28181/bean/SubscribeInfo.java index 373533a..434a639 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/bean/SubscribeInfo.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/bean/SubscribeInfo.java @@ -14,19 +14,15 @@ public SubscribeInfo(RequestEvent evt, String id) { this.id = id; Request request = evt.getRequest(); - CallIdHeader callIdHeader = (CallIdHeader)request.getHeader(CallIdHeader.NAME); - this.callId = callIdHeader.getCallId(); - FromHeader fromHeader = (FromHeader)request.getHeader(FromHeader.NAME); - this.fromTag = fromHeader.getTag(); ExpiresHeader expiresHeader = (ExpiresHeader)request.getHeader(ExpiresHeader.NAME); this.expires = expiresHeader.getExpires(); EventHeader eventHeader = (EventHeader)request.getHeader(EventHeader.NAME); this.eventId = eventHeader.getEventId(); this.eventType = eventHeader.getEventType(); - ViaHeader viaHeader = (ViaHeader)request.getHeader(ViaHeader.NAME); - this.branch = viaHeader.getBranch(); this.transaction = evt.getServerTransaction(); this.dialog = evt.getDialog(); + CallIdHeader callIdHeader = (CallIdHeader)evt.getRequest().getHeader(CallIdHeader.NAME); + this.callId = callIdHeader.getCallId(); } private String id; @@ -34,9 +30,6 @@ private String callId; private String eventId; private String eventType; - private String fromTag; - private String toTag; - private String branch; private ServerTransaction transaction; private Dialog dialog; @@ -52,18 +45,6 @@ return callId; } - public String getFromTag() { - return fromTag; - } - - public void setToTag(String toTag) { - this.toTag = toTag; - } - - public String getToTag() { - return toTag; - } - public void setId(String id) { this.id = id; } @@ -74,10 +55,6 @@ public void setCallId(String callId) { this.callId = callId; - } - - public void setFromTag(String fromTag) { - this.fromTag = fromTag; } public String getEventId() { @@ -94,14 +71,6 @@ public void setEventType(String eventType) { this.eventType = eventType; - } - - public String getBranch() { - return branch; - } - - public void setBranch(String branch) { - this.branch = branch; } public ServerTransaction getTransaction() { diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/event/SipSubscribe.java b/src/main/java/com/genersoft/iot/vmp/gb28181/event/SipSubscribe.java index 49c52d5..bc775e4 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/event/SipSubscribe.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/event/SipSubscribe.java @@ -30,7 +30,7 @@ // @Scheduled(fixedRate= 100 * 60 * 60 ) @Scheduled(cron="0 0/5 * * * ?") //姣�5鍒嗛挓鎵ц涓�娆� public void execute(){ - logger.info("[瀹氭椂浠诲姟] 娓呯悊杩囨湡鐨勮闃呬俊鎭�"); + logger.info("[瀹氭椂浠诲姟] 娓呯悊杩囨湡鐨凷IP璁㈤槄淇℃伅"); Calendar calendar = Calendar.getInstance(); calendar.setTime(new Date()); calendar.set(Calendar.MINUTE, calendar.get(Calendar.MINUTE) - 5); @@ -49,10 +49,10 @@ errorTimeSubscribes.remove(key); } } - logger.info("okTimeSubscribes.size:{}",okTimeSubscribes.size()); - logger.info("okSubscribes.size:{}",okSubscribes.size()); - logger.info("errorTimeSubscribes.size:{}",errorTimeSubscribes.size()); - logger.info("errorSubscribes.size:{}",errorSubscribes.size()); + logger.debug("okTimeSubscribes.size:{}",okTimeSubscribes.size()); + logger.debug("okSubscribes.size:{}",okSubscribes.size()); + logger.debug("errorTimeSubscribes.size:{}",errorTimeSubscribes.size()); + logger.debug("errorSubscribes.size:{}",errorSubscribes.size()); } public interface Event { diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/event/online/OnlineEventListener.java b/src/main/java/com/genersoft/iot/vmp/gb28181/event/online/OnlineEventListener.java index 27bc4bc..d3580d3 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/event/online/OnlineEventListener.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/event/online/OnlineEventListener.java @@ -68,8 +68,6 @@ String key = VideoManagerConstants.KEEPLIVEKEY_PREFIX + userSetup.getServerId() + "_" + event.getDevice().getDeviceId(); Device deviceInStore = storager.queryVideoDevice(device.getDeviceId()); device.setOnline(1); - // 澶勭悊涓婄嚎鐩戝惉 - storager.updateDevice(device); switch (event.getFrom()) { // 娉ㄥ唽鏃惰Е鍙戠殑鍦ㄧ嚎浜嬩欢锛屽厛鍦╮edis涓鍔犺秴鏃惰秴鏃剁洃鍚� case VideoManagerConstants.EVENT_ONLINE_REGISTER: @@ -98,7 +96,8 @@ break; } - + // 澶勭悊涓婄嚎鐩戝惉 + storager.updateDevice(device); List<DeviceChannel> deviceChannelList = storager.queryOnlineChannelsByDeviceId(device.getDeviceId()); eventPublisher.catalogEventPublish(null, deviceChannelList, CatalogEvent.ON); // 涓婄嚎娣诲姞璁㈤槄 diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/event/subscribe/catalog/CatalogEventLister.java b/src/main/java/com/genersoft/iot/vmp/gb28181/event/subscribe/catalog/CatalogEventLister.java index 9e3b352..d511f42 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/event/subscribe/catalog/CatalogEventLister.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/event/subscribe/catalog/CatalogEventLister.java @@ -74,7 +74,7 @@ } }else { // 鑾峰彇鎵�鐢ㄨ闃� - List<String> platforms = redisCatchStorage.getAllSubscribePlatform(); + List<String> platforms = subscribeHolder.getAllCatalogSubscribePlatform(); if (event.getDeviceChannels() != null) { if (platforms.size() > 0) { for (DeviceChannel deviceChannel : event.getDeviceChannels()) { @@ -117,8 +117,6 @@ List<ParentPlatform> parentPlatforms = parentPlatformMap.get(gbId); if (parentPlatforms != null && parentPlatforms.size() > 0) { for (ParentPlatform platform : parentPlatforms) { - String key = VideoManagerConstants.SIP_SUBSCRIBE_PREFIX + userSetup.getServerId() + "_Catalog_" + platform.getServerGBId(); -// SubscribeInfo subscribeInfo = redisCatchStorage.getSubscribe(key); SubscribeInfo subscribeInfo = subscribeHolder.getCatalogSubscribe(platform.getServerGBId()); if (subscribeInfo == null) continue; logger.info("[Catalog浜嬩欢: {}]骞冲彴锛歿}锛屽奖鍝嶉�氶亾{}", event.getType(), platform.getServerGBId(), gbId); diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPProcessorObserver.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPProcessorObserver.java index 30efa20..6439e8c 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPProcessorObserver.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPProcessorObserver.java @@ -95,14 +95,14 @@ logger.debug("\n鏀跺埌鍝嶅簲锛歕n{}", responseEvent.getResponse()); int status = response.getStatusCode(); - if (((status >= 200) && (status < 300)) || status == 401) { // Success! + if (((status >= 200) && (status < 300)) || status == Response.UNAUTHORIZED) { // Success! CSeqHeader cseqHeader = (CSeqHeader) responseEvent.getResponse().getHeader(CSeqHeader.NAME); String method = cseqHeader.getMethod(); ISIPResponseProcessor sipRequestProcessor = responseProcessorMap.get(method); if (sipRequestProcessor != null) { sipRequestProcessor.process(responseEvent); } - if (responseEvent.getResponse() != null && sipSubscribe.getOkSubscribesSize() > 0 ) { + if (status != Response.UNAUTHORIZED && responseEvent.getResponse() != null && sipSubscribe.getOkSubscribesSize() > 0 ) { CallIdHeader callIdHeader = (CallIdHeader)responseEvent.getResponse().getHeader(CallIdHeader.NAME); if (callIdHeader != null) { SipSubscribe.Event subscribe = sipSubscribe.getOkSubscribe(callIdHeader.getCallId()); diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/ISIPCommander.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/ISIPCommander.java index 67be247..409eedb 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/ISIPCommander.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/ISIPCommander.java @@ -2,6 +2,7 @@ import com.genersoft.iot.vmp.common.StreamInfo; import com.genersoft.iot.vmp.gb28181.bean.Device; +import com.genersoft.iot.vmp.gb28181.bean.InviteStreamCallback; import com.genersoft.iot.vmp.gb28181.event.SipSubscribe; import com.genersoft.iot.vmp.media.zlm.ZLMHttpHookSubscribe; import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; @@ -103,7 +104,7 @@ * @param startTime 寮�濮嬫椂闂�,鏍煎紡瑕佹眰锛歽yyy-MM-dd HH:mm:ss * @param endTime 缁撴潫鏃堕棿,鏍煎紡瑕佹眰锛歽yyy-MM-dd HH:mm:ss */ - void playbackStreamCmd(MediaServerItem mediaServerItem, SSRCInfo ssrcInf, Device device, String channelId, String startTime, String endTime, ZLMHttpHookSubscribe.Event event, SipSubscribe.Event errorEvent); + void playbackStreamCmd(MediaServerItem mediaServerItem, SSRCInfo ssrcInf, Device device, String channelId, String startTime, String endTime,InviteStreamCallback inviteStreamCallback, InviteStreamCallback event, SipSubscribe.Event errorEvent); /** * 璇锋眰鍘嗗彶濯掍綋涓嬭浇 @@ -114,13 +115,13 @@ * @param endTime 缁撴潫鏃堕棿,鏍煎紡瑕佹眰锛歽yyy-MM-dd HH:mm:ss * @param downloadSpeed 涓嬭浇鍊嶉�熷弬鏁� */ - void downloadStreamCmd(MediaServerItem mediaServerItem, SSRCInfo ssrcInfo, Device device, String channelId, String startTime, String endTime, String downloadSpeed, ZLMHttpHookSubscribe.Event event, SipSubscribe.Event errorEvent); + void downloadStreamCmd(MediaServerItem mediaServerItem, SSRCInfo ssrcInfo, Device device, String channelId, String startTime, String endTime, String downloadSpeed, InviteStreamCallback event, SipSubscribe.Event errorEvent); /** * 瑙嗛娴佸仠姝� */ - void streamByeCmd(String deviceId, String channelId, String stream, SipSubscribe.Event okEvent); - void streamByeCmd(String deviceId, String channelId, String stream); + void streamByeCmd(String deviceId, String channelId, String stream, String callId, SipSubscribe.Event okEvent); + void streamByeCmd(String deviceId, String channelId, String stream, String callId); /** * 鍥炴斁鏆傚仠 diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java index b38a8c1..5df6314 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java @@ -6,6 +6,8 @@ import com.genersoft.iot.vmp.conf.SipConfig; import com.genersoft.iot.vmp.conf.UserSetup; import com.genersoft.iot.vmp.gb28181.bean.Device; +import com.genersoft.iot.vmp.gb28181.bean.InviteStreamCallback; +import com.genersoft.iot.vmp.gb28181.bean.InviteStreamInfo; import com.genersoft.iot.vmp.gb28181.bean.SsrcTransaction; import com.genersoft.iot.vmp.gb28181.event.SipSubscribe; import com.genersoft.iot.vmp.gb28181.session.VideoStreamSessionManager; @@ -445,26 +447,12 @@ * @param endTime 缁撴潫鏃堕棿,鏍煎紡瑕佹眰锛歽yyy-MM-dd HH:mm:ss */ @Override - public void playbackStreamCmd(MediaServerItem mediaServerItem, SSRCInfo ssrcInfo, Device device, String channelId, String startTime, String endTime, ZLMHttpHookSubscribe.Event event - , SipSubscribe.Event errorEvent) { + public void playbackStreamCmd(MediaServerItem mediaServerItem, SSRCInfo ssrcInfo, Device device, String channelId, + String startTime, String endTime, InviteStreamCallback inviteStreamCallback, InviteStreamCallback hookEvent, + SipSubscribe.Event errorEvent) { try { logger.info("{} 鍒嗛厤鐨刏LM涓�: {} [{}:{}]", ssrcInfo.getStream(), mediaServerItem.getId(), mediaServerItem.getIp(), ssrcInfo.getPort()); - - // 娣诲姞璁㈤槄 - JSONObject subscribeKey = new JSONObject(); - subscribeKey.put("app", "rtp"); - subscribeKey.put("stream", ssrcInfo.getStream()); - subscribeKey.put("regist", true); - subscribeKey.put("schema", "rtmp"); - subscribeKey.put("mediaServerId", mediaServerItem.getId()); - logger.debug("褰曞儚鍥炴斁娣诲姞璁㈤槄锛岃闃呭唴瀹癸細" + subscribeKey.toString()); - subscribe.addSubscribe(ZLMHttpHookSubscribe.HookType.on_stream_changed, subscribeKey, - (MediaServerItem mediaServerItemInUse, JSONObject json)->{ - if (event != null) { - event.response(mediaServerItemInUse, json); - } - }); StringBuffer content = new StringBuffer(200); content.append("v=0\r\n"); @@ -530,6 +518,21 @@ CallIdHeader callIdHeader = device.getTransport().equals("TCP") ? tcpSipProvider.getNewCallId() : udpSipProvider.getNewCallId(); + // 娣诲姞璁㈤槄 + JSONObject subscribeKey = new JSONObject(); + subscribeKey.put("app", "rtp"); + subscribeKey.put("stream", ssrcInfo.getStream()); + subscribeKey.put("regist", true); + subscribeKey.put("schema", "rtmp"); + subscribeKey.put("mediaServerId", mediaServerItem.getId()); + logger.debug("褰曞儚鍥炴斁娣诲姞璁㈤槄锛岃闃呭唴瀹癸細" + subscribeKey); + subscribe.addSubscribe(ZLMHttpHookSubscribe.HookType.on_stream_changed, subscribeKey, + (MediaServerItem mediaServerItemInUse, JSONObject json)->{ + if (hookEvent != null) { + InviteStreamInfo inviteStreamInfo = new InviteStreamInfo(mediaServerItemInUse, json, callIdHeader.getCallId(), "rtp", ssrcInfo.getStream()); + hookEvent.call(inviteStreamInfo); + } + }); Request request = headerProvider.createPlaybackInviteRequest(device, channelId, content.toString(), null, "fromplybck" + tm, null, callIdHeader, ssrcInfo.getSsrc()); transmitRequest(device, request, errorEvent, okEvent -> { @@ -537,6 +540,9 @@ streamSession.put(device.getDeviceId(), channelId, callIdHeader.getCallId(), ssrcInfo.getStream(), ssrcInfo.getSsrc(), mediaServerItem.getId(), responseEvent.getClientTransaction()); streamSession.put(device.getDeviceId(), channelId, callIdHeader.getCallId(), okEvent.dialog); }); + if (inviteStreamCallback != null) { + inviteStreamCallback.call(new InviteStreamInfo(mediaServerItem, null, callIdHeader.getCallId(), "rtp", ssrcInfo.getStream())); + } } catch ( SipException | ParseException | InvalidArgumentException e) { e.printStackTrace(); } @@ -552,23 +558,10 @@ * @param downloadSpeed 涓嬭浇鍊嶉�熷弬鏁� */ @Override - public void downloadStreamCmd(MediaServerItem mediaServerItem, SSRCInfo ssrcInfo, Device device, String channelId, String startTime, String endTime, String downloadSpeed, ZLMHttpHookSubscribe.Event event + public void downloadStreamCmd(MediaServerItem mediaServerItem, SSRCInfo ssrcInfo, Device device, String channelId, String startTime, String endTime, String downloadSpeed, InviteStreamCallback event , SipSubscribe.Event errorEvent) { try { logger.info("{} 鍒嗛厤鐨刏LM涓�: {} [{}:{}]", ssrcInfo.getStream(), mediaServerItem.getId(), mediaServerItem.getIp(), ssrcInfo.getPort()); - - // 娣诲姞璁㈤槄 - JSONObject subscribeKey = new JSONObject(); - subscribeKey.put("app", "rtp"); - subscribeKey.put("stream", ssrcInfo.getStream()); - subscribeKey.put("regist", true); - subscribeKey.put("mediaServerId", mediaServerItem.getId()); - logger.debug("褰曞儚鍥炴斁娣诲姞璁㈤槄锛岃闃呭唴瀹癸細" + subscribeKey.toString()); - subscribe.addSubscribe(ZLMHttpHookSubscribe.HookType.on_stream_changed, subscribeKey, - (MediaServerItem mediaServerItemInUse, JSONObject json)->{ - event.response(mediaServerItemInUse, json); - subscribe.removeSubscribe(ZLMHttpHookSubscribe.HookType.on_stream_changed, subscribeKey); - }); StringBuffer content = new StringBuffer(200); content.append("v=0\r\n"); @@ -637,6 +630,19 @@ CallIdHeader callIdHeader = device.getTransport().equals("TCP") ? tcpSipProvider.getNewCallId() : udpSipProvider.getNewCallId(); + // 娣诲姞璁㈤槄 + JSONObject subscribeKey = new JSONObject(); + subscribeKey.put("app", "rtp"); + subscribeKey.put("stream", ssrcInfo.getStream()); + subscribeKey.put("regist", true); + subscribeKey.put("mediaServerId", mediaServerItem.getId()); + logger.debug("褰曞儚鍥炴斁娣诲姞璁㈤槄锛岃闃呭唴瀹癸細" + subscribeKey.toString()); + subscribe.addSubscribe(ZLMHttpHookSubscribe.HookType.on_stream_changed, subscribeKey, + (MediaServerItem mediaServerItemInUse, JSONObject json)->{ + event.call(new InviteStreamInfo(mediaServerItem, json, callIdHeader.getCallId(), "rtp", ssrcInfo.getStream())); + subscribe.removeSubscribe(ZLMHttpHookSubscribe.HookType.on_stream_changed, subscribeKey); + }); + Request request = headerProvider.createPlaybackInviteRequest(device, channelId, content.toString(), null, "fromplybck" + tm, null, callIdHeader, ssrcInfo.getSsrc()); ClientTransaction transaction = transmitRequest(device, request, errorEvent); @@ -652,15 +658,15 @@ * 瑙嗛娴佸仠姝�, 涓嶄娇鐢ㄥ洖璋� */ @Override - public void streamByeCmd(String deviceId, String channelId, String stream) { - streamByeCmd(deviceId, channelId, stream, null); + public void streamByeCmd(String deviceId, String channelId, String stream, String callId) { + streamByeCmd(deviceId, channelId, stream, callId, null); } /** * 瑙嗛娴佸仠姝� */ @Override - public void streamByeCmd(String deviceId, String channelId, String stream, SipSubscribe.Event okEvent) { + public void streamByeCmd(String deviceId, String channelId, String stream, String callId, SipSubscribe.Event okEvent) { try { SsrcTransaction ssrcTransaction = streamSession.getSsrcTransaction(deviceId, channelId, null, stream); ClientTransaction transaction = streamSession.getTransactionByStream(deviceId, channelId, stream); @@ -672,7 +678,15 @@ } return; } - SIPDialog dialog = streamSession.getDialogByStream(deviceId, channelId, stream); + SIPDialog dialog; + if (callId != null) { + dialog = streamSession.getDialogByCallId(deviceId, channelId, callId); + }else { + if (stream == null) return; + dialog = streamSession.getDialogByStream(deviceId, channelId, stream); + } + + if (dialog == null) { logger.warn("[ {} -> {}]鍋滄瑙嗛娴佺殑鏃跺�欏彂鐜板璇濆凡涓㈠け", deviceId, channelId); return; diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommanderFroPlatform.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommanderFroPlatform.java index a379f39..6f1d031 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommanderFroPlatform.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommanderFroPlatform.java @@ -13,6 +13,7 @@ import com.genersoft.iot.vmp.utils.SerializeUtils; import gov.nist.javax.sip.SipProviderImpl; import gov.nist.javax.sip.SipStackImpl; +import gov.nist.javax.sip.message.MessageFactoryImpl; import gov.nist.javax.sip.message.SIPRequest; import gov.nist.javax.sip.stack.SIPDialog; import org.slf4j.Logger; @@ -77,11 +78,11 @@ @Override public boolean unregister(ParentPlatform parentPlatform, SipSubscribe.Event errorEvent , SipSubscribe.Event okEvent) { ParentPlatformCatch parentPlatformCatch = redisCatchStorage.queryPlatformCatchInfo(parentPlatform.getServerGBId()); + parentPlatform.setExpires("0"); if (parentPlatformCatch != null) { parentPlatformCatch.setParentPlatform(parentPlatform); redisCatchStorage.updatePlatformCatchInfo(parentPlatformCatch); } - parentPlatform.setExpires("0"); return register(parentPlatform, null, null, errorEvent, okEvent, false); } @@ -101,7 +102,9 @@ callIdHeader = udpSipProvider.getNewCallId(); } - request = headerProviderPlarformProvider.createRegisterRequest(parentPlatform, redisCatchStorage.getCSEQ(Request.REGISTER), "FromRegister" + tm, null, callIdHeader); + request = headerProviderPlarformProvider.createRegisterRequest(parentPlatform, + redisCatchStorage.getCSEQ(Request.REGISTER), "FromRegister" + tm, + "z9hG4bK-" + UUID.randomUUID().toString().replace("-", ""), callIdHeader); // 灏� callid 鍐欏叆缂撳瓨锛� 绛夋敞鍐屾垚鍔熷彲浠ユ洿鏂扮姸鎬� String callIdFromHeader = callIdHeader.getCallId(); redisCatchStorage.updatePlatformRegisterInfo(callIdFromHeader, parentPlatform.getServerGBId()); @@ -414,11 +417,13 @@ private void sendNotify(ParentPlatform parentPlatform, String catalogXmlContent, SubscribeInfo subscribeInfo, SipSubscribe.Event errorEvent, SipSubscribe.Event okEvent ) throws NoSuchFieldException, IllegalAccessException, SipException, ParseException { + MessageFactoryImpl messageFactory = (MessageFactoryImpl) sipFactory.createMessageFactory(); + // 璁剧疆缂栫爜锛� 闃叉涓枃涔辩爜 + messageFactory.setDefaultContentEncodingCharset("gb2312"); Dialog dialog = subscribeInfo.getDialog(); - Request notifyRequest = dialog.createRequest(Request.NOTIFY); - + if (dialog == null) return; + SIPRequest notifyRequest = (SIPRequest)dialog.createRequest(Request.NOTIFY); ContentTypeHeader contentTypeHeader = sipFactory.createHeaderFactory().createContentTypeHeader("Application", "MANSCDP+xml"); - notifyRequest.setContent(catalogXmlContent, contentTypeHeader); SubscriptionStateHeader subscriptionState = sipFactory.createHeaderFactory() @@ -509,7 +514,8 @@ } @Override - public boolean sendNotifyForCatalogOther(String type, ParentPlatform parentPlatform, List<DeviceChannel> deviceChannels, SubscribeInfo subscribeInfo, Integer index) { + public boolean sendNotifyForCatalogOther(String type, ParentPlatform parentPlatform, List<DeviceChannel> deviceChannels, + SubscribeInfo subscribeInfo, Integer index) { if (parentPlatform == null || deviceChannels == null || deviceChannels.size() == 0 @@ -577,24 +583,30 @@ recordXml.append("<SN>" +recordInfo.getSn() + "</SN>\r\n"); recordXml.append("<DeviceID>" + recordInfo.getDeviceId() + "</DeviceID>\r\n"); recordXml.append("<SumNum>" + recordInfo.getSumNum() + "</SumNum>\r\n"); - recordXml.append("<RecordList Num=\"" + recordInfo.getRecordList().size()+"\">\r\n"); - for (RecordItem recordItem : recordInfo.getRecordList()) { - recordXml.append("<Item>\r\n"); - if (deviceChannel != null) { - recordXml.append("<DeviceID>" + recordItem.getDeviceId() + "</DeviceID>\r\n"); - recordXml.append("<Name>" + recordItem.getName() + "</Name>\r\n"); - recordXml.append("<StartTime>" + DateUtil.yyyy_MM_dd_HH_mm_ssToISO8601(recordItem.getStartTime()) + "</StartTime>\r\n"); - recordXml.append("<EndTime>" + DateUtil.yyyy_MM_dd_HH_mm_ssToISO8601(recordItem.getEndTime()) + "</EndTime>\r\n"); - recordXml.append("<Secrecy>" + recordItem.getSecrecy() + "</Secrecy>\r\n"); - recordXml.append("<Type>" + recordItem.getType() + "</Type>\r\n"); - if (!StringUtils.isEmpty(recordItem.getFileSize())) { - recordXml.append("<FileSize>" + recordItem.getFileSize() + "</FileSize>\r\n"); - } - if (!StringUtils.isEmpty(recordItem.getFilePath())) { - recordXml.append("<FilePath>" + recordItem.getFilePath() + "</FilePath>\r\n"); + if (recordInfo.getRecordList() == null ) { + recordXml.append("<RecordList Num=\"0\">\r\n"); + }else { + recordXml.append("<RecordList Num=\"" + recordInfo.getRecordList().size()+"\">\r\n"); + if (recordInfo.getRecordList().size() > 0) { + for (RecordItem recordItem : recordInfo.getRecordList()) { + recordXml.append("<Item>\r\n"); + if (deviceChannel != null) { + recordXml.append("<DeviceID>" + recordItem.getDeviceId() + "</DeviceID>\r\n"); + recordXml.append("<Name>" + recordItem.getName() + "</Name>\r\n"); + recordXml.append("<StartTime>" + DateUtil.yyyy_MM_dd_HH_mm_ssToISO8601(recordItem.getStartTime()) + "</StartTime>\r\n"); + recordXml.append("<EndTime>" + DateUtil.yyyy_MM_dd_HH_mm_ssToISO8601(recordItem.getEndTime()) + "</EndTime>\r\n"); + recordXml.append("<Secrecy>" + recordItem.getSecrecy() + "</Secrecy>\r\n"); + recordXml.append("<Type>" + recordItem.getType() + "</Type>\r\n"); + if (!StringUtils.isEmpty(recordItem.getFileSize())) { + recordXml.append("<FileSize>" + recordItem.getFileSize() + "</FileSize>\r\n"); + } + if (!StringUtils.isEmpty(recordItem.getFilePath())) { + recordXml.append("<FilePath>" + recordItem.getFilePath() + "</FilePath>\r\n"); + } + } + recordXml.append("</Item>\r\n"); } } - recordXml.append("</Item>\r\n"); } recordXml.append("</RecordList>\r\n"); diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/AckRequestProcessor.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/AckRequestProcessor.java index 8556730..ec83fa8 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/AckRequestProcessor.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/AckRequestProcessor.java @@ -27,10 +27,7 @@ import javax.sip.header.FromHeader; import javax.sip.header.HeaderAddress; import javax.sip.header.ToHeader; -import java.util.HashMap; -import java.util.Map; -import java.util.Timer; -import java.util.TimerTask; +import java.util.*; /** * SIP鍛戒护绫诲瀷锛� ACK璇锋眰 @@ -84,44 +81,72 @@ String channelId = ((SipURI) ((HeaderAddress) evt.getRequest().getHeader(ToHeader.NAME)).getAddress().getURI()).getUser(); SendRtpItem sendRtpItem = redisCatchStorage.querySendRTPServer(platformGbId, channelId, null, callIdHeader.getCallId()); String is_Udp = sendRtpItem.isTcp() ? "0" : "1"; - String deviceId = sendRtpItem.getDeviceId(); - StreamInfo streamInfo = null; - if (sendRtpItem.isPlay()) { - streamInfo = redisCatchStorage.queryPlayByDevice(deviceId, channelId); - }else { - streamInfo = redisCatchStorage.queryPlaybackByDevice(deviceId, channelId); - } - if (streamInfo == null) { - streamInfo = new StreamInfo(); - streamInfo.setApp(sendRtpItem.getApp()); - streamInfo.setStream(sendRtpItem.getStreamId()); - } - redisCatchStorage.updateSendRTPSever(sendRtpItem); + MediaServerItem mediaInfo = mediaServerService.getOne(sendRtpItem.getMediaServerId()); + logger.info("鏀跺埌ACK锛屽紑濮嬪悜涓婄骇鎺ㄦ祦 rtp/{}", sendRtpItem.getStreamId()); Map<String, Object> param = new HashMap<>(); param.put("vhost","__defaultVhost__"); - param.put("app",streamInfo.getApp()); - param.put("stream",streamInfo.getStream()); + param.put("app",sendRtpItem.getApp()); + param.put("stream",sendRtpItem.getStreamId()); param.put("ssrc", sendRtpItem.getSsrc()); param.put("dst_url",sendRtpItem.getIp()); param.put("dst_port", sendRtpItem.getPort()); param.put("is_udp", is_Udp); - MediaServerItem mediaInfo = mediaServerService.getOne(sendRtpItem.getMediaServerId()); - JSONObject jsonObject = zlmrtpServerFactory.startSendRtpStream(mediaInfo, param); - if (jsonObject.getInteger("code") != 0) { - logger.info("鐩戝惉娴佷互绛夊緟娴佷笂绾縶}/{}", streamInfo.getApp(), streamInfo.getStream()); - // 鐩戝惉娴佷笂绾� - // 娣诲姞璁㈤槄 - JSONObject subscribeKey = new JSONObject(); - subscribeKey.put("app", "rtp"); - subscribeKey.put("stream", streamInfo.getStream()); - subscribeKey.put("regist", true); - subscribeKey.put("schema", "rtmp"); - subscribeKey.put("mediaServerId", sendRtpItem.getMediaServerId()); - subscribe.addSubscribe(ZLMHttpHookSubscribe.HookType.on_stream_changed, subscribeKey, - (MediaServerItem mediaServerItemInUse, JSONObject json)->{ - zlmrtpServerFactory.startSendRtpStream(mediaInfo, param); - }); - } + param.put("src_port", sendRtpItem.getLocalPort()); + zlmrtpServerFactory.startSendRtpStream(mediaInfo, param); + + + +// if (streamInfo == null) { // 娴佽繕娌′笂鏉ワ紝瀵规柟灏卞洖澶峚ck +// logger.info("鐩戝惉娴佷互绛夊緟娴佷笂绾�1 rtp/{}", sendRtpItem.getStreamId()); +// // 鐩戝惉娴佷笂绾� +// // 娣诲姞璁㈤槄 +// JSONObject subscribeKey = new JSONObject(); +// subscribeKey.put("app", "rtp"); +// subscribeKey.put("stream", sendRtpItem.getStreamId()); +// subscribeKey.put("regist", true); +// subscribeKey.put("schema", "rtmp"); +// subscribeKey.put("mediaServerId", sendRtpItem.getMediaServerId()); +// subscribe.addSubscribe(ZLMHttpHookSubscribe.HookType.on_stream_changed, subscribeKey, +// (MediaServerItem mediaServerItemInUse, JSONObject json)->{ +// Map<String, Object> param = new HashMap<>(); +// param.put("vhost","__defaultVhost__"); +// param.put("app",json.getString("app")); +// param.put("stream",json.getString("stream")); +// param.put("ssrc", sendRtpItem.getSsrc()); +// param.put("dst_url",sendRtpItem.getIp()); +// param.put("dst_port", sendRtpItem.getPort()); +// param.put("is_udp", is_Udp); +// param.put("src_port", sendRtpItem.getLocalPort()); +// zlmrtpServerFactory.startSendRtpStream(mediaInfo, param); +// }); +// }else { +// Map<String, Object> param = new HashMap<>(); +// param.put("vhost","__defaultVhost__"); +// param.put("app",streamInfo.getApp()); +// param.put("stream",streamInfo.getStream()); +// param.put("ssrc", sendRtpItem.getSsrc()); +// param.put("dst_url",sendRtpItem.getIp()); +// param.put("dst_port", sendRtpItem.getPort()); +// param.put("is_udp", is_Udp); +// param.put("src_port", sendRtpItem.getLocalPort()); +// +// JSONObject jsonObject = zlmrtpServerFactory.startSendRtpStream(mediaInfo, param); +// if (jsonObject.getInteger("code") != 0) { +// logger.info("鐩戝惉娴佷互绛夊緟娴佷笂绾�2 {}/{}", streamInfo.getApp(), streamInfo.getStream()); +// // 鐩戝惉娴佷笂绾� +// // 娣诲姞璁㈤槄 +// JSONObject subscribeKey = new JSONObject(); +// subscribeKey.put("app", "rtp"); +// subscribeKey.put("stream", streamInfo.getStream()); +// subscribeKey.put("regist", true); +// subscribeKey.put("schema", "rtmp"); +// subscribeKey.put("mediaServerId", sendRtpItem.getMediaServerId()); +// subscribe.addSubscribe(ZLMHttpHookSubscribe.HookType.on_stream_changed, subscribeKey, +// (MediaServerItem mediaServerItemInUse, JSONObject json)->{ +// zlmrtpServerFactory.startSendRtpStream(mediaInfo, param); +// }); +// } +// } } } } diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/ByeRequestProcessor.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/ByeRequestProcessor.java index 2811c4f..e487447 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/ByeRequestProcessor.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/ByeRequestProcessor.java @@ -93,14 +93,16 @@ param.put("app",sendRtpItem.getApp()); param.put("stream",streamId); param.put("ssrc",sendRtpItem.getSsrc()); - logger.info("鍋滄鍚戜笂绾ф帹娴侊細" + streamId); + logger.info("鏀跺埌bye:鍋滄鍚戜笂绾ф帹娴侊細" + streamId); MediaServerItem mediaInfo = mediaServerService.getOne(sendRtpItem.getMediaServerId()); zlmrtpServerFactory.stopSendRtpStream(mediaInfo, param); redisCatchStorage.deleteSendRTPServer(platformGbId, channelId, callIdHeader.getCallId(), null); int totalReaderCount = zlmrtpServerFactory.totalReaderCount(mediaInfo, sendRtpItem.getApp(), streamId); if (totalReaderCount <= 0) { - logger.info(streamId + "鏃犲叾瀹冭鐪嬭�咃紝閫氱煡璁惧鍋滄鎺ㄦ祦"); - cmder.streamByeCmd(sendRtpItem.getDeviceId(), channelId, streamId); + logger.info("鏀跺埌bye: {}鏃犲叾瀹冭鐪嬭�咃紝閫氱煡璁惧鍋滄鎺ㄦ祦", streamId); + if (sendRtpItem.isPlay()) { + cmder.streamByeCmd(sendRtpItem.getDeviceId(), channelId, streamId, null); + } } } // 鍙兘鏄澶囦富鍔ㄥ仠姝� diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/InviteRequestProcessor.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/InviteRequestProcessor.java index f82f781..fef3412 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/InviteRequestProcessor.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/InviteRequestProcessor.java @@ -6,6 +6,7 @@ import com.genersoft.iot.vmp.conf.DynamicTask; import com.genersoft.iot.vmp.gb28181.bean.*; import com.genersoft.iot.vmp.gb28181.event.SipSubscribe; +import com.genersoft.iot.vmp.gb28181.session.VideoStreamSessionManager; import com.genersoft.iot.vmp.gb28181.transmit.SIPProcessorObserver; import com.genersoft.iot.vmp.gb28181.transmit.callback.RequestMessage; import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommander; @@ -90,6 +91,9 @@ @Autowired private SIPProcessorObserver sipProcessorObserver; + + @Autowired + private VideoStreamSessionManager sessionManager; @Override @@ -233,6 +237,7 @@ } String username = sdp.getOrigin().getUsername(); String addressStr = sdp.getOrigin().getAddress(); + logger.info("[涓婄骇鐐规挱]鐢ㄦ埛锛歿}锛� 鍦板潃锛歿}:{}锛� ssrc锛歿}", username, addressStr, port, ssrc); Device device = null; // 閫氳繃 channel 鍜� gbStream 鏄惁涓簄ull 鍊煎垽鏂潵婧愭槸鐩存挱娴佸悎閫傚浗鏍� @@ -266,13 +271,14 @@ sendRtpItem.setDialog(dialogByteArray); byte[] transactionByteArray = SerializeUtils.serialize(evt.getServerTransaction()); sendRtpItem.setTransaction(transactionByteArray); - // 鍐欏叆redis锛� 瓒呮椂鏃跺洖澶� - redisCatchStorage.updateSendRTPSever(sendRtpItem); + Long finalStartTime = startTime; Long finalStopTime = stopTime; ZLMHttpHookSubscribe.Event hookEvent = (mediaServerItemInUSe, responseJSON)->{ - logger.info("[涓婄骇鐐规挱]涓嬬骇宸茬粡寮�濮嬫帹娴併�� 鍥炲200OK(SDP)锛� {}/{}", sendRtpItem.getApp(), sendRtpItem.getStreamId()); + String app = responseJSON.getString("app"); + String stream = responseJSON.getString("stream"); + logger.info("[涓婄骇鐐规挱]涓嬬骇宸茬粡寮�濮嬫帹娴併�� 鍥炲200OK(SDP)锛� {}/{}", app, stream); // * 0 绛夊緟璁惧鎺ㄦ祦涓婃潵 // * 1 涓嬬骇宸茬粡鎺ㄦ祦锛岀瓑寰呬笂绾у钩鍙板洖澶峚ck // * 2 鎺ㄦ祦涓� @@ -325,46 +331,66 @@ e.printStackTrace(); } }); + sendRtpItem.setApp("rtp"); if ("Playback".equals(sessionName)) { sendRtpItem.setPlay(false); - sendRtpItem.setStreamId(ssrc); + SSRCInfo ssrcInfo = mediaServerService.openRTPServer(mediaServerItem, null, true); + sendRtpItem.setStreamId(ssrcInfo.getStream()); + // 鍐欏叆redis锛� 瓒呮椂鏃跺洖澶� + redisCatchStorage.updateSendRTPSever(sendRtpItem); SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); - playService.playBack(device.getDeviceId(), channelId, format.format(start), format.format(end),result -> { - if (result.getCode() != 0){ - logger.warn("褰曞儚鍥炴斁澶辫触"); - if (result.getEvent() != null) { - errorEvent.response(result.getEvent()); + playService.playBack(mediaServerItem, ssrcInfo, device.getDeviceId(), channelId, format.format(start), + format.format(end), null, result -> { + if (result.getCode() != 0){ + logger.warn("褰曞儚鍥炴斁澶辫触"); + if (result.getEvent() != null) { + errorEvent.response(result.getEvent()); + } + redisCatchStorage.deleteSendRTPServer(platform.getServerGBId(), channelId, callIdHeader.getCallId(), null); + try { + responseAck(evt, Response.REQUEST_TIMEOUT); + } catch (SipException e) { + e.printStackTrace(); + } catch (InvalidArgumentException e) { + e.printStackTrace(); + } catch (ParseException e) { + e.printStackTrace(); + } + }else { + if (result.getMediaServerItem() != null) { + hookEvent.response(result.getMediaServerItem(), result.getResponse()); + } } - redisCatchStorage.deleteSendRTPServer(platform.getServerGBId(), channelId, callIdHeader.getCallId(), null); - try { - responseAck(evt, Response.REQUEST_TIMEOUT); - } catch (SipException e) { - e.printStackTrace(); - } catch (InvalidArgumentException e) { - e.printStackTrace(); - } catch (ParseException e) { - e.printStackTrace(); - } - }else { - if (result.getMediaServerItem() != null) { - hookEvent.response(result.getMediaServerItem(), result.getResponse()); - } - } - }); + }); }else { sendRtpItem.setPlay(true); - StreamInfo streamInfo = redisCatchStorage.queryPlayByDevice(device.getDeviceId(), channelId); - if (streamInfo == null) { + SsrcTransaction playTransaction = sessionManager.getSsrcTransaction(device.getDeviceId(), channelId, "play", null); + if (playTransaction != null) { + Boolean streamReady = zlmrtpServerFactory.isStreamReady(mediaServerItem, "rtp", playTransaction.getStream()); + if (!streamReady) { + playTransaction = null; + } + } + if (playTransaction == null) { + SSRCInfo ssrcInfo = mediaServerService.openRTPServer(mediaServerItem, null, true); if (mediaServerItem.isRtpEnable()) { sendRtpItem.setStreamId(String.format("%s_%s", device.getDeviceId(), channelId)); + }else { + sendRtpItem.setStreamId(ssrcInfo.getStream()); } - sendRtpItem.setPlay(false); - playService.play(mediaServerItem,device.getDeviceId(), channelId, hookEvent, errorEvent, ()->{ + // 鍐欏叆redis锛� 瓒呮椂鏃跺洖澶� + redisCatchStorage.updateSendRTPSever(sendRtpItem); + playService.play(mediaServerItem, ssrcInfo, device, channelId, hookEvent, errorEvent, (code, msg)->{ redisCatchStorage.deleteSendRTPServer(platform.getServerGBId(), channelId, callIdHeader.getCallId(), null); - }); + }, null); }else { - sendRtpItem.setStreamId(streamInfo.getStream()); - hookEvent.response(mediaServerItem, null); + sendRtpItem.setStreamId(playTransaction.getStream()); + // 鍐欏叆redis锛� 瓒呮椂鏃跺洖澶� + redisCatchStorage.updateSendRTPSever(sendRtpItem); + JSONObject jsonObject = new JSONObject(); + jsonObject.put("app", sendRtpItem.getApp()); + jsonObject.put("stream", sendRtpItem.getStreamId()); + hookEvent.response(mediaServerItem, jsonObject); } } }else if (gbStream != null) { diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/NotifyRequestProcessor.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/NotifyRequestProcessor.java index 6ae0f3e..3961eea 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/NotifyRequestProcessor.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/NotifyRequestProcessor.java @@ -233,7 +233,6 @@ */ private void processNotifyCatalogList(RequestEvent evt) { try { - System.out.println(343434); FromHeader fromHeader = (FromHeader) evt.getRequest().getHeader(FromHeader.NAME); String deviceId = SipUtils.getUserIdFromFromHeader(fromHeader); diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/SubscribeRequestProcessor.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/SubscribeRequestProcessor.java index e1e7125..4acec14 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/SubscribeRequestProcessor.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/SubscribeRequestProcessor.java @@ -158,20 +158,14 @@ String interval = XmlUtil.getText(rootElement, "Interval"); // GPS涓婃姤鏃堕棿闂撮殧 dynamicTask.startCron(key, new GPSSubscribeTask(redisCatchStorage, sipCommanderForPlatform, storager, platformId, sn, key, subscribeHolder), Integer.parseInt(interval)); subscribeHolder.putMobilePositionSubscribe(platformId, subscribeInfo); -// redisCatchStorage.updateSubscribe(key, subscribeInfo); }else if (subscribeInfo.getExpires() == 0) { dynamicTask.stop(key); -// redisCatchStorage.delSubscribe(key); subscribeHolder.removeMobilePositionSubscribe(platformId); } try { ParentPlatform parentPlatform = storager.queryParentPlatByServerGBId(platformId); - Response response = responseXmlAck(evt, resultXml.toString(), parentPlatform); - ToHeader toHeader = (ToHeader)response.getHeader(ToHeader.NAME); - subscribeInfo.setToTag(toHeader.getTag()); - redisCatchStorage.updateSubscribe(key, subscribeInfo); - + responseXmlAck(evt, resultXml.toString(), parentPlatform); } catch (SipException e) { e.printStackTrace(); } catch (InvalidArgumentException e) { @@ -211,21 +205,14 @@ .append("</Response>\r\n"); if (subscribeInfo.getExpires() > 0) { -// redisCatchStorage.updateSubscribe(key, subscribeInfo); subscribeHolder.putCatalogSubscribe(platformId, subscribeInfo); }else if (subscribeInfo.getExpires() == 0) { -// redisCatchStorage.delSubscribe(key); subscribeHolder.removeCatalogSubscribe(platformId); } try { ParentPlatform parentPlatform = storager.queryParentPlatByServerGBId(platformId); - Response response = responseXmlAck(evt, resultXml.toString(), parentPlatform); - ToHeader toHeader = (ToHeader)response.getHeader(ToHeader.NAME); - subscribeInfo.setToTag(toHeader.getTag()); -// redisCatchStorage.updateSubscribe(key, subscribeInfo); - subscribeHolder.putCatalogSubscribe(platformId, subscribeInfo); - + responseXmlAck(evt, resultXml.toString(), parentPlatform); } catch (SipException e) { e.printStackTrace(); } catch (InvalidArgumentException e) { diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/MessageRequestProcessor.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/MessageRequestProcessor.java index 5813998..e126fba 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/MessageRequestProcessor.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/MessageRequestProcessor.java @@ -67,9 +67,6 @@ // 鏌ヨ璁惧鏄惁瀛樺湪 CSeqHeader cseqHeader = (CSeqHeader) evt.getRequest().getHeader(CSeqHeader.NAME); String method = cseqHeader.getMethod(); - if (method.equals("MESSAGE")) { - System.out.println(); - } Device device = redisCatchStorage.getDevice(deviceId); // 鏌ヨ涓婄骇骞冲彴鏄惁瀛樺湪 ParentPlatform parentPlatform = storage.queryParentPlatByServerGBId(deviceId); diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/MediaStatusNotifyMessageHandler.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/MediaStatusNotifyMessageHandler.java index 3c83ec2..8235ade 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/MediaStatusNotifyMessageHandler.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/MediaStatusNotifyMessageHandler.java @@ -18,6 +18,7 @@ import javax.sip.InvalidArgumentException; import javax.sip.RequestEvent; import javax.sip.SipException; +import javax.sip.header.CallIdHeader; import javax.sip.message.Response; import java.text.ParseException; @@ -56,14 +57,15 @@ } catch (ParseException e) { e.printStackTrace(); } + CallIdHeader callIdHeader = (CallIdHeader)evt.getRequest().getHeader(CallIdHeader.NAME); String NotifyType =getText(rootElement, "NotifyType"); if (NotifyType.equals("121")){ logger.info("濯掍綋鎾斁瀹屾瘯锛岄�氱煡鍏虫祦"); - StreamInfo streamInfo = redisCatchStorage.queryPlaybackByDevice(device.getDeviceId(), "*"); - if (streamInfo != null) { - redisCatchStorage.stopPlayback(streamInfo); - cmder.streamByeCmd(streamInfo.getDeviceID(), streamInfo.getChannelId(), streamInfo.getStream()); - } + String channelId =getText(rootElement, "DeviceID"); + redisCatchStorage.stopPlayback(device.getDeviceId(), channelId, null, callIdHeader.getCallId()); + cmder.streamByeCmd(device.getDeviceId(), channelId, null, callIdHeader.getCallId()); + // TODO 濡傛灉绾ц仈鎾斁锛岄渶瑕佺粰涓婄骇鍙戦�佹閫氱煡 + } } diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/query/cmd/RecordInfoQueryMessageHandler.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/query/cmd/RecordInfoQueryMessageHandler.java index a273314..460f0f9 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/query/cmd/RecordInfoQueryMessageHandler.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/query/cmd/RecordInfoQueryMessageHandler.java @@ -88,7 +88,7 @@ Element secrecyElement = rootElement.element("Secrecy"); int secrecy = 0; if (secrecyElement != null) { - secrecy = Integer.parseInt(secrecyElement.getText()); + secrecy = Integer.parseInt(secrecyElement.getText().trim()); } String type = "all"; Element typeElement = rootElement.element("Type"); diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/response/impl/RegisterResponseProcessor.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/response/impl/RegisterResponseProcessor.java index ffac1d0..1cb1128 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/response/impl/RegisterResponseProcessor.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/response/impl/RegisterResponseProcessor.java @@ -2,6 +2,7 @@ import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform; import com.genersoft.iot.vmp.gb28181.bean.ParentPlatformCatch; +import com.genersoft.iot.vmp.gb28181.bean.SubscribeHolder; import com.genersoft.iot.vmp.gb28181.transmit.SIPProcessorObserver; import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform; import com.genersoft.iot.vmp.gb28181.transmit.event.response.SIPResponseProcessorAbstract; @@ -39,6 +40,9 @@ @Autowired private SIPProcessorObserver sipProcessorObserver; + + @Autowired + private SubscribeHolder subscribeHolder; @Override public void afterPropertiesSet() throws Exception { @@ -83,19 +87,19 @@ // 娉ㄥ唽/娉ㄩ攢鎴愬姛 logger.info(String.format("%s %s鎴愬姛", platformGBId, action)); redisCatchStorage.delPlatformRegisterInfo(callId); - parentPlatform.setStatus("娉ㄥ唽".equals(action)); + redisCatchStorage.delPlatformCatchInfo(platformGBId); // 鍙栧洖Expires璁剧疆锛岄伩鍏嶆敞閿�杩囩▼涓缃负0 - if (!parentPlatformCatch.getParentPlatform().getExpires().equals("0")) { - ParentPlatform parentPlatformTmp = storager.queryParentPlatByServerGBId(platformGBId); - String expires = parentPlatformTmp.getExpires(); - parentPlatform.setExpires(expires); - parentPlatform.setId(parentPlatformTmp.getId()); - redisCatchStorage.updatePlatformRegister(parentPlatform); - redisCatchStorage.updatePlatformKeepalive(parentPlatform); - parentPlatformCatch.setParentPlatform(parentPlatform); - redisCatchStorage.updatePlatformCatchInfo(parentPlatformCatch); - } + ParentPlatform parentPlatformTmp = storager.queryParentPlatByServerGBId(platformGBId); + parentPlatformTmp.setStatus("娉ㄥ唽".equals(action)); + redisCatchStorage.updatePlatformRegister(parentPlatformTmp); + redisCatchStorage.updatePlatformKeepalive(parentPlatformTmp); + parentPlatformCatch.setParentPlatform(parentPlatformTmp); + redisCatchStorage.updatePlatformCatchInfo(parentPlatformCatch); storager.updateParentPlatformStatus(platformGBId, "娉ㄥ唽".equals(action)); + if ("娉ㄩ攢".equals(action)) { + subscribeHolder.removeCatalogSubscribe(platformGBId); + subscribeHolder.removeMobilePositionSubscribe(platformGBId); + } } } diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java index d325075..a491387 100644 --- a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java +++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java @@ -9,9 +9,12 @@ import com.genersoft.iot.vmp.conf.MediaConfig; import com.genersoft.iot.vmp.conf.UserSetup; import com.genersoft.iot.vmp.gb28181.bean.Device; +import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel; import com.genersoft.iot.vmp.gb28181.bean.GbStream; +import com.genersoft.iot.vmp.gb28181.bean.SsrcTransaction; import com.genersoft.iot.vmp.gb28181.event.EventPublisher; import com.genersoft.iot.vmp.gb28181.event.subscribe.catalog.CatalogEvent; +import com.genersoft.iot.vmp.gb28181.session.VideoStreamSessionManager; import com.genersoft.iot.vmp.media.zlm.dto.*; import com.genersoft.iot.vmp.service.*; import com.genersoft.iot.vmp.service.bean.SSRCInfo; @@ -81,7 +84,7 @@ private UserSetup userSetup; @Autowired - private MediaConfig mediaConfig; + private VideoStreamSessionManager sessionManager; @Autowired private ZLMRESTfulUtils zlmresTfulUtils; @@ -207,15 +210,15 @@ }else { ret.put("enableMP4", userSetup.isRecordPushLive()); } - StreamInfo streamInfo = redisCatchStorage.queryPlaybackByStreamId(stream); - - // 褰曞儚鍥炴斁鏃朵笉杩涜褰曞儚涓嬭浇 - if (streamInfo != null) { - ret.put("enableMP4", false); - }else { - ret.put("enableMP4", userSetup.isRecordPushLive()); + List<SsrcTransaction> ssrcTransactionForAll = sessionManager.getSsrcTransactionForAll(null, null, null, stream); + if (ssrcTransactionForAll != null && ssrcTransactionForAll.size() == 1) { + String deviceId = ssrcTransactionForAll.get(0).getDeviceId(); + String channelId = ssrcTransactionForAll.get(0).getChannelId(); + DeviceChannel deviceChannel = storager.queryChannel(deviceId, channelId); + if (deviceChannel != null) { + ret.put("enable_audio", deviceChannel.isHasAudio()); + } } - return new ResponseEntity<String>(ret.toString(), HttpStatus.OK); } @@ -350,8 +353,12 @@ redisCatchStorage.stopPlay(streamInfo); storager.stopPlay(streamInfo.getDeviceID(), streamInfo.getChannelId()); }else{ - streamInfo = redisCatchStorage.queryPlaybackByStreamId(streamId); - redisCatchStorage.stopPlayback(streamInfo); + streamInfo = redisCatchStorage.queryPlayback(null, null, streamId, null); + if (streamInfo != null) { + redisCatchStorage.stopPlayback(streamInfo.getDeviceID(), streamInfo.getChannelId(), + streamInfo.getStream(), null); + } + } }else { if (!"rtp".equals(app)){ @@ -443,18 +450,19 @@ ret.put("close", false); } else { cmder.streamByeCmd(streamInfoForPlayCatch.getDeviceID(), streamInfoForPlayCatch.getChannelId(), - streamInfoForPlayCatch.getStream()); + streamInfoForPlayCatch.getStream(), null); redisCatchStorage.stopPlay(streamInfoForPlayCatch); storager.stopPlay(streamInfoForPlayCatch.getDeviceID(), streamInfoForPlayCatch.getChannelId()); } }else{ - StreamInfo streamInfoForPlayBackCatch = redisCatchStorage.queryPlaybackByStreamId(streamId); + StreamInfo streamInfoForPlayBackCatch = redisCatchStorage.queryPlayback(null, null, streamId, null); if (streamInfoForPlayBackCatch != null) { cmder.streamByeCmd(streamInfoForPlayBackCatch.getDeviceID(), - streamInfoForPlayBackCatch.getChannelId(), streamInfoForPlayBackCatch.getStream()); - redisCatchStorage.stopPlayback(streamInfoForPlayBackCatch); + streamInfoForPlayBackCatch.getChannelId(), streamInfoForPlayBackCatch.getStream(), null); + redisCatchStorage.stopPlayback(streamInfoForPlayBackCatch.getDeviceID(), + streamInfoForPlayBackCatch.getChannelId(), streamInfoForPlayBackCatch.getStream(), null); }else { - StreamInfo streamInfoForDownload = redisCatchStorage.queryDownloadByStreamId(streamId); + StreamInfo streamInfoForDownload = redisCatchStorage.queryDownload(null, null, streamId, null); // 杩涜褰曞儚涓嬭浇鏃舵棤浜鸿鐪嬩笉鏂祦 if (streamInfoForDownload != null) { ret.put("close", false); @@ -462,7 +470,7 @@ } } MediaServerItem mediaServerItem = mediaServerService.getOne(mediaServerId); - if (mediaServerItem != null && "-1".equals(mediaServerItem.getStreamNoneReaderDelayMS())) { + if (mediaServerItem != null && mediaServerItem.getStreamNoneReaderDelayMS() == -1) { ret.put("close", false); } return new ResponseEntity<String>(ret.toString(),HttpStatus.OK); diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRTPServerFactory.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRTPServerFactory.java index a0b7e75..5d1e8af 100644 --- a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRTPServerFactory.java +++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRTPServerFactory.java @@ -45,12 +45,8 @@ Map<String, Object> param = new HashMap<>(); int result = -1; - /** - * 涓嶈缃帹娴佺鍙g鍒欎娇鐢ㄩ殢鏈虹鍙� - */ - if (StringUtils.isEmpty(mediaServerItem.getSendRtpPortRange())){ - param.put("port", 0); - }else { + // 涓嶈缃帹娴佺鍙g鍒欎娇鐢ㄩ殢鏈虹鍙� + if (!StringUtils.isEmpty(mediaServerItem.getSendRtpPortRange())){ int newPort = getPortFromportRange(mediaServerItem); param.put("port", newPort); } diff --git a/src/main/java/com/genersoft/iot/vmp/service/IPlayService.java b/src/main/java/com/genersoft/iot/vmp/service/IPlayService.java index 80ededa..4cff4a6 100644 --- a/src/main/java/com/genersoft/iot/vmp/service/IPlayService.java +++ b/src/main/java/com/genersoft/iot/vmp/service/IPlayService.java @@ -2,10 +2,14 @@ import com.alibaba.fastjson.JSONObject; import com.genersoft.iot.vmp.gb28181.bean.Device; +import com.genersoft.iot.vmp.gb28181.bean.InviteStreamCallback; +import com.genersoft.iot.vmp.gb28181.bean.InviteStreamInfo; import com.genersoft.iot.vmp.gb28181.event.SipSubscribe; import com.genersoft.iot.vmp.media.zlm.ZLMHttpHookSubscribe; import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; +import com.genersoft.iot.vmp.service.bean.InviteTimeOutCallback; import com.genersoft.iot.vmp.service.bean.PlayBackCallback; +import com.genersoft.iot.vmp.service.bean.SSRCInfo; import com.genersoft.iot.vmp.vmanager.gb28181.play.bean.PlayResult; import org.springframework.http.ResponseEntity; import org.springframework.web.context.request.async.DeferredResult; @@ -17,13 +21,17 @@ void onPublishHandlerForPlay(MediaServerItem mediaServerItem, JSONObject resonse, String deviceId, String channelId, String uuid); + void play(MediaServerItem mediaServerItem, SSRCInfo ssrcInfo, Device device, String channelId, + ZLMHttpHookSubscribe.Event hookEvent, SipSubscribe.Event errorEvent, + InviteTimeOutCallback timeoutCallback, String uuid); PlayResult play(MediaServerItem mediaServerItem, String deviceId, String channelId, ZLMHttpHookSubscribe.Event event, SipSubscribe.Event errorEvent, Runnable timeoutCallback); MediaServerItem getNewMediaServerItem(Device device); - void onPublishHandlerForDownload(MediaServerItem mediaServerItem, JSONObject response, String deviceId, String channelId, String toString); + void onPublishHandlerForDownload(InviteStreamInfo inviteStreamInfo, String deviceId, String channelId, String toString); - DeferredResult<ResponseEntity<String>> playBack(String deviceId, String channelId, String startTime, String endTime, PlayBackCallback errorCallBack); + DeferredResult<ResponseEntity<String>> playBack(String deviceId, String channelId, String startTime, String endTime, InviteStreamCallback infoCallBack, PlayBackCallback hookCallBack); + DeferredResult<ResponseEntity<String>> playBack(MediaServerItem mediaServerItem, SSRCInfo ssrcInfo,String deviceId, String channelId, String startTime, String endTime, InviteStreamCallback infoCallBack, PlayBackCallback hookCallBack); void zlmServerOffline(String mediaServerId); } diff --git a/src/main/java/com/genersoft/iot/vmp/service/bean/InviteTimeOutCallback.java b/src/main/java/com/genersoft/iot/vmp/service/bean/InviteTimeOutCallback.java new file mode 100644 index 0000000..e30db5d --- /dev/null +++ b/src/main/java/com/genersoft/iot/vmp/service/bean/InviteTimeOutCallback.java @@ -0,0 +1,6 @@ +package com.genersoft.iot.vmp.service.bean; + +public interface InviteTimeOutCallback { + + void run(int code, String msg); // code: 0 sip瓒呮椂, 1 鏀舵祦瓒呮椂 +} diff --git a/src/main/java/com/genersoft/iot/vmp/service/bean/PlayBackResult.java b/src/main/java/com/genersoft/iot/vmp/service/bean/PlayBackResult.java index 10a2759..8029b5a 100644 --- a/src/main/java/com/genersoft/iot/vmp/service/bean/PlayBackResult.java +++ b/src/main/java/com/genersoft/iot/vmp/service/bean/PlayBackResult.java @@ -7,9 +7,9 @@ import javax.sip.RequestEvent; public class PlayBackResult<T> { - private int code; - private T data; - private MediaServerItem mediaServerItem; + private int code; + private T data; + private MediaServerItem mediaServerItem; private JSONObject response; private SipSubscribe.EventResult event; diff --git a/src/main/java/com/genersoft/iot/vmp/service/impl/MediaServerServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/service/impl/MediaServerServiceImpl.java index 4b44242..d369587 100644 --- a/src/main/java/com/genersoft/iot/vmp/service/impl/MediaServerServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/service/impl/MediaServerServiceImpl.java @@ -512,7 +512,7 @@ param.put("hook.on_stream_not_found",String.format("%s/on_stream_not_found", hookPrex)); param.put("hook.on_server_keepalive",String.format("%s/on_server_keepalive", hookPrex)); param.put("hook.timeoutSec","20"); - param.put("general.streamNoneReaderDelayMS","-1".equals(mediaServerItem.getStreamNoneReaderDelayMS())?"3600000":mediaServerItem.getStreamNoneReaderDelayMS() ); + param.put("general.streamNoneReaderDelayMS",mediaServerItem.getStreamNoneReaderDelayMS()==-1?"3600000":mediaServerItem.getStreamNoneReaderDelayMS() ); // 鎺ㄦ祦鏂紑鍚庡彲浠ュ湪瓒呮椂鏃堕棿鍐呴噸鏂拌繛鎺ヤ笂缁х画鎺ㄦ祦锛岃繖鏍锋挱鏀惧櫒浼氭帴鐫�鎾斁銆� // 缃�0鍏抽棴姝ょ壒鎬�(鎺ㄦ祦鏂紑浼氬鑷寸珛鍗虫柇寮�鎾斁鍣�) // 姝ゅ弬鏁颁笉搴斿ぇ浜庢挱鏀惧櫒瓒呮椂鏃堕棿 diff --git a/src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java index 2df78b7..9ee5867 100644 --- a/src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java @@ -16,6 +16,7 @@ import com.genersoft.iot.vmp.media.zlm.ZLMRESTfulUtils; import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; import com.genersoft.iot.vmp.service.IMediaServerService; +import com.genersoft.iot.vmp.service.bean.InviteTimeOutCallback; import com.genersoft.iot.vmp.service.bean.PlayBackCallback; import com.genersoft.iot.vmp.service.bean.PlayBackResult; import com.genersoft.iot.vmp.service.bean.SSRCInfo; @@ -27,6 +28,7 @@ import com.genersoft.iot.vmp.service.IMediaService; import com.genersoft.iot.vmp.service.IPlayService; import gov.nist.javax.sip.stack.SIPDialog; +import jdk.nashorn.internal.ir.RuntimeNode; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -36,6 +38,9 @@ import org.springframework.util.ResourceUtils; import org.springframework.web.context.request.async.DeferredResult; +import javax.sip.header.CallIdHeader; +import javax.sip.header.Header; +import javax.sip.message.Request; import java.io.FileNotFoundException; import java.util.*; @@ -77,6 +82,8 @@ @Autowired private UserSetup userSetup; + + @Override @@ -141,67 +148,7 @@ e.printStackTrace(); } }); - if (streamInfo == null) { - String streamId = null; - if (mediaServerItem.isRtpEnable()) { - streamId = String.format("%s_%s", device.getDeviceId(), channelId); - } - SSRCInfo ssrcInfo = mediaServerService.openRTPServer(mediaServerItem, streamId); - // 瓒呮椂澶勭悊 - Timer timer = new Timer(); - timer.schedule(new TimerTask() { - @Override - public void run() { - logger.warn(String.format("璁惧鐐规挱瓒呮椂锛宒eviceId锛�%s 锛宑hannelId锛�%s", deviceId, channelId)); - if (timeoutCallback != null) { - timeoutCallback.run(); - } - WVPResult wvpResult = new WVPResult(); - wvpResult.setCode(-1); - SIPDialog dialog = streamSession.getDialogByStream(deviceId, channelId, ssrcInfo.getStream()); - if (dialog != null) { - wvpResult.setMsg("鏀舵祦瓒呮椂锛岃绋嶅�欓噸璇�"); - // 鐐规挱瓒呮椂鍥炲BYE 鍚屾椂閲婃斁ssrc浠ュ強姝ゆ鐐规挱鐨勮祫婧� - cmder.streamByeCmd(device.getDeviceId(), channelId, ssrcInfo.getStream()); - }else { - wvpResult.setMsg("鐐规挱瓒呮椂锛岃绋嶅�欓噸璇�"); - mediaServerService.releaseSsrc(mediaServerItem.getId(), ssrcInfo.getSsrc()); - mediaServerService.closeRTPServer(deviceId, channelId, ssrcInfo.getStream()); - streamSession.remove(deviceId, channelId, ssrcInfo.getStream()); - } - - msg.setData(wvpResult); - - // 鍥炲涔嬪墠鎵�鏈夌殑鐐规挱璇锋眰 - resultHolder.invokeAllResult(msg); - } - }, userSetup.getPlayTimeout()); - // 鍙戦�佺偣鎾秷鎭� - cmder.playStreamCmd(mediaServerItem, ssrcInfo, device, channelId, (MediaServerItem mediaServerItemInUse, JSONObject response) -> { - logger.info("鏀跺埌璁㈤槄娑堟伅锛� " + response.toJSONString()); - timer.cancel(); - onPublishHandlerForPlay(mediaServerItemInUse, response, deviceId, channelId, uuid); - if (hookEvent != null) { - hookEvent.response(mediaServerItem, response); - } - }, (event) -> { - timer.cancel(); - WVPResult wvpResult = new WVPResult(); - wvpResult.setCode(-1); - // 鐐规挱杩斿洖sip閿欒 - mediaServerService.closeRTPServer(playResult.getDevice().getDeviceId(), channelId, ssrcInfo.getStream()); - // 閲婃斁ssrc - mediaServerService.releaseSsrc(mediaServerItem.getId(), ssrcInfo.getSsrc()); - streamSession.remove(deviceId, channelId, ssrcInfo.getStream()); - - wvpResult.setMsg(String.format("鐐规挱澶辫触锛� 閿欒鐮侊細 %s, %s", event.statusCode, event.msg)); - msg.setData(wvpResult); - resultHolder.invokeAllResult(msg); - if (errorEvent != null) { - errorEvent.response(event); - } - }); - } else { + if (streamInfo != null) { String streamId = streamInfo.getStream(); if (streamId == null) { WVPResult wvpResult = new WVPResult(); @@ -227,67 +174,109 @@ if (hookEvent != null) { hookEvent.response(mediaServerItem, JSONObject.parseObject(JSON.toJSONString(streamInfo))); } - } else { - // TODO 鐐规挱鍓嶆槸鍚﹂噸缃姸鎬� + }else { redisCatchStorage.stopPlay(streamInfo); storager.stopPlay(streamInfo.getDeviceID(), streamInfo.getChannelId()); - String streamId2 = null; - if (mediaServerItem.isRtpEnable()) { - streamId2 = String.format("%s_%s", device.getDeviceId(), channelId); - } - SSRCInfo ssrcInfo = mediaServerService.openRTPServer(mediaServerItem, streamId2); - // 瓒呮椂澶勭悊 - Timer timer = new Timer(); - timer.schedule(new TimerTask() { - @Override - public void run() { - logger.warn(String.format("璁惧鐐规挱瓒呮椂锛宒eviceId锛�%s 锛宑hannelId锛�%s", deviceId, channelId)); - if (timeoutCallback != null) { - timeoutCallback.run(); - } - WVPResult wvpResult = new WVPResult(); - wvpResult.setCode(-1); - SIPDialog dialog = streamSession.getDialogByStream(deviceId, channelId, ssrcInfo.getStream()); - if (dialog != null) { - wvpResult.setMsg("鏀舵祦瓒呮椂锛岃绋嶅�欓噸璇�"); - // 鐐规挱瓒呮椂鍥炲BYE 鍚屾椂閲婃斁ssrc浠ュ強姝ゆ鐐规挱鐨勮祫婧� - cmder.streamByeCmd(device.getDeviceId(), channelId, ssrcInfo.getStream()); - }else { - wvpResult.setMsg("鐐规挱瓒呮椂锛岃绋嶅�欓噸璇�"); - mediaServerService.releaseSsrc(mediaServerItem.getId(), ssrcInfo.getSsrc()); - mediaServerService.closeRTPServer(deviceId, channelId, ssrcInfo.getStream()); - streamSession.remove(deviceId, channelId, ssrcInfo.getStream()); - } - - msg.setData(wvpResult); - // 鍥炲涔嬪墠鎵�鏈夌殑鐐规挱璇锋眰 - resultHolder.invokeAllResult(msg); - } - }, userSetup.getPlayTimeout()); - cmder.playStreamCmd(mediaServerItem, ssrcInfo, device, channelId, (MediaServerItem mediaServerItemInuse, JSONObject response) -> { - logger.info("鏀跺埌璁㈤槄娑堟伅锛� " + response.toJSONString()); - onPublishHandlerForPlay(mediaServerItemInuse, response, deviceId, channelId, uuid); - }, (event) -> { - mediaServerService.closeRTPServer(playResult.getDevice().getDeviceId(), channelId, ssrcInfo.getStream()); - // 閲婃斁ssrc - mediaServerService.releaseSsrc(mediaServerItem.getId(), ssrcInfo.getSsrc()); - streamSession.remove(deviceId, channelId, ssrcInfo.getStream()); - WVPResult wvpResult = new WVPResult(); - wvpResult.setCode(-1); - wvpResult.setMsg(String.format("鐐规挱澶辫触锛� 閿欒鐮侊細 %s, %s", event.statusCode, event.msg)); - msg.setData(wvpResult); - resultHolder.invokeAllResult(msg); - }); + streamInfo = null; } + + } + if (streamInfo == null) { + String streamId = null; + if (mediaServerItem.isRtpEnable()) { + streamId = String.format("%s_%s", device.getDeviceId(), channelId); + } + SSRCInfo ssrcInfo = mediaServerService.openRTPServer(mediaServerItem, streamId); + play(mediaServerItem, ssrcInfo, device, channelId, (mediaServerItemInUse, response)->{ + if (hookEvent != null) { + hookEvent.response(mediaServerItem, response); + } + }, event -> { + // sip error閿欒 + WVPResult wvpResult = new WVPResult(); + wvpResult.setCode(-1); + wvpResult.setMsg(String.format("鐐规挱澶辫触锛� 閿欒鐮侊細 %s, %s", event.statusCode, event.msg)); + msg.setData(wvpResult); + resultHolder.invokeAllResult(msg); + if (errorEvent != null) { + errorEvent.response(event); + } + }, (code, msgStr)->{ + // invite鐐规挱瓒呮椂 + WVPResult wvpResult = new WVPResult(); + wvpResult.setCode(-1); + if (code == 0) { + wvpResult.setMsg("鐐规挱瓒呮椂锛岃绋嶅�欓噸璇�"); + }else if (code == 1) { + wvpResult.setMsg("鏀舵祦瓒呮椂锛岃绋嶅�欓噸璇�"); + } + msg.setData(wvpResult); + // 鍥炲涔嬪墠鎵�鏈夌殑鐐规挱璇锋眰 + resultHolder.invokeAllResult(msg); + }, uuid); + } + return playResult; + } + + + + @Override + public void play(MediaServerItem mediaServerItem, SSRCInfo ssrcInfo, Device device, String channelId, + ZLMHttpHookSubscribe.Event hookEvent, SipSubscribe.Event errorEvent, + InviteTimeOutCallback timeoutCallback, String uuid) { + + String streamId = null; + if (mediaServerItem.isRtpEnable()) { + streamId = String.format("%s_%s", device.getDeviceId(), channelId); + } + if (ssrcInfo == null) { + ssrcInfo = mediaServerService.openRTPServer(mediaServerItem, streamId); } - return playResult; + // 瓒呮椂澶勭悊 + Timer timer = new Timer(); + SSRCInfo finalSsrcInfo = ssrcInfo; + timer.schedule(new TimerTask() { + @Override + public void run() { + logger.warn(String.format("璁惧鐐规挱瓒呮椂锛宒eviceId锛�%s 锛宑hannelId锛�%s", device.getDeviceId(), channelId)); + + SIPDialog dialog = streamSession.getDialogByStream(device.getDeviceId(), channelId, finalSsrcInfo.getStream()); + if (dialog != null) { + timeoutCallback.run(1, "鏀舵祦瓒呮椂"); + // 鐐规挱瓒呮椂鍥炲BYE 鍚屾椂閲婃斁ssrc浠ュ強姝ゆ鐐规挱鐨勮祫婧� + cmder.streamByeCmd(device.getDeviceId(), channelId, finalSsrcInfo.getStream(), null); + }else { + timeoutCallback.run(0, "鐐规挱瓒呮椂"); + mediaServerService.releaseSsrc(mediaServerItem.getId(), finalSsrcInfo.getSsrc()); + mediaServerService.closeRTPServer(device.getDeviceId(), channelId, finalSsrcInfo.getStream()); + streamSession.remove(device.getDeviceId(), channelId, finalSsrcInfo.getStream()); + } + } + }, userSetup.getPlayTimeout()); + + cmder.playStreamCmd(mediaServerItem, ssrcInfo, device, channelId, (MediaServerItem mediaServerItemInuse, JSONObject response) -> { + logger.info("鏀跺埌璁㈤槄娑堟伅锛� " + response.toJSONString()); + timer.cancel(); + // hook鍝嶅簲 + onPublishHandlerForPlay(mediaServerItemInuse, response, device.getDeviceId(), channelId, uuid); + hookEvent.response(mediaServerItemInuse, response); + }, (event) -> { + timer.cancel(); + mediaServerService.closeRTPServer(device.getDeviceId(), channelId, finalSsrcInfo.getStream()); + // 閲婃斁ssrc + mediaServerService.releaseSsrc(mediaServerItem.getId(), finalSsrcInfo.getSsrc()); + streamSession.remove(device.getDeviceId(), channelId, finalSsrcInfo.getStream()); + errorEvent.response(event); + }); } @Override public void onPublishHandlerForPlay(MediaServerItem mediaServerItem, JSONObject response, String deviceId, String channelId, String uuid) { RequestMessage msg = new RequestMessage(); - msg.setId(uuid); + if (uuid != null) { + msg.setId(uuid); + } msg.setKey(DeferredResultHolder.CALLBACK_CMD_PLAY + deviceId + channelId); StreamInfo streamInfo = onPublishHandler(mediaServerItem, response, deviceId, channelId); if (streamInfo != null) { @@ -297,7 +286,6 @@ storager.startPlay(deviceId, channelId, streamInfo.getStream()); } redisCatchStorage.startPlay(streamInfo); - msg.setData(JSON.toJSONString(streamInfo)); WVPResult wvpResult = new WVPResult(); wvpResult.setCode(0); @@ -329,9 +317,24 @@ return mediaServerItem; } + @Override + public DeferredResult<ResponseEntity<String>> playBack(String deviceId, String channelId, String startTime, + String endTime,InviteStreamCallback inviteStreamCallback, + PlayBackCallback callback) { + Device device = storager.queryVideoDevice(deviceId); + if (device == null) return null; + MediaServerItem newMediaServerItem = getNewMediaServerItem(device); + SSRCInfo ssrcInfo = mediaServerService.openRTPServer(newMediaServerItem, null, true); + + return playBack(newMediaServerItem, ssrcInfo, deviceId, channelId, startTime, endTime, inviteStreamCallback, callback); + } @Override - public DeferredResult<ResponseEntity<String>> playBack(String deviceId, String channelId, String startTime, String endTime, PlayBackCallback callback) { + public DeferredResult<ResponseEntity<String>> playBack(MediaServerItem mediaServerItem, SSRCInfo ssrcInfo, + String deviceId, String channelId, String startTime, + String endTime, InviteStreamCallback infoCallBack, + PlayBackCallback playBackCallback) { + if (mediaServerItem == null || ssrcInfo == null) return null; String uuid = UUID.randomUUID().toString(); String key = DeferredResultHolder.CALLBACK_CMD_PLAYBACK + deviceId + channelId; DeferredResult<ResponseEntity<String>> result = new DeferredResult<>(30000L); @@ -341,8 +344,6 @@ return result; } - MediaServerItem newMediaServerItem = getNewMediaServerItem(device); - SSRCInfo ssrcInfo = mediaServerService.openRTPServer(newMediaServerItem, null, true); resultHolder.put(DeferredResultHolder.CALLBACK_CMD_PLAY + deviceId + channelId, uuid, result); RequestMessage msg = new RequestMessage(); msg.setId(uuid); @@ -356,63 +357,62 @@ logger.warn(String.format("璁惧鍥炴斁瓒呮椂锛宒eviceId锛�%s 锛宑hannelId锛�%s", deviceId, channelId)); playBackResult.setCode(-1); playBackResult.setData(msg); - callback.call(playBackResult); + playBackCallback.call(playBackResult); SIPDialog dialog = streamSession.getDialogByStream(deviceId, channelId, ssrcInfo.getStream()); // 鐐规挱瓒呮椂鍥炲BYE 鍚屾椂閲婃斁ssrc浠ュ強姝ゆ鐐规挱鐨勮祫婧� if (dialog != null) { // 鐐规挱瓒呮椂鍥炲BYE 鍚屾椂閲婃斁ssrc浠ュ強姝ゆ鐐规挱鐨勮祫婧� - cmder.streamByeCmd(device.getDeviceId(), channelId, ssrcInfo.getStream()); + cmder.streamByeCmd(device.getDeviceId(), channelId, ssrcInfo.getStream(), null); }else { - mediaServerService.releaseSsrc(newMediaServerItem.getId(), ssrcInfo.getSsrc()); + mediaServerService.releaseSsrc(mediaServerItem.getId(), ssrcInfo.getSsrc()); mediaServerService.closeRTPServer(deviceId, channelId, ssrcInfo.getStream()); streamSession.remove(deviceId, channelId, ssrcInfo.getStream()); } - cmder.streamByeCmd(device.getDeviceId(), channelId, ssrcInfo.getStream()); + cmder.streamByeCmd(device.getDeviceId(), channelId, ssrcInfo.getStream(), null); // 鍥炲涔嬪墠鎵�鏈夌殑鐐规挱璇锋眰 - callback.call(playBackResult); + playBackCallback.call(playBackResult); } }, userSetup.getPlayTimeout()); - cmder.playbackStreamCmd(newMediaServerItem, ssrcInfo, device, channelId, startTime, endTime, (MediaServerItem mediaServerItem, JSONObject response) -> { - logger.info("鏀跺埌璁㈤槄娑堟伅锛� " + response.toJSONString()); - timer.cancel(); - StreamInfo streamInfo = onPublishHandler(mediaServerItem, response, deviceId, channelId); - if (streamInfo == null) { - logger.warn("璁惧鍥炴斁API璋冪敤澶辫触锛�"); - msg.setData("璁惧鍥炴斁API璋冪敤澶辫触锛�"); - playBackResult.setCode(-1); - playBackResult.setData(msg); - callback.call(playBackResult); - return; - } - redisCatchStorage.startPlayback(streamInfo); - msg.setData(JSON.toJSONString(streamInfo)); - playBackResult.setCode(0); - playBackResult.setData(msg); - playBackResult.setMediaServerItem(mediaServerItem); - playBackResult.setResponse(response); - callback.call(playBackResult); - }, event -> { - timer.cancel(); - msg.setData(String.format("鍥炴斁澶辫触锛� 閿欒鐮侊細 %s, %s", event.statusCode, event.msg)); - playBackResult.setCode(-1); - playBackResult.setData(msg); - playBackResult.setEvent(event); - callback.call(playBackResult); - streamSession.remove(device.getDeviceId(), channelId, ssrcInfo.getStream()); - }); + cmder.playbackStreamCmd(mediaServerItem, ssrcInfo, device, channelId, startTime, endTime, infoCallBack, + (InviteStreamInfo inviteStreamInfo) -> { + logger.info("鏀跺埌璁㈤槄娑堟伅锛� " + inviteStreamInfo.getResponse().toJSONString()); + timer.cancel(); + StreamInfo streamInfo = onPublishHandler(inviteStreamInfo.getMediaServerItem(), inviteStreamInfo.getResponse(), deviceId, channelId); + if (streamInfo == null) { + logger.warn("璁惧鍥炴斁API璋冪敤澶辫触锛�"); + msg.setData("璁惧鍥炴斁API璋冪敤澶辫触锛�"); + playBackResult.setCode(-1); + playBackResult.setData(msg); + playBackCallback.call(playBackResult); + return; + } + redisCatchStorage.startPlayback(streamInfo, inviteStreamInfo.getCallId()); + msg.setData(JSON.toJSONString(streamInfo)); + playBackResult.setCode(0); + playBackResult.setData(msg); + playBackResult.setMediaServerItem(inviteStreamInfo.getMediaServerItem()); + playBackResult.setResponse(inviteStreamInfo.getResponse()); + playBackCallback.call(playBackResult); + }, event -> { + timer.cancel(); + msg.setData(String.format("鍥炴斁澶辫触锛� 閿欒鐮侊細 %s, %s", event.statusCode, event.msg)); + playBackResult.setCode(-1); + playBackResult.setData(msg); + playBackResult.setEvent(event); + playBackCallback.call(playBackResult); + streamSession.remove(device.getDeviceId(), channelId, ssrcInfo.getStream()); + }); return result; } - - @Override - public void onPublishHandlerForDownload(MediaServerItem mediaServerItem, JSONObject response, String deviceId, String channelId, String uuid) { + public void onPublishHandlerForDownload(InviteStreamInfo inviteStreamInfo, String deviceId, String channelId, String uuid) { RequestMessage msg = new RequestMessage(); msg.setKey(DeferredResultHolder.CALLBACK_CMD_DOWNLOAD + deviceId + channelId); msg.setId(uuid); - StreamInfo streamInfo = onPublishHandler(mediaServerItem, response, deviceId, channelId); + StreamInfo streamInfo = onPublishHandler(inviteStreamInfo.getMediaServerItem(), inviteStreamInfo.getResponse(), deviceId, channelId); if (streamInfo != null) { - redisCatchStorage.startDownload(streamInfo); + redisCatchStorage.startDownload(streamInfo, inviteStreamInfo.getCallId()); msg.setData(JSON.toJSONString(streamInfo)); resultHolder.invokeResult(msg); } else { @@ -449,7 +449,8 @@ if (allSsrc.size() > 0) { for (SsrcTransaction ssrcTransaction : allSsrc) { if(ssrcTransaction.getMediaServerId().equals(mediaServerId)) { - cmder.streamByeCmd(ssrcTransaction.getDeviceId(), ssrcTransaction.getChannelId(), ssrcTransaction.getStream()); + cmder.streamByeCmd(ssrcTransaction.getDeviceId(), ssrcTransaction.getChannelId(), + ssrcTransaction.getStream(), null); } } } diff --git a/src/main/java/com/genersoft/iot/vmp/storager/IRedisCatchStorage.java b/src/main/java/com/genersoft/iot/vmp/storager/IRedisCatchStorage.java index b0edc06..5094853 100644 --- a/src/main/java/com/genersoft/iot/vmp/storager/IRedisCatchStorage.java +++ b/src/main/java/com/genersoft/iot/vmp/storager/IRedisCatchStorage.java @@ -47,17 +47,15 @@ StreamInfo queryPlayByStreamId(String steamId); - StreamInfo queryPlaybackByStreamId(String steamId); - StreamInfo queryPlayByDevice(String deviceId, String channelId); Map<String, StreamInfo> queryPlayByDeviceId(String deviceId); - boolean startPlayback(StreamInfo stream); + boolean startPlayback(StreamInfo stream, String callId); - boolean stopPlayback(StreamInfo streamInfo); + boolean stopPlayback(String deviceId, String channelId, String stream, String callId); - StreamInfo queryPlaybackByDevice(String deviceId, String code); + StreamInfo queryPlayback(String deviceId, String channelID, String stream, String callId); void updatePlatformCatchInfo(ParentPlatformCatch parentPlatformCatch); @@ -167,9 +165,9 @@ * 寮�濮嬩笅杞藉綍鍍忔椂瀛樺叆 * @param streamInfo */ - boolean startDownload(StreamInfo streamInfo); + boolean startDownload(StreamInfo streamInfo, String callId); - StreamInfo queryDownloadByStreamId(String streamId); + StreamInfo queryDownload(String deviceId, String channelId, String stream, String callId); /** * 鏌ユ壘绗笁鏂圭郴缁熺暀涓嬬殑鍥芥爣棰勮鍊� @@ -204,17 +202,7 @@ void resetAllSN(); - void updateSubscribe(String key, SubscribeInfo subscribeInfo); - - SubscribeInfo getSubscribe(String key); - - void delSubscribe(String key); - MediaItem getStreamInfo(String app, String streamId, String mediaServerId); - - List<SubscribeInfo> getAllSubscribe(); - - List<String> getAllSubscribePlatform(); void addCpuInfo(double cpuInfo); diff --git a/src/main/java/com/genersoft/iot/vmp/storager/dao/DeviceChannelMapper.java b/src/main/java/com/genersoft/iot/vmp/storager/dao/DeviceChannelMapper.java index 2431699..e4fc1eb 100644 --- a/src/main/java/com/genersoft/iot/vmp/storager/dao/DeviceChannelMapper.java +++ b/src/main/java/com/genersoft/iot/vmp/storager/dao/DeviceChannelMapper.java @@ -231,7 +231,6 @@ " name as title,\n" + " channelId as \"value\",\n" + " channelId as \"key\",\n" + - " channelId,\n" + " longitude,\n" + " latitude\n" + " from device_channel\n" + @@ -248,4 +247,13 @@ "<foreach collection='channels' item='item' open='(' separator=',' close=')' > #{item.channelId}</foreach>" + " </script>"}) int cleanChannelsNotInList(String deviceId, List<DeviceChannel> channels); + + @Update(" update device_channel" + + " set subCount = (select *" + + " from (select count(0)" + + " from device_channel" + + " where deviceId = #{deviceId} and parentId = #{channelId}) as temp)" + + " where deviceId = #{deviceId} " + + " and channelId = #{channelId}") + int updateChannelSubCount(String deviceId, String channelId); } diff --git a/src/main/java/com/genersoft/iot/vmp/storager/dao/PlatformChannelMapper.java b/src/main/java/com/genersoft/iot/vmp/storager/dao/PlatformChannelMapper.java index f1d23f1..e048f31 100644 --- a/src/main/java/com/genersoft/iot/vmp/storager/dao/PlatformChannelMapper.java +++ b/src/main/java/com/genersoft/iot/vmp/storager/dao/PlatformChannelMapper.java @@ -55,7 +55,7 @@ int cleanChannelForGB(String platformId); @Select("SELECT dc.* FROM platform_gb_channel pgc left join device_channel dc on dc.id = pgc.deviceChannelId WHERE dc.channelId='${channelId}' and pgc.platformId='${platformId}'") - DeviceChannel queryChannelInParentPlatform(String platformId, String channelId); + List<DeviceChannel> queryChannelInParentPlatform(String platformId, String channelId); @Select(" select dc.channelId as id, dc.name as name, pgc.platformId as platformId, pgc.catalogId as parentId, 0 as childrenCount, 1 as type " + " from device_channel dc left join platform_gb_channel pgc on dc.id = pgc.deviceChannelId " + @@ -67,7 +67,7 @@ " left join device_channel dc on dc.id = pgc.deviceChannelId\n" + " left join device d on dc.deviceId = d.deviceId\n" + "where dc.channelId = #{channelId} and pgc.platformId=#{platformId}") - Device queryVideoDeviceByPlatformIdAndChannelId(String platformId, String channelId); + List<Device> queryVideoDeviceByPlatformIdAndChannelId(String platformId, String channelId); @Delete("<script> "+ "DELETE FROM platform_gb_channel WHERE catalogId=#{id}" + diff --git a/src/main/java/com/genersoft/iot/vmp/storager/impl/RedisCatchStorageImpl.java b/src/main/java/com/genersoft/iot/vmp/storager/impl/RedisCatchStorageImpl.java index 0641348..6ad654e 100644 --- a/src/main/java/com/genersoft/iot/vmp/storager/impl/RedisCatchStorageImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/storager/impl/RedisCatchStorageImpl.java @@ -134,13 +134,6 @@ } @Override - public StreamInfo queryPlaybackByStreamId(String streamId) { - List<Object> playLeys = redis.scan(String.format("%S_%s_%s_*", VideoManagerConstants.PLAY_BLACK_PREFIX, userSetup.getServerId(), streamId)); - if (playLeys == null || playLeys.size() == 0) return null; - return (StreamInfo)redis.get(playLeys.get(0).toString()); - } - - @Override public StreamInfo queryPlayByDevice(String deviceId, String channelId) { List<Object> playLeys = redis.scan(String.format("%S_%s_*_%s_%s", VideoManagerConstants.PLAYER_PREFIX, userSetup.getServerId(), @@ -166,49 +159,67 @@ @Override - public boolean startPlayback(StreamInfo stream) { - return redis.set(String.format("%S_%s_%s_%s_%s", VideoManagerConstants.PLAY_BLACK_PREFIX, - userSetup.getServerId(), stream.getStream(), stream.getDeviceID(), stream.getChannelId()), stream); + public boolean startPlayback(StreamInfo stream, String callId) { + return redis.set(String.format("%S_%s_%s_%s_%s_%s", VideoManagerConstants.PLAY_BLACK_PREFIX, + userSetup.getServerId(), stream.getDeviceID(), stream.getChannelId(), stream.getStream(), callId), stream); } @Override - public boolean startDownload(StreamInfo streamInfo) { - return redis.set(String.format("%S_%s_%s_%s_%s", VideoManagerConstants.DOWNLOAD_PREFIX, userSetup.getServerId(), - streamInfo.getStream(), streamInfo.getDeviceID(), streamInfo.getChannelId()), streamInfo); + public boolean startDownload(StreamInfo stream, String callId) { + return redis.set(String.format("%S_%s_%s_%s_%s_%s", VideoManagerConstants.DOWNLOAD_PREFIX, + userSetup.getServerId(), stream.getDeviceID(), stream.getChannelId(), stream.getStream(), callId), stream); } @Override - public boolean stopPlayback(StreamInfo streamInfo) { - if (streamInfo == null) return false; - DeviceChannel deviceChannel = deviceChannelMapper.queryChannel(streamInfo.getDeviceID(), streamInfo.getChannelId()); + public boolean stopPlayback(String deviceId, String channelId, String stream, String callId) { + DeviceChannel deviceChannel = deviceChannelMapper.queryChannel(deviceId, channelId); if (deviceChannel != null) { deviceChannel.setStreamId(null); - deviceChannel.setDeviceId(streamInfo.getDeviceID()); + deviceChannel.setDeviceId(deviceId); deviceChannelMapper.update(deviceChannel); } - return redis.del(String.format("%S_%s_%s_%s_%s", VideoManagerConstants.PLAY_BLACK_PREFIX, + if (deviceId == null) deviceId = "*"; + if (channelId == null) channelId = "*"; + if (stream == null) stream = "*"; + if (callId == null) callId = "*"; + String key = String.format("%S_%s_%s_%s_%s_%s", VideoManagerConstants.PLAY_BLACK_PREFIX, userSetup.getServerId(), - streamInfo.getStream(), - streamInfo.getDeviceID(), - streamInfo.getChannelId())); + deviceId, + channelId, + stream, + callId + ); + List<Object> scan = redis.scan(key); + if (scan.size() > 0) { + for (Object keyObj : scan) { + redis.del((String) keyObj); + } + } + return true; } @Override - public StreamInfo queryPlaybackByDevice(String deviceId, String code) { - // String format = String.format("%S_*_%s_%s", VideoManagerConstants.PLAY_BLACK_PREFIX, - // deviceId, - // code); - List<Object> playLeys = redis.scan(String.format("%S_%s_*_%s_%s", VideoManagerConstants.PLAY_BLACK_PREFIX, + public StreamInfo queryPlayback(String deviceId, String channelId, String stream, String callId) { + if (stream == null && callId == null) { + return null; + } + if (deviceId == null) deviceId = "*"; + if (channelId == null) channelId = "*"; + if (stream == null) stream = "*"; + if (callId == null) callId = "*"; + String key = String.format("%S_%s_%s_%s_%s_%s", VideoManagerConstants.PLAY_BLACK_PREFIX, userSetup.getServerId(), deviceId, - code)); - if (playLeys == null || playLeys.size() == 0) { - playLeys = redis.scan(String.format("%S_%s_*_*_%s", VideoManagerConstants.PLAY_BLACK_PREFIX, - userSetup.getServerId(), - deviceId)); + channelId, + stream, + callId + ); + List<Object> streamInfoScan = redis.scan(key); + if (streamInfoScan.size() > 0) { + return (StreamInfo) redis.get((String) streamInfoScan.get(0)); + }else { + return null; } - if (playLeys == null || playLeys.size() == 0) return null; - return (StreamInfo)redis.get(playLeys.get(0).toString()); } @Override @@ -361,7 +372,7 @@ } } - List<Object> playBackers = redis.scan(String.format("%S_%s_*_%s_*", VideoManagerConstants.PLAY_BLACK_PREFIX, + List<Object> playBackers = redis.scan(String.format("%S_%s_%s_*_*_*", VideoManagerConstants.PLAY_BLACK_PREFIX, userSetup.getServerId(), deviceId)); if (playBackers.size() > 0) { @@ -426,10 +437,27 @@ } @Override - public StreamInfo queryDownloadByStreamId(String streamId) { - List<Object> playLeys = redis.scan(String.format("%S_%s_%s_*", VideoManagerConstants.DOWNLOAD_PREFIX, userSetup.getServerId(), streamId)); - if (playLeys == null || playLeys.size() == 0) return null; - return (StreamInfo)redis.get(playLeys.get(0).toString()); + public StreamInfo queryDownload(String deviceId, String channelId, String stream, String callId) { + if (stream == null && callId == null) { + return null; + } + if (deviceId == null) deviceId = "*"; + if (channelId == null) channelId = "*"; + if (stream == null) stream = "*"; + if (callId == null) callId = "*"; + String key = String.format("%S_%s_%s_%s_%s_%s", VideoManagerConstants.DOWNLOAD_PREFIX, + userSetup.getServerId(), + deviceId, + channelId, + stream, + callId + ); + List<Object> streamInfoScan = redis.scan(key); + if (streamInfoScan.size() > 0) { + return (StreamInfo) redis.get((String) streamInfoScan.get(0)); + }else { + return null; + } } @Override @@ -491,21 +519,6 @@ } @Override - public void updateSubscribe(String key, SubscribeInfo subscribeInfo) { - redis.set(key, subscribeInfo, subscribeInfo.getExpires()); - } - - @Override - public SubscribeInfo getSubscribe(String key) { - return (SubscribeInfo)redis.get(key); - } - - @Override - public void delSubscribe(String key) { - redis.del(key); - } - - @Override public List<GPSMsgInfo> getAllGpsMsgInfo() { String scanKey = VideoManagerConstants.WVP_STREAM_GPS_MSG_PREFIX + userSetup.getServerId() + "_*"; List<GPSMsgInfo> result = new ArrayList<>(); @@ -532,32 +545,6 @@ result = (MediaItem)redis.get(key); } - return result; - } - - @Override - public List<SubscribeInfo> getAllSubscribe() { - String scanKey = VideoManagerConstants.SIP_SUBSCRIBE_PREFIX + userSetup.getServerId() + "_Catalog_*"; - List<SubscribeInfo> result = new ArrayList<>(); - List<Object> keys = redis.scan(scanKey); - for (int i = 0; i < keys.size(); i++) { - String key = (String) keys.get(i); - SubscribeInfo subscribeInfo = (SubscribeInfo) redis.get(key); - result.add(subscribeInfo); - } - return result; - } - - @Override - public List<String> getAllSubscribePlatform() { - String scanKey = VideoManagerConstants.SIP_SUBSCRIBE_PREFIX + userSetup.getServerId() + "_Catalog_*"; - List<String> result = new ArrayList<>(); - List<Object> keys = redis.scan(scanKey); - for (int i = 0; i < keys.size(); i++) { - String key = (String) keys.get(i); - String platformId = key.substring(scanKey.length() - 1); - result.add(platformId); - } return result; } diff --git a/src/main/java/com/genersoft/iot/vmp/storager/impl/VideoManagerStoragerImpl.java b/src/main/java/com/genersoft/iot/vmp/storager/impl/VideoManagerStoragerImpl.java index 0cba4b0..bb265a5 100644 --- a/src/main/java/com/genersoft/iot/vmp/storager/impl/VideoManagerStoragerImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/storager/impl/VideoManagerStoragerImpl.java @@ -42,7 +42,7 @@ @Component public class VideoManagerStoragerImpl implements IVideoManagerStorager { - private Logger logger = LoggerFactory.getLogger(VideoManagerStoragerImpl.class); + private final Logger logger = LoggerFactory.getLogger(VideoManagerStoragerImpl.class); @Autowired EventPublisher eventPublisher; @@ -171,6 +171,7 @@ }else { deviceChannelMapper.update(channel); } + deviceChannelMapper.updateChannelSubCount(deviceId,channel.getParentId()); } @Override @@ -542,7 +543,7 @@ if (parentPlatformCatch == null) { // serverGBId 宸插彉鍖� ParentPlatform parentPlatById = platformMapper.getParentPlatById(parentPlatform.getId()); // 浣跨敤鏃х殑鏌ュ嚭缂撳瓨ID - parentPlatformCatch = redisCatchStorage.queryPlatformCatchInfo(parentPlatById.getServerGBId()); + parentPlatformCatch = new ParentPlatformCatch(); parentPlatformCatch.setId(parentPlatform.getServerGBId()); redisCatchStorage.delPlatformCatchInfo(parentPlatById.getServerGBId()); } @@ -662,8 +663,16 @@ @Override public DeviceChannel queryChannelInParentPlatform(String platformId, String channelId) { - DeviceChannel channel = platformChannelMapper.queryChannelInParentPlatform(platformId, channelId); - return channel; + List<DeviceChannel> channels = platformChannelMapper.queryChannelInParentPlatform(platformId, channelId); + if (channels.size() > 1) { + // 鍑虹幇闀垮害澶т簬0鐨勬椂鍊欒偗瀹氭槸鍥芥爣閫氶亾鐨処D閲嶅浜� + logger.warn("鍥芥爣ID瀛樺湪閲嶅锛歿}", channelId); + } + if (channels.size() == 0) { + return null; + }else { + return channels.get(0); + } } @Override @@ -680,8 +689,18 @@ @Override public Device queryVideoDeviceByPlatformIdAndChannelId(String platformId, String channelId) { - Device device = platformChannelMapper.queryVideoDeviceByPlatformIdAndChannelId(platformId, channelId); - return device; + List<Device> devices = platformChannelMapper.queryVideoDeviceByPlatformIdAndChannelId(platformId, channelId); + if (devices.size() > 1) { + // 鍑虹幇闀垮害澶т簬0鐨勬椂鍊欒偗瀹氭槸鍥芥爣閫氶亾鐨処D閲嶅浜� + logger.warn("鍥芥爣ID瀛樺湪閲嶅锛歿}", channelId); + } + if (devices.size() == 0) { + return null; + }else { + return devices.get(0); + } + + } /** @@ -1083,6 +1102,9 @@ @Override public List<ParentPlatform> queryPlatFormListForStreamWithGBId(String app, String stream, List<String> platforms) { + if (platforms == null || platforms.size() == 0) { + return new ArrayList<>(); + } return platformGbStreamMapper.queryPlatFormListForGBWithGBId(app, stream, platforms); } diff --git a/src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/platform/PlatformController.java b/src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/platform/PlatformController.java index 4f4d800..c3435fd 100644 --- a/src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/platform/PlatformController.java +++ b/src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/platform/PlatformController.java @@ -7,6 +7,7 @@ import com.genersoft.iot.vmp.conf.UserSetup; import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform; import com.genersoft.iot.vmp.gb28181.bean.PlatformCatalog; +import com.genersoft.iot.vmp.gb28181.bean.SubscribeHolder; import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform; import com.genersoft.iot.vmp.storager.IRedisCatchStorage; import com.genersoft.iot.vmp.storager.IVideoManagerStorager; @@ -48,6 +49,9 @@ @Autowired private IRedisCatchStorage redisCatchStorage; + + @Autowired + private SubscribeHolder subscribeHolder; @Autowired private ISIPCommanderForPlatform commanderForPlatform; @@ -110,10 +114,14 @@ }) public PageInfo<ParentPlatform> platforms(@PathVariable int page, @PathVariable int count) { -// if (logger.isDebugEnabled()) { -// logger.debug("鏌ヨ鎵�鏈変笂绾ц澶嘇PI璋冪敤"); -// } - return storager.queryParentPlatformList(page, count); + PageInfo<ParentPlatform> parentPlatformPageInfo = storager.queryParentPlatformList(page, count); + if (parentPlatformPageInfo.getList().size() > 0) { + for (ParentPlatform platform : parentPlatformPageInfo.getList()) { + platform.setGpsSubscribe(subscribeHolder.getMobilePositionSubscribe(platform.getServerGBId()) != null); + platform.setCatalogSubscribe(subscribeHolder.getCatalogSubscribe(platform.getServerGBId()) != null); + } + } + return parentPlatformPageInfo; } /** diff --git a/src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/play/PlayController.java b/src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/play/PlayController.java index 4a22546..16e8eec 100644 --- a/src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/play/PlayController.java +++ b/src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/play/PlayController.java @@ -120,7 +120,7 @@ storager.stopPlay(deviceId, channelId); return result; } - cmder.streamByeCmd(deviceId, channelId, streamInfo.getStream(), (event) -> { + cmder.streamByeCmd(deviceId, channelId, streamInfo.getStream(), null, (event) -> { redisCatchStorage.stopPlay(streamInfo); storager.stopPlay(streamInfo.getDeviceID(), streamInfo.getChannelId()); RequestMessage msg = new RequestMessage(); @@ -174,7 +174,7 @@ public ResponseEntity<String> playConvert(@PathVariable String streamId) { StreamInfo streamInfo = redisCatchStorage.queryPlayByStreamId(streamId); if (streamInfo == null) { - streamInfo = redisCatchStorage.queryPlaybackByStreamId(streamId); + streamInfo = redisCatchStorage.queryPlayback(null, null, streamId, null); } if (streamInfo == null) { logger.warn("瑙嗛杞爜API璋冪敤澶辫触锛�, 瑙嗛娴佸凡缁忓仠姝�!"); diff --git a/src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/playback/DownloadController.java b/src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/playback/DownloadController.java index c2053e6..4ffbd4b 100644 --- a/src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/playback/DownloadController.java +++ b/src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/playback/DownloadController.java @@ -1,6 +1,7 @@ package com.genersoft.iot.vmp.vmanager.gb28181.playback; import com.genersoft.iot.vmp.common.StreamInfo; +import com.genersoft.iot.vmp.gb28181.bean.InviteStreamInfo; import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder; import com.genersoft.iot.vmp.gb28181.transmit.callback.RequestMessage; import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; @@ -93,11 +94,6 @@ } resultHolder.put(key, uuid, result); Device device = storager.queryVideoDevice(deviceId); - StreamInfo streamInfo = redisCatchStorage.queryPlaybackByDevice(deviceId, channelId); - if (streamInfo != null) { - // 鍋滄涔嬪墠鐨勪笅杞� - cmder.streamByeCmd(deviceId, channelId, streamInfo.getStream()); - } MediaServerItem newMediaServerItem = playService.getNewMediaServerItem(device); if (newMediaServerItem == null) { @@ -112,9 +108,9 @@ SSRCInfo ssrcInfo = mediaServerService.openRTPServer(newMediaServerItem, null, true); - cmder.downloadStreamCmd(newMediaServerItem, ssrcInfo, device, channelId, startTime, endTime, downloadSpeed, (MediaServerItem mediaServerItem, JSONObject response) -> { - logger.info("鏀跺埌璁㈤槄娑堟伅锛� " + response.toJSONString()); - playService.onPublishHandlerForDownload(mediaServerItem, response, deviceId, channelId, uuid); + cmder.downloadStreamCmd(newMediaServerItem, ssrcInfo, device, channelId, startTime, endTime, downloadSpeed, (InviteStreamInfo inviteStreamInfo) -> { + logger.info("鏀跺埌璁㈤槄娑堟伅锛� " + inviteStreamInfo.getResponse().toJSONString()); + playService.onPublishHandlerForDownload(inviteStreamInfo, deviceId, channelId, uuid); }, event -> { RequestMessage msg = new RequestMessage(); msg.setId(uuid); @@ -135,7 +131,7 @@ @GetMapping("/stop/{deviceId}/{channelId}/{stream}") public ResponseEntity<String> playStop(@PathVariable String deviceId, @PathVariable String channelId, @PathVariable String stream) { - cmder.streamByeCmd(deviceId, channelId, stream); + cmder.streamByeCmd(deviceId, channelId, stream, null); if (logger.isDebugEnabled()) { logger.debug(String.format("璁惧鍘嗗彶濯掍綋涓嬭浇鍋滄 API璋冪敤锛宒eviceId/channelId锛�%s_%s", deviceId, channelId)); diff --git a/src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/playback/PlaybackController.java b/src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/playback/PlaybackController.java index b864f46..2fccaa8 100644 --- a/src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/playback/PlaybackController.java +++ b/src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/playback/PlaybackController.java @@ -77,7 +77,7 @@ logger.debug(String.format("璁惧鍥炴斁 API璋冪敤锛宒eviceId锛�%s 锛宑hannelId锛�%s", deviceId, channelId)); } - DeferredResult<ResponseEntity<String>> result = playService.playBack(deviceId, channelId, startTime, endTime, wvpResult->{ + DeferredResult<ResponseEntity<String>> result = playService.playBack(deviceId, channelId, startTime, endTime, null, wvpResult->{ resultHolder.invokeResult(wvpResult.getData()); }); @@ -96,7 +96,7 @@ @PathVariable String channelId, @PathVariable String stream) { - cmder.streamByeCmd(deviceId, channelId, stream); + cmder.streamByeCmd(deviceId, channelId, stream, null); if (logger.isDebugEnabled()) { logger.debug(String.format("璁惧褰曞儚鍥炴斁鍋滄 API璋冪敤锛宒eviceId/channelId锛�%s/%s", deviceId, channelId)); @@ -124,7 +124,7 @@ public ResponseEntity<String> playPause(@PathVariable String streamId) { logger.info("playPause: "+streamId); JSONObject json = new JSONObject(); - StreamInfo streamInfo = redisCatchStorage.queryPlaybackByStreamId(streamId); + StreamInfo streamInfo = redisCatchStorage.queryPlayback(null, null, streamId, null); if (null == streamInfo) { json.put("msg", "streamId涓嶅瓨鍦�"); logger.warn("streamId涓嶅瓨鍦�!"); @@ -144,7 +144,7 @@ public ResponseEntity<String> playResume(@PathVariable String streamId) { logger.info("playResume: "+streamId); JSONObject json = new JSONObject(); - StreamInfo streamInfo = redisCatchStorage.queryPlaybackByStreamId(streamId); + StreamInfo streamInfo = redisCatchStorage.queryPlayback(null, null, streamId, null); if (null == streamInfo) { json.put("msg", "streamId涓嶅瓨鍦�"); logger.warn("streamId涓嶅瓨鍦�!"); @@ -165,7 +165,7 @@ public ResponseEntity<String> playSeek(@PathVariable String streamId, @PathVariable long seekTime) { logger.info("playSeek: "+streamId+", "+seekTime); JSONObject json = new JSONObject(); - StreamInfo streamInfo = redisCatchStorage.queryPlaybackByStreamId(streamId); + StreamInfo streamInfo = redisCatchStorage.queryPlayback(null, null, streamId, null); if (null == streamInfo) { json.put("msg", "streamId涓嶅瓨鍦�"); logger.warn("streamId涓嶅瓨鍦�!"); @@ -186,7 +186,7 @@ public ResponseEntity<String> playSpeed(@PathVariable String streamId, @PathVariable Double speed) { logger.info("playSpeed: "+streamId+", "+speed); JSONObject json = new JSONObject(); - StreamInfo streamInfo = redisCatchStorage.queryPlaybackByStreamId(streamId); + StreamInfo streamInfo = redisCatchStorage.queryPlayback(null, null, streamId, null); if (null == streamInfo) { json.put("msg", "streamId涓嶅瓨鍦�"); logger.warn("streamId涓嶅瓨鍦�!"); diff --git a/src/main/java/com/genersoft/iot/vmp/web/gb28181/ApiStreamController.java b/src/main/java/com/genersoft/iot/vmp/web/gb28181/ApiStreamController.java index 955b68b..dfc2c44 100644 --- a/src/main/java/com/genersoft/iot/vmp/web/gb28181/ApiStreamController.java +++ b/src/main/java/com/genersoft/iot/vmp/web/gb28181/ApiStreamController.java @@ -177,7 +177,7 @@ result.put("error","鏈壘鍒版祦淇℃伅"); return result; } - cmder.streamByeCmd(serial, code, streamInfo.getStream()); + cmder.streamByeCmd(serial, code, streamInfo.getStream(), null); redisCatchStorage.stopPlay(streamInfo); storager.stopPlay(streamInfo.getDeviceID(), streamInfo.getChannelId()); return null; diff --git a/web_src/src/components/ParentPlatformList.vue b/web_src/src/components/ParentPlatformList.vue index a3f1120..ff3de48 100644 --- a/web_src/src/components/ParentPlatformList.vue +++ b/web_src/src/components/ParentPlatformList.vue @@ -13,7 +13,7 @@ </div> <!--璁惧鍒楄〃--> <el-table :data="platformList" border style="width: 100%" :height="winHeight"> - <el-table-column prop="name" label="鍚嶇О" width="240" align="center"></el-table-column> + <el-table-column prop="name" label="鍚嶇О" align="center"></el-table-column> <el-table-column prop="serverGBId" label="骞冲彴缂栧彿" width="180" align="center"></el-table-column> <el-table-column label="鏄惁鍚敤" width="120" align="center"> <template slot-scope="scope"> @@ -38,9 +38,19 @@ </div> </template> </el-table-column> - <el-table-column prop="deviceGBId" label="璁惧鍥芥爣缂栧彿" width="240" align="center"></el-table-column> + <el-table-column prop="deviceGBId" label="璁惧鍥芥爣缂栧彿" width="200" align="center"></el-table-column> <el-table-column prop="transport" label="淇′护浼犺緭妯″紡" width="120" align="center"></el-table-column> - <el-table-column prop="channelCount" label="閫氶亾鏁�" align="center"></el-table-column> + <el-table-column prop="channelCount" label="閫氶亾鏁�" width="120" align="center"></el-table-column> + <el-table-column label="璁㈤槄淇℃伅" width="240" align="center" fixed="right"> + <template slot-scope="scope"> + <i v-if="scope.row.alarmSubscribe" style="font-size: 1.5rem;" title="鎶ヨ璁㈤槄" class="subscribe-on iconfont icon-gbaojings" ></i> + <i v-if="!scope.row.alarmSubscribe" style="font-size: 1.5rem;" title="鎶ヨ璁㈤槄" class="subscribe-off iconfont icon-gbaojings" ></i> + <i v-if="scope.row.catalogSubscribe" title="鐩綍璁㈤槄" class="subscribe-on iconfont icon-gjichus" ></i> + <i v-if="!scope.row.catalogSubscribe" title="鐩綍璁㈤槄" class="subscribe-off iconfont icon-gjichus" ></i> + <i v-if="scope.row.gpsSubscribe" title="浣嶇疆璁㈤槄" class="subscribe-on iconfont icon-gxunjians" ></i> + <i v-if="!scope.row.gpsSubscribe" title="浣嶇疆璁㈤槄" class="subscribe-off iconfont icon-gxunjians" ></i> + </template> + </el-table-column> <el-table-column label="鎿嶄綔" width="300" align="center" fixed="right"> <template slot-scope="scope"> @@ -169,3 +179,13 @@ } }; </script> +<style> +.subscribe-on{ + color: #409EFF; + font-size: 1.3rem; +} +.subscribe-off{ + color: #afafb3; + font-size: 1.3rem; +} +</style> diff --git a/web_src/src/components/dialog/StreamProxyEdit.vue b/web_src/src/components/dialog/StreamProxyEdit.vue index 470e12e..dea93de 100644 --- a/web_src/src/components/dialog/StreamProxyEdit.vue +++ b/web_src/src/components/dialog/StreamProxyEdit.vue @@ -193,6 +193,7 @@ this.mediaServer.getOnlineMediaServerList((data)=>{ this.mediaServerList = data.data; this.proxyParam.mediaServerId = this.mediaServerList[0].id + this.mediaServerIdChange() }) }, mediaServerIdChange:function (){ @@ -206,6 +207,7 @@ } }).then(function (res) { that.ffmpegCmdList = res.data.data; + that.proxyParam.ffmpeg_cmd_key = Object.keys(res.data.data)[0]; }).catch(function (error) { console.log(error); }); diff --git a/web_src/src/components/dialog/chooseChannelForGb.vue b/web_src/src/components/dialog/chooseChannelForGb.vue index 50a495a..78bfddf 100644 --- a/web_src/src/components/dialog/chooseChannelForGb.vue +++ b/web_src/src/components/dialog/chooseChannelForGb.vue @@ -1,8 +1,8 @@ <template> <div id="chooseChannelForGb" > <div style="font-size: 17px; color: #606060; white-space: nowrap; line-height: 30px; font-family: monospace;"> - <span v-if="catalogId == null">{{catalogName}}鐨勭洿鎾祦</span> - <span v-if="catalogId != null">{{catalogName}}({{catalogId}})鐨勭洿鎾祦</span> + <span v-if="catalogId == null">{{catalogName}}鐨勫浗鏍囬�氶亾</span> + <span v-if="catalogId != null">{{catalogName}}({{catalogId}})鐨勫浗鏍囬�氶亾</span> </div> <div style="background-color: #FFFFFF; position: relative; padding: 0.5rem; text-align: left;font-size: 14px;"> 鎼滅储: <el-input @input="search" style="margin-right: 1rem; width: auto;" size="mini" placeholder="鍏抽敭瀛�" prefix-icon="el-icon-search" v-model="searchSrt" clearable> </el-input> diff --git a/web_src/src/components/dialog/chooseChannelForStream.vue b/web_src/src/components/dialog/chooseChannelForStream.vue index 11d7861..eeee14e 100644 --- a/web_src/src/components/dialog/chooseChannelForStream.vue +++ b/web_src/src/components/dialog/chooseChannelForStream.vue @@ -1,8 +1,8 @@ <template> <div id="chooseChannelFoStream" > <div style="font-size: 17px; color: #606060; white-space: nowrap; line-height: 30px; font-family: monospace;"> - <span v-if="catalogId == null">{{catalogName}}鐨勭洿鎾祦</span> - <span v-if="catalogId != null">{{catalogName}}({{catalogId}})鐨勭洿鎾祦</span> + <span v-if="catalogId == null">{{catalogName}}鐨勭洿鎾�氶亾</span> + <span v-if="catalogId != null">{{catalogName}}({{catalogId}})鐨勭洿鎾�氶亾</span> </div> <div style="background-color: #FFFFFF; margin-bottom: 1rem; position: relative; padding: 0.5rem; text-align: left;font-size: 14px;"> diff --git a/web_src/static/css/iconfont.css b/web_src/static/css/iconfont.css index 93259b0..0698271 100644 --- a/web_src/static/css/iconfont.css +++ b/web_src/static/css/iconfont.css @@ -1,8 +1,8 @@ @font-face { font-family: "iconfont"; /* Project id 1291092 */ - src: url('iconfont.woff2?t=1644809302709') format('woff2'), - url('iconfont.woff?t=1644809302709') format('woff'), - url('iconfont.ttf?t=1644809302709') format('truetype'); + src: url('iconfont.woff2?t=1647245982270') format('woff2'), + url('iconfont.woff?t=1647245982270') format('woff'), + url('iconfont.ttf?t=1647245982270') format('truetype'); } .iconfont { @@ -13,6 +13,22 @@ -moz-osx-font-smoothing: grayscale; } +.icon-xitongxinxi:before { + content: "\e7d6"; +} + +.icon-gbaojings:before { + content: "\e7d7"; +} + +.icon-gjichus:before { + content: "\e7d8"; +} + +.icon-gxunjians:before { + content: "\e7d9"; +} + .icon-ziyuan:before { content: "\e7d5"; } diff --git a/web_src/static/css/iconfont.woff2 b/web_src/static/css/iconfont.woff2 index 4db77e2..4833708 100644 --- a/web_src/static/css/iconfont.woff2 +++ b/web_src/static/css/iconfont.woff2 Binary files differ -- Gitblit v1.8.0