From 652489b47ef582b3f492039ab7fd58c558c1ba36 Mon Sep 17 00:00:00 2001 From: ‘sxh’ <1632740646@qq.com> Date: 星期四, 15 六月 2023 11:10:20 +0800 Subject: [PATCH] Merge remote-tracking branch 'origin/wvp-28181-2.0' into wvp-28181-2.0 --- src/main/java/com/genersoft/iot/vmp/conf/redis/RedisMsgListenConfig.java | 4 src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/response/cmd/MobilePositionResponseMessageHandler.java | 30 + src/main/java/com/genersoft/iot/vmp/service/impl/StreamPushServiceImpl.java | 1 src/main/java/com/genersoft/iot/vmp/gb28181/bean/Gb28181Sdp.java | 46 ++ src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/MobilePositionNotifyMessageHandler.java | 10 src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java | 10 src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRTPServerFactory.java | 4 src/main/java/com/genersoft/iot/vmp/media/zlm/dto/StreamProxyItem.java | 100 ++--- doc/_media/903207146.jpg | 0 src/main/java/com/genersoft/iot/vmp/gb28181/session/SSRCFactory.java | 24 - src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/AlarmNotifyMessageHandler.java | 2 src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/device/DeviceQuery.java | 6 src/main/java/com/genersoft/iot/vmp/service/redisMsg/RedisCloseStreamMsgListener.java | 59 +++ src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/SIPRequestHeaderPlarformProvider.java | 4 pom.xml | 2 sql/2.6.8升级2.6.9.sql | 4 src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/response/impl/InviteResponseProcessor.java | 17 src/main/java/com/genersoft/iot/vmp/storager/impl/RedisCatchStorageImpl.java | 23 + web_src/src/components/dialog/devicePlayer.vue | 11 src/main/java/com/genersoft/iot/vmp/storager/IRedisCatchStorage.java | 1 src/main/java/com/genersoft/iot/vmp/storager/dao/PlatformCatalogMapper.java | 8 doc/README.md | 24 doc/_media/1372762149.jpg | 0 src/main/java/com/genersoft/iot/vmp/service/impl/MediaServerServiceImpl.java | 2 web_src/src/components/dialog/StreamProxyEdit.vue | 73 ++-- src/main/java/com/genersoft/iot/vmp/vmanager/bean/ErrorCode.java | 2 src/main/java/com/genersoft/iot/vmp/service/impl/DeviceServiceImpl.java | 2 src/main/java/com/genersoft/iot/vmp/vmanager/bean/SnapPath.java | 50 +++ src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/NotifyRequestForCatalogProcessor.java | 13 web_src/src/components/StreamProxyList.vue | 51 +- src/main/java/com/genersoft/iot/vmp/service/IStreamProxyService.java | 3 src/main/java/com/genersoft/iot/vmp/storager/dao/ParentPlatformMapper.java | 2 src/main/java/com/genersoft/iot/vmp/vmanager/streamProxy/StreamProxyController.java | 44 ++ src/main/resources/all-application.yml | 4 src/main/java/com/genersoft/iot/vmp/gb28181/transmit/callback/DeferredResultHolder.java | 4 README.md | 3 src/main/java/com/genersoft/iot/vmp/common/VideoManagerConstants.java | 5 src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/InviteRequestProcessor.java | 37 - src/main/java/com/genersoft/iot/vmp/common/GeneralCallback.java | 5 src/main/java/com/genersoft/iot/vmp/gb28181/utils/SipUtils.java | 77 ++++ src/main/java/com/genersoft/iot/vmp/storager/dao/StreamProxyMapper.java | 24 src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/NotifyRequestProcessor.java | 11 src/main/java/com/genersoft/iot/vmp/service/impl/StreamProxyServiceImpl.java | 111 +++++- src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/MobilePosition/MobilePositionController.java | 2 44 files changed, 645 insertions(+), 270 deletions(-) diff --git a/README.md b/README.md index 572746d..10cd12a 100644 --- a/README.md +++ b/README.md @@ -27,7 +27,7 @@ ZLM浣跨敤鏂囨。 [https://github.com/ZLMediaKit/ZLMediaKit](https://github.com/ZLMediaKit/ZLMediaKit) > wvp鏂囨。鐢眊itee鎻愪緵鏈嶅姟锛屽鏋滈亣鍒版墦涓嶅紑璇峰鍒锋柊鍑犳銆� -# 绀剧兢鍦板潃 +# 浠樿垂绀剧兢 [](https://t.zsxq.com/0d8VAD3Dm) > 鏀惰垂鏄负浜嗘彁渚涙洿濂界殑鏈嶅姟锛屼篃鏄浣滆�呮洿澶х殑婵�鍔便�傚姞鍏ユ槦鐞冪殑鐢ㄦ埛涓夊ぉ鍚庡彲浠ョ淇℃垜鐣欎笅寰俊鍙凤紝鎴戜細鎷夊ぇ瀹跺叆缇ゃ�傚姞鍏ヤ笁澶╁唴涓嶆弧鎰忓彲浠ョ洿鎺ラ��娆撅紝澶у涓嶉渶瑕佹湁椤捐檻锛屾潵鐧藉珫涓夊ぉ涔熶笉鏄笉鍙互銆� @@ -105,6 +105,7 @@ - [X] 鏀寔鎵撳寘鍙墽琛宩ar鍜寃ar - [X] 鏀寔璺ㄥ煙璇锋眰锛屾敮鎸佸墠鍚庣鍒嗙閮ㄧ讲 - [X] 鏀寔Mysql锛孭ostgresql锛岄噾浠撶瓑鏁版嵁搴� +- [X] 鏀寔Onvif(鐩墠鍦╫nvif鍒嗘敮锛岄渶瑕佸畨瑁卭nvif鏈嶅姟锛屾湇鍔¤鍦ㄧ煡璇嗘槦鐞冭幏鍙�) # 鎺堟潈鍗忚 鏈」鐩嚜鏈変唬鐮佷娇鐢ㄥ鏉剧殑MIT鍗忚锛屽湪淇濈暀鐗堟潈淇℃伅鐨勬儏鍐典笅鍙互鑷敱搴旂敤浜庡悇鑷晢鐢ㄣ�侀潪鍟嗕笟鐨勯」鐩�� 浣嗘槸鏈」鐩篃闆剁鐨勪娇鐢ㄤ簡涓�浜涘叾浠栫殑寮�婧愪唬鐮侊紝鍦ㄥ晢鐢ㄧ殑鎯呭喌涓嬭鑷鏇夸唬鎴栧墧闄わ紱 鐢变簬浣跨敤鏈」鐩�屼骇鐢熺殑鍟嗕笟绾犵悍鎴栦镜鏉冭涓轰竴姒備笌鏈」鐩強寮�鍙戣�呮棤鍏筹紝璇疯嚜琛屾壙鎷呮硶寰嬮闄┿�� 鍦ㄤ娇鐢ㄦ湰椤圭洰浠g爜鏃讹紝涔熷簲璇ュ湪鎺堟潈鍗忚涓悓鏃惰〃鏄庢湰椤圭洰渚濊禆鐨勭涓夋柟搴撶殑鍗忚 diff --git a/doc/README.md b/doc/README.md index 3d2f09f..c2cbfba 100644 --- a/doc/README.md +++ b/doc/README.md @@ -14,7 +14,7 @@ - 瀹屽叏寮�婧愶紝涓斾娇鐢∕IT璁稿彲鍗忚銆備繚鐣欑増鏉冪殑鎯呭喌涓嬪彲浠ョ敤浜庡晢涓氶」鐩�� - 鏀寔澶氭祦濯掍綋鑺傜偣璐熻浇鍧囪 銆� -# 绀剧兢 +# 浠樿垂绀剧兢 [](https://t.zsxq.com/0d8VAD3Dm) > 鏀惰垂鏄负浜嗘彁渚涙洿濂界殑鏈嶅姟锛屼篃鏄浣滆�呮洿澶х殑婵�鍔便�傚姞鍏ユ槦鐞冪殑鐢ㄦ埛涓夊ぉ鍚庡彲浠ョ淇℃垜鐣欎笅寰俊鍙凤紝鎴戜細鎷夊ぇ瀹跺叆缇ゃ�傚姞鍏ヤ笁澶╁唴涓嶆弧鎰忓彲浠ョ洿鎺ラ��娆撅紝澶у涓嶉渶瑕佹湁椤捐檻锛屾潵鐧藉珫涓夊ぉ涔熶笉鏄笉鍙互銆� @@ -62,16 +62,16 @@ - [X] 娉ㄥ唽 - [X] 娉ㄩ攢 - [X] 瀹炴椂瑙嗛煶棰戠偣鎾� -- [ ] 璁惧鎺у埗 - - [ ] 浜戝彴鎺у埗 +- [X] 璁惧鎺у埗 + - [X] 浜戝彴鎺у埗 - [ ] 杩滅▼鍚姩 - - [ ] 褰曞儚鎺у埗 - - [ ] 鎶ヨ甯冮槻/鎾ら槻 - - [ ] 鎶ヨ澶嶄綅 - - [ ] 寮哄埗鍏抽敭甯� - - [ ] 鎷夋鏀惧ぇ - - [ ] 鎷夋缂╁皬 - - [ ] 鐪嬪畧浣嶆帶鍒� + - [X] 褰曞儚鎺у埗 + - [X] 鎶ヨ甯冮槻/鎾ら槻 + - [X] 鎶ヨ澶嶄綅 + - [X] 寮哄埗鍏抽敭甯� + - [X] 鎷夋鏀惧ぇ + - [X] 鎷夋缂╁皬 + - [X] 鐪嬪畧浣嶆帶鍒� - [ ] 璁惧閰嶇疆 - [ ] 鎶ヨ浜嬩欢閫氱煡鍜屽垎鍙� - [X] 璁惧鐩綍璁㈤槄 @@ -79,7 +79,7 @@ - [X] 璁惧鐩綍鏌ヨ - [X] 璁惧鐘舵�佹煡璇� - [ ] 璁惧閰嶇疆鏌ヨ - - [ ] 璁惧棰勭疆浣嶆煡璇� + - [X] 璁惧棰勭疆浣嶆煡璇� - [X] 鐘舵�佷俊鎭姤閫� - [X] 璁惧瑙嗛煶棰戞枃浠舵绱� - [X] 鍘嗗彶瑙嗛煶棰戠殑鍥炴斁 @@ -87,7 +87,7 @@ - [x] 鏆傚仠 - [x] 杩�/閫� - [x] 鍋滄 -- [ ] 瑙嗛煶棰戞枃浠朵笅杞� +- [X] 瑙嗛煶棰戞枃浠朵笅杞� - [ ] ~~鏍℃椂~~ - [X] 璁㈤槄鍜岄�氱煡 - [X] 浜嬩欢璁㈤槄 diff --git a/doc/_media/1372762149.jpg b/doc/_media/1372762149.jpg new file mode 100644 index 0000000..471ec07 --- /dev/null +++ b/doc/_media/1372762149.jpg Binary files differ diff --git a/doc/_media/903207146.jpg b/doc/_media/903207146.jpg new file mode 100644 index 0000000..0bbc7e6 --- /dev/null +++ b/doc/_media/903207146.jpg Binary files differ diff --git a/pom.xml b/pom.xml index bb0de72..2ecfad3 100644 --- a/pom.xml +++ b/pom.xml @@ -11,7 +11,7 @@ <groupId>com.genersoft</groupId> <artifactId>wvp-pro</artifactId> - <version>2.6.8</version> + <version>2.6.9</version> <name>web video platform</name> <description>鍥芥爣28181瑙嗛骞冲彴</description> <packaging>${project.packaging}</packaging> diff --git "a/sql/2.6.8\345\215\207\347\272\2472.6.9.sql" "b/sql/2.6.8\345\215\207\347\272\2472.6.9.sql" index d6d3a6b..a6b9f12 100644 --- "a/sql/2.6.8\345\215\207\347\272\2472.6.9.sql" +++ "b/sql/2.6.8\345\215\207\347\272\2472.6.9.sql" @@ -180,10 +180,6 @@ change createTime create_time varchar(50) null; alter table gb_stream - add constraint gb_stream_pk - primary key (gbStreamId); - -alter table gb_stream change gbStreamId gb_stream_id int auto_increment; alter table gb_stream diff --git a/src/main/java/com/genersoft/iot/vmp/common/GeneralCallback.java b/src/main/java/com/genersoft/iot/vmp/common/GeneralCallback.java new file mode 100644 index 0000000..df07fac --- /dev/null +++ b/src/main/java/com/genersoft/iot/vmp/common/GeneralCallback.java @@ -0,0 +1,5 @@ +package com.genersoft.iot.vmp.common; + +public interface GeneralCallback<T>{ + void run(int code, String msg, T data); +} diff --git a/src/main/java/com/genersoft/iot/vmp/common/VideoManagerConstants.java b/src/main/java/com/genersoft/iot/vmp/common/VideoManagerConstants.java index 51c2ab1..a06c6d0 100644 --- a/src/main/java/com/genersoft/iot/vmp/common/VideoManagerConstants.java +++ b/src/main/java/com/genersoft/iot/vmp/common/VideoManagerConstants.java @@ -107,6 +107,11 @@ public static final String VM_MSG_STREAM_PUSH_RESPONSE = "VM_MSG_STREAM_PUSH_RESPONSE"; /** + * redis 閫氱煡骞冲彴鍏抽棴鎺ㄦ祦 + */ + public static final String VM_MSG_STREAM_PUSH_CLOSE = "VM_MSG_STREAM_PUSH_CLOSE"; + + /** * redis 娑堟伅璇锋眰鎵�鏈夌殑鍦ㄧ嚎閫氶亾 */ public static final String VM_MSG_GET_ALL_ONLINE_REQUESTED = "VM_MSG_GET_ALL_ONLINE_REQUESTED"; diff --git a/src/main/java/com/genersoft/iot/vmp/conf/redis/RedisMsgListenConfig.java b/src/main/java/com/genersoft/iot/vmp/conf/redis/RedisMsgListenConfig.java index 9f48426..7e1cc1d 100644 --- a/src/main/java/com/genersoft/iot/vmp/conf/redis/RedisMsgListenConfig.java +++ b/src/main/java/com/genersoft/iot/vmp/conf/redis/RedisMsgListenConfig.java @@ -43,6 +43,9 @@ @Autowired private RedisPushStreamResponseListener redisPushStreamResponseListener; + @Autowired + private RedisCloseStreamMsgListener redisCloseStreamMsgListener; + /** * redis娑堟伅鐩戝惉鍣ㄥ鍣� 鍙互娣诲姞澶氫釜鐩戝惉涓嶅悓璇濋鐨剅edis鐩戝惉鍣紝鍙渶瑕佹妸娑堟伅鐩戝惉鍣ㄥ拰鐩稿簲鐨勬秷鎭闃呭鐞嗗櫒缁戝畾锛岃娑堟伅鐩戝惉鍣� @@ -63,6 +66,7 @@ container.addMessageListener(redisPushStreamStatusMsgListener, new PatternTopic(VideoManagerConstants.VM_MSG_PUSH_STREAM_STATUS_CHANGE)); container.addMessageListener(redisPushStreamListMsgListener, new PatternTopic(VideoManagerConstants.VM_MSG_PUSH_STREAM_LIST_CHANGE)); container.addMessageListener(redisPushStreamResponseListener, new PatternTopic(VideoManagerConstants.VM_MSG_STREAM_PUSH_RESPONSE)); + container.addMessageListener(redisCloseStreamMsgListener, new PatternTopic(VideoManagerConstants.VM_MSG_STREAM_PUSH_CLOSE)); return container; } } diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/bean/Gb28181Sdp.java b/src/main/java/com/genersoft/iot/vmp/gb28181/bean/Gb28181Sdp.java new file mode 100644 index 0000000..4b9e26a --- /dev/null +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/bean/Gb28181Sdp.java @@ -0,0 +1,46 @@ +package com.genersoft.iot.vmp.gb28181.bean; + +import javax.sdp.SessionDescription; + +/** + * 28181 鐨凷DP瑙f瀽鍣� + */ +public class Gb28181Sdp { + private SessionDescription baseSdb; + private String ssrc; + + private String mediaDescription; + + public static Gb28181Sdp getInstance(SessionDescription baseSdb, String ssrc, String mediaDescription) { + Gb28181Sdp gb28181Sdp = new Gb28181Sdp(); + gb28181Sdp.setBaseSdb(baseSdb); + gb28181Sdp.setSsrc(ssrc); + gb28181Sdp.setMediaDescription(mediaDescription); + return gb28181Sdp; + } + + + public SessionDescription getBaseSdb() { + return baseSdb; + } + + public void setBaseSdb(SessionDescription baseSdb) { + this.baseSdb = baseSdb; + } + + public String getSsrc() { + return ssrc; + } + + public void setSsrc(String ssrc) { + this.ssrc = ssrc; + } + + public String getMediaDescription() { + return mediaDescription; + } + + public void setMediaDescription(String mediaDescription) { + this.mediaDescription = mediaDescription; + } +} diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/session/SSRCFactory.java b/src/main/java/com/genersoft/iot/vmp/gb28181/session/SSRCFactory.java index ec8e0ba..657bb2f 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/session/SSRCFactory.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/session/SSRCFactory.java @@ -1,6 +1,7 @@ package com.genersoft.iot.vmp.gb28181.session; import com.genersoft.iot.vmp.conf.SipConfig; +import com.genersoft.iot.vmp.conf.UserSetting; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.stereotype.Component; @@ -31,10 +32,13 @@ @Autowired private SipConfig sipConfig; + @Autowired + private UserSetting userSetting; + public void initMediaServerSSRC(String mediaServerId, Set<String> usedSet) { String ssrcPrefix = sipConfig.getDomain().substring(3, 8); - String redisKey = SSRC_INFO_KEY + mediaServerId; + String redisKey = SSRC_INFO_KEY + userSetting.getServerId() + "_" + mediaServerId; List<String> ssrcList = new ArrayList<>(); for (int i = 1; i < MAX_STREAM_COUNT; i++) { String ssrc = String.format("%s%04d", ssrcPrefix, i); @@ -77,7 +81,7 @@ return; } String sn = ssrc.substring(1); - String redisKey = SSRC_INFO_KEY + mediaServerId; + String redisKey = SSRC_INFO_KEY + userSetting.getServerId() + "_" + mediaServerId; redisTemplate.opsForSet().add(redisKey, sn); } @@ -86,7 +90,7 @@ */ private String getSN(String mediaServerId) { String sn = null; - String redisKey = SSRC_INFO_KEY + mediaServerId; + String redisKey = SSRC_INFO_KEY + userSetting.getServerId() + "_" + mediaServerId; Long size = redisTemplate.opsForSet().size(redisKey); if (size == null || size == 0) { throw new RuntimeException("ssrc宸茬粡鐢ㄥ畬"); @@ -113,20 +117,8 @@ * @param mediaServerId 娴佸獟浣撴湇鍔D */ public boolean hasMediaServerSSRC(String mediaServerId) { - String redisKey = SSRC_INFO_KEY + mediaServerId; + String redisKey = SSRC_INFO_KEY + userSetting.getServerId() + "_" + mediaServerId; return redisTemplate.opsForSet().members(redisKey) != null; } - /** - * 鏌ヨssrc鏄惁鍙敤 - * - * @param mediaServerId - * @param ssrc - * @return - */ - public boolean checkSsrc(String mediaServerId, String ssrc) { - String sn = ssrc.substring(1); - String redisKey = SSRC_INFO_KEY + mediaServerId; - return redisTemplate.opsForSet().isMember(redisKey, sn) != null; - } } diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/callback/DeferredResultHolder.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/callback/DeferredResultHolder.java index 9b57fb0..5677c95 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/callback/DeferredResultHolder.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/callback/DeferredResultHolder.java @@ -39,11 +39,13 @@ public static final String CALLBACK_CMD_DOWNLOAD = "CALLBACK_DOWNLOAD"; + public static final String CALLBACK_CMD_PROXY = "CALLBACK_PROXY"; + public static final String CALLBACK_CMD_STOP = "CALLBACK_STOP"; public static final String UPLOAD_FILE_CHANNEL = "UPLOAD_FILE_CHANNEL"; - public static final String CALLBACK_CMD_MOBILEPOSITION = "CALLBACK_MOBILEPOSITION"; + public static final String CALLBACK_CMD_MOBILE_POSITION = "CALLBACK_CMD_MOBILE_POSITION"; public static final String CALLBACK_CMD_PRESETQUERY = "CALLBACK_PRESETQUERY"; diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/SIPRequestHeaderPlarformProvider.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/SIPRequestHeaderPlarformProvider.java index 831897a..22017df 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/SIPRequestHeaderPlarformProvider.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/SIPRequestHeaderPlarformProvider.java @@ -54,8 +54,8 @@ parentPlatform.getServerIP() + ":" + parentPlatform.getServerPort()); //via ArrayList<ViaHeader> viaHeaders = new ArrayList<ViaHeader>(); - ViaHeader viaHeader = SipFactory.getInstance().createHeaderFactory().createViaHeader(parentPlatform.getServerIP(), - parentPlatform.getServerPort(), parentPlatform.getTransport(), SipUtils.getNewViaTag()); + ViaHeader viaHeader = SipFactory.getInstance().createHeaderFactory().createViaHeader(parentPlatform.getDeviceIp(), + Integer.parseInt(parentPlatform.getDevicePort()), parentPlatform.getTransport(), SipUtils.getNewViaTag()); viaHeader.setRPort(); viaHeaders.add(viaHeader); //from 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 f2300e8..ccf8151 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 @@ -472,7 +472,7 @@ } subscribe.removeSubscribe(hookSubscribe); }); - Request request = headerProvider.createPlaybackInviteRequest(device, channelId, content.toString(), null, SipUtils.getNewFromTag(), null,sipSender.getNewCallIdHeader(sipLayer.getLocalIp(device.getLocalIp()),device.getTransport()), ssrcInfo.getSsrc()); + Request request = headerProvider.createPlaybackInviteRequest(device, channelId, content.toString(), SipUtils.getNewViaTag(), SipUtils.getNewFromTag(), null,sipSender.getNewCallIdHeader(sipLayer.getLocalIp(device.getLocalIp()),device.getTransport()), ssrcInfo.getSsrc()); sipSender.transmitRequest(sipLayer.getLocalIp(device.getLocalIp()), request, errorEvent, event -> { ResponseEvent responseEvent = (ResponseEvent) event.event; @@ -588,17 +588,13 @@ }); }); - Request request = headerProvider.createPlaybackInviteRequest(device, channelId, content.toString(), null, SipUtils.getNewFromTag(), null,newCallIdHeader, ssrcInfo.getSsrc()); + Request request = headerProvider.createPlaybackInviteRequest(device, channelId, content.toString(), SipUtils.getNewViaTag(), SipUtils.getNewFromTag(), null,newCallIdHeader, ssrcInfo.getSsrc()); sipSender.transmitRequest(sipLayer.getLocalIp(device.getLocalIp()), request, errorEvent, event -> { ResponseEvent responseEvent = (ResponseEvent) event.event; SIPResponse response = (SIPResponse) responseEvent.getResponse(); String contentString =new String(response.getRawContent()); - int ssrcIndex = contentString.indexOf("y="); - String ssrc=ssrcInfo.getSsrc(); - if (ssrcIndex >= 0) { - ssrc = contentString.substring(ssrcIndex + 2, ssrcIndex + 12); - } + String ssrc = SipUtils.getSsrcFromSdp(contentString); streamSession.put(device.getDeviceId(), channelId, response.getCallIdHeader().getCallId(), ssrcInfo.getStream(), ssrc, mediaServerItem.getId(), response, InviteSessionType.DOWNLOAD); okEvent.response(event); }); 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 f9a51af..a159189 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 @@ -241,18 +241,8 @@ // 瑙f瀽sdp娑堟伅, 浣跨敤jainsip 鑷甫鐨剆dp瑙f瀽鏂瑰紡 String contentString = new String(request.getRawContent()); - // jainSip涓嶆敮鎸亂=瀛楁锛� 绉婚櫎浠ヨВ鏋愩�� - // 妫�鏌ユ槸鍚︽湁y瀛楁 - int ssrcIndex = contentString.indexOf("y="); - - SessionDescription sdp; - if (ssrcIndex >= 0) { - //ssrc瑙勫畾闀垮害涓�10涓瓧鑺傦紝涓嶅彇浣欎笅闀垮害浠ラ伩鍏嶅悗缁繕鏈夆�渇=鈥濆瓧娈� - String substring = contentString.substring(0, ssrcIndex); - sdp = SdpFactory.getInstance().createSessionDescription(substring); - } else { - sdp = SdpFactory.getInstance().createSessionDescription(contentString); - } + Gb28181Sdp gb28181Sdp = SipUtils.parseSDP(contentString); + SessionDescription sdp = gb28181Sdp.getBaseSdb(); String sessionName = sdp.getSessionName().getValue(); Long startTime = null; @@ -340,11 +330,11 @@ } String ssrc; - if (userSetting.getUseCustomSsrcForParentInvite() || ssrcIndex < 0) { + if (userSetting.getUseCustomSsrcForParentInvite() || gb28181Sdp.getSsrc() == null) { // 涓婄骇骞冲彴鐐规挱鏃朵笉浣跨敤涓婄骇骞冲彴鎸囧畾鐨剆src锛屼娇鐢ㄨ嚜瀹氫箟鐨剆src锛屽弬鑰冨浗鏍囨枃妗�-鐐规挱澶栧煙璁惧濯掍綋娴丼SRC澶勭悊鏂瑰紡 ssrc = "Play".equalsIgnoreCase(sessionName) ? ssrcFactory.getPlaySsrc(mediaServerItem.getId()) : ssrcFactory.getPlayBackSsrc(mediaServerItem.getId()); }else { - ssrc = contentString.substring(ssrcIndex + 2, ssrcIndex + 12); + ssrc = gb28181Sdp.getSsrc(); } String streamTypeStr = null; if (mediaTransmissionTCP) { @@ -513,11 +503,11 @@ } else if (gbStream != null) { String ssrc; - if (userSetting.getUseCustomSsrcForParentInvite() || ssrcIndex < 0) { + if (userSetting.getUseCustomSsrcForParentInvite() || gb28181Sdp.getSsrc() == null) { // 涓婄骇骞冲彴鐐规挱鏃朵笉浣跨敤涓婄骇骞冲彴鎸囧畾鐨剆src锛屼娇鐢ㄨ嚜瀹氫箟鐨剆src锛屽弬鑰冨浗鏍囨枃妗�-鐐规挱澶栧煙璁惧濯掍綋娴丼SRC澶勭悊鏂瑰紡 ssrc = "Play".equalsIgnoreCase(sessionName) ? ssrcFactory.getPlaySsrc(mediaServerItem.getId()) : ssrcFactory.getPlayBackSsrc(mediaServerItem.getId()); }else { - ssrc = contentString.substring(ssrcIndex + 2, ssrcIndex + 12); + ssrc = gb28181Sdp.getSsrc(); } if("push".equals(gbStream.getStreamType())) { @@ -891,20 +881,11 @@ } String contentString = new String(request.getRawContent()); // jainSip涓嶆敮鎸亂=瀛楁锛� 绉婚櫎绉婚櫎浠ヨВ鏋愩�� - String substring = contentString; String ssrc = "0000000404"; - int ssrcIndex = contentString.indexOf("y="); - if (ssrcIndex > 0) { - substring = contentString.substring(0, ssrcIndex); - ssrc = contentString.substring(ssrcIndex + 2, ssrcIndex + 12); - } - ssrcIndex = substring.indexOf("f="); - if (ssrcIndex > 0) { - substring = contentString.substring(0, ssrcIndex); - } - SessionDescription sdp = null; + try { - sdp = SdpFactory.getInstance().createSessionDescription(substring); + Gb28181Sdp gb28181Sdp = SipUtils.parseSDP(contentString); + SessionDescription sdp = gb28181Sdp.getBaseSdb(); // 鑾峰彇鏀寔鐨勬牸寮� Vector mediaDescriptions = sdp.getMediaDescriptions(true); // 鏌ョ湅鏄惁鏀寔PS 璐熻浇96 diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/NotifyRequestForCatalogProcessor.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/NotifyRequestForCatalogProcessor.java index e614bf9..c0b1be4 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/NotifyRequestForCatalogProcessor.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/NotifyRequestForCatalogProcessor.java @@ -175,6 +175,11 @@ } }else { addChannelMap.put(channel.getChannelId(), channel); + if (userSetting.getDeviceStatusNotify()) { + // 鍙戦�乺edis娑堟伅 + redisCatchStorage.sendChannelAddOrDelete(device.getDeviceId(), channel.getChannelId(), true); + } + if (addChannelMap.keySet().size() > 300) { executeSaveForAdd(); } @@ -185,6 +190,10 @@ // 鍒犻櫎 logger.info("[鏀跺埌鍒犻櫎閫氶亾閫氱煡] 鏉ヨ嚜璁惧: {}, 閫氶亾 {}", device.getDeviceId(), channel.getChannelId()); deleteChannelList.add(channel); + if (userSetting.getDeviceStatusNotify()) { + // 鍙戦�乺edis娑堟伅 + redisCatchStorage.sendChannelAddOrDelete(device.getDeviceId(), channel.getChannelId(), false); + } if (deleteChannelList.size() > 300) { executeSaveForDelete(); } @@ -205,6 +214,10 @@ if (addChannelMap.keySet().size() > 300) { executeSaveForAdd(); } + if (userSetting.getDeviceStatusNotify()) { + // 鍙戦�乺edis娑堟伅 + redisCatchStorage.sendChannelAddOrDelete(device.getDeviceId(), channel.getChannelId(), true); + } } break; default: 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 cb780e7..e97b720 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 @@ -192,7 +192,12 @@ mobilePosition.setDeviceId(device.getDeviceId()); mobilePosition.setChannelId(channelId); String time = XmlUtil.getText(rootElement, "Time"); - mobilePosition.setTime(time); + if (ObjectUtils.isEmpty(time)){ + mobilePosition.setTime(DateUtil.getNow()); + }else { + mobilePosition.setTime(SipUtils.parseTime(time)); + } + mobilePosition.setLongitude(Double.parseDouble(XmlUtil.getText(rootElement, "Longitude"))); mobilePosition.setLatitude(Double.parseDouble(XmlUtil.getText(rootElement, "Latitude"))); if (NumericUtil.isDouble(XmlUtil.getText(rootElement, "Speed"))) { @@ -237,7 +242,7 @@ // 鍙戦�乺edis娑堟伅銆� 閫氱煡浣嶇疆淇℃伅鐨勫彉鍖� JSONObject jsonObject = new JSONObject(); - jsonObject.put("time", time); + jsonObject.put("time", DateUtil.yyyy_MM_dd_HH_mm_ssToISO8601(mobilePosition.getTime())); jsonObject.put("serial", deviceId); jsonObject.put("code", channelId); jsonObject.put("longitude", mobilePosition.getLongitude()); @@ -339,7 +344,7 @@ storager.updateChannelPosition(deviceChannel); // 鍙戦�乺edis娑堟伅銆� 閫氱煡浣嶇疆淇℃伅鐨勫彉鍖� JSONObject jsonObject = new JSONObject(); - jsonObject.put("time", mobilePosition.getTime()); + jsonObject.put("time", DateUtil.yyyy_MM_dd_HH_mm_ssToISO8601(mobilePosition.getTime())); jsonObject.put("serial", deviceChannel.getDeviceId()); jsonObject.put("code", deviceChannel.getChannelId()); jsonObject.put("longitude", mobilePosition.getLongitude()); diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/AlarmNotifyMessageHandler.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/AlarmNotifyMessageHandler.java index 9268e9b..6928def 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/AlarmNotifyMessageHandler.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/AlarmNotifyMessageHandler.java @@ -164,7 +164,7 @@ // 鍙戦�乺edis娑堟伅銆� 閫氱煡浣嶇疆淇℃伅鐨勫彉鍖� JSONObject jsonObject = new JSONObject(); - jsonObject.put("time", mobilePosition.getTime()); + jsonObject.put("time", DateUtil.yyyy_MM_dd_HH_mm_ssToISO8601(mobilePosition.getTime())); jsonObject.put("serial", deviceChannel.getDeviceId()); jsonObject.put("code", deviceChannel.getChannelId()); jsonObject.put("longitude", mobilePosition.getLongitude()); diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/MobilePositionNotifyMessageHandler.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/MobilePositionNotifyMessageHandler.java index 1f0bdf1..9a82b8a 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/MobilePositionNotifyMessageHandler.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/MobilePositionNotifyMessageHandler.java @@ -7,6 +7,7 @@ import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.IMessageHandler; import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.notify.NotifyMessageHandler; import com.genersoft.iot.vmp.gb28181.utils.NumericUtil; +import com.genersoft.iot.vmp.gb28181.utils.SipUtils; import com.genersoft.iot.vmp.service.IDeviceChannelService; import com.genersoft.iot.vmp.storager.IRedisCatchStorage; import com.genersoft.iot.vmp.storager.IVideoManagerStorage; @@ -95,7 +96,12 @@ } mobilePosition.setDeviceId(sipMsgInfo.getDevice().getDeviceId()); mobilePosition.setChannelId(getText(rootElementAfterCharset, "DeviceID")); - mobilePosition.setTime(getText(rootElementAfterCharset, "Time")); + String time = getText(rootElementAfterCharset, "Time"); + if (ObjectUtils.isEmpty(time)){ + mobilePosition.setTime(DateUtil.getNow()); + }else { + mobilePosition.setTime(SipUtils.parseTime(time)); + } mobilePosition.setLongitude(Double.parseDouble(getText(rootElementAfterCharset, "Longitude"))); mobilePosition.setLatitude(Double.parseDouble(getText(rootElementAfterCharset, "Latitude"))); if (NumericUtil.isDouble(getText(rootElementAfterCharset, "Speed"))) { @@ -138,7 +144,7 @@ // 鍙戦�乺edis娑堟伅銆� 閫氱煡浣嶇疆淇℃伅鐨勫彉鍖� JSONObject jsonObject = new JSONObject(); - jsonObject.put("time", mobilePosition.getTime()); + jsonObject.put("time", DateUtil.yyyy_MM_dd_HH_mm_ssToISO8601(mobilePosition.getTime())); jsonObject.put("serial", deviceChannel.getDeviceId()); jsonObject.put("code", deviceChannel.getChannelId()); jsonObject.put("longitude", mobilePosition.getLongitude()); diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/response/cmd/MobilePositionResponseMessageHandler.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/response/cmd/MobilePositionResponseMessageHandler.java index 332f363..36a72bc 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/response/cmd/MobilePositionResponseMessageHandler.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/response/cmd/MobilePositionResponseMessageHandler.java @@ -2,17 +2,21 @@ import com.alibaba.fastjson2.JSONObject; import com.genersoft.iot.vmp.conf.UserSetting; -import com.genersoft.iot.vmp.gb28181.bean.*; +import com.genersoft.iot.vmp.gb28181.bean.Device; +import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel; +import com.genersoft.iot.vmp.gb28181.bean.MobilePosition; +import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform; +import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder; +import com.genersoft.iot.vmp.gb28181.transmit.callback.RequestMessage; import com.genersoft.iot.vmp.gb28181.transmit.event.request.SIPRequestProcessorParent; import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.IMessageHandler; import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.response.ResponseMessageHandler; -import com.genersoft.iot.vmp.gb28181.utils.Coordtransform; import com.genersoft.iot.vmp.gb28181.utils.NumericUtil; +import com.genersoft.iot.vmp.gb28181.utils.SipUtils; import com.genersoft.iot.vmp.service.IDeviceChannelService; import com.genersoft.iot.vmp.storager.IRedisCatchStorage; import com.genersoft.iot.vmp.storager.IVideoManagerStorage; import com.genersoft.iot.vmp.utils.DateUtil; -import com.genersoft.iot.vmp.utils.GpsUtil; import gov.nist.javax.sip.message.SIPRequest; import org.dom4j.DocumentException; import org.dom4j.Element; @@ -56,6 +60,9 @@ @Autowired private IDeviceChannelService deviceChannelService; + @Autowired + private DeferredResultHolder resultHolder; + @Override public void afterPropertiesSet() throws Exception { responseMessageHandler.addHandler(cmdType, this); @@ -83,7 +90,13 @@ } mobilePosition.setDeviceId(device.getDeviceId()); mobilePosition.setChannelId(getText(rootElement, "DeviceID")); - mobilePosition.setTime(getText(rootElement, "Time")); + //鍏煎ISO 8601鏍煎紡鏃堕棿 + String time = getText(rootElement, "Time"); + if (ObjectUtils.isEmpty(time)){ + mobilePosition.setTime(DateUtil.getNow()); + }else { + mobilePosition.setTime(SipUtils.parseTime(time)); + } mobilePosition.setLongitude(Double.parseDouble(getText(rootElement, "Longitude"))); mobilePosition.setLatitude(Double.parseDouble(getText(rootElement, "Latitude"))); if (NumericUtil.isDouble(getText(rootElement, "Speed"))) { @@ -121,11 +134,18 @@ if (userSetting.getSavePositionHistory()) { storager.insertMobilePosition(mobilePosition); } + storager.updateChannelPosition(deviceChannel); + + String key = DeferredResultHolder.CALLBACK_CMD_MOBILE_POSITION + device.getDeviceId(); + RequestMessage msg = new RequestMessage(); + msg.setKey(key); + msg.setData(mobilePosition); + resultHolder.invokeAllResult(msg); // 鍙戦�乺edis娑堟伅銆� 閫氱煡浣嶇疆淇℃伅鐨勫彉鍖� JSONObject jsonObject = new JSONObject(); - jsonObject.put("time", mobilePosition.getTime()); + jsonObject.put("time", DateUtil.yyyy_MM_dd_HH_mm_ssToISO8601(mobilePosition.getTime())); jsonObject.put("serial", deviceChannel.getDeviceId()); jsonObject.put("code", deviceChannel.getChannelId()); jsonObject.put("longitude", mobilePosition.getLongitude()); diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/response/impl/InviteResponseProcessor.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/response/impl/InviteResponseProcessor.java index f647b96..436d2a4 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/response/impl/InviteResponseProcessor.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/response/impl/InviteResponseProcessor.java @@ -1,10 +1,12 @@ package com.genersoft.iot.vmp.gb28181.transmit.event.response.impl; import com.genersoft.iot.vmp.gb28181.SipLayer; +import com.genersoft.iot.vmp.gb28181.bean.Gb28181Sdp; import com.genersoft.iot.vmp.gb28181.transmit.SIPProcessorObserver; import com.genersoft.iot.vmp.gb28181.transmit.SIPSender; import com.genersoft.iot.vmp.gb28181.transmit.cmd.SIPRequestHeaderProvider; import com.genersoft.iot.vmp.gb28181.transmit.event.response.SIPResponseProcessorAbstract; +import com.genersoft.iot.vmp.gb28181.utils.SipUtils; import gov.nist.javax.sip.ResponseEventExt; import gov.nist.javax.sip.message.SIPResponse; import org.slf4j.Logger; @@ -12,7 +14,6 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; -import javax.sdp.SdpFactory; import javax.sdp.SdpParseException; import javax.sdp.SessionDescription; import javax.sip.InvalidArgumentException; @@ -79,18 +80,8 @@ ResponseEventExt event = (ResponseEventExt)evt; String contentString = new String(response.getRawContent()); - // jainSip涓嶆敮鎸亂=瀛楁锛� 绉婚櫎浠ヨВ鏋愩�� - int ssrcIndex = contentString.indexOf("y="); - // 妫�鏌ユ槸鍚︽湁y瀛楁 - SessionDescription sdp; - if (ssrcIndex >= 0) { - //ssrc瑙勫畾闀垮害涓�10瀛楄妭锛屼笉鍙栦綑涓嬮暱搴︿互閬垮厤鍚庣画杩樻湁鈥渇=鈥濆瓧娈� - String substring = contentString.substring(0, contentString.indexOf("y=")); - sdp = SdpFactory.getInstance().createSessionDescription(substring); - } else { - sdp = SdpFactory.getInstance().createSessionDescription(contentString); - } - + Gb28181Sdp gb28181Sdp = SipUtils.parseSDP(contentString); + SessionDescription sdp = gb28181Sdp.getBaseSdb(); SipURI requestUri = SipFactory.getInstance().createAddressFactory().createSipURI(sdp.getOrigin().getUsername(), event.getRemoteIpAddress() + ":" + event.getRemotePort()); Request reqAck = headerProvider.createAckRequest(response.getLocalAddress().getHostAddress(), requestUri, response); diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/utils/SipUtils.java b/src/main/java/com/genersoft/iot/vmp/gb28181/utils/SipUtils.java index a7ce8c0..2cfe16e 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/utils/SipUtils.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/utils/SipUtils.java @@ -1,14 +1,22 @@ package com.genersoft.iot.vmp.gb28181.utils; import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel; +import com.genersoft.iot.vmp.gb28181.bean.Gb28181Sdp; import com.genersoft.iot.vmp.gb28181.bean.RemoteAddressInfo; +import com.genersoft.iot.vmp.utils.DateUtil; import com.genersoft.iot.vmp.utils.GitUtil; import gov.nist.javax.sip.address.AddressImpl; import gov.nist.javax.sip.address.SipUri; import gov.nist.javax.sip.header.Subject; import gov.nist.javax.sip.message.SIPRequest; +import org.apache.commons.lang3.RandomStringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.util.ObjectUtils; +import javax.sdp.SdpFactory; +import javax.sdp.SdpParseException; +import javax.sdp.SessionDescription; import javax.sip.PeerUnavailableException; import javax.sip.SipFactory; import javax.sip.header.FromHeader; @@ -16,6 +24,8 @@ import javax.sip.header.UserAgentHeader; import javax.sip.message.Request; import java.text.ParseException; +import java.time.LocalDateTime; +import java.time.format.DateTimeParseException; import java.util.ArrayList; import java.util.List; import java.util.UUID; @@ -27,6 +37,8 @@ * @createTime 2021骞�09鏈�27鏃� 15:12:00 */ public class SipUtils { + + private final static Logger logger = LoggerFactory.getLogger(SipUtils.class); public static String getUserIdFromFromHeader(Request request) { FromHeader fromHeader = (FromHeader)request.getHeader(FromHeader.NAME); @@ -51,7 +63,7 @@ } public static String getNewViaTag() { - return "z9hG4bK" + System.currentTimeMillis(); + return "z9hG4bK" + RandomStringUtils.randomNumeric(10); } public static UserAgentHeader createUserAgentHeader(GitUtil gitUtil) throws PeerUnavailableException, ParseException { @@ -189,4 +201,67 @@ } return deviceChannel; } + + public static Gb28181Sdp parseSDP(String sdpStr) throws SdpParseException { + + // jainSip涓嶆敮鎸亂= f=瀛楁锛� 绉婚櫎浠ヨВ鏋愩�� + int ssrcIndex = sdpStr.indexOf("y="); + int mediaDescriptionIndex = sdpStr.indexOf("f="); + // 妫�鏌ユ槸鍚︽湁y瀛楁 + SessionDescription sdp; + String ssrc = null; + String mediaDescription = null; + if (mediaDescriptionIndex == 0 && ssrcIndex == 0) { + sdp = SdpFactory.getInstance().createSessionDescription(sdpStr); + }else { + String lines[] = sdpStr.split("\\r?\\n"); + StringBuilder sdpBuffer = new StringBuilder(); + for (String line : lines) { + if (line.trim().startsWith("y=")) { + ssrc = line.substring(2); + }else if (line.trim().startsWith("f=")) { + mediaDescription = line.substring(2); + }else { + sdpBuffer.append(line.trim()).append("\r\n"); + } + } + sdp = SdpFactory.getInstance().createSessionDescription(sdpBuffer.toString()); + } + return Gb28181Sdp.getInstance(sdp, ssrc, mediaDescription); + } + + public static String getSsrcFromSdp(String sdpStr) { + + // jainSip涓嶆敮鎸亂= f=瀛楁锛� 绉婚櫎浠ヨВ鏋愩�� + int ssrcIndex = sdpStr.indexOf("y="); + if (ssrcIndex == 0) { + return null; + } + String lines[] = sdpStr.split("\\r?\\n"); + for (String line : lines) { + if (line.trim().startsWith("y=")) { + return line.substring(2); + } + } + return null; + } + + public static String parseTime(String timeStr) { + if (ObjectUtils.isEmpty(timeStr)){ + return null; + } + System.out.println(timeStr); + LocalDateTime localDateTime; + try { + localDateTime = LocalDateTime.parse(timeStr); + }catch (DateTimeParseException e) { + try { + localDateTime = LocalDateTime.parse(timeStr, DateUtil.formatterISO8601); + }catch (DateTimeParseException e2) { + logger.error("[鏍煎紡鍖栨椂闂碷 鏃犳硶鏍煎紡鍖栨椂闂达細 {}", timeStr); + return null; + } + } + return localDateTime.format(DateUtil.formatterISO8601); + } } 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 9a642d8..081d919 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 @@ -6,7 +6,9 @@ import com.genersoft.iot.vmp.common.CommonCallback; import com.genersoft.iot.vmp.conf.UserSetting; import com.genersoft.iot.vmp.gb28181.bean.SendRtpItem; -import com.genersoft.iot.vmp.media.zlm.dto.*; +import com.genersoft.iot.vmp.media.zlm.dto.HookSubscribeFactory; +import com.genersoft.iot.vmp.media.zlm.dto.HookSubscribeForRtpServerTimeout; +import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/dto/StreamProxyItem.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/dto/StreamProxyItem.java index b0e74e8..dd517e3 100644 --- a/src/main/java/com/genersoft/iot/vmp/media/zlm/dto/StreamProxyItem.java +++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/dto/StreamProxyItem.java @@ -20,28 +20,26 @@ @Schema(description = "鎷夋祦鍦板潃") private String url; @Schema(description = "鎷夋祦鍦板潃") - private String src_url; + private String srcUrl; @Schema(description = "鐩爣鍦板潃") - private String dst_url; + private String dstUrl; @Schema(description = "瓒呮椂鏃堕棿") - private int timeout_ms; + private int timeoutMs; @Schema(description = "ffmpeg妯℃澘KEY") - private String ffmpeg_cmd_key; + private String ffmpegCmdKey; @Schema(description = "rtsp鎷夋祦鏃讹紝鎷夋祦鏂瑰紡锛�0锛歵cp锛�1锛歶dp锛�2锛氱粍鎾�") - private String rtp_type; + private String rtpType; @Schema(description = "鏄惁鍚敤") private boolean enable; @Schema(description = "鏄惁鍚敤闊抽") - private boolean enable_audio; + private boolean enableAudio; @Schema(description = "鏄惁鍚敤MP4") - private boolean enable_mp4; + private boolean enableMp4; @Schema(description = "鏄惁 鏃犱汉瑙傜湅鏃跺垹闄�") - private boolean enable_remove_none_reader; + private boolean enableRemoveNoneReader; @Schema(description = "鏄惁 鏃犱汉瑙傜湅鏃惰嚜鍔ㄥ仠鐢�") - private boolean enable_disable_none_reader; - @Schema(description = "鍒涘缓鏃堕棿") - private String createTime; + private boolean enableDisableNoneReader; public String getType() { return type; @@ -89,44 +87,44 @@ this.url = url; } - public String getSrc_url() { - return src_url; + public String getSrcUrl() { + return srcUrl; } - public void setSrc_url(String src_url) { - this.src_url = src_url; + public void setSrcUrl(String src_url) { + this.srcUrl = src_url; } - public String getDst_url() { - return dst_url; + public String getDstUrl() { + return dstUrl; } - public void setDst_url(String dst_url) { - this.dst_url = dst_url; + public void setDstUrl(String dst_url) { + this.dstUrl = dst_url; } - public int getTimeout_ms() { - return timeout_ms; + public int getTimeoutMs() { + return timeoutMs; } - public void setTimeout_ms(int timeout_ms) { - this.timeout_ms = timeout_ms; + public void setTimeoutMs(int timeout_ms) { + this.timeoutMs = timeout_ms; } - public String getFfmpeg_cmd_key() { - return ffmpeg_cmd_key; + public String getFfmpegCmdKey() { + return ffmpegCmdKey; } - public void setFfmpeg_cmd_key(String ffmpeg_cmd_key) { - this.ffmpeg_cmd_key = ffmpeg_cmd_key; + public void setFfmpegCmdKey(String ffmpeg_cmd_key) { + this.ffmpegCmdKey = ffmpeg_cmd_key; } - public String getRtp_type() { - return rtp_type; + public String getRtpType() { + return rtpType; } - public void setRtp_type(String rtp_type) { - this.rtp_type = rtp_type; + public void setRtpType(String rtp_type) { + this.rtpType = rtp_type; } public boolean isEnable() { @@ -137,45 +135,37 @@ this.enable = enable; } - public boolean isEnable_mp4() { - return enable_mp4; + public boolean isEnableMp4() { + return enableMp4; } - public void setEnable_mp4(boolean enable_mp4) { - this.enable_mp4 = enable_mp4; + public void setEnableMp4(boolean enable_mp4) { + this.enableMp4 = enable_mp4; } - @Override - public String getCreateTime() { - return createTime; + public boolean isEnableRemoveNoneReader() { + return enableRemoveNoneReader; } - @Override - public void setCreateTime(String createTime) { - this.createTime = createTime; + public void setEnableRemoveNoneReader(boolean enable_remove_none_reader) { + this.enableRemoveNoneReader = enable_remove_none_reader; } - public boolean isEnable_remove_none_reader() { - return enable_remove_none_reader; + public boolean isEnableDisableNoneReader() { + return enableDisableNoneReader; } - public void setEnable_remove_none_reader(boolean enable_remove_none_reader) { - this.enable_remove_none_reader = enable_remove_none_reader; + public void setEnableDisableNoneReader(boolean enable_disable_none_reader) { + this.enableDisableNoneReader = enable_disable_none_reader; } - public boolean isEnable_disable_none_reader() { - return enable_disable_none_reader; + public boolean isEnableAudio() { + return enableAudio; } - public void setEnable_disable_none_reader(boolean enable_disable_none_reader) { - this.enable_disable_none_reader = enable_disable_none_reader; + public void setEnableAudio(boolean enable_audio) { + this.enableAudio = enable_audio; } - public boolean isEnable_audio() { - return enable_audio; - } - public void setEnable_audio(boolean enable_audio) { - this.enable_audio = enable_audio; - } } diff --git a/src/main/java/com/genersoft/iot/vmp/service/IStreamProxyService.java b/src/main/java/com/genersoft/iot/vmp/service/IStreamProxyService.java index 0e1c97b..c4968a7 100644 --- a/src/main/java/com/genersoft/iot/vmp/service/IStreamProxyService.java +++ b/src/main/java/com/genersoft/iot/vmp/service/IStreamProxyService.java @@ -1,6 +1,7 @@ package com.genersoft.iot.vmp.service; import com.alibaba.fastjson2.JSONObject; +import com.genersoft.iot.vmp.common.GeneralCallback; import com.genersoft.iot.vmp.common.StreamInfo; import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; import com.genersoft.iot.vmp.media.zlm.dto.StreamProxyItem; @@ -13,7 +14,7 @@ * 淇濆瓨瑙嗛浠g悊 * @param param */ - StreamInfo save(StreamProxyItem param); + void save(StreamProxyItem param, GeneralCallback<StreamInfo> callback); /** * 娣诲姞瑙嗛浠g悊鍒皕lm diff --git a/src/main/java/com/genersoft/iot/vmp/service/impl/DeviceServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/service/impl/DeviceServiceImpl.java index 195b1e6..5f779aa 100644 --- a/src/main/java/com/genersoft/iot/vmp/service/impl/DeviceServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/service/impl/DeviceServiceImpl.java @@ -187,7 +187,7 @@ @Override public void offline(String deviceId, String reason) { - logger.error("[璁惧绂荤嚎]锛寋}, device锛歿}", reason, deviceId); + logger.warn("[璁惧绂荤嚎]锛寋}, device锛歿}", reason, deviceId); Device device = deviceMapper.getDeviceByDeviceId(deviceId); if (device == null) { return; 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 d997a43..7f8af3f 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 @@ -418,7 +418,7 @@ } final String zlmKeepaliveKey = zlmKeepaliveKeyPrefix + serverItem.getId(); dynamicTask.stop(zlmKeepaliveKey); - dynamicTask.startDelay(zlmKeepaliveKey, new KeepAliveTimeoutRunnable(serverItem), (Math.getExponent(serverItem.getHookAliveInterval()) + 5) * 1000); + dynamicTask.startDelay(zlmKeepaliveKey, new KeepAliveTimeoutRunnable(serverItem), (serverItem.getHookAliveInterval().intValue() + 5) * 1000); publisher.zlmOnlineEventPublish(serverItem.getId()); logger.info("[ZLM] 杩炴帴鎴愬姛 {} - {}:{} ", diff --git a/src/main/java/com/genersoft/iot/vmp/service/impl/StreamProxyServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/service/impl/StreamProxyServiceImpl.java index 3037e3f..9ac6ab9 100644 --- a/src/main/java/com/genersoft/iot/vmp/service/impl/StreamProxyServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/service/impl/StreamProxyServiceImpl.java @@ -2,12 +2,16 @@ import com.alibaba.fastjson2.JSONArray; import com.alibaba.fastjson2.JSONObject; +import com.genersoft.iot.vmp.common.GeneralCallback; import com.genersoft.iot.vmp.common.StreamInfo; import com.genersoft.iot.vmp.conf.UserSetting; import com.genersoft.iot.vmp.conf.exception.ControllerException; import com.genersoft.iot.vmp.gb28181.event.EventPublisher; import com.genersoft.iot.vmp.gb28181.event.subscribe.catalog.CatalogEvent; import com.genersoft.iot.vmp.media.zlm.ZLMRESTfulUtils; +import com.genersoft.iot.vmp.media.zlm.ZlmHttpHookSubscribe; +import com.genersoft.iot.vmp.media.zlm.dto.HookSubscribeFactory; +import com.genersoft.iot.vmp.media.zlm.dto.HookSubscribeForStreamChange; import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; import com.genersoft.iot.vmp.media.zlm.dto.StreamProxyItem; import com.genersoft.iot.vmp.media.zlm.dto.hook.OnStreamChangedHookParam; @@ -86,6 +90,9 @@ private IMediaServerService mediaServerService; @Autowired + private ZlmHttpHookSubscribe hookSubscribe; + + @Autowired DataSourceTransactionManager dataSourceTransactionManager; @Autowired @@ -93,7 +100,7 @@ @Override - public StreamInfo save(StreamProxyItem param) { + public void save(StreamProxyItem param, GeneralCallback<StreamInfo> callback) { MediaServerItem mediaInfo; if (ObjectUtils.isEmpty(param.getMediaServerId()) || "auto".equals(param.getMediaServerId())){ mediaInfo = mediaServerService.getMediaServerForMinimumLoad(null); @@ -104,10 +111,43 @@ logger.warn("淇濆瓨浠g悊鏈壘鍒板湪绾跨殑ZLM..."); throw new ControllerException(ErrorCode.ERROR100.getCode(), "淇濆瓨浠g悊鏈壘鍒板湪绾跨殑ZLM"); } - String dstUrl = String.format("rtmp://%s:%s/%s/%s", "127.0.0.1", mediaInfo.getRtmpPort(), param.getApp(), - param.getStream() ); - param.setDst_url(dstUrl); - StringBuffer resultMsg = new StringBuffer(); + String dstUrl; + if ("ffmpeg".equalsIgnoreCase(param.getType())) { + JSONObject jsonObject = zlmresTfulUtils.getMediaServerConfig(mediaInfo); + if (jsonObject.getInteger("code") != 0) { + throw new ControllerException(ErrorCode.ERROR100.getCode(), "鑾峰彇娴佸獟浣撻厤缃け璐�"); + } + JSONArray dataArray = jsonObject.getJSONArray("data"); + JSONObject mediaServerConfig = dataArray.getJSONObject(0); + String ffmpegCmd = mediaServerConfig.getString(param.getFfmpegCmdKey()); + String schema = getSchemaFromFFmpegCmd(ffmpegCmd); + if (schema == null) { + throw new ControllerException(ErrorCode.ERROR100.getCode(), "ffmpeg鎷夋祦浠g悊鏃犳硶浠巉fmpeg cmd涓幏鍙栧埌杈撳嚭鏍煎紡"); + } + int port; + String schemaForUri; + if (schema.equalsIgnoreCase("rtsp")) { + port = mediaInfo.getRtspPort(); + schemaForUri = schema; + }else if (schema.equalsIgnoreCase("flv")) { + port = mediaInfo.getHttpPort(); + schemaForUri = "http"; + }else if (schema.equalsIgnoreCase("rtmp")) { + port = mediaInfo.getRtmpPort(); + schemaForUri = schema; + }else { + port = mediaInfo.getRtmpPort(); + schemaForUri = schema; + } + + dstUrl = String.format("%s://%s:%s/%s/%s", schemaForUri, "127.0.0.1", port, param.getApp(), + param.getStream()); + }else { + dstUrl = String.format("rtmp://%s:%s/%s/%s", "127.0.0.1", mediaInfo.getRtmpPort(), param.getApp(), + param.getStream()); + } + param.setDstUrl(dstUrl); + logger.info("[鎷夋祦浠g悊] 杈撳嚭鍦板潃涓猴細{}", dstUrl); param.setMediaServerId(mediaInfo.getId()); boolean saveResult; // 鏇存柊 @@ -117,29 +157,60 @@ saveResult = addStreamProxy(param); } if (!saveResult) { - throw new ControllerException(ErrorCode.ERROR100.getCode(),"淇濆瓨澶辫触"); + callback.run(ErrorCode.ERROR100.getCode(), "淇濆瓨澶辫触", null); + return; } - StreamInfo resultForStreamInfo = null; - resultMsg.append("淇濆瓨鎴愬姛"); + + HookSubscribeForStreamChange hookSubscribeForStreamChange = HookSubscribeFactory.on_stream_changed(param.getApp(), param.getStream(), true, "rtsp", mediaInfo.getId()); + hookSubscribe.addSubscribe(hookSubscribeForStreamChange, (mediaServerItem, response) -> { + StreamInfo streamInfo = mediaService.getStreamInfoByAppAndStream( + mediaInfo, param.getApp(), param.getStream(), null, null); + callback.run(ErrorCode.SUCCESS.getCode(), ErrorCode.SUCCESS.getMsg(), streamInfo); + }); + if (param.isEnable()) { JSONObject jsonObject = addStreamProxyToZlm(param); - if (jsonObject == null || jsonObject.getInteger("code") != 0) { - resultMsg.append(", 浣嗘槸鍚敤澶辫触锛岃妫�鏌ユ祦鍦板潃鏄惁鍙敤"); + if (jsonObject != null && jsonObject.getInteger("code") == 0) { + hookSubscribe.removeSubscribe(hookSubscribeForStreamChange); + StreamInfo streamInfo = mediaService.getStreamInfoByAppAndStream( + mediaInfo, param.getApp(), param.getStream(), null, null); + callback.run(ErrorCode.SUCCESS.getCode(), ErrorCode.SUCCESS.getMsg(), streamInfo); + }else { param.setEnable(false); // 鐩存帴绉婚櫎 - if (param.isEnable_remove_none_reader()) { + if (param.isEnableRemoveNoneReader()) { del(param.getApp(), param.getStream()); }else { updateStreamProxy(param); } + if (jsonObject == null){ + callback.run(ErrorCode.ERROR100.getCode(), "璁板綍宸蹭繚瀛橈紝鍚敤澶辫触", null); + return; + }else { + callback.run(ErrorCode.ERROR100.getCode(), jsonObject.getString("msg"), null); + return; + } + } + } + } - }else { - resultForStreamInfo = mediaService.getStreamInfoByAppAndStream( - mediaInfo, param.getApp(), param.getStream(), null, null); + private String getSchemaFromFFmpegCmd(String ffmpegCmd) { + ffmpegCmd = ffmpegCmd.replaceAll(" + ", " "); + String[] paramArray = ffmpegCmd.split(" "); + if (paramArray.length == 0) { + return null; + } + for (int i = 0; i < paramArray.length; i++) { + if (paramArray[i].equalsIgnoreCase("-f")) { + if (i + 1 < paramArray.length - 1) { + return paramArray[i+1]; + }else { + return null; + } } } - return resultForStreamInfo; + return null; } /** @@ -228,11 +299,11 @@ } if ("default".equals(param.getType())){ result = zlmresTfulUtils.addStreamProxy(mediaServerItem, param.getApp(), param.getStream(), param.getUrl(), - param.isEnable_audio(), param.isEnable_mp4(), param.getRtp_type()); + param.isEnableAudio(), param.isEnableMp4(), param.getRtpType()); }else if ("ffmpeg".equals(param.getType())) { - result = zlmresTfulUtils.addFFmpegSource(mediaServerItem, param.getSrc_url(), param.getDst_url(), - param.getTimeout_ms() + "", param.isEnable_audio(), param.isEnable_mp4(), - param.getFfmpeg_cmd_key()); + result = zlmresTfulUtils.addFFmpegSource(mediaServerItem, param.getSrcUrl(), param.getDstUrl(), + param.getTimeoutMs() + "", param.isEnableAudio(), param.isEnableMp4(), + param.getFfmpegCmdKey()); } return result; } @@ -286,7 +357,7 @@ updateStreamProxy(streamProxy); }else { logger.info("鍚敤浠g悊澶辫触锛� {}/{}->{}({})", app, stream, jsonObject.getString("msg"), - streamProxy.getSrc_url() == null? streamProxy.getUrl():streamProxy.getSrc_url()); + streamProxy.getSrcUrl() == null? streamProxy.getUrl():streamProxy.getSrcUrl()); } } return result; diff --git a/src/main/java/com/genersoft/iot/vmp/service/impl/StreamPushServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/service/impl/StreamPushServiceImpl.java index 0a03c66..dcaab9e 100644 --- a/src/main/java/com/genersoft/iot/vmp/service/impl/StreamPushServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/service/impl/StreamPushServiceImpl.java @@ -183,6 +183,7 @@ @Override public boolean stop(String app, String streamId) { + logger.info("[鎺ㄦ祦 ] 鍋滄娴侊細 {}/{}", app, streamId); StreamPushItem streamPushItem = streamPushMapper.selectOne(app, streamId); if (streamPushItem != null) { gbStreamService.sendCatalogMsg(streamPushItem, CatalogEvent.DEL); diff --git a/src/main/java/com/genersoft/iot/vmp/service/redisMsg/RedisCloseStreamMsgListener.java b/src/main/java/com/genersoft/iot/vmp/service/redisMsg/RedisCloseStreamMsgListener.java new file mode 100644 index 0000000..d010475 --- /dev/null +++ b/src/main/java/com/genersoft/iot/vmp/service/redisMsg/RedisCloseStreamMsgListener.java @@ -0,0 +1,59 @@ +package com.genersoft.iot.vmp.service.redisMsg; + +import com.alibaba.fastjson2.JSON; +import com.alibaba.fastjson2.JSONObject; +import com.genersoft.iot.vmp.service.IStreamPushService; +import org.jetbrains.annotations.NotNull; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.data.redis.connection.Message; +import org.springframework.data.redis.connection.MessageListener; +import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; +import org.springframework.stereotype.Component; + +import java.util.concurrent.ConcurrentLinkedQueue; + +/** + * 鎺ユ敹鏉ヨ嚜redis鐨勫叧闂祦鏇存柊閫氱煡 + * @author lin + */ +@Component +public class RedisCloseStreamMsgListener implements MessageListener { + + private final static Logger logger = LoggerFactory.getLogger(RedisCloseStreamMsgListener.class); + + + @Autowired + private IStreamPushService pushService; + + private ConcurrentLinkedQueue<Message> taskQueue = new ConcurrentLinkedQueue<>(); + + @Qualifier("taskExecutor") + @Autowired + private ThreadPoolTaskExecutor taskExecutor; + + @Override + public void onMessage(@NotNull Message message, byte[] bytes) { + boolean isEmpty = taskQueue.isEmpty(); + taskQueue.offer(message); + if (isEmpty) { + taskExecutor.execute(() -> { + while (!taskQueue.isEmpty()) { + Message msg = taskQueue.poll(); + try { + JSONObject jsonObject = JSON.parseObject(msg.getBody()); + String app = jsonObject.getString("app"); + String stream = jsonObject.getString("stream"); + pushService.stop(app, stream); + + }catch (Exception e) { + logger.warn("[REDIS鐨勫叧闂帹娴侀�氱煡] 鍙戠幇鏈鐞嗙殑寮傚父, \r\n{}", JSON.toJSONString(message)); + logger.error("[REDIS鐨勫叧闂帹娴侀�氱煡] 寮傚父鍐呭锛� ", e); + } + } + }); + } + } +} 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 5e6c16b..469f6c8 100644 --- a/src/main/java/com/genersoft/iot/vmp/storager/IRedisCatchStorage.java +++ b/src/main/java/com/genersoft/iot/vmp/storager/IRedisCatchStorage.java @@ -202,4 +202,5 @@ void removeAllDevice(); void sendDeviceOrChannelStatus(String deviceId, String channelId, boolean online); + void sendChannelAddOrDelete(String deviceId, String channelId, boolean add); } diff --git a/src/main/java/com/genersoft/iot/vmp/storager/dao/ParentPlatformMapper.java b/src/main/java/com/genersoft/iot/vmp/storager/dao/ParentPlatformMapper.java index 056b409..2c6852a 100644 --- a/src/main/java/com/genersoft/iot/vmp/storager/dao/ParentPlatformMapper.java +++ b/src/main/java/com/genersoft/iot/vmp/storager/dao/ParentPlatformMapper.java @@ -96,6 +96,6 @@ @Select("select 'channel' as name, count(pgc.platform_id) count from wvp_platform_gb_channel pgc left join wvp_device_channel dc on dc.id = pgc.device_channel_id where pgc.platform_id=#{platform_id} and dc.channel_id =#{gbId} " + "union " + - "select 'stream' as name, count(pgs.platform_id) count from wvp_platform_gb_stream pgs left join wvp_gb_stream gs on pgs.gb_stream_id = gs.gb_stream_id where pgs.platform_id=#{platform_id} and gs.gb_id #{gbId}") + "select 'stream' as name, count(pgs.platform_id) count from wvp_platform_gb_stream pgs left join wvp_gb_stream gs on pgs.gb_stream_id = gs.gb_stream_id where pgs.platform_id=#{platform_id} and gs.gb_id =#{gbId}") List<ChannelSourceInfo> getChannelSource(String platform_id, String gbId); } diff --git a/src/main/java/com/genersoft/iot/vmp/storager/dao/PlatformCatalogMapper.java b/src/main/java/com/genersoft/iot/vmp/storager/dao/PlatformCatalogMapper.java index 19e7d1a..15fed7b 100644 --- a/src/main/java/com/genersoft/iot/vmp/storager/dao/PlatformCatalogMapper.java +++ b/src/main/java/com/genersoft/iot/vmp/storager/dao/PlatformCatalogMapper.java @@ -12,7 +12,7 @@ @Repository public interface PlatformCatalogMapper { - @Insert("INSERT INTO platform_catalog (id, name, platform_id, parent_id, civil_code, business_group_id) VALUES" + + @Insert("INSERT INTO wvp_platform_catalog (id, name, platform_id, parent_id, civil_code, business_group_id) VALUES" + "(#{id}, #{name}, #{platformId}, #{parentId}, #{civilCode}, #{businessGroupId})") int add(PlatformCatalog platformCatalog); @@ -32,7 +32,7 @@ PlatformCatalog select(String id); @Update(value = {" <script>" + - "UPDATE platform_catalog " + + "UPDATE wvp_platform_catalog " + "SET name=#{name}" + "WHERE id=#{id}"+ "</script>"}) @@ -41,11 +41,11 @@ @Select("SELECT *, (SELECT COUNT(1) from wvp_platform_catalog where parent_id = pc.id) as children_count from wvp_platform_catalog pc WHERE pc.platform_id=#{platformId}") List<PlatformCatalog> selectByPlatForm(String platformId); - @Select("SELECT pc.* FROM platform_catalog pc WHERE pc.id = (SELECT pp.catalog_id from wvp_platform pp WHERE pp.server_gb_id=#{platformId})") + @Select("SELECT pc.* FROM wvp_platform_catalog pc WHERE pc.id = (SELECT pp.catalog_id from wvp_platform pp WHERE pp.server_gb_id=#{platformId})") PlatformCatalog selectDefaultByPlatFormId(String platformId); - @Select("SELECT pc.* FROM platform_catalog pc WHERE pc.id = #{id}") + @Select("SELECT pc.* FROM wvp_platform_catalog pc WHERE pc.id = #{id}") PlatformCatalog selectParentCatalog(String id); @Select("SELECT pc.id as channel_id, pc.name, pc.civil_code, pc.business_group_id,'1' as parental, pc.parent_id " + diff --git a/src/main/java/com/genersoft/iot/vmp/storager/dao/StreamProxyMapper.java b/src/main/java/com/genersoft/iot/vmp/storager/dao/StreamProxyMapper.java index 3a1a69e..a5a80c4 100644 --- a/src/main/java/com/genersoft/iot/vmp/storager/dao/StreamProxyMapper.java +++ b/src/main/java/com/genersoft/iot/vmp/storager/dao/StreamProxyMapper.java @@ -13,9 +13,9 @@ @Insert("INSERT INTO wvp_stream_proxy (type, name, app, stream,media_server_id, url, src_url, dst_url, " + "timeout_ms, ffmpeg_cmd_key, rtp_type, enable_audio, enable_mp4, enable, status, enable_remove_none_reader, enable_disable_none_reader, create_time) VALUES" + - "(#{type}, #{name}, #{app}, #{stream}, #{mediaServerId}, #{url}, #{src_url}, #{dst_url}, " + - "#{timeout_ms}, #{ffmpeg_cmd_key}, #{rtp_type}, #{enable_audio}, #{enable_mp4}, #{enable}, #{status}, " + - "#{enable_remove_none_reader}, #{enable_disable_none_reader}, #{createTime} )") + "(#{type}, #{name}, #{app}, #{stream}, #{mediaServerId}, #{url}, #{srcUrl}, #{dstUrl}, " + + "#{timeoutMs}, #{ffmpegCmdKey}, #{rtpType}, #{enableAudio}, #{enableMp4}, #{enable}, #{status}, " + + "#{enableRemoveNoneReader}, #{enableDisableNoneReader}, #{createTime} )") int add(StreamProxyItem streamProxyDto); @Update("UPDATE wvp_stream_proxy " + @@ -25,17 +25,17 @@ "stream=#{stream}," + "url=#{url}, " + "media_server_id=#{mediaServerId}, " + - "src_url=#{src_url}," + - "dst_url=#{dst_url}, " + - "timeout_ms=#{timeout_ms}, " + - "ffmpeg_cmd_key=#{ffmpeg_cmd_key}, " + - "rtp_type=#{rtp_type}, " + - "enable_audio=#{enable_audio}, " + + "src_url=#{srcUrl}," + + "dst_url=#{dstUrl}, " + + "timeout_ms=#{timeoutMs}, " + + "ffmpeg_cmd_key=#{ffmpegCmdKey}, " + + "rtp_type=#{rtpType}, " + + "enable_audio=#{enableAudio}, " + "enable=#{enable}, " + "status=#{status}, " + - "enable_remove_none_reader=#{enable_remove_none_reader}, " + - "enable_disable_none_reader=#{enable_disable_none_reader}, " + - "enable_mp4=#{enable_mp4} " + + "enable_remove_none_reader=#{enableRemoveNoneReader}, " + + "enable_disable_none_reader=#{enableDisableNoneReader}, " + + "enable_mp4=#{enableMp4} " + "WHERE app=#{app} AND stream=#{stream}") int update(StreamProxyItem streamProxyDto); 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 75e9198..5360294 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 @@ -596,18 +596,29 @@ @Override public void sendDeviceOrChannelStatus(String deviceId, String channelId, boolean online) { String key = VideoManagerConstants.VM_MSG_SUBSCRIBE_DEVICE_STATUS; - if (channelId == null) { - logger.info("[redis閫氱煡] 鎺ㄩ�佽澶囩姸鎬侊紝 {}-{}", deviceId, online); - }else { - logger.info("[redis閫氱煡] 鎺ㄩ�侀�氶亾鐘舵�侊紝 {}/{}-{}", deviceId, channelId, online); - } - StringBuilder msg = new StringBuilder(); msg.append(deviceId); if (channelId != null) { msg.append(":").append(channelId); } msg.append(" ").append(online? "ON":"OFF"); + logger.info("[redis閫氱煡] 鎺ㄩ�佺姸鎬�-> {} ", msg); + // 浣跨敤 RedisTemplate<Object, Object> 鍙戦�佸瓧绗︿覆娑堟伅浼氬鑷村彂閫佺殑娑堟伅澶氬甫浜嗗弻寮曞彿 + stringRedisTemplate.convertAndSend(key, msg.toString()); + } + + @Override + public void sendChannelAddOrDelete(String deviceId, String channelId, boolean add) { + String key = VideoManagerConstants.VM_MSG_SUBSCRIBE_DEVICE_STATUS; + + + StringBuilder msg = new StringBuilder(); + msg.append(deviceId); + if (channelId != null) { + msg.append(":").append(channelId); + } + msg.append(" ").append(add? "ADD":"DELETE"); + logger.info("[redis閫氱煡] 鎺ㄩ�侀�氶亾-> {}", msg); // 浣跨敤 RedisTemplate<Object, Object> 鍙戦�佸瓧绗︿覆娑堟伅浼氬鑷村彂閫佺殑娑堟伅澶氬甫浜嗗弻寮曞彿 stringRedisTemplate.convertAndSend(key, msg.toString()); } diff --git a/src/main/java/com/genersoft/iot/vmp/vmanager/bean/ErrorCode.java b/src/main/java/com/genersoft/iot/vmp/vmanager/bean/ErrorCode.java index 7e2b512..e2e3879 100644 --- a/src/main/java/com/genersoft/iot/vmp/vmanager/bean/ErrorCode.java +++ b/src/main/java/com/genersoft/iot/vmp/vmanager/bean/ErrorCode.java @@ -6,7 +6,7 @@ public enum ErrorCode { SUCCESS(0, "鎴愬姛"), ERROR100(100, "澶辫触"), - ERROR400(400, "鍙傛暟涓嶅叏鎴栬�呴敊璇�"), + ERROR400(400, "鍙傛暟鎴栨柟娉曢敊璇�"), ERROR404(404, "璧勬簮鏈壘鍒�"), ERROR403(403, "鏃犳潈闄愭搷浣�"), ERROR401(401, "璇风櫥褰曞悗閲嶆柊璇锋眰"), diff --git a/src/main/java/com/genersoft/iot/vmp/vmanager/bean/SnapPath.java b/src/main/java/com/genersoft/iot/vmp/vmanager/bean/SnapPath.java new file mode 100644 index 0000000..ce34d72 --- /dev/null +++ b/src/main/java/com/genersoft/iot/vmp/vmanager/bean/SnapPath.java @@ -0,0 +1,50 @@ +package com.genersoft.iot.vmp.vmanager.bean; + +import io.swagger.v3.oas.annotations.media.Schema; + +@Schema(description = "鎴浘鍦板潃淇℃伅") +public class SnapPath { + + @Schema(description = "鐩稿鍦板潃") + private String path; + + @Schema(description = "缁濆鍦板潃") + private String absoluteFilePath; + + @Schema(description = "璇锋眰鍦板潃") + private String url; + + + public static SnapPath getInstance(String path, String absoluteFilePath, String url) { + SnapPath snapPath = new SnapPath(); + snapPath.setPath(path); + snapPath.setAbsoluteFilePath(absoluteFilePath); + snapPath.setUrl(url); + return snapPath; + } + + + public String getPath() { + return path; + } + + public void setPath(String path) { + this.path = path; + } + + public String getAbsoluteFilePath() { + return absoluteFilePath; + } + + public void setAbsoluteFilePath(String absoluteFilePath) { + this.absoluteFilePath = absoluteFilePath; + } + + public String getUrl() { + return url; + } + + public void setUrl(String url) { + this.url = url; + } +} diff --git a/src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/MobilePosition/MobilePositionController.java b/src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/MobilePosition/MobilePositionController.java index 5046faa..684708c 100644 --- a/src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/MobilePosition/MobilePositionController.java +++ b/src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/MobilePosition/MobilePositionController.java @@ -102,7 +102,7 @@ public DeferredResult<MobilePosition> realTimePosition(@PathVariable String deviceId) { Device device = storager.queryVideoDevice(deviceId); String uuid = UUID.randomUUID().toString(); - String key = DeferredResultHolder.CALLBACK_CMD_MOBILEPOSITION + deviceId; + String key = DeferredResultHolder.CALLBACK_CMD_MOBILE_POSITION + deviceId; try { cmder.mobilePostitionQuery(device, event -> { RequestMessage msg = new RequestMessage(); diff --git a/src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/device/DeviceQuery.java b/src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/device/DeviceQuery.java index 0ff8ba1..06dfb00 100644 --- a/src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/device/DeviceQuery.java +++ b/src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/device/DeviceQuery.java @@ -466,10 +466,12 @@ @Operation(summary = "璇锋眰鎴浘") @Parameter(name = "deviceId", description = "璁惧鍥芥爣缂栧彿", required = true) @Parameter(name = "channelId", description = "閫氶亾鍥芥爣缂栧彿", required = true) - public void getSnap(HttpServletResponse resp, @PathVariable String deviceId, @PathVariable String channelId) { + @Parameter(name = "mark", description = "鏍囪瘑", required = false) + public void getSnap(HttpServletResponse resp, @PathVariable String deviceId, @PathVariable String channelId, @RequestParam(required = false) String mark) { try { - final InputStream in = Files.newInputStream(new File("snap" + File.separator + deviceId + "_" + channelId + ".jpg").toPath()); + + final InputStream in = Files.newInputStream(new File("snap" + File.separator + deviceId + "_" + channelId + (mark == null? ".jpg": ("_" + mark + ".jpg"))).toPath()); resp.setContentType(MediaType.IMAGE_PNG_VALUE); IOUtils.copy(in, resp.getOutputStream()); } catch (IOException e) { diff --git a/src/main/java/com/genersoft/iot/vmp/vmanager/streamProxy/StreamProxyController.java b/src/main/java/com/genersoft/iot/vmp/vmanager/streamProxy/StreamProxyController.java index 4a8522b..0689f42 100644 --- a/src/main/java/com/genersoft/iot/vmp/vmanager/streamProxy/StreamProxyController.java +++ b/src/main/java/com/genersoft/iot/vmp/vmanager/streamProxy/StreamProxyController.java @@ -1,13 +1,18 @@ package com.genersoft.iot.vmp.vmanager.streamProxy; import com.alibaba.fastjson2.JSONObject; +import com.genersoft.iot.vmp.common.StreamInfo; +import com.genersoft.iot.vmp.conf.UserSetting; import com.genersoft.iot.vmp.conf.exception.ControllerException; +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; import com.genersoft.iot.vmp.media.zlm.dto.StreamProxyItem; import com.genersoft.iot.vmp.service.IMediaServerService; import com.genersoft.iot.vmp.service.IStreamProxyService; import com.genersoft.iot.vmp.vmanager.bean.ErrorCode; import com.genersoft.iot.vmp.vmanager.bean.StreamContent; +import com.genersoft.iot.vmp.vmanager.bean.WVPResult; import com.github.pagehelper.PageInfo; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; @@ -18,6 +23,9 @@ import org.springframework.stereotype.Controller; import org.springframework.util.ObjectUtils; import org.springframework.web.bind.annotation.*; +import org.springframework.web.context.request.async.DeferredResult; + +import java.util.UUID; @SuppressWarnings("rawtypes") /** @@ -36,6 +44,12 @@ @Autowired private IStreamProxyService streamProxyService; + + @Autowired + private DeferredResultHolder resultHolder; + + @Autowired + private UserSetting userSetting; @Operation(summary = "鍒嗛〉鏌ヨ娴佷唬鐞�") @@ -58,7 +72,7 @@ }) @PostMapping(value = "/save") @ResponseBody - public StreamContent save(@RequestBody StreamProxyItem param){ + public DeferredResult<Object> save(@RequestBody StreamProxyItem param){ logger.info("娣诲姞浠g悊锛� " + JSONObject.toJSONString(param)); if (ObjectUtils.isEmpty(param.getMediaServerId())) { param.setMediaServerId("auto"); @@ -69,7 +83,33 @@ if (ObjectUtils.isEmpty(param.getGbId())) { param.setGbId(null); } - return new StreamContent(streamProxyService.save(param)); + + RequestMessage requestMessage = new RequestMessage(); + String key = DeferredResultHolder.CALLBACK_CMD_PROXY + param.getApp() + param.getStream(); + requestMessage.setKey(key); + String uuid = UUID.randomUUID().toString(); + requestMessage.setId(uuid); + DeferredResult<Object> result = new DeferredResult<>(userSetting.getPlayTimeout().longValue()); + // 褰曞儚鏌ヨ浠hannelId浣滀负deviceId鏌ヨ + resultHolder.put(key, uuid, result); + result.onTimeout(()->{ + WVPResult<StreamInfo> wvpResult = new WVPResult<>(); + wvpResult.setCode(ErrorCode.ERROR100.getCode()); + wvpResult.setMsg("瓒呮椂"); + requestMessage.setData(wvpResult); + resultHolder.invokeAllResult(requestMessage); + }); + + streamProxyService.save(param, (code, msg, streamInfo) -> { + logger.info("[鎷夋祦浠g悊] {}", code == ErrorCode.SUCCESS.getCode()? "鎴愬姛":"澶辫触锛� " + msg); + if (code == ErrorCode.SUCCESS.getCode()) { + requestMessage.setData(new StreamContent(streamInfo)); + }else { + requestMessage.setData(WVPResult.fail(code, msg)); + } + resultHolder.invokeAllResult(requestMessage); + }); + return result; } @GetMapping(value = "/ffmpeg_cmd/list") diff --git a/src/main/resources/all-application.yml b/src/main/resources/all-application.yml index def2a3c..d67eac5 100644 --- a/src/main/resources/all-application.yml +++ b/src/main/resources/all-application.yml @@ -43,10 +43,6 @@ idle-timeout: 300000 # 鍏佽杩炴帴鍦ㄨ繛鎺ユ睜涓┖闂茬殑鏈�闀挎椂闂达紙浠ユ绉掍负鍗曚綅锛� max-lifetime: 1200000 # 鏄睜涓繛鎺ュ叧闂悗鐨勬渶闀跨敓鍛藉懆鏈燂紙浠ユ绉掍负鍗曚綅) -# 淇敼涓烘暟鎹簱瀛楁涓嬪垝绾垮垎闅旂洿鎺ュ搴攋ava椹煎嘲鍛藉悕 -mybatis: - configuration: - map-underscore-to-camel-case: true # 淇敼鍒嗛〉鎻掍欢涓� postgresql锛� 鏁版嵁搴撶被鍨嬩负mysql涓嶉渶瑕� #pagehelper: diff --git a/web_src/src/components/StreamProxyList.vue b/web_src/src/components/StreamProxyList.vue index 47ccde8..ff079cb 100644 --- a/web_src/src/components/StreamProxyList.vue +++ b/web_src/src/components/StreamProxyList.vue @@ -22,8 +22,8 @@ {{scope.row.url}} </el-tag> <el-tag size="medium" v-if="scope.row.type != 'default'"> - <i class="cpoy-btn el-icon-document-copy" title="鐐瑰嚮鎷疯礉" v-clipboard="scope.row.src_url" @success="$message({type:'success', message:'鎴愬姛鎷疯礉鍒扮矘璐存澘'})"></i> - {{scope.row.src_url}} + <i class="cpoy-btn el-icon-document-copy" title="鐐瑰嚮鎷疯礉" v-clipboard="scope.row.srcUrl" @success="$message({type:'success', message:'鎴愬姛鎷疯礉鍒扮矘璐存澘'})"></i> + {{scope.row.srcUrl}} </el-tag> </div> </template> @@ -58,25 +58,25 @@ <el-table-column label="闊抽" min-width="120" > <template slot-scope="scope"> <div slot="reference" class="name-wrapper"> - <el-tag size="medium" v-if="scope.row.enable_audio">宸插惎鐢�</el-tag> - <el-tag size="medium" type="info" v-if="!scope.row.enable_audio">鏈惎鐢�</el-tag> + <el-tag size="medium" v-if="scope.row.enableAudio">宸插惎鐢�</el-tag> + <el-tag size="medium" type="info" v-if="!scope.row.enableAudio">鏈惎鐢�</el-tag> </div> </template> </el-table-column> <el-table-column label="褰曞埗" min-width="120" > <template slot-scope="scope"> <div slot="reference" class="name-wrapper"> - <el-tag size="medium" v-if="scope.row.enable_mp4">宸插惎鐢�</el-tag> - <el-tag size="medium" type="info" v-if="!scope.row.enable_mp4">鏈惎鐢�</el-tag> + <el-tag size="medium" v-if="scope.row.enableMp4">宸插惎鐢�</el-tag> + <el-tag size="medium" type="info" v-if="!scope.row.enableMp4">鏈惎鐢�</el-tag> </div> </template> </el-table-column> <el-table-column label="鏃犱汉瑙傜湅" min-width="160" > <template slot-scope="scope"> <div slot="reference" class="name-wrapper"> - <el-tag size="medium" v-if="scope.row.enable_remove_none_reader">绉婚櫎</el-tag> - <el-tag size="medium" v-if="scope.row.enable_disable_none_reader">鍋滅敤</el-tag> - <el-tag size="medium" type="info" v-if="!scope.row.enable_remove_none_reader && !scope.row.enable_disable_none_reader">涓嶅仛澶勭悊</el-tag> + <el-tag size="medium" v-if="scope.row.enableRemoveNoneReader">绉婚櫎</el-tag> + <el-tag size="medium" v-if="scope.row.enableDisableNoneReader">鍋滅敤</el-tag> + <el-tag size="medium" type="info" v-if="!scope.row.enableRemoveNoneReader && !scope.row.enableDisableNoneReader">涓嶅仛澶勭悊</el-tag> </div> </template> </el-table-column> @@ -197,7 +197,7 @@ this.$refs.onvifEdit.openDialog(res.data.data, (url)=>{ if (url != null) { this.$refs.onvifEdit.close(); - this.$refs.streamProxyEdit.openDialog({type: "default", url: url, src_url: url}, this.initData()) + this.$refs.streamProxyEdit.openDialog({type: "default", url: url, srcUrl: url}, this.initData()) } }) }else { @@ -245,18 +245,25 @@ }, deleteStreamProxy: function(row){ let that = this; - that.$axios({ - method:"delete", - url:"/api/proxy/del", - params:{ - app: row.app, - stream: row.stream - } - }).then((res)=>{ - that.initData() - }).catch(function (error) { - console.log(error); - }); + this.$confirm('纭畾鍒犻櫎姝や唬鐞嗗悧锛�', '鎻愮ず', { + confirmButtonText: '纭畾', + cancelButtonText: '鍙栨秷', + type: 'warning' + }).then(() => { + that.$axios({ + method:"delete", + url:"/api/proxy/del", + params:{ + app: row.app, + stream: row.stream + } + }).then((res)=>{ + that.initData() + }).catch(function (error) { + console.log(error); + }); + }).catch(() => { + }); }, start: function(row){ this.stopUpdateList() diff --git a/web_src/src/components/dialog/StreamProxyEdit.vue b/web_src/src/components/dialog/StreamProxyEdit.vue index 76011fa..588f114 100644 --- a/web_src/src/components/dialog/StreamProxyEdit.vue +++ b/web_src/src/components/dialog/StreamProxyEdit.vue @@ -33,13 +33,13 @@ <el-form-item label="鎷夋祦鍦板潃" prop="url" v-if="proxyParam.type=='default'"> <el-input v-model="proxyParam.url" clearable></el-input> </el-form-item> - <el-form-item label="鎷夋祦鍦板潃" prop="src_url" v-if="proxyParam.type=='ffmpeg'"> - <el-input v-model="proxyParam.src_url" clearable></el-input> + <el-form-item label="鎷夋祦鍦板潃" prop="srcUrl" v-if="proxyParam.type=='ffmpeg'"> + <el-input v-model="proxyParam.srcUrl" clearable></el-input> </el-form-item> - <el-form-item label="瓒呮椂鏃堕棿:姣" prop="timeout_ms" v-if="proxyParam.type=='ffmpeg'"> - <el-input v-model="proxyParam.timeout_ms" clearable></el-input> + <el-form-item label="瓒呮椂鏃堕棿:姣" prop="timeoutMs" v-if="proxyParam.type=='ffmpeg'"> + <el-input v-model="proxyParam.timeoutMs" clearable></el-input> </el-form-item> - <el-form-item label="鑺傜偣閫夋嫨" prop="rtp_type"> + <el-form-item label="鑺傜偣閫夋嫨" prop="rtpType"> <el-select v-model="proxyParam.mediaServerId" @change="mediaServerIdChange" @@ -54,10 +54,9 @@ </el-option> </el-select> </el-form-item> - <el-form-item label="FFmpeg鍛戒护妯℃澘" prop="ffmpeg_cmd_key" v-if="proxyParam.type=='ffmpeg'"> -<!-- <el-input v-model="proxyParam.ffmpeg_cmd_key" clearable></el-input>--> + <el-form-item label="FFmpeg鍛戒护妯℃澘" prop="ffmpegCmdKey" v-if="proxyParam.type=='ffmpeg'"> <el-select - v-model="proxyParam.ffmpeg_cmd_key" + v-model="proxyParam.ffmpegCmdKey" style="width: 100%" placeholder="璇烽�夋嫨FFmpeg鍛戒护妯℃澘" > @@ -72,9 +71,9 @@ <el-form-item label="鍥芥爣缂栫爜" prop="gbId"> <el-input v-model="proxyParam.gbId" placeholder="璁剧疆鍥芥爣缂栫爜鍙帹閫佸埌鍥芥爣" clearable></el-input> </el-form-item> - <el-form-item label="鎷夋祦鏂瑰紡" prop="rtp_type" v-if="proxyParam.type=='default'"> + <el-form-item label="鎷夋祦鏂瑰紡" prop="rtpType" v-if="proxyParam.type=='default'"> <el-select - v-model="proxyParam.rtp_type" + v-model="proxyParam.rtpType" style="width: 100%" placeholder="璇烽�夋嫨鎷夋祦鏂瑰紡" > @@ -83,10 +82,10 @@ <el-option label="缁勬挱" value="2"></el-option> </el-select> </el-form-item> - <el-form-item label="鏃犱汉瑙傜湅" prop="rtp_type" > + <el-form-item label="鏃犱汉瑙傜湅" prop="rtpType" > <el-select @change="noneReaderHandler" - v-model="proxyParam.none_reader" + v-model="proxyParam.noneReader" style="width: 100%" placeholder="璇烽�夋嫨鏃犱汉瑙傜湅鐨勫鐞嗘柟寮�" > @@ -98,8 +97,8 @@ <el-form-item label="鍏朵粬閫夐」"> <div style="float: left;"> <el-checkbox label="鍚敤" v-model="proxyParam.enable" ></el-checkbox> - <el-checkbox label="寮�鍚煶棰�" v-model="proxyParam.enable_audio" ></el-checkbox> - <el-checkbox label="褰曞埗" v-model="proxyParam.enable_mp4" ></el-checkbox> + <el-checkbox label="寮�鍚煶棰�" v-model="proxyParam.enableAudio" ></el-checkbox> + <el-checkbox label="褰曞埗" v-model="proxyParam.enableMp4" ></el-checkbox> </div> </el-form-item> @@ -155,17 +154,17 @@ app: null, stream: null, url: "", - src_url: null, - timeout_ms: null, - ffmpeg_cmd_key: null, + srcUrl: null, + timeoutMs: null, + ffmpegCmdKey: null, gbId: null, - rtp_type: null, + rtpType: null, enable: true, - enable_audio: true, - enable_mp4: false, - none_reader: null, - enable_remove_none_reader: false, - enable_disable_none_reader: false, + enableAudio: true, + enableMp4: false, + noneReader: null, + enableRemoveNoneReader: false, + enableDisableNoneReader: false, platformGbId: null, mediaServerId: null, }, @@ -177,9 +176,9 @@ app: [{ required: true, message: "璇疯緭鍏ュ簲鐢ㄥ悕", trigger: "blur" }], stream: [{ required: true, message: "璇疯緭鍏ユ祦ID", trigger: "blur" }], url: [{ required: true, message: "璇疯緭鍏ヨ浠g悊鐨勬祦", trigger: "blur" }], - src_url: [{ required: true, message: "璇疯緭鍏ヨ浠g悊鐨勬祦", trigger: "blur" }], - timeout_ms: [{ required: true, message: "璇疯緭鍏Fmpeg鎺ㄦ祦鎴愬姛瓒呮椂鏃堕棿", trigger: "blur" }], - ffmpeg_cmd_key: [{ required: false, message: "璇疯緭鍏Fmpeg鍛戒护鍙傛暟妯℃澘锛堝彲閫夛級", trigger: "blur" }], + srcUrl: [{ required: true, message: "璇疯緭鍏ヨ浠g悊鐨勬祦", trigger: "blur" }], + timeoutMs: [{ required: true, message: "璇疯緭鍏Fmpeg鎺ㄦ祦鎴愬姛瓒呮椂鏃堕棿", trigger: "blur" }], + ffmpegCmdKey: [{ required: false, message: "璇疯緭鍏Fmpeg鍛戒护鍙傛暟妯℃澘锛堝彲閫夛級", trigger: "blur" }], }, }; }, @@ -189,7 +188,7 @@ this.listChangeCallback = callback; if (proxyParam != null) { this.proxyParam = proxyParam; - this.proxyParam.none_reader = null; + this.proxyParam.noneReader = null; } let that = this; @@ -218,7 +217,7 @@ } }).then(function (res) { that.ffmpegCmdList = res.data.data; - that.proxyParam.ffmpeg_cmd_key = Object.keys(res.data.data)[0]; + that.proxyParam.ffmpegCmdKey = Object.keys(res.data.data)[0]; }).catch(function (error) { console.log(error); }); @@ -275,15 +274,15 @@ } }, noneReaderHandler: function() { - if (this.proxyParam.none_reader === null || this.proxyParam.none_reader === "0") { - this.proxyParam.enable_disable_none_reader = false; - this.proxyParam.enable_remove_none_reader = false; - }else if (this.proxyParam.none_reader === "1"){ - this.proxyParam.enable_disable_none_reader = true; - this.proxyParam.enable_remove_none_reader = false; - }else if (this.proxyParam.none_reader ==="2"){ - this.proxyParam.enable_disable_none_reader = false; - this.proxyParam.enable_remove_none_reader = true; + if (this.proxyParam.noneReader === null || this.proxyParam.noneReader === "0") { + this.proxyParam.enableDisableNoneReader = false; + this.proxyParam.enableRemoveNoneReader = false; + }else if (this.proxyParam.noneReader === "1"){ + this.proxyParam.enableDisableNoneReader = true; + this.proxyParam.enableRemoveNoneReader = false; + }else if (this.proxyParam.noneReader ==="2"){ + this.proxyParam.enableDisableNoneReader = false; + this.proxyParam.enableRemoveNoneReader = true; } }, }, diff --git a/web_src/src/components/dialog/devicePlayer.vue b/web_src/src/components/dialog/devicePlayer.vue index e83a29c..9e4eea0 100644 --- a/web_src/src/components/dialog/devicePlayer.vue +++ b/web_src/src/components/dialog/devicePlayer.vue @@ -14,7 +14,6 @@ <rtc-player v-if="activePlayer === 'webRTC'" ref="webRTC" :visible.sync="showVideoDialog" :videoUrl="videoUrl" :error="videoError" :message="videoError" height="100px" :hasAudio="hasAudio" fluent autoplay live ></rtc-player> </el-tab-pane> <el-tab-pane label="h265web">h265web鏁鏈熷緟</el-tab-pane> - <el-tab-pane label="wsPlayer">wsPlayer 鏁鏈熷緟</el-tab-pane> </el-tabs> <jessibucaPlayer v-if="Object.keys(this.player).length == 1 && this.player.jessibuca" ref="jessibuca" :visible.sync="showVideoDialog" :videoUrl="videoUrl" :error="videoError" :message="videoError" height="100px" :hasAudio="hasAudio" fluent autoplay live ></jessibucaPlayer> <rtc-player v-if="Object.keys(this.player).length == 1 && this.player.webRTC" ref="jessibuca" :visible.sync="showVideoDialog" :videoUrl="videoUrl" :error="videoError" :message="videoError" height="100px" :hasAudio="hasAudio" fluent autoplay live ></rtc-player> @@ -451,7 +450,15 @@ playFromStreamInfo: function (realHasAudio, streamInfo) { this.showVideoDialog = true; this.hasaudio = realHasAudio && this.hasaudio; - this.$refs[this.activePlayer].play(this.getUrlByStreamInfo(streamInfo)) + if (this.$refs[this.activePlayer]) { + this.$refs[this.activePlayer].play(this.getUrlByStreamInfo(streamInfo)) + }else { + this.$nextTick(() => { + this.$refs[this.activePlayer].play(this.getUrlByStreamInfo(streamInfo)) + }); + } + + }, close: function () { console.log('鍏抽棴瑙嗛'); -- Gitblit v1.8.0