From 34135cce5d59f6ad7653737dd035bb1d441e185f Mon Sep 17 00:00:00 2001 From: panlinlin <648540858@qq.com> Date: 星期二, 05 一月 2021 15:56:19 +0800 Subject: [PATCH] Merge remote-tracking branch 'origin/master' into wvp-28181-2.0 --- src/main/java/com/genersoft/iot/vmp/gb28181/transmit/response/impl/InviteResponseProcessor.java | 41 src/main/java/com/genersoft/iot/vmp/gb28181/bean/Device.java | 57 src/main/java/com/genersoft/iot/vmp/vmanager/play/PlayController.java | 120 + src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java | 251 ++++- src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRTPServerFactory.java | 95 ++ src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRESTfulUtils.java | 4 src/main/java/com/genersoft/iot/vmp/common/StreamInfo.java | 9 pom.xml | 88 +- src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/ISIPCommander.java | 18 src/main/java/com/genersoft/iot/vmp/storager/dao/DeviceMapper.java | 66 + src/main/java/com/genersoft/iot/vmp/gb28181/auth/RegisterLogicHandler.java | 2 src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/SIPRequestHeaderProvider.java | 24 src/main/java/com/genersoft/iot/vmp/gb28181/bean/DeviceChannel.java | 37 src/main/java/com/genersoft/iot/vmp/storager/impl/RedisCatchStorageImpl.java | 166 +++ src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/RegisterRequestProcessor.java | 16 src/main/java/com/genersoft/iot/vmp/vmanager/service/impl/PlayServiceImpl.java | 19 src/main/java/com/genersoft/iot/vmp/storager/IRedisCatchStorage.java | 58 + src/main/java/com/genersoft/iot/vmp/web/ApiDeviceController.java | 23 src/main/java/com/genersoft/iot/vmp/gb28181/auth/DigestServerAuthenticationHelper.java | 98 ++ src/main/resources/application-dev.yml | 34 src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRunner.java | 6 src/main/java/com/genersoft/iot/vmp/gb28181/event/SipSubscribe.java | 50 + web_src/src/components/videoList.vue | 42 src/main/resources/wvp.sqlite | 0 web_src/src/components/gb28181/devicePlayer.vue | 21 src/main/java/com/genersoft/iot/vmp/gb28181/transmit/callback/DeferredResultHolder.java | 7 src/main/java/com/genersoft/iot/vmp/storager/impl/VideoManagerStoragerImpl.java | 202 ++++ src/main/java/com/genersoft/iot/vmp/vmanager/playback/PlaybackController.java | 15 src/main/java/com/genersoft/iot/vmp/conf/ApplicationCheckRunner.java | 63 + src/main/java/com/genersoft/iot/vmp/storager/IVideoManagerStorager.java | 102 -- src/main/java/com/genersoft/iot/vmp/vmanager/ptz/PtzController.java | 17 src/main/java/com/genersoft/iot/vmp/web/ApiStreamController.java | 152 -- /dev/null | 385 -------- src/main/java/com/genersoft/iot/vmp/gb28181/SipLayer.java | 28 web_src/src/components/channelList.vue | 40 src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java | 95 +- src/main/java/com/genersoft/iot/vmp/vmanager/device/DeviceController.java | 63 + src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPProcessorFactory.java | 14 src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHTTPProxyController.java | 8 src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/MessageRequestProcessor.java | 32 src/main/java/com/genersoft/iot/vmp/utils/SpringBeanFactory.java | 1 src/main/java/com/genersoft/iot/vmp/vmanager/record/RecordController.java | 13 src/main/java/com/genersoft/iot/vmp/storager/dao/DeviceChannelMapper.java | 51 + 43 files changed, 1,616 insertions(+), 1,017 deletions(-) diff --git a/pom.xml b/pom.xml index 86b4c17..2f45a6d 100644 --- a/pom.xml +++ b/pom.xml @@ -13,13 +13,38 @@ <artifactId>wvp</artifactId> <name>web video platform</name> + <repositories> + <repository> + <id>nexus-aliyun</id> + <name>Nexus aliyun</name> + <url>https://maven.aliyun.com/repository/public</url> + <layout>default</layout> + <snapshots> + <enabled>false</enabled> + </snapshots> + <releases> + <enabled>true</enabled> + </releases> + </repository> + </repositories> + <pluginRepositories> + <pluginRepository> + <id>nexus-aliyun</id> + <name>Nexus aliyun</name> + <url>https://maven.aliyun.com/repository/public</url> + <snapshots> + <enabled>false</enabled> + </snapshots> + <releases> + <enabled>true</enabled> + </releases> + </pluginRepository> + </pluginRepositories> + <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <!-- 渚濊禆鐗堟湰 --> - <mapper.version>4.1.5</mapper.version> - <mybatis.version>3.5.5</mybatis.version> - <mybatis.spring.version>2.0.5</mybatis.spring.version> <pagehelper.version>5.2.0</pagehelper.version> <snippetsDirectory>${project.build.directory}/generated-snippets</snippetsDirectory> <asciidoctor.input.directory>${project.basedir}/docs/asciidoc</asciidoctor.input.directory> @@ -31,30 +56,16 @@ <dependencies> <dependency> <groupId>org.springframework.boot</groupId> - <artifactId>spring-boot-starter-jdbc</artifactId> - </dependency> - <dependency> - <groupId>org.springframework.boot</groupId> - <artifactId>spring-boot-starter-tomcat</artifactId> + <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> - <groupId>org.springframework</groupId> - <artifactId>spring-context</artifactId> - </dependency> - - <!-- redis --> - <dependency> - <groupId>org.springframework.data</groupId> - <artifactId>spring-data-redis</artifactId> - </dependency> - <dependency> - <groupId>redis.clients</groupId> - <artifactId>jedis</artifactId> - <version>3.3.0</version> + <groupId>org.mybatis.spring.boot</groupId> + <artifactId>mybatis-spring-boot-starter</artifactId> + <version>2.1.4</version> </dependency> <!-- druid鏁版嵁搴撹繛鎺ユ睜 --> @@ -71,36 +82,25 @@ <version>8.0.22</version> </dependency> - <!--Mybatis --> + <!-- 娣诲姞sqlite-jdbc鏁版嵁搴撻┍鍔� --> <dependency> - <groupId>org.mybatis</groupId> - <artifactId>mybatis</artifactId> - <version>${mybatis.version}</version> - </dependency> - <dependency> - <groupId>org.mybatis</groupId> - <artifactId>mybatis-spring</artifactId> - <version>${mybatis.spring.version}</version> + <groupId>org.xerial</groupId> + <artifactId>sqlite-jdbc</artifactId> + <version>3.32.3.2</version> </dependency> - <!--鍒嗛〉鎻掍欢 --> + <!--Mybatis鍒嗛〉鎻掍欢 --> <dependency> <groupId>com.github.pagehelper</groupId> - <artifactId>pagehelper</artifactId> - <version>${pagehelper.version}</version> + <artifactId>pagehelper-spring-boot-starter</artifactId> + <version>1.2.10</version> </dependency> - <!--閫氱敤Mapper --> - <dependency> - <groupId>tk.mybatis</groupId> - <artifactId>mapper</artifactId> - <version>${mapper.version}</version> - </dependency> - <dependency> - <groupId>org.apache.commons</groupId> - <artifactId>commons-lang3</artifactId> - <version>3.11</version> - </dependency> +<!-- <dependency>--> +<!-- <groupId>org.apache.commons</groupId>--> +<!-- <artifactId>commons-lang3</artifactId>--> +<!-- <version>3.11</version>--> +<!-- </dependency>--> <!--Swagger2 --> <!--鍦ㄧ嚎鏂囨。 --> diff --git a/src/main/java/com/genersoft/iot/vmp/common/PageResult.java b/src/main/java/com/genersoft/iot/vmp/common/PageResult.java deleted file mode 100644 index 6d7c89e..0000000 --- a/src/main/java/com/genersoft/iot/vmp/common/PageResult.java +++ /dev/null @@ -1,45 +0,0 @@ -package com.genersoft.iot.vmp.common; - - -import java.util.List; - -public class PageResult<T> { - - private int page; - private int count; - private int total; - - private List<T> data; - - public List<T> getData() { - return data; - } - - public int getPage() { - return page; - } - - public void setPage(int page) { - this.page = page; - } - - public int getCount() { - return count; - } - - public void setCount(int count) { - this.count = count; - } - - public int getTotal() { - return total; - } - - public void setTotal(int total) { - this.total = total; - } - - public void setData(List<T> data) { - this.data = data; - } -} diff --git a/src/main/java/com/genersoft/iot/vmp/common/StreamInfo.java b/src/main/java/com/genersoft/iot/vmp/common/StreamInfo.java index 53bda91..0fb76b9 100644 --- a/src/main/java/com/genersoft/iot/vmp/common/StreamInfo.java +++ b/src/main/java/com/genersoft/iot/vmp/common/StreamInfo.java @@ -4,7 +4,6 @@ public class StreamInfo { - private String ssrc; private String streamId; private String deviceID; private String cahnnelId; @@ -19,14 +18,6 @@ private String rtmp; private String rtsp; private JSONArray tracks; - - public String getSsrc() { - return ssrc; - } - - public void setSsrc(String ssrc) { - this.ssrc = ssrc; - } public String getDeviceID() { return deviceID; diff --git a/src/main/java/com/genersoft/iot/vmp/conf/ApplicationCheckRunner.java b/src/main/java/com/genersoft/iot/vmp/conf/ApplicationCheckRunner.java new file mode 100644 index 0000000..faa9ef1 --- /dev/null +++ b/src/main/java/com/genersoft/iot/vmp/conf/ApplicationCheckRunner.java @@ -0,0 +1,63 @@ +package com.genersoft.iot.vmp.conf; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.CommandLineRunner; +import org.springframework.core.annotation.Order; +import org.springframework.stereotype.Component; + + +/** + * 瀵归厤缃枃浠惰繘琛屾牎楠� + */ +@Component +@Order(value=2) +public class ApplicationCheckRunner implements CommandLineRunner { + + private Logger logger = LoggerFactory.getLogger("ApplicationCheckRunner"); + + @Value("${sip.ip}") + private String sipIp; + + @Value("${media.ip}") + private String mediaIp; + + @Value("${media.wanIp}") + private String mediaWanIp; + + @Value("${media.hookIp}") + private String mediaHookIp; + + @Value("${media.port}") + private int mediaPort; + + @Value("${media.secret}") + private String mediaSecret; + + @Value("${media.streamNoneReaderDelayMS}") + private String streamNoneReaderDelayMS; + + @Value("${sip.ip}") + private String sipIP; + + @Value("${server.port}") + private String serverPort; + + @Value("${media.autoConfig}") + private boolean autoConfig; + + + @Override + public void run(String... args) throws Exception { + if (sipIP.equals("localhost") || sipIP.equals("127.0.0.1")) { + logger.error("sip.ip涓嶈兘浣跨敤 {} ,璇蜂娇鐢ㄧ被浼�192.168.1.44杩欐牱鐨勬潵鑷綉鍗$殑IP!!!", sipIP ); + System.exit(1); + } + + if (mediaIp.equals("localhost") || mediaIp.equals("127.0.0.1")) { + logger.warn("mediaIp.ip浣跨敤 {} ,灏嗘棤娉曟敹鍒扮綉缁滃唴鍏朵粬璁惧鐨勬帹娴�!!!", mediaIp ); + } + + } +} diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/SipLayer.java b/src/main/java/com/genersoft/iot/vmp/gb28181/SipLayer.java index 54c0711..0b4ecbb 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/SipLayer.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/SipLayer.java @@ -8,8 +8,10 @@ import java.util.concurrent.TimeUnit; import javax.sip.*; +import javax.sip.header.CallIdHeader; import javax.sip.message.Response; +import com.genersoft.iot.vmp.gb28181.event.SipSubscribe; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -33,6 +35,9 @@ @Autowired private SIPProcessorFactory processorFactory; + + @Autowired + private SipSubscribe sipSubscribe; private SipStack sipStack; @@ -133,17 +138,34 @@ // TODO Auto-generated catch block e.printStackTrace(); } + if (evt.getResponse() != null && sipSubscribe.getOkSubscribesSize() > 0 ) { + CallIdHeader callIdHeader = (CallIdHeader)evt.getResponse().getHeader(CallIdHeader.NAME); + if (callIdHeader != null) { + SipSubscribe.Event subscribe = sipSubscribe.getOkSubscribe(callIdHeader.getCallId()); + if (subscribe != null) { + subscribe.response(evt); + } + } + } // } else if (status == Response.TRYING) { // trying涓嶄細鍥炲 } else if ((status >= 100) && (status < 200)) { // 澧炲姞鍏跺畠鏃犻渶鍥炲鐨勫搷搴旓紝濡�101銆�180绛� } else { logger.warn("鎺ユ敹鍒板け璐ョ殑response鍝嶅簲锛乻tatus锛�" + status + ",message:" + response.getReasonPhrase()/* .getContent().toString()*/); + if (evt.getResponse() != null && sipSubscribe.getErrorSubscribesSize() > 0 ) { + CallIdHeader callIdHeader = (CallIdHeader)evt.getResponse().getHeader(CallIdHeader.NAME); + if (callIdHeader != null) { + SipSubscribe.Event subscribe = sipSubscribe.getErrorSubscribe(callIdHeader.getCallId()); + if (subscribe != null) { + subscribe.response(evt); + } + } + } } - // trying涓嶄細鍥炲 - // if (status == Response.TRYING) { - // } + + } /** diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/auth/DigestServerAuthenticationHelper.java b/src/main/java/com/genersoft/iot/vmp/gb28181/auth/DigestServerAuthenticationHelper.java index 637ee9a..16ed56a 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/auth/DigestServerAuthenticationHelper.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/auth/DigestServerAuthenticationHelper.java @@ -27,6 +27,7 @@ import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; +import java.text.DecimalFormat; import java.util.Date; import java.util.Random; @@ -103,9 +104,12 @@ .createWWWAuthenticateHeader(DEFAULT_SCHEME); proxyAuthenticate.setParameter("realm", realm); proxyAuthenticate.setParameter("nonce", generateNonce()); + proxyAuthenticate.setParameter("opaque", ""); proxyAuthenticate.setParameter("stale", "FALSE"); proxyAuthenticate.setParameter("algorithm", DEFAULT_ALGORITHM); + +// proxyAuthenticate.setParameter("qop", "auth"); response.setHeader(proxyAuthenticate); } catch (Exception ex) { InternalErrorHandler.handleException(ex); @@ -170,42 +174,116 @@ public boolean doAuthenticatePlainTextPassword(Request request, String pass) { AuthorizationHeader authHeader = (AuthorizationHeader) request.getHeader(AuthorizationHeader.NAME); if ( authHeader == null ) return false; - String realm = authHeader.getRealm(); - String username = authHeader.getUsername(); - - + String realm = authHeader.getRealm().trim(); + String username = authHeader.getUsername().trim(); + if ( username == null || realm == null ) { return false; } - String nonce = authHeader.getNonce(); URI uri = authHeader.getURI(); if (uri == null) { return false; } - + // qop 淇濇姢璐ㄩ噺 鍖呭惈auth锛堥粯璁ょ殑锛夊拰auth-int锛堝鍔犱簡鎶ユ枃瀹屾暣鎬ф娴嬶級涓ょ绛栫暐 + String qop = authHeader.getQop(); + + // 瀹㈡埛绔殢鏈烘暟锛岃繖鏄竴涓笉閫忔槑鐨勫瓧绗︿覆鍊硷紝鐢卞鎴风鎻愪緵锛屽苟涓斿鎴风鍜屾湇鍔″櫒閮戒細浣跨敤锛屼互閬垮厤鐢ㄦ槑鏂囨枃鏈�� + // 杩欎娇寰楀弻鏂归兘鍙互鏌ラ獙瀵规柟鐨勮韩浠斤紝骞跺娑堟伅鐨勫畬鏁存�ф彁渚涗竴浜涗繚鎶� + String cNonce = authHeader.getCNonce(); + + // nonce璁℃暟鍣紝鏄竴涓�16杩涘埗鐨勬暟鍊硷紝琛ㄧず鍚屼竴nonce涓嬪鎴风鍙戦�佸嚭璇锋眰鐨勬暟閲� + int nc = authHeader.getNonceCount(); + String ncStr = new DecimalFormat("00000000").format(nc); +// String ncStr = new DecimalFormat("00000000").format(Integer.parseInt(nc + "", 16)); String A1 = username + ":" + realm + ":" + pass; String A2 = request.getMethod().toUpperCase() + ":" + uri.toString(); byte mdbytes[] = messageDigest.digest(A1.getBytes()); String HA1 = toHexString(mdbytes); + System.out.println("A1: " + A1); + System.out.println("A2: " + A2); - mdbytes = messageDigest.digest(A2.getBytes()); String HA2 = toHexString(mdbytes); - + System.out.println("HA1: " + HA1); + System.out.println("HA2: " + HA2); String cnonce = authHeader.getCNonce(); + System.out.println("nonce: " + nonce); + System.out.println("nc: " + ncStr); + System.out.println("cnonce: " + cnonce); + System.out.println("qop: " + qop); String KD = HA1 + ":" + nonce; - if (cnonce != null) { - KD += ":" + cnonce; + + if (qop != null && qop.equals("auth") ) { + if (nc != -1) { + KD += ":" + ncStr; + } + if (cnonce != null) { + KD += ":" + cnonce; + } + KD += ":" + qop; } KD += ":" + HA2; + System.out.println("KD: " + KD); mdbytes = messageDigest.digest(KD.getBytes()); String mdString = toHexString(mdbytes); + System.out.println("mdString: " + mdString); String response = authHeader.getResponse(); + System.out.println("response: " + response); return mdString.equals(response); } + + public static void main(String[] args) throws NoSuchAlgorithmException { + MessageDigest messageDigest2 = MessageDigest.getInstance(DEFAULT_ALGORITHM); + String realm = "DS-2CD2520F"; + String username = "admin"; + String passwd = "12345"; + + String nonce = "4d6a553452444d30525441364e6d4d304e6a68684e47553d"; + + String uri = "/ISAPI/Streaming/channels/101/picture"; + // qop 淇濇姢璐ㄩ噺 鍖呭惈auth锛堥粯璁ょ殑锛夊拰auth-int锛堝鍔犱簡鎶ユ枃瀹屾暣鎬ф娴嬶級涓ょ绛栫暐 + String qop = "auth"; + + // 瀹㈡埛绔殢鏈烘暟锛岃繖鏄竴涓笉閫忔槑鐨勫瓧绗︿覆鍊硷紝鐢卞鎴风鎻愪緵锛屽苟涓斿鎴风鍜屾湇鍔″櫒閮戒細浣跨敤锛屼互閬垮厤鐢ㄦ槑鏂囨枃鏈�� + // 杩欎娇寰楀弻鏂归兘鍙互鏌ラ獙瀵规柟鐨勮韩浠斤紝骞跺娑堟伅鐨勫畬鏁存�ф彁渚涗竴浜涗繚鎶� + String cNonce = "C1A5298F939E87E8F962A5EDFC206918"; + + // nonce璁℃暟鍣紝鏄竴涓�16杩涘埗鐨勬暟鍊硷紝琛ㄧず鍚屼竴nonce涓嬪鎴风鍙戦�佸嚭璇锋眰鐨勬暟閲� + int nc = 1; + + String A1 = username + ":" + realm + ":" + passwd; + System.out.println("A1: " + A1); + String A2 = "GET" + ":" + uri.toString(); + System.out.println("A2: " + A2); + byte mdbytes[] = messageDigest2.digest(A1.getBytes()); + String HA1 = toHexString(mdbytes); + System.out.println("HA1: " + HA1); + + mdbytes = messageDigest2.digest(A2.getBytes()); + String HA2 = toHexString(mdbytes); + System.out.println("HA2: " + HA2); + String cnonce = "93d4d37df32e1a85"; + String KD = HA1 + ":" + nonce; + + if (nc != -1) { + KD += ":" + "00000001"; + } + if (cnonce != null) { + KD += ":" + cnonce; + } + if (qop != null) { + KD += ":" + qop; + } + KD += ":" + HA2; + System.out.println("KD: " + KD); + mdbytes = messageDigest2.digest(KD.getBytes()); + String mdString = toHexString(mdbytes); + String response = "3993a815e5cdaf4470e9b4f9bd41cf4a"; + System.out.println(mdString); + } } diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/auth/RegisterLogicHandler.java b/src/main/java/com/genersoft/iot/vmp/gb28181/auth/RegisterLogicHandler.java index 6e4588d..6fe63cc 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/auth/RegisterLogicHandler.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/auth/RegisterLogicHandler.java @@ -21,6 +21,6 @@ // TODO 鍚庣画澶勭悊锛屽彧鏈夌涓�娆℃敞鍐屾椂璋冪敤鏌ヨ璁惧淇℃伅锛屽闇�鏇存柊璋冪敤鏇存柊API鎺ュ彛 cmder.deviceInfoQuery(device); - cmder.catalogQuery(device); + cmder.catalogQuery(device, null); } } diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/bean/Device.java b/src/main/java/com/genersoft/iot/vmp/gb28181/bean/Device.java index de52ac6..9393106 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/bean/Device.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/bean/Device.java @@ -1,9 +1,6 @@ package com.genersoft.iot.vmp.gb28181.bean; -import java.util.List; -import java.util.Map; - public class Device { /** @@ -46,23 +43,35 @@ private String streamMode; /** + * wan鍦板潃_ip + */ + private String ip; + + /** + * wan鍦板潃_port + */ + private int port; + + /** * wan鍦板潃 */ - private Host host; + private String hostAddress; /** * 鍦ㄧ嚎 */ private int online; + /** - * 閫氶亾鍒楄〃 + * 娉ㄥ唽鏃堕棿 */ -// private Map<String,DeviceChannel> channelMap; + private Long registerTimeMillis; + /** + * 閫氶亾涓暟 + */ private int channelCount; - - private List<String> channelList; public String getDeviceId() { return deviceId; @@ -120,12 +129,28 @@ this.streamMode = streamMode; } - public Host getHost() { - return host; + public String getIp() { + return ip; } - public void setHost(Host host) { - this.host = host; + public void setIp(String ip) { + this.ip = ip; + } + + public int getPort() { + return port; + } + + public void setPort(int port) { + this.port = port; + } + + public String getHostAddress() { + return hostAddress; + } + + public void setHostAddress(String hostAddress) { + this.hostAddress = hostAddress; } public int getOnline() { @@ -144,11 +169,11 @@ this.channelCount = channelCount; } - public List<String> getChannelList() { - return channelList; + public Long getRegisterTimeMillis() { + return registerTimeMillis; } - public void setChannelList(List<String> channelList) { - this.channelList = channelList; + public void setRegisterTimeMillis(Long registerTimeMillis) { + this.registerTimeMillis = registerTimeMillis; } } diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/bean/DeviceChannel.java b/src/main/java/com/genersoft/iot/vmp/gb28181/bean/DeviceChannel.java index 810feab..ca6ef60 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/bean/DeviceChannel.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/bean/DeviceChannel.java @@ -2,10 +2,17 @@ public class DeviceChannel { + + /** * 閫氶亾id */ private String channelId; + + /** + * 璁惧id + */ + private String deviceId; /** * 閫氶亾鍚� @@ -141,18 +148,20 @@ /** * 娴佸敮涓�缂栧彿锛屽瓨鍦ㄨ〃绀烘鍦ㄧ洿鎾� */ - private String ssrc; + private String streamId; /** * 鏄惁鍚湁闊抽 */ - private boolean hasAudio; + private boolean hasAudio; - /** - * 鏄惁姝e湪鎾斁 - */ - private boolean play; + public String getDeviceId() { + return deviceId; + } + public void setDeviceId(String deviceId) { + this.deviceId = deviceId; + } public void setPTZType(int PTZType) { this.PTZType = PTZType; @@ -379,14 +388,6 @@ this.subCount = subCount; } - public String getSsrc() { - return ssrc; - } - - public void setSsrc(String ssrc) { - this.ssrc = ssrc; - } - public boolean isHasAudio() { return hasAudio; } @@ -395,11 +396,11 @@ this.hasAudio = hasAudio; } - public boolean isPlay() { - return play; + public String getStreamId() { + return streamId; } - public void setPlay(boolean play) { - this.play = play; + public void setStreamId(String streamId) { + this.streamId = streamId; } } 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 new file mode 100644 index 0000000..176a435 --- /dev/null +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/event/SipSubscribe.java @@ -0,0 +1,50 @@ +package com.genersoft.iot.vmp.gb28181.event; + +import com.alibaba.fastjson.JSONObject; +import com.genersoft.iot.vmp.media.zlm.ZLMHttpHookSubscribe; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; + +import javax.sip.ResponseEvent; +import javax.sip.message.Request; +import java.util.EventObject; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +@Component +public class SipSubscribe { + + private final static Logger logger = LoggerFactory.getLogger(SipSubscribe.class); + + private Map<String, SipSubscribe.Event> errorSubscribes = new ConcurrentHashMap<>(); + + private Map<String, SipSubscribe.Event> okSubscribes = new ConcurrentHashMap<>(); + + public interface Event { + void response(ResponseEvent event); + } + + public void addErrorSubscribe(String key, SipSubscribe.Event event) { + errorSubscribes.put(key, event); + } + + public void addOkSubscribe(String key, SipSubscribe.Event event) { + okSubscribes.put(key, event); + } + + public SipSubscribe.Event getErrorSubscribe(String key) { + return errorSubscribes.get(key); + } + + public SipSubscribe.Event getOkSubscribe(String key) { + return okSubscribes.get(key); + } + + public int getErrorSubscribesSize(){ + return errorSubscribes.size(); + } + public int getOkSubscribesSize(){ + return okSubscribes.size(); + } +} diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPProcessorFactory.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPProcessorFactory.java index f063b49..1e374ad 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPProcessorFactory.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPProcessorFactory.java @@ -7,7 +7,9 @@ import javax.sip.message.Request; import javax.sip.message.Response; +import com.genersoft.iot.vmp.storager.IRedisCatchStorage; import com.alibaba.fastjson.JSON; +import com.genersoft.iot.vmp.gb28181.transmit.response.impl.*; import com.genersoft.iot.vmp.gb28181.transmit.response.impl.*; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -54,7 +56,10 @@ @Autowired private IVideoManagerStorager storager; - + + @Autowired + private IRedisCatchStorage redisCatchStorage; + @Autowired private EventPublisher publisher; @@ -82,10 +87,11 @@ @Autowired @Lazy private RegisterResponseProcessor registerResponseProcessor; - + @Autowired private OtherResponseProcessor otherResponseProcessor; - + + // 娉細杩欓噷浣跨敤娉ㄨВ浼氬鑷村惊鐜緷璧栨敞鍏ワ紝鏆傜敤springBean private SipProvider tcpSipProvider; @@ -140,6 +146,7 @@ processor.setOffLineDetector(offLineDetector); processor.setCmder(cmder); processor.setStorager(storager); + processor.setRedisCatchStorage(redisCatchStorage); return processor; } else { return new OtherRequestProcessor(); @@ -147,6 +154,7 @@ } public ISIPResponseProcessor createResponseProcessor(ResponseEvent evt) { + Response response = evt.getResponse(); CSeqHeader cseqHeader = (CSeqHeader) response.getHeader(CSeqHeader.NAME); String method = cseqHeader.getMethod(); 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 0c1e63d..0759d7f 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 @@ -2,6 +2,7 @@ import java.util.HashMap; import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; @@ -24,8 +25,10 @@ public static final String CALLBACK_CMD_PlAY = "CALLBACK_PLAY"; - private Map<String, DeferredResult> map = new HashMap<String, DeferredResult>(); - + public static final String CALLBACK_CMD_STOP = "CALLBACK_STOP"; + + private Map<String, DeferredResult> map = new ConcurrentHashMap<String, DeferredResult>(); + public void put(String key, DeferredResult result) { map.put(key, result); } 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 d3f36cd..67fd996 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,8 +2,8 @@ import com.genersoft.iot.vmp.common.StreamInfo; import com.genersoft.iot.vmp.gb28181.bean.Device; +import com.genersoft.iot.vmp.gb28181.event.SipSubscribe; import com.genersoft.iot.vmp.media.zlm.ZLMHttpHookSubscribe; -import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform; /** * @Description:璁惧鑳藉姏鎺ュ彛锛岀敤浜庡畾涔夎澶囩殑鎺у埗銆佹煡璇㈣兘鍔� @@ -84,7 +84,7 @@ * @param device 瑙嗛璁惧 * @param channelId 棰勮閫氶亾 */ - void playStreamCmd(Device device, String channelId, ZLMHttpHookSubscribe.Event event); + void playStreamCmd(Device device, String channelId, ZLMHttpHookSubscribe.Event event, SipSubscribe.Event errorEvent); /** * 璇锋眰鍥炴斁瑙嗛娴� @@ -94,15 +94,16 @@ * @param startTime 寮�濮嬫椂闂�,鏍煎紡瑕佹眰锛歽yyy-MM-dd HH:mm:ss * @param endTime 缁撴潫鏃堕棿,鏍煎紡瑕佹眰锛歽yyy-MM-dd HH:mm:ss */ - void playbackStreamCmd(Device device, String channelId, String startTime, String endTime, ZLMHttpHookSubscribe.Event event); + void playbackStreamCmd(Device device, String channelId, String startTime, String endTime, ZLMHttpHookSubscribe.Event event, SipSubscribe.Event errorEvent); /** * 瑙嗛娴佸仠姝� * * @param ssrc ssrc */ + void streamByeCmd(String ssrc, SipSubscribe.Event okEvent); void streamByeCmd(String ssrc); - + /** * 璇煶骞挎挱 * @@ -176,7 +177,7 @@ * * @param device 瑙嗛璁惧 */ - boolean catalogQuery(Device device); + boolean catalogQuery(Device device, SipSubscribe.Event errorEvent); /** * 鏌ヨ褰曞儚淇℃伅 @@ -214,4 +215,11 @@ * @param device 瑙嗛璁惧 */ boolean mobilePostitionQuery(Device device); + + /** + * 閲婃斁rtpserver + * @param device + * @param channelId + */ + void closeRTPServer(Device device, String channelId); } diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/SIPRequestHeaderProvider.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/SIPRequestHeaderProvider.java index 6982144..739d5a9 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/SIPRequestHeaderProvider.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/SIPRequestHeaderProvider.java @@ -47,9 +47,8 @@ public Request createMessageRequest(Device device, String content, String viaTag, String fromTag, String toTag) throws ParseException, InvalidArgumentException, PeerUnavailableException { Request request = null; - Host host = device.getHost(); // sipuri - SipURI requestURI = sipFactory.createAddressFactory().createSipURI(device.getDeviceId(), host.getAddress()); + SipURI requestURI = sipFactory.createAddressFactory().createSipURI(device.getDeviceId(), device.getHostAddress()); // via ArrayList<ViaHeader> viaHeaders = new ArrayList<ViaHeader>(); ViaHeader viaHeader = sipFactory.createHeaderFactory().createViaHeader(sipConfig.getSipIp(), sipConfig.getSipPort(), @@ -75,22 +74,21 @@ request = sipFactory.createMessageFactory().createRequest(requestURI, Request.MESSAGE, callIdHeader, cSeqHeader, fromHeader, toHeader, viaHeaders, maxForwards); - ContentTypeHeader contentTypeHeader = sipFactory.createHeaderFactory().createContentTypeHeader("Application", "MANSCDP+xml"); + ContentTypeHeader contentTypeHeader = sipFactory.createHeaderFactory().createContentTypeHeader("APPLICATION", "MANSCDP+xml"); request.setContent(content, contentTypeHeader); return request; } public Request createInviteRequest(Device device, String channelId, String content, String viaTag, String fromTag, String toTag, String ssrc) throws ParseException, InvalidArgumentException, PeerUnavailableException { Request request = null; - Host host = device.getHost(); //璇锋眰琛� - SipURI requestLine = sipFactory.createAddressFactory().createSipURI(channelId, host.getAddress()); + SipURI requestLine = sipFactory.createAddressFactory().createSipURI(channelId, device.getHostAddress()); //via ArrayList<ViaHeader> viaHeaders = new ArrayList<ViaHeader>(); - // ViaHeader viaHeader = sipFactory.createHeaderFactory().createViaHeader(sipConfig.getSipIp(), sipConfig.getSipPort(), device.getTransport(), viaTag); - ViaHeader viaHeader = sipFactory.createHeaderFactory().createViaHeader(device.getHost().getIp(), device.getHost().getPort(), device.getTransport(), viaTag); + ViaHeader viaHeader = sipFactory.createHeaderFactory().createViaHeader(device.getIp(), device.getPort(), device.getTransport(), viaTag); viaHeader.setRPort(); viaHeaders.add(viaHeader); + //from SipURI fromSipURI = sipFactory.createAddressFactory().createSipURI(sipConfig.getSipId(),sipConfig.getSipDomain()); Address fromAddress = sipFactory.createAddressFactory().createAddress(fromSipURI); @@ -122,20 +120,18 @@ // Subject SubjectHeader subjectHeader = sipFactory.createHeaderFactory().createSubjectHeader(String.format("%s:%s,%s:%s", channelId, ssrc, sipConfig.getSipId(), 0)); request.addHeader(subjectHeader); - ContentTypeHeader contentTypeHeader = sipFactory.createHeaderFactory().createContentTypeHeader("Application", "SDP"); + ContentTypeHeader contentTypeHeader = sipFactory.createHeaderFactory().createContentTypeHeader("APPLICATION", "SDP"); request.setContent(content, contentTypeHeader); return request; } public Request createPlaybackInviteRequest(Device device, String channelId, String content, String viaTag, String fromTag, String toTag) throws ParseException, InvalidArgumentException, PeerUnavailableException { Request request = null; - Host host = device.getHost(); //璇锋眰琛� - SipURI requestLine = sipFactory.createAddressFactory().createSipURI(device.getDeviceId(), host.getAddress()); - //via + SipURI requestLine = sipFactory.createAddressFactory().createSipURI(device.getDeviceId(), device.getHostAddress()); + // via ArrayList<ViaHeader> viaHeaders = new ArrayList<ViaHeader>(); - // ViaHeader viaHeader = sipFactory.createHeaderFactory().createViaHeader(sipConfig.getSipIp(), sipConfig.getSipPort(), device.getTransport(), viaTag); - ViaHeader viaHeader = sipFactory.createHeaderFactory().createViaHeader(device.getHost().getIp(), device.getHost().getPort(), device.getTransport(), viaTag); + ViaHeader viaHeader = sipFactory.createHeaderFactory().createViaHeader(device.getIp(), device.getPort(), device.getTransport(), viaTag); viaHeader.setRPort(); viaHeaders.add(viaHeader); //from @@ -167,7 +163,7 @@ // Address concatAddress = sipFactory.createAddressFactory().createAddress(sipFactory.createAddressFactory().createSipURI(sipConfig.getSipId(), device.getHost().getIp()+":"+device.getHost().getPort())); request.addHeader(sipFactory.createHeaderFactory().createContactHeader(concatAddress)); - ContentTypeHeader contentTypeHeader = sipFactory.createHeaderFactory().createContentTypeHeader("Application", "SDP"); + ContentTypeHeader contentTypeHeader = sipFactory.createHeaderFactory().createContentTypeHeader("APPLICATION", "SDP"); request.setContent(content, contentTypeHeader); return request; } 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 3d5aacc..e1d474f 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 @@ -1,17 +1,14 @@ package com.genersoft.iot.vmp.gb28181.transmit.cmd.impl; import java.text.ParseException; +import java.util.UUID; import java.util.regex.Matcher; import java.util.regex.Pattern; -import javax.sip.ClientTransaction; -import javax.sip.Dialog; -import javax.sip.InvalidArgumentException; -import javax.sip.SipException; -import javax.sip.SipFactory; -import javax.sip.SipProvider; -import javax.sip.TransactionDoesNotExistException; +import javax.sip.*; import javax.sip.address.SipURI; +import javax.sip.header.CallIdHeader; +import javax.sip.header.Header; import javax.sip.header.ViaHeader; import javax.sip.message.Request; @@ -19,9 +16,13 @@ import com.genersoft.iot.vmp.common.StreamInfo; import com.genersoft.iot.vmp.conf.MediaServerConfig; import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel; +import com.genersoft.iot.vmp.gb28181.event.SipSubscribe; import com.genersoft.iot.vmp.media.zlm.ZLMHttpHookSubscribe; -import com.genersoft.iot.vmp.media.zlm.ZLMUtils; +import com.genersoft.iot.vmp.media.zlm.ZLMRTPServerFactory; +import com.genersoft.iot.vmp.storager.IRedisCatchStorage; import com.genersoft.iot.vmp.storager.IVideoManagerStorager; +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.beans.factory.annotation.Value; @@ -41,6 +42,8 @@ */ @Component public class SIPCommander implements ISIPCommander { + + private final Logger logger = LoggerFactory.getLogger(SIPCommander.class); @Autowired private SipConfig sipConfig; @@ -53,6 +56,9 @@ @Autowired private IVideoManagerStorager storager; + + @Autowired + private IRedisCatchStorage redisCatchStorage; @Autowired @Qualifier(value="tcpSipProvider") @@ -63,13 +69,19 @@ private SipProvider udpSipProvider; @Autowired - private ZLMUtils zlmUtils; + private ZLMRTPServerFactory zlmrtpServerFactory; @Value("${media.rtp.enable}") private boolean rtpEnable; + @Value("${media.seniorSdp}") + private boolean seniorSdp; + @Autowired private ZLMHttpHookSubscribe subscribe; + + @Autowired + private SipSubscribe sipSubscribe; @@ -176,19 +188,29 @@ * @param moveSpeed 闀滃ご绉诲姩閫熷害 榛樿 0XFF (0-255) * @param zoomSpeed 闀滃ご缂╂斁閫熷害 榛樿 0X1 (0-255) */ - public static String frontEndCmdString(int cmdCode, int parameter1, int parameter2, int combineCode2) { + + /** + * 浜戝彴鎸囦护鐮佽绠� + * + * @param cmdCode 鎸囦护鐮� + * @param horizonSpeed 姘村钩绉诲姩閫熷害 + * @param verticalSpeed 鍨傜洿绉诲姩閫熷害 + * @param zoomSpeed 缂╂斁閫熷害 + * @return + */ + public static String frontEndCmdString(int cmdCode, int horizonSpeed, int verticalSpeed, int zoomSpeed) { StringBuilder builder = new StringBuilder("A50F01"); String strTmp; strTmp = String.format("%02X", cmdCode); builder.append(strTmp, 0, 2); - strTmp = String.format("%02X", parameter1); + strTmp = String.format("%02X", horizonSpeed); builder.append(strTmp, 0, 2); - strTmp = String.format("%02X", parameter2); + strTmp = String.format("%02X", verticalSpeed); builder.append(strTmp, 0, 2); - strTmp = String.format("%X", combineCode2); + strTmp = String.format("%X", zoomSpeed); builder.append(strTmp, 0, 1).append("0"); //璁$畻鏍¢獙鐮� - int checkCode = (0XA5 + 0X0F + 0X01 + cmdCode + parameter1 + parameter2 + (combineCode2 & 0XF0)) % 0X100; + int checkCode = (0XA5 + 0X0F + 0X01 + cmdCode + horizonSpeed + verticalSpeed + (zoomSpeed & 0XF0)) % 0X100; strTmp = String.format("%02X", checkCode); builder.append(strTmp, 0, 2); return builder.toString(); @@ -237,14 +259,14 @@ * @param device 鎺у埗璁惧 * @param channelId 棰勮閫氶亾 * @param cmdCode 鎸囦护鐮� - * @param parameter1 鏁版嵁1 - * @param parameter2 鏁版嵁2 - * @param combineCode2 缁勫悎鐮�2 + * @param horizonSpeed 姘村钩绉诲姩閫熷害 + * @param verticalSpeed 鍨傜洿绉诲姩閫熷害 + * @param zoomSpeed 缂╂斁閫熷害 */ @Override - public boolean frontEndCmd(Device device, String channelId, int cmdCode, int parameter1, int parameter2, int combineCode2) { + public boolean frontEndCmd(Device device, String channelId, int cmdCode, int horizonSpeed, int verticalSpeed, int zoomSpeed) { try { - String cmdStr= frontEndCmdString(cmdCode, parameter1, parameter2, combineCode2); + String cmdStr= frontEndCmdString(cmdCode, horizonSpeed, verticalSpeed, zoomSpeed); System.out.println("鎺у埗瀛楃涓诧細" + cmdStr); StringBuffer ptzXml = new StringBuffer(200); ptzXml.append("<?xml version=\"1.0\" ?>\r\n"); @@ -258,7 +280,6 @@ ptzXml.append("</Control>\r\n"); Request request = headerProvider.createMessageRequest(device, ptzXml.toString(), "ViaPtzBranch", "FromPtzTag", "ToPtzTag"); - transmitRequest(device, request); return true; } catch (SipException | ParseException | InvalidArgumentException e) { @@ -266,28 +287,39 @@ } return false; } + /** - * 璇锋眰棰勮瑙嗛娴� - * + * 璇锋眰棰勮瑙嗛娴� * @param device 瑙嗛璁惧 * @param channelId 棰勮閫氶亾 + * @param event hook璁㈤槄 + * @param errorEvent sip閿欒璁㈤槄 */ @Override - public void playStreamCmd(Device device, String channelId, ZLMHttpHookSubscribe.Event event) { + public void playStreamCmd(Device device, String channelId, ZLMHttpHookSubscribe.Event event, SipSubscribe.Event errorEvent) { try { String ssrc = streamSession.createPlaySsrc(); + String streamId = null; + if (rtpEnable) { + streamId = String.format("gb_play_%s_%s", device.getDeviceId(), channelId); + }else { + streamId = String.format("%08x", Integer.parseInt(ssrc)).toUpperCase(); + } String streamMode = device.getStreamMode().toUpperCase(); - MediaServerConfig mediaInfo = storager.getMediaInfo(); + MediaServerConfig mediaInfo = redisCatchStorage.getMediaInfo(); + if (mediaInfo == null) { + logger.warn("鐐规挱鏃跺彂鐜癦LM灏氭湭杩炴帴..."); + return; + } String mediaPort = null; // 浣跨敤鍔ㄦ�乽dp绔彛 if (rtpEnable) { - mediaPort = zlmUtils.getNewRTPPort(ssrc) + ""; + mediaPort = zlmrtpServerFactory.createRTPServer(streamId) + ""; }else { mediaPort = mediaInfo.getRtpProxyPort(); } - String streamId = String.format("%08x", Integer.parseInt(ssrc)).toUpperCase(); // 娣诲姞璁㈤槄 JSONObject subscribeKey = new JSONObject(); subscribeKey.put("app", "rtp"); @@ -297,7 +329,8 @@ // StringBuffer content = new StringBuffer(200); content.append("v=0\r\n"); - content.append("o="+channelId+" 0 0 IN IP4 "+mediaInfo.getWanIp()+"\r\n"); +// content.append("o="+channelId+" 0 0 IN IP4 "+mediaInfo.getWanIp()+"\r\n"); + content.append("o="+"00000"+" 0 0 IN IP4 "+mediaInfo.getWanIp()+"\r\n"); content.append("s=Play\r\n"); content.append("c=IN IP4 "+mediaInfo.getWanIp()+"\r\n"); content.append("t=0 0\r\n"); @@ -327,17 +360,14 @@ } content.append("y="+ssrc+"\r\n");//ssrc +// String fromTag = UUID.randomUUID().toString(); +// Request request = headerProvider.createInviteRequest(device, channelId, content.toString(), null, fromTag, null, ssrc); + Request request = headerProvider.createInviteRequest(device, channelId, content.toString(), null, "live", null, ssrc); - ClientTransaction transaction = transmitRequest(device, request); - streamSession.put(ssrc, transaction); - DeviceChannel deviceChannel = storager.queryChannel(device.getDeviceId(), channelId); - if (deviceChannel != null) { - deviceChannel.setSsrc(ssrc); - storager.updateChannel(device.getDeviceId(), deviceChannel); - } + ClientTransaction transaction = transmitRequest(device, request, errorEvent); + streamSession.put(streamId, transaction); - // TODO 璁㈤槄SIP response锛屽鐞嗗鏂圭殑閿欒杩斿洖 } catch ( SipException | ParseException | InvalidArgumentException e) { @@ -354,9 +384,10 @@ * @param endTime 缁撴潫鏃堕棿,鏍煎紡瑕佹眰锛歽yyy-MM-dd HH:mm:ss */ @Override - public void playbackStreamCmd(Device device, String channelId, String startTime, String endTime, ZLMHttpHookSubscribe.Event event) { + public void playbackStreamCmd(Device device, String channelId, String startTime, String endTime, ZLMHttpHookSubscribe.Event event + , SipSubscribe.Event errorEvent) { try { - MediaServerConfig mediaInfo = storager.getMediaInfo(); + MediaServerConfig mediaInfo = redisCatchStorage.getMediaInfo(); String ssrc = streamSession.createPlayBackSsrc(); String streamId = String.format("%08x", Integer.parseInt(ssrc)).toUpperCase(); // 娣诲姞璁㈤槄 @@ -378,57 +409,91 @@ String mediaPort = null; // 浣跨敤鍔ㄦ�乽dp绔彛 if (rtpEnable) { - mediaPort = zlmUtils.getNewRTPPort(ssrc) + ""; + mediaPort = zlmrtpServerFactory.createRTPServer(streamId) + ""; }else { mediaPort = mediaInfo.getRtpProxyPort(); } String streamMode = device.getStreamMode().toUpperCase(); - if("TCP-PASSIVE".equals(streamMode)) { - content.append("m=video "+ mediaPort +" TCP/RTP/AVP 126 125 99 34 98 97 96\r\n"); - }else if ("TCP-ACTIVE".equals(streamMode)) { - content.append("m=video "+ mediaPort +" TCP/RTP/AVP 126 125 99 34 98 97 96\r\n"); - }else if("UDP".equals(streamMode)) { - content.append("m=video "+ mediaPort +" RTP/AVP 126 125 99 34 98 97 96\r\n"); + + if (seniorSdp) { + if("TCP-PASSIVE".equals(streamMode)) { + content.append("m=video "+ mediaPort +" TCP/RTP/AVP 126 125 99 34 98 97 96\r\n"); + }else if ("TCP-ACTIVE".equals(streamMode)) { + content.append("m=video "+ mediaPort +" TCP/RTP/AVP 126 125 99 34 98 97 96\r\n"); + }else if("UDP".equals(streamMode)) { + content.append("m=video "+ mediaPort +" RTP/AVP 126 125 99 34 98 97 96\r\n"); + } + content.append("a=recvonly\r\n"); + content.append("a=fmtp:126 profile-level-id=42e01e\r\n"); + content.append("a=rtpmap:126 H264/90000\r\n"); + content.append("a=rtpmap:125 H264S/90000\r\n"); + content.append("a=fmtp:125 profile-level-id=42e01e\r\n"); + content.append("a=rtpmap:99 MP4V-ES/90000\r\n"); + content.append("a=fmtp:99 profile-level-id=3\r\n"); + content.append("a=rtpmap:98 H264/90000\r\n"); + content.append("a=rtpmap:97 MPEG4/90000\r\n"); + content.append("a=rtpmap:96 PS/90000\r\n"); + if("TCP-PASSIVE".equals(streamMode)){ // tcp琚姩妯″紡 + content.append("a=setup:passive\r\n"); + content.append("a=connection:new\r\n"); + }else if ("TCP-ACTIVE".equals(streamMode)) { // tcp涓诲姩妯″紡 + content.append("a=setup:active\r\n"); + content.append("a=connection:new\r\n"); + } + }else { + if("TCP-PASSIVE".equals(streamMode)) { + content.append("m=video "+ mediaPort +" TCP/RTP/AVP 96 98 97\r\n"); + }else if ("TCP-ACTIVE".equals(streamMode)) { + content.append("m=video "+ mediaPort +" TCP/RTP/AVP 96 98 97\r\n"); + }else if("UDP".equals(streamMode)) { + content.append("m=video "+ mediaPort +" RTP/AVP 96 98 97\r\n"); + } + content.append("a=recvonly\r\n"); + content.append("a=rtpmap:96 PS/90000\r\n"); + content.append("a=rtpmap:98 H264/90000\r\n"); + content.append("a=rtpmap:97 MPEG4/90000\r\n"); + if("TCP-PASSIVE".equals(streamMode)){ // tcp琚姩妯″紡 + content.append("a=setup:passive\r\n"); + content.append("a=connection:new\r\n"); + }else if ("TCP-ACTIVE".equals(streamMode)) { // tcp涓诲姩妯″紡 + content.append("a=setup:active\r\n"); + content.append("a=connection:new\r\n"); + } } - content.append("a=recvonly\r\n"); - content.append("a=fmtp:126 profile-level-id=42e01e\r\n"); - content.append("a=rtpmap:126 H264/90000\r\n"); - content.append("a=rtpmap:125 H264S/90000\r\n"); - content.append("a=fmtp:125 profile-level-id=42e01e\r\n"); - content.append("a=rtpmap:99 MP4V-ES/90000\r\n"); - content.append("a=fmtp:99 profile-level-id=3\r\n"); - content.append("a=rtpmap:98 H264/90000\r\n"); - content.append("a=rtpmap:97 MPEG4/90000\r\n"); - content.append("a=rtpmap:96 PS/90000\r\n"); - if("TCP-PASSIVE".equals(streamMode)){ // tcp琚姩妯″紡 - content.append("a=setup:passive\r\n"); - content.append("a=connection:new\r\n"); - }else if ("TCP-ACTIVE".equals(streamMode)) { // tcp涓诲姩妯″紡 - content.append("a=setup:active\r\n"); - content.append("a=connection:new\r\n"); - } + content.append("y="+ssrc+"\r\n");//ssrc Request request = headerProvider.createPlaybackInviteRequest(device, channelId, content.toString(), null, "playback", null); - - ClientTransaction transaction = transmitRequest(device, request); - streamSession.put(ssrc, transaction); + + ClientTransaction transaction = transmitRequest(device, request, errorEvent); + streamSession.put(streamId, transaction); } catch ( SipException | ParseException | InvalidArgumentException e) { e.printStackTrace(); } } - + + + /** * 瑙嗛娴佸仠姝� * */ @Override public void streamByeCmd(String ssrc) { + streamByeCmd(ssrc, null); + } + @Override + public void streamByeCmd(String streamId, SipSubscribe.Event okEvent) { try { - ClientTransaction transaction = streamSession.get(ssrc); + ClientTransaction transaction = streamSession.get(streamId); + // 鏈嶅姟閲嶅惎鍚� if (transaction == null) { + StreamInfo streamInfo = redisCatchStorage.queryPlayByStreamId(streamId); + if (streamInfo != null) { + + } return; } @@ -436,6 +501,9 @@ if (dialog == null) { return; } + + + Request byeRequest = dialog.createRequest(Request.BYE); SipURI byeURI = (SipURI) byeRequest.getRequestURI(); String vh = transaction.getRequest().getHeader(ViaHeader.NAME).toString(); @@ -452,8 +520,16 @@ } else if("UDP".equals(protocol)) { clientTransaction = udpSipProvider.getNewClientTransaction(byeRequest); } + + CallIdHeader callIdHeader = (CallIdHeader) byeRequest.getHeader(CallIdHeader.NAME); + if (okEvent != null) { + sipSubscribe.addOkSubscribe(callIdHeader.getCallId(), okEvent); + } + dialog.sendRequest(clientTransaction); - streamSession.remove(ssrc); + + streamSession.remove(streamId); + zlmrtpServerFactory.closeRTPServer(streamId); } catch (TransactionDoesNotExistException e) { e.printStackTrace(); } catch (SipException e) { @@ -571,6 +647,7 @@ catalogXml.append("</Query>\r\n"); Request request = headerProvider.createMessageRequest(device, catalogXml.toString(), "ViaDeviceInfoBranch", "FromDeviceInfoTag", "ToDeviceInfoTag"); + transmitRequest(device, request); } catch (SipException | ParseException | InvalidArgumentException e) { @@ -586,7 +663,7 @@ * @param device 瑙嗛璁惧 */ @Override - public boolean catalogQuery(Device device) { + public boolean catalogQuery(Device device, SipSubscribe.Event errorEvent) { // 娓呯┖閫氶亾 storager.cleanChannelsForDevice(device.getDeviceId()); try { @@ -598,8 +675,9 @@ catalogXml.append("<DeviceID>" + device.getDeviceId() + "</DeviceID>\r\n"); catalogXml.append("</Query>\r\n"); - Request request = headerProvider.createMessageRequest(device, catalogXml.toString(), "ViaCatalogBranch", "FromCatalogTag", "ToCatalogTag"); - transmitRequest(device, request); + Request request = headerProvider.createMessageRequest(device, catalogXml.toString(), "ViaCatalogBranch", "FromCatalogTag", null); + + transmitRequest(device, request, errorEvent); } catch (SipException | ParseException | InvalidArgumentException e) { e.printStackTrace(); return false; @@ -631,7 +709,8 @@ recordInfoXml.append("<Type>all</Type>\r\n"); recordInfoXml.append("</Query>\r\n"); - Request request = headerProvider.createMessageRequest(device, recordInfoXml.toString(), "ViaRecordInfoBranch", "FromRecordInfoTag", "ToRecordInfoTag"); + Request request = headerProvider.createMessageRequest(device, recordInfoXml.toString(), "ViaRecordInfoBranch", "FromRecordInfoTag", null); + transmitRequest(device, request); } catch (SipException | ParseException | InvalidArgumentException e) { e.printStackTrace(); @@ -683,17 +762,45 @@ // TODO Auto-generated method stub return false; } - + private ClientTransaction transmitRequest(Device device, Request request) throws SipException { + return transmitRequest(device, request, null, null); + } + + private ClientTransaction transmitRequest(Device device, Request request, SipSubscribe.Event errorEvent) throws SipException { + return transmitRequest(device, request, errorEvent, null); + } + + private ClientTransaction transmitRequest(Device device, Request request, SipSubscribe.Event errorEvent , SipSubscribe.Event okEvent) throws SipException { ClientTransaction clientTransaction = null; if("TCP".equals(device.getTransport())) { clientTransaction = tcpSipProvider.getNewClientTransaction(request); } else if("UDP".equals(device.getTransport())) { clientTransaction = udpSipProvider.getNewClientTransaction(request); } + + CallIdHeader callIdHeader = (CallIdHeader)request.getHeader(CallIdHeader.NAME); + // 娣诲姞閿欒璁㈤槄 + if (errorEvent != null) { + sipSubscribe.addErrorSubscribe(callIdHeader.getCallId(), errorEvent); + } + // 娣诲姞璁㈤槄 + if (okEvent != null) { + sipSubscribe.addOkSubscribe(callIdHeader.getCallId(), okEvent); + } + clientTransaction.sendRequest(); return clientTransaction; } + + + @Override + public void closeRTPServer(Device device, String channelId) { + if (rtpEnable) { + String streamId = String.format("gb_play_%s_%s", device.getDeviceId(), channelId); + zlmrtpServerFactory.closeRTPServer(streamId); + } + } } diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/MessageRequestProcessor.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/MessageRequestProcessor.java index c987f5e..cab4a9b 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/MessageRequestProcessor.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/MessageRequestProcessor.java @@ -10,6 +10,7 @@ import javax.sip.message.Request; import javax.sip.message.Response; +import com.genersoft.iot.vmp.storager.IRedisCatchStorage; import org.dom4j.Document; import org.dom4j.DocumentException; import org.dom4j.Element; @@ -47,6 +48,8 @@ private SIPCommander cmder; private IVideoManagerStorager storager; + + private IRedisCatchStorage redisCatchStorage; private EventPublisher publisher; @@ -294,7 +297,7 @@ device.setStreamMode("UDP"); } storager.updateDevice(device); - cmder.catalogQuery(device); + cmder.catalogQuery(device, null); // 鍥炲200 OK responseAck(evt); if (offLineDetector.isOnline(deviceId)) { @@ -315,12 +318,16 @@ try { Element rootElement = getRootElement(evt); String deviceId = XmlUtil.getText(rootElement, "DeviceID"); - // 鍥炲200 OK - responseAck(evt); - if (offLineDetector.isOnline(deviceId)) { - publisher.onlineEventPublish(deviceId, VideoManagerConstants.EVENT_ONLINE_KEEPLIVE); - } else { + // 妫�鏌ヨ澶囨槸鍚﹀瓨鍦紝 涓嶅瓨鍦ㄥ垯涓嶅洖澶� + if (storager.exists(deviceId)) { + // 鍥炲200 OK + responseAck(evt); + if (offLineDetector.isOnline(deviceId)) { + publisher.onlineEventPublish(deviceId, VideoManagerConstants.EVENT_ONLINE_KEEPLIVE); + } else { + } } + } catch (ParseException | SipException | InvalidArgumentException | DocumentException e) { e.printStackTrace(); } @@ -447,10 +454,10 @@ String NotifyType =XmlUtil.getText(rootElement, "NotifyType"); if (NotifyType.equals("121")){ logger.info("濯掍綋鎾斁瀹屾瘯锛岄�氱煡鍏虫祦"); - StreamInfo streamInfo = storager.queryPlaybackByDevice(deviceId, "*"); + StreamInfo streamInfo = redisCatchStorage.queryPlaybackByDevice(deviceId, "*"); if (streamInfo != null) { - storager.stopPlayback(streamInfo); - cmder.streamByeCmd(streamInfo.getSsrc()); + redisCatchStorage.stopPlayback(streamInfo); + cmder.streamByeCmd(streamInfo.getStreamId()); } } } catch (ParseException | SipException | InvalidArgumentException | DocumentException e) { @@ -503,4 +510,11 @@ this.offLineDetector = offLineDetector; } + public IRedisCatchStorage getRedisCatchStorage() { + return redisCatchStorage; + } + + public void setRedisCatchStorage(IRedisCatchStorage redisCatchStorage) { + this.redisCatchStorage = redisCatchStorage; + } } diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/RegisterRequestProcessor.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/RegisterRequestProcessor.java index be076bd..4faab0e 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/RegisterRequestProcessor.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/RegisterRequestProcessor.java @@ -107,17 +107,15 @@ rPort = viaHeader.getPort(); } // - Host host = new Host(); - host.setIp(received); - host.setPort(rPort); - host.setAddress(received.concat(":").concat(String.valueOf(rPort))); AddressImpl address = (AddressImpl) fromHeader.getAddress(); SipUri uri = (SipUri) address.getURI(); String deviceId = uri.getUser(); device = new Device(); device.setStreamMode("UDP"); device.setDeviceId(deviceId); - device.setHost(host); + device.setIp(received); + device.setPort(rPort); + device.setHostAddress(received.concat(":").concat(String.valueOf(rPort))); // 娉ㄩ攢鎴愬姛 if (expiresHeader != null && expiresHeader.getExpires() == 0) { registerFlag = 2; @@ -141,9 +139,15 @@ // 涓嬪彂catelog鏌ヨ鐩綍 if (registerFlag == 1 && device != null) { logger.info("娉ㄥ唽鎴愬姛! deviceId:" + device.getDeviceId()); + boolean exists = storager.exists(device.getDeviceId()); + device.setRegisterTimeMillis(System.currentTimeMillis()); storager.updateDevice(device); publisher.onlineEventPublish(device.getDeviceId(), VideoManagerConstants.EVENT_ONLINE_REGISTER); - handler.onRegister(device); + + // 鍙湁绗竴娆℃敞鍐屾墠鏇存柊閫氶亾 + if (!exists) { + handler.onRegister(device); + } } else if (registerFlag == 2) { logger.info("娉ㄩ攢鎴愬姛! deviceId:" + device.getDeviceId()); publisher.outlineEventPublish(device.getDeviceId(), VideoManagerConstants.EVENT_OUTLINE_UNREGISTER); diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/response/impl/InviteResponseProcessor.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/response/impl/InviteResponseProcessor.java index ae7182d..93f533f 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/response/impl/InviteResponseProcessor.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/response/impl/InviteResponseProcessor.java @@ -12,6 +12,7 @@ import javax.sip.message.Request; import javax.sip.message.Response; +import gov.nist.javax.sip.header.CSeq; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; @@ -23,14 +24,14 @@ /** - * @Description:澶勭悊INVITE鍝嶅簲 + * @Description:澶勭悊INVITE鍝嶅簲 * @author: swwheihei - * @date: 2020骞�5鏈�3鏃� 涓嬪崍4:43:52 + * @date: 2020骞�5鏈�3鏃� 涓嬪崍4:43:52 */ @Component public class InviteResponseProcessor implements ISIPResponseProcessor { - private final static Logger logger = LoggerFactory.getLogger(SIPProcessorFactory.class); + private final static Logger logger = LoggerFactory.getLogger(InviteResponseProcessor.class); /** * 澶勭悊invite鍝嶅簲 @@ -49,48 +50,16 @@ // 鎴愬姛鍝嶅簲 // 涓嬪彂ack if (statusCode == Response.OK) { - // ClientTransaction clientTransaction = evt.getClientTransaction(); - // if(clientTransaction == null){ - // logger.error("鍥炲ACK鏃讹紝clientTransaction涓簄ull >>> {}",response); - // return; - // } - // Dialog clientDialog = clientTransaction.getDialog(); - - // CSeqHeader clientCSeqHeader = (CSeqHeader) - // response.getHeader(CSeqHeader.NAME); - // long cseqId = clientCSeqHeader.getSeqNumber(); - // /* - // createAck鍑芥暟锛屽垱寤虹殑ackRequest锛屼細閲囩敤Invite鍝嶅簲鐨�200OK锛屼腑鐨刢ontact瀛楁涓殑鍦板潃锛屼綔涓虹洰鏍囧湴鍧�銆� - // 鏈夌殑缁堢浼犱笂鏉ョ殑鍙兘杩樻槸鍐呯綉鍦板潃锛屼細閫犳垚ack鍙戦�佷笉鍑哄幓銆傛帴鍙椾笉鍒伴煶瑙嗛娴� - // 鎵�浠ュ湪姝ゅ缁熶竴鏇挎崲鍦板潃銆傚拰鍝嶅簲娑堟伅鐨刅ia澶翠腑鐨勫湴鍧�淇濇寔涓�鑷淬�� - // */ - // Request ackRequest = clientDialog.createAck(cseqId); - // SipURI requestURI = (SipURI) ackRequest.getRequestURI(); - // ViaHeader viaHeader = (ViaHeader) response.getHeader(ViaHeader.NAME); - // try { - // requestURI.setHost(viaHeader.getHost()); - // } catch (Exception e) { - // e.printStackTrace(); - // } - // requestURI.setPort(viaHeader.getPort()); - // clientDialog.sendAck(ackRequest); - Dialog dialog = evt.getDialog(); CSeqHeader cseq = (CSeqHeader) response.getHeader(CSeqHeader.NAME); Request reqAck = dialog.createAck(cseq.getSeqNumber()); SipURI requestURI = (SipURI) reqAck.getRequestURI(); ViaHeader viaHeader = (ViaHeader) response.getHeader(ViaHeader.NAME); - // String viaHost =viaHeader.getHost(); - //getHost()鍑芥暟鍙栧洖鐨処P鍦板潃鏄�淸xxx.xxx.xxx.xxx:yyyy]鈥濈殑鏍煎紡锛岄渶鐢ㄦ鍒欒〃杈惧紡鎴彇涓衡�渪xx.xxx.xxx.xxx"鏍煎紡 - // Pattern p = Pattern.compile("(?<=//|)((\\w)+\\.)+\\w+"); - // Matcher matcher = p.matcher(viaHeader.getHost()); - // if (matcher.find()) { - // requestURI.setHost(matcher.group()); - // } requestURI.setHost(viaHeader.getHost()); requestURI.setPort(viaHeader.getPort()); reqAck.setRequestURI(requestURI); + dialog.sendAck(reqAck); } } catch (InvalidArgumentException | SipException e) { diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHTTPProxyController.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHTTPProxyController.java index f76cdd9..9daef23 100644 --- a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHTTPProxyController.java +++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHTTPProxyController.java @@ -2,6 +2,7 @@ import com.alibaba.fastjson.JSONObject; import com.genersoft.iot.vmp.conf.MediaServerConfig; +import com.genersoft.iot.vmp.storager.IRedisCatchStorage; import com.genersoft.iot.vmp.storager.IVideoManagerStorager; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -29,6 +30,9 @@ @Autowired private IVideoManagerStorager storager; + @Autowired + private IRedisCatchStorage redisCatchStorage; + @Value("${media.port}") private int mediaHttpPort; @@ -36,10 +40,10 @@ @RequestMapping(value = "/**/**/**", produces = "application/json;charset=UTF-8") public Object proxy(HttpServletRequest request, HttpServletResponse response){ - if (storager.getMediaInfo() == null) { + if (redisCatchStorage.getMediaInfo() == null) { return "鏈帴鍏ユ祦濯掍綋"; } - MediaServerConfig mediaInfo = storager.getMediaInfo(); + MediaServerConfig mediaInfo = redisCatchStorage.getMediaInfo(); String requestURI = String.format("http://%s:%s%s?%s&%s", mediaInfo.getLocalIP(), mediaHttpPort, 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 99da624..cb8ad05 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 @@ -4,13 +4,17 @@ import java.text.DecimalFormat; import java.util.ArrayList; import java.util.List; +import java.util.UUID; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONArray; import com.genersoft.iot.vmp.common.StreamInfo; import com.genersoft.iot.vmp.conf.MediaServerConfig; +import com.genersoft.iot.vmp.gb28181.bean.Device; +import com.genersoft.iot.vmp.storager.IRedisCatchStorage; import com.genersoft.iot.vmp.storager.IVideoManagerStorager; import com.genersoft.iot.vmp.utils.IpUtil; +import com.genersoft.iot.vmp.vmanager.service.IPlayService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -44,13 +48,22 @@ private SIPCommander cmder; @Autowired + private IPlayService playService; + + @Autowired private IVideoManagerStorager storager; + + @Autowired + private IRedisCatchStorage redisCatchStorage; @Autowired private ZLMRESTfulUtils zlmresTfulUtils; @Autowired private ZLMHttpHookSubscribe subscribe; + + @Value("${media.autoApplyPlay}") + private boolean autoApplyPlay; @Value("${media.ip}") private String mediaIp; @@ -135,34 +148,6 @@ ZLMHttpHookSubscribe.Event subscribe = this.subscribe.getSubscribe(ZLMHttpHookSubscribe.HookType.on_publish, json); if (subscribe != null) subscribe.response(json); -// if ("rtp".equals(app)) { -// String ssrc = new DecimalFormat("0000000000").format(Integer.parseInt(streamId, 16)); -// StreamInfo streamInfoForPlay = storager.queryPlayBySSRC(ssrc); -// if ("rtp".equals(app) && streamInfoForPlay != null ) { -// MediaServerConfig mediaInfo = storager.getMediaInfo(); -// streamInfoForPlay.setFlv(String.format("http://%s:%s/rtp/%s.flv", mediaInfo.getWanIp(), mediaInfo.getHttpPort(), streamId)); -// streamInfoForPlay.setWs_flv(String.format("ws://%s:%s/rtp/%s.flv", mediaInfo.getWanIp(), mediaInfo.getHttpPort(), streamId)); -// streamInfoForPlay.setFmp4(String.format("http://%s:%s/rtp/%s.live.mp4", mediaInfo.getWanIp(), mediaInfo.getHttpPort(), streamId)); -// streamInfoForPlay.setWs_fmp4(String.format("ws://%s:%s/rtp/%s.live.mp4", mediaInfo.getWanIp(), mediaInfo.getHttpPort(), streamId)); -// streamInfoForPlay.setRtmp(String.format("rtmp://%s:%s/rtp/%s", mediaInfo.getWanIp(), mediaInfo.getRtmpPort(), streamId)); -// streamInfoForPlay.setHls(String.format("http://%s:%s/rtp/%s/hls.m3u8", mediaInfo.getWanIp(), mediaInfo.getHttpPort(), streamId)); -// streamInfoForPlay.setRtsp(String.format("rtsp://%s:%s/rtp/%s", mediaInfo.getWanIp(), mediaInfo.getRtspPort(), streamId)); -// storager.startPlay(streamInfoForPlay); -// } -// -// StreamInfo streamInfoForPlayBack = storager.queryPlaybackBySSRC(ssrc); -// if ("rtp".equals(app) && streamInfoForPlayBack != null ) { -// MediaServerConfig mediaInfo = storager.getMediaInfo(); -// streamInfoForPlayBack.setFlv(String.format("http://%s:%s/rtp/%s.flv", mediaInfo.getWanIp(), mediaInfo.getHttpPort(), streamId)); -// streamInfoForPlayBack.setWs_flv(String.format("ws://%s:%s/rtp/%s.flv", mediaInfo.getWanIp(), mediaInfo.getHttpPort(), streamId)); -// streamInfoForPlayBack.setFmp4(String.format("http://%s:%s/rtp/%s.live.mp4", mediaInfo.getWanIp(), mediaInfo.getHttpPort(), streamId)); -// streamInfoForPlayBack.setWs_fmp4(String.format("ws://%s:%s/rtp/%s.live.mp4", mediaInfo.getWanIp(), mediaInfo.getHttpPort(), streamId)); -// streamInfoForPlayBack.setRtmp(String.format("rtmp://%s:%s/rtp/%s", mediaInfo.getWanIp(), mediaInfo.getRtmpPort(), streamId)); -// streamInfoForPlayBack.setHls(String.format("http://%s:%s/rtp/%s/hls.m3u8", mediaInfo.getWanIp(), mediaInfo.getHttpPort(), streamId)); -// streamInfoForPlayBack.setRtsp(String.format("rtsp://%s:%s/rtp/%s", mediaInfo.getWanIp(), mediaInfo.getRtspPort(), streamId)); -// storager.startPlayback(streamInfoForPlayBack); -// } -// } // TODO Auto-generated method stub @@ -268,15 +253,13 @@ String app = json.getString("app"); String streamId = json.getString("stream"); boolean regist = json.getBoolean("regist"); -// String ssrc = String.format("%10d", Integer.parseInt(streamId, 16)); // ZLM 瑕佹眰澶у啓涓旈浣嶈ˉ闆� - String ssrc = new DecimalFormat("0000000000").format(Integer.parseInt(streamId, 16)); - StreamInfo streamInfo = storager.queryPlayBySSRC(ssrc); + StreamInfo streamInfo = redisCatchStorage.queryPlayByStreamId(streamId); if ("rtp".equals(app) && !regist ) { if (streamInfo!=null){ - storager.stopPlay(streamInfo); + redisCatchStorage.stopPlay(streamInfo); }else{ - streamInfo = storager.queryPlaybackBySSRC(ssrc); - storager.stopPlayback(streamInfo); + streamInfo = redisCatchStorage.queryPlaybackByStreamId(streamId); + redisCatchStorage.stopPlayback(streamInfo); } } @@ -299,17 +282,15 @@ logger.debug("ZLM HOOK on_stream_none_reader API璋冪敤锛屽弬鏁帮細" + json.toString()); } - BigInteger bigint=new BigInteger(json.getString("stream"), 16); - int numb=bigint.intValue(); - String ssrc = String.format("%010d", numb); - - cmder.streamByeCmd(ssrc); - StreamInfo streamInfo = storager.queryPlayBySSRC(ssrc); + String streamId = json.getString("stream"); + + cmder.streamByeCmd(streamId); + StreamInfo streamInfo = redisCatchStorage.queryPlayByStreamId(streamId); if (streamInfo!=null){ - storager.stopPlay(streamInfo); + redisCatchStorage.stopPlay(streamInfo); }else{ - streamInfo = storager.queryPlaybackBySSRC(ssrc); - storager.stopPlayback(streamInfo); + streamInfo = redisCatchStorage.queryPlaybackByStreamId(streamId); + redisCatchStorage.stopPlayback(streamInfo); } JSONObject ret = new JSONObject(); @@ -330,7 +311,31 @@ logger.debug("ZLM HOOK on_stream_not_found API璋冪敤锛屽弬鏁帮細" + json.toString()); } // TODO Auto-generated method stub - + + if (autoApplyPlay) { + String app = json.getString("app"); + String streamId = json.getString("stream"); + StreamInfo streamInfo = redisCatchStorage.queryPlayByStreamId(streamId); + if ("rtp".equals(app) && streamId.indexOf("gb_play") > -1 && streamInfo == null) { + String[] s = streamId.split("_"); + if (s.length == 4) { + String deviceId = s[2]; + String channelId = s[3]; + Device device = storager.queryVideoDevice(deviceId); + if (device != null) { + UUID uuid = UUID.randomUUID(); + cmder.playStreamCmd(device, channelId, (JSONObject response) -> { + logger.info("鏀跺埌璁㈤槄娑堟伅锛� " + response.toJSONString()); + playService.onPublishHandlerForPlay(response, deviceId, channelId, uuid.toString()); + }, null); + } + + } + + } + + } + JSONObject ret = new JSONObject(); ret.put("code", 0); ret.put("msg", "success"); @@ -354,7 +359,7 @@ // MediaServerConfig mediaServerConfig = mediaServerConfigs.get(0); MediaServerConfig mediaServerConfig = JSON.toJavaObject(json, MediaServerConfig.class); mediaServerConfig.setLocalIP(mediaIp); - storager.updateMediaInfo(mediaServerConfig); + redisCatchStorage.updateMediaInfo(mediaServerConfig); // TODO Auto-generated method stub JSONObject ret = new JSONObject(); diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRESTfulUtils.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRESTfulUtils.java index 1e38bdc..ac1f51a 100644 --- a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRESTfulUtils.java +++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRESTfulUtils.java @@ -116,4 +116,8 @@ public JSONObject openRtpServer(Map<String, Object> param){ return sendPost("openRtpServer",param); } + + public JSONObject closeRtpServer(Map<String, Object> param) { + return sendPost("closeRtpServer",param); + } } 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 new file mode 100644 index 0000000..f69ff0f --- /dev/null +++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRTPServerFactory.java @@ -0,0 +1,95 @@ +package com.genersoft.iot.vmp.media.zlm; + +import com.alibaba.fastjson.JSONObject; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; + +import java.util.HashMap; +import java.util.Map; + +@Component +public class ZLMRTPServerFactory { + + private Logger logger = LoggerFactory.getLogger("ZLMRTPServerFactory"); + + @Value("${media.rtp.udpPortRange}") + private String udpPortRange; + + @Autowired + private ZLMRESTfulUtils zlmresTfulUtils; + + private int[] udpPortRangeArray = new int[2]; + + private int currentPort = 0; + + public int createRTPServer(String streamId) { + Map<String, Object> param = new HashMap<>(); + int result = -1; + int newPort = getPortFromUdpPortRange(); + param.put("port", newPort); + param.put("enable_tcp", 1); + param.put("stream_id", streamId); + JSONObject jsonObject = zlmresTfulUtils.openRtpServer(param); + System.out.println(jsonObject); + + if (jsonObject != null) { + switch (jsonObject.getInteger("code")){ + case 0: + result= newPort; + break; + case -300: // id宸茬粡瀛樺湪 + result = newPort; + break; + case -400: // 绔彛鍗犵敤 + result= createRTPServer(streamId); + break; + default: + logger.error("鍒涘缓RTP Server 澶辫触: " + jsonObject.getString("msg")); + break; + } + }else { + // 妫�鏌LM鐘舵�� + logger.error("鍒涘缓RTP Server 澶辫触: 璇锋鏌LM鏈嶅姟"); + } + return result; + } + + public boolean closeRTPServer(String streamId) { + boolean result = false; + Map<String, Object> param = new HashMap<>(); + param.put("stream_id", streamId); + JSONObject jsonObject = zlmresTfulUtils.closeRtpServer(param); + if (jsonObject != null ) { + if (jsonObject.getInteger("code") == 0) { + result = jsonObject.getInteger("hit") == 1; + }else { + logger.error("鍏抽棴RTP Server 澶辫触: " + jsonObject.getString("msg")); + } + }else { + // 妫�鏌LM鐘舵�� + logger.error("鍏抽棴RTP Server 澶辫触: 璇锋鏌LM鏈嶅姟"); + } + return result; + } + + private int getPortFromUdpPortRange() { + if (currentPort == 0) { + String[] udpPortRangeStrArray = udpPortRange.split(","); + udpPortRangeArray[0] = Integer.parseInt(udpPortRangeStrArray[0]); + udpPortRangeArray[1] = Integer.parseInt(udpPortRangeStrArray[1]); + } + + if (currentPort == 0 || currentPort++ > udpPortRangeArray[1]) { + currentPort = udpPortRangeArray[0]; + return udpPortRangeArray[0]; + } else { + if (currentPort % 2 == 1) { + currentPort++; + } + return currentPort++; + } + } +} diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRunner.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRunner.java index 3f88b2a..282699f 100644 --- a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRunner.java +++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRunner.java @@ -4,6 +4,7 @@ import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.genersoft.iot.vmp.conf.MediaServerConfig; +import com.genersoft.iot.vmp.storager.IRedisCatchStorage; import com.genersoft.iot.vmp.storager.IVideoManagerStorager; import okhttp3.*; import org.slf4j.Logger; @@ -29,6 +30,9 @@ @Autowired private IVideoManagerStorager storager; + + @Autowired + private IRedisCatchStorage redisCatchStorage; @Value("${media.ip}") private String mediaIp; @@ -69,7 +73,7 @@ logger.info("zlm鎺ュ叆鎴愬姛..."); if (autoConfig) saveZLMConfig(); mediaServerConfig = getMediaServerConfig(); - storager.updateMediaInfo(mediaServerConfig); + redisCatchStorage.updateMediaInfo(mediaServerConfig); } } diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMUtils.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMUtils.java deleted file mode 100644 index 8195b65..0000000 --- a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMUtils.java +++ /dev/null @@ -1,56 +0,0 @@ -package com.genersoft.iot.vmp.media.zlm; - -import com.alibaba.fastjson.JSONObject; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.stereotype.Component; - -import java.util.HashMap; -import java.util.Map; - -@Component -public class ZLMUtils { - - @Value("${media.rtp.udpPortRange}") - private String udpPortRange; - - @Autowired - private ZLMRESTfulUtils zlmresTfulUtils; - - private int[] udpPortRangeArray = new int[2]; - - private int currentPort = 0; - - public int getNewRTPPort(String ssrc) { - String streamId = String.format("%08x", Integer.parseInt(ssrc)).toUpperCase(); - Map<String, Object> param = new HashMap<>(); - int newPort = getPortFromUdpPortRange(); - param.put("port", newPort); - param.put("enable_tcp", 1); - param.put("stream_id", streamId); - JSONObject jsonObject = zlmresTfulUtils.openRtpServer(param); - if (jsonObject != null && jsonObject.getInteger("code") == 0) { - return newPort; - } else { - return getNewRTPPort(ssrc); - } - } - - private int getPortFromUdpPortRange() { - if (currentPort == 0) { - String[] udpPortRangeStrArray = udpPortRange.split(","); - udpPortRangeArray[0] = Integer.parseInt(udpPortRangeStrArray[0]); - udpPortRangeArray[1] = Integer.parseInt(udpPortRangeStrArray[1]); - } - - if (currentPort == 0 || currentPort++ > udpPortRangeArray[1]) { - currentPort = udpPortRangeArray[0]; - return udpPortRangeArray[0]; - } else { - if (currentPort % 2 == 1) { - currentPort++; - } - return currentPort++; - } - } -} diff --git a/src/main/java/com/genersoft/iot/vmp/storager/IRedisCatchStorage.java b/src/main/java/com/genersoft/iot/vmp/storager/IRedisCatchStorage.java new file mode 100644 index 0000000..8bc78b9 --- /dev/null +++ b/src/main/java/com/genersoft/iot/vmp/storager/IRedisCatchStorage.java @@ -0,0 +1,58 @@ +package com.genersoft.iot.vmp.storager; + +import com.genersoft.iot.vmp.common.StreamInfo; +import com.genersoft.iot.vmp.conf.MediaServerConfig; + +import java.util.Map; + +public interface IRedisCatchStorage { + + /** + * 寮�濮嬫挱鏀炬椂灏嗘祦瀛樺叆 + * + * @param stream 娴佷俊鎭� + * @return + */ + boolean startPlay(StreamInfo stream); + + + /** + * 鍋滄鎾斁鏃跺垹闄� + * + * @return + */ + boolean stopPlay(StreamInfo streamInfo); + + /** + * 鏌ヨ鎾斁鍒楄〃 + * @return + */ + StreamInfo queryPlay(StreamInfo streamInfo); + + StreamInfo queryPlayByStreamId(String steamId); + + StreamInfo queryPlaybackByStreamId(String steamId); + + StreamInfo queryPlayByDevice(String deviceId, String code); + + /** + * 鏇存柊娴佸獟浣撲俊鎭� + * @param mediaServerConfig + * @return + */ + boolean updateMediaInfo(MediaServerConfig mediaServerConfig); + + /** + * 鑾峰彇娴佸獟浣撲俊鎭� + * @return + */ + MediaServerConfig getMediaInfo(); + + Map<String, StreamInfo> queryPlayByDeviceId(String deviceId); + + boolean startPlayback(StreamInfo stream); + + boolean stopPlayback(StreamInfo streamInfo); + + StreamInfo queryPlaybackByDevice(String deviceId, String code); +} diff --git a/src/main/java/com/genersoft/iot/vmp/storager/IVideoManagerStorager.java b/src/main/java/com/genersoft/iot/vmp/storager/IVideoManagerStorager.java index b58caae..c601f7e 100644 --- a/src/main/java/com/genersoft/iot/vmp/storager/IVideoManagerStorager.java +++ b/src/main/java/com/genersoft/iot/vmp/storager/IVideoManagerStorager.java @@ -1,15 +1,10 @@ package com.genersoft.iot.vmp.storager; import java.util.List; -import java.util.Map; -import com.alibaba.fastjson.JSONObject; -import com.genersoft.iot.vmp.common.PageResult; -import com.genersoft.iot.vmp.common.StreamInfo; -import com.genersoft.iot.vmp.conf.MediaServerConfig; import com.genersoft.iot.vmp.gb28181.bean.Device; import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel; -import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform; +import com.github.pagehelper.PageInfo; /** * @Description:瑙嗛璁惧鏁版嵁瀛樺偍鎺ュ彛 @@ -17,19 +12,6 @@ * @date: 2020骞�5鏈�6鏃� 涓嬪崍2:14:31 */ public interface IVideoManagerStorager { - - /** - * 鏇存柊娴佸獟浣撲俊鎭� - * @param mediaServerConfig - * @return - */ - public boolean updateMediaInfo(MediaServerConfig mediaServerConfig); - - /** - * 鑾峰彇娴佸獟浣撲俊鎭� - * @return - */ - public MediaServerConfig getMediaInfo(); /** * 鏍规嵁璁惧ID鍒ゆ柇璁惧鏄惁瀛樺湪 @@ -79,7 +61,7 @@ * @param count 姣忛〉鏁伴噺 * @return */ - public PageResult queryChannelsByDeviceId(String deviceId, String query, Boolean hasSubChannel, String online, int page, int count); + public PageInfo queryChannelsByDeviceId(String deviceId, String query, Boolean hasSubChannel, Boolean online, int page, int count); /** * 鑾峰彇鏌愪釜璁惧鐨勯�氶亾鍒楄〃 @@ -88,6 +70,7 @@ * @return */ public List<DeviceChannel> queryChannelsByDeviceId(String deviceId); + /** * 鑾峰彇鏌愪釜璁惧鐨勯�氶亾 * @param deviceId 璁惧ID @@ -95,21 +78,20 @@ */ public DeviceChannel queryChannel(String deviceId, String channelId); - /** + /** * 鑾峰彇澶氫釜璁惧 - * - * @param deviceIds 璁惧ID鏁扮粍 + * @param page 褰撳墠椤垫暟 + * @param count 姣忛〉鏁伴噺 * @return List<Device> 璁惧瀵硅薄鏁扮粍 */ - public PageResult<Device> queryVideoDeviceList(String[] deviceIds, int page, int count); + public PageInfo<Device> queryVideoDeviceList(int page, int count); /** * 鑾峰彇澶氫釜璁惧 * - * @param deviceIds 璁惧ID鏁扮粍 * @return List<Device> 璁惧瀵硅薄鏁扮粍 */ - public List<Device> queryVideoDeviceList(String[] deviceIds); + public List<Device> queryVideoDeviceList(); /** * 鍒犻櫎璁惧 @@ -135,27 +117,6 @@ */ public boolean outline(String deviceId); - /** - * 寮�濮嬫挱鏀炬椂灏嗘祦瀛樺叆 - * - * @param stream 娴佷俊鎭� - * @return - */ - public boolean startPlay(StreamInfo stream); - - /** - * 鍋滄鎾斁鏃跺垹闄� - * - * @return - */ - public boolean stopPlay(StreamInfo streamInfo); - - /** - * 鏌ユ壘瑙嗛娴� - * - * @return - */ - public StreamInfo queryPlay(StreamInfo streamInfo); /** * 鏌ヨ瀛愯澶� @@ -166,12 +127,8 @@ * @param count * @return */ - PageResult querySubChannels(String deviceId, String channelId, String query, Boolean hasSubChannel, String online, int page, int count); + PageInfo querySubChannels(String deviceId, String channelId, String query, Boolean hasSubChannel, String online, int page, int count); - /** - * 鏇存柊缂撳瓨 - */ - public void updateCatch(); /** * 娓呯┖閫氶亾 @@ -179,45 +136,4 @@ */ void cleanChannelsForDevice(String deviceId); - StreamInfo queryPlayBySSRC(String ssrc); - - StreamInfo queryPlayByDevice(String deviceId, String code); - - Map<String, StreamInfo> queryPlayByDeviceId(String deviceId); - - boolean startPlayback(StreamInfo streamInfo); - - boolean stopPlayback(StreamInfo streamInfo); - - StreamInfo queryPlaybackByDevice(String deviceId, String channelId); - - StreamInfo queryPlaybackBySSRC(String ssrc); - - /** - * 鏇存柊鎴栨坊鍔犱笂绾у钩鍙� - * @param parentPlatform - */ - boolean updateParentPlatform(ParentPlatform parentPlatform); - - /** - * 鍒犻櫎涓婄骇骞冲彴 - * @param parentPlatform - */ - boolean deleteParentPlatform(ParentPlatform parentPlatform); - - - /** - * 鍒嗛〉鑾峰彇涓婄骇骞冲彴 - * @param page - * @param count - * @return - */ - public PageResult<ParentPlatform> queryParentPlatformList(int page, int count); - - /** - * 鑾峰彇涓婄骇骞冲彴 - * @param platformGbId - * @return - */ - public ParentPlatform queryParentPlatById(String platformGbId); } diff --git a/src/main/java/com/genersoft/iot/vmp/storager/VideoManagerStoragerFactory.java b/src/main/java/com/genersoft/iot/vmp/storager/VideoManagerStoragerFactory.java deleted file mode 100644 index 70bdad7..0000000 --- a/src/main/java/com/genersoft/iot/vmp/storager/VideoManagerStoragerFactory.java +++ /dev/null @@ -1,36 +0,0 @@ -package com.genersoft.iot.vmp.storager; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.annotation.Bean; -import org.springframework.stereotype.Component; - -import com.genersoft.iot.vmp.conf.VManagerConfig; - -/** - * @Description:瑙嗛璁惧鏁版嵁瀛樺偍宸ュ巶锛屾牴鎹瓨鍌ㄧ瓥鐣ワ紝杩斿洖瀵瑰簲鐨勫瓨鍌ㄥ櫒 - * @author: swwheihei - * @date: 2020骞�5鏈�6鏃� 涓嬪崍2:15:16 - */ -@Component -public class VideoManagerStoragerFactory { - - @Autowired - private VManagerConfig vmConfig; - - @Autowired - private IVideoManagerStorager jdbcStorager; - - @Autowired - private IVideoManagerStorager redisStorager; - - @Bean("storager") - public IVideoManagerStorager getStorager() { - if ("redis".equals(vmConfig.getDatabase().toLowerCase())) { - return redisStorager; - } else if ("jdbc".equals(vmConfig.getDatabase().toLowerCase())) { - return jdbcStorager; - } - return redisStorager; - } - -} diff --git a/src/main/java/com/genersoft/iot/vmp/storager/VodeoMannagerTask.java b/src/main/java/com/genersoft/iot/vmp/storager/VodeoMannagerTask.java deleted file mode 100644 index c96e4bb..0000000 --- a/src/main/java/com/genersoft/iot/vmp/storager/VodeoMannagerTask.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.genersoft.iot.vmp.storager; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.CommandLineRunner; -import org.springframework.stereotype.Component; - -@Component -public class VodeoMannagerTask implements CommandLineRunner { - - @Autowired - private IVideoManagerStorager storager; - - @Override - public void run(String... strings) throws Exception { - storager.updateCatch(); - } -} 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 new file mode 100644 index 0000000..eecc0bb --- /dev/null +++ b/src/main/java/com/genersoft/iot/vmp/storager/dao/DeviceChannelMapper.java @@ -0,0 +1,51 @@ +package com.genersoft.iot.vmp.storager.dao; + +import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel; +import org.apache.ibatis.annotations.*; + +import java.util.List; + +/** + * 鐢ㄤ簬瀛樺偍璁惧閫氶亾淇℃伅 + */ +@Mapper +public interface DeviceChannelMapper { + + @Insert("INSERT INTO device_channel (channelId, deviceId, name, manufacture, model, owner, civilCode, block, " + + "address, parental, parentId, safetyWay, registerWay, certNum, certifiable, errCode, secrecy, " + + "ipAddress, port, password, PTZType, status) " + + "VALUES ('${channelId}', '${deviceId}', '${name}', '${manufacture}', '${model}', '${owner}', '${civilCode}', '${block}'," + + "'${address}', ${parental}, '${parentId}', ${safetyWay}, ${registerWay}, '${certNum}', ${certifiable}, ${errCode}, '${secrecy}', " + + "'${ipAddress}', ${port}, '${password}', ${PTZType}, ${status})") + int add(DeviceChannel channel); + + @Update("UPDATE device_channel " + + "SET name=#{name}, manufacture=#{manufacture}, model=#{model}, owner=#{owner}, civilCode=#{civilCode}, " + + "block=#{block}, address=#{address}, parental=#{parental}, parentId=#{parentId}, safetyWay=#{safetyWay}, " + + "registerWay=#{registerWay}, certNum=#{certNum}, certifiable=#{certifiable}, errCode=#{errCode}, secrecy=#{secrecy}, " + + "ipAddress=#{ipAddress}, port=#{port}, password=#{password}, PTZType=#{PTZType}, status=#{status}, streamId=#{streamId}, " + + "hasAudio=#{hasAudio}" + + "WHERE deviceId=#{deviceId} AND channelId=#{channelId}") + int update(DeviceChannel channel); + + @Select(value = {" <script>" + + "SELECT * FROM ( "+ + " SELECT * , (SELECT count(0) FROM device_channel WHERE parentId=dc.channelId) as subCount FROM device_channel dc " + + " WHERE dc.deviceId=#{deviceId} " + + " <if test=\"query != null\"> AND (dc.channelId LIKE '%${query}%' OR dc.name LIKE '%${query}%' OR dc.name LIKE '%${query}%')</if> " + + " <if test=\"parentChannelId != null\"> AND dc.parentId=#{parentChannelId} </if> " + + " <if test=\"online == true\" > AND dc.status=1</if>" + + " <if test=\"online == false\" > AND dc.status=0</if>) dcr" + + " WHERE 1=1 " + + " <if test=\"hasSubChannel == true\" > AND subCount >0</if>" + + " <if test=\"hasSubChannel == false\" > AND subCount=0</if>" + + " </script>"}) + List<DeviceChannel> queryChannelsByDeviceId(String deviceId, String parentChannelId, String query, Boolean hasSubChannel, Boolean online); + + @Select("SELECT * FROM device_channel WHERE deviceId=#{deviceId} AND channelId=#{channelId}") + DeviceChannel queryChannel(String deviceId, String channelId); + + @Delete("DELETE FROM device_channel WHERE deviceId=#{deviceId}") + int cleanChannelsByDeviceId(String deviceId); + +} diff --git a/src/main/java/com/genersoft/iot/vmp/storager/dao/DeviceMapper.java b/src/main/java/com/genersoft/iot/vmp/storager/dao/DeviceMapper.java new file mode 100644 index 0000000..3c10618 --- /dev/null +++ b/src/main/java/com/genersoft/iot/vmp/storager/dao/DeviceMapper.java @@ -0,0 +1,66 @@ +package com.genersoft.iot.vmp.storager.dao; + +import com.genersoft.iot.vmp.gb28181.bean.Device; +import org.apache.ibatis.annotations.*; +import org.springframework.stereotype.Repository; + +import java.util.List; + +/** + * 鐢ㄤ簬瀛樺偍璁惧淇℃伅 + */ +@Mapper +@Repository +public interface DeviceMapper { + + @Select("SELECT * FROM device WHERE deviceId = #{deviceId}") + Device getDeviceByDeviceId(String deviceId); + + @Insert("INSERT INTO device (" + + "deviceId, " + + "name, " + + "manufacturer, " + + "model, " + + "firmware, " + + "transport," + + "streamMode," + + "ip," + + "port," + + "hostAddress," + + "online" + + ") VALUES (" + + "#{deviceId}," + + "#{name}," + + "#{manufacturer}," + + "#{model}," + + "#{firmware}," + + "#{transport}," + + "#{streamMode}," + + "#{ip}," + + "#{port}," + + "#{hostAddress}," + + "#{online}" + + ")") + int add(Device device); + + + @Update("UPDATE device " + + "SET name=#{name}, " + + "manufacturer=#{manufacturer}," + + "model=#{model}," + + "firmware=#{firmware}, " + + "transport=#{transport}," + + "streamMode=#{streamMode}, " + + "ip=#{ip}, " + + "port=#{port}, " + + "hostAddress=#{hostAddress}, " + + "online=#{online} " + + "WHERE deviceId=#{deviceId}") + int update(Device device); + + @Select("SELECT *, (SELECT count(0) FROM device_channel WHERE deviceId=de.deviceId) as channelCount FROM device de") + List<Device> getDevices(); + + @Delete("DELETE FROM device WHERE deviceId=#{deviceId}") + int del(String deviceId); +} 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 new file mode 100644 index 0000000..cebb30b --- /dev/null +++ b/src/main/java/com/genersoft/iot/vmp/storager/impl/RedisCatchStorageImpl.java @@ -0,0 +1,166 @@ +package com.genersoft.iot.vmp.storager.impl; + +import com.genersoft.iot.vmp.common.StreamInfo; +import com.genersoft.iot.vmp.common.VideoManagerConstants; +import com.genersoft.iot.vmp.conf.MediaServerConfig; +import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel; +import com.genersoft.iot.vmp.storager.IRedisCatchStorage; +import com.genersoft.iot.vmp.storager.dao.DeviceChannelMapper; +import com.genersoft.iot.vmp.utils.redis.RedisUtil; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; + +@Component +public class RedisCatchStorageImpl implements IRedisCatchStorage { + + @Autowired + private RedisUtil redis; + + @Autowired + private DeviceChannelMapper deviceChannelMapper; + + + /** + * 寮�濮嬫挱鏀炬椂灏嗘祦瀛樺叆redis + * + * @return + */ + @Override + public boolean startPlay(StreamInfo stream) { + return redis.set(String.format("%S_%s_%s_%s", VideoManagerConstants.PLAYER_PREFIX, stream.getStreamId(),stream.getDeviceID(), stream.getCahnnelId()), + stream); + } + + /** + * 鍋滄鎾斁鏃朵粠redis鍒犻櫎 + * + * @return + */ + @Override + public boolean stopPlay(StreamInfo streamInfo) { + if (streamInfo == null) return false; + DeviceChannel deviceChannel = deviceChannelMapper.queryChannel(streamInfo.getDeviceID(), streamInfo.getCahnnelId()); + if (deviceChannel != null) { + deviceChannel.setStreamId(null); + deviceChannel.setDeviceId(streamInfo.getDeviceID()); + deviceChannelMapper.update(deviceChannel); + } + return redis.del(String.format("%S_%s_%s_%s", VideoManagerConstants.PLAYER_PREFIX, + streamInfo.getStreamId(), + streamInfo.getDeviceID(), + streamInfo.getCahnnelId())); + } + + /** + * 鏌ヨ鎾斁鍒楄〃 + * @return + */ + @Override + public StreamInfo queryPlay(StreamInfo streamInfo) { + return (StreamInfo)redis.get(String.format("%S_%s_%s_%s", + VideoManagerConstants.PLAYER_PREFIX, + streamInfo.getStreamId(), + streamInfo.getDeviceID(), + streamInfo.getCahnnelId())); + } + @Override + public StreamInfo queryPlayByStreamId(String steamId) { + List<Object> playLeys = redis.scan(String.format("%S_%s_*", VideoManagerConstants.PLAYER_PREFIX, steamId)); + if (playLeys == null || playLeys.size() == 0) return null; + return (StreamInfo)redis.get(playLeys.get(0).toString()); + } + + @Override + public StreamInfo queryPlaybackByStreamId(String steamId) { + List<Object> playLeys = redis.scan(String.format("%S_%s_*", VideoManagerConstants.PLAY_BLACK_PREFIX, steamId)); + if (playLeys == null || playLeys.size() == 0) return null; + return (StreamInfo)redis.get(playLeys.get(0).toString()); + } + + @Override + public StreamInfo queryPlayByDevice(String deviceId, String code) { +// List<Object> playLeys = redis.keys(String.format("%S_*_%s_%s", VideoManagerConstants.PLAYER_PREFIX, + List<Object> playLeys = redis.scan(String.format("%S_*_%s_%s", VideoManagerConstants.PLAYER_PREFIX, + deviceId, + code)); + if (playLeys == null || playLeys.size() == 0) return null; + return (StreamInfo)redis.get(playLeys.get(0).toString()); + } + + /** + * 鏇存柊娴佸獟浣撲俊鎭� + * @param mediaServerConfig + * @return + */ + @Override + public boolean updateMediaInfo(MediaServerConfig mediaServerConfig) { + return redis.set(VideoManagerConstants.MEDIA_SERVER_PREFIX,mediaServerConfig); + } + + /** + * 鑾峰彇娴佸獟浣撲俊鎭� + * @return + */ + @Override + public MediaServerConfig getMediaInfo() { + return (MediaServerConfig)redis.get(VideoManagerConstants.MEDIA_SERVER_PREFIX); + } + + @Override + public Map<String, StreamInfo> queryPlayByDeviceId(String deviceId) { + Map<String, StreamInfo> streamInfos = new HashMap<>(); +// List<Object> playLeys = redis.keys(String.format("%S_*_%S_*", VideoManagerConstants.PLAYER_PREFIX, deviceId)); + List<Object> players = redis.scan(String.format("%S_*_%S_*", VideoManagerConstants.PLAYER_PREFIX, deviceId)); + if (players.size() == 0) return streamInfos; + for (int i = 0; i < players.size(); i++) { + String key = (String) players.get(i); + StreamInfo streamInfo = (StreamInfo)redis.get(key); + streamInfos.put(streamInfo.getDeviceID() + "_" + streamInfo.getCahnnelId(), streamInfo); + } + return streamInfos; + } + + + @Override + public boolean startPlayback(StreamInfo stream) { + return redis.set(String.format("%S_%s_%s_%s", VideoManagerConstants.PLAY_BLACK_PREFIX, stream.getStreamId(),stream.getDeviceID(), stream.getCahnnelId()), + stream); + } + + + @Override + public boolean stopPlayback(StreamInfo streamInfo) { + if (streamInfo == null) return false; + DeviceChannel deviceChannel = deviceChannelMapper.queryChannel(streamInfo.getDeviceID(), streamInfo.getCahnnelId()); + if (deviceChannel != null) { + deviceChannel.setStreamId(null); + deviceChannel.setDeviceId(streamInfo.getDeviceID()); + deviceChannelMapper.update(deviceChannel); + } + return redis.del(String.format("%S_%s_%s_%s", VideoManagerConstants.PLAY_BLACK_PREFIX, + streamInfo.getStreamId(), + streamInfo.getDeviceID(), + streamInfo.getCahnnelId())); + } + + @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", VideoManagerConstants.PLAY_BLACK_PREFIX, + deviceId, + code)); + if (playLeys == null || playLeys.size() == 0) { + playLeys = redis.scan(String.format("%S_*_*_%s", VideoManagerConstants.PLAY_BLACK_PREFIX, + deviceId)); + } + if (playLeys == null || playLeys.size() == 0) return null; + return (StreamInfo)redis.get(playLeys.get(0).toString()); + } +} 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 new file mode 100644 index 0000000..01ed247 --- /dev/null +++ b/src/main/java/com/genersoft/iot/vmp/storager/impl/VideoManagerStoragerImpl.java @@ -0,0 +1,202 @@ +package com.genersoft.iot.vmp.storager.impl; + +import java.util.*; + +import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel; +import com.genersoft.iot.vmp.storager.dao.DeviceChannelMapper; +import com.genersoft.iot.vmp.storager.dao.DeviceMapper; +import com.github.pagehelper.PageHelper; +import com.github.pagehelper.PageInfo; +import io.swagger.models.auth.In; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import com.genersoft.iot.vmp.gb28181.bean.Device; +import com.genersoft.iot.vmp.storager.IVideoManagerStorager; +import org.springframework.util.StringUtils; + +/** + * @Description:瑙嗛璁惧鏁版嵁瀛樺偍-jdbc瀹炵幇 + * @author: swwheihei + * @date: 2020骞�5鏈�6鏃� 涓嬪崍2:31:42 + */ +@Component +public class VideoManagerStoragerImpl implements IVideoManagerStorager { + + @Autowired + private DeviceMapper deviceMapper; + + @Autowired + private DeviceChannelMapper deviceChannelMapper; + + + /** + * 鏍规嵁璁惧ID鍒ゆ柇璁惧鏄惁瀛樺湪 + * + * @param deviceId 璁惧ID + * @return true:瀛樺湪 false锛氫笉瀛樺湪 + */ + @Override + public boolean exists(String deviceId) { + return deviceMapper.getDeviceByDeviceId(deviceId) != null; + } + + /** + * 瑙嗛璁惧鍒涘缓 + * + * @param device 璁惧瀵硅薄 + * @return true锛氬垱寤烘垚鍔� false锛氬垱寤哄け璐� + */ + @Override + public synchronized boolean create(Device device) { + return deviceMapper.add(device) > 0; + } + + + + /** + * 瑙嗛璁惧鏇存柊 + * + * @param device 璁惧瀵硅薄 + * @return true锛氭洿鏂版垚鍔� false锛氭洿鏂板け璐� + */ + @Override + public synchronized boolean updateDevice(Device device) { + Device deviceByDeviceId = deviceMapper.getDeviceByDeviceId(device.getDeviceId()); + if (deviceByDeviceId == null) { + return deviceMapper.add(device) > 0; + }else { + return deviceMapper.update(device) > 0; + } + + } + + @Override + public synchronized void updateChannel(String deviceId, DeviceChannel channel) { + String channelId = channel.getChannelId(); + channel.setDeviceId(deviceId); + DeviceChannel deviceChannel = deviceChannelMapper.queryChannel(deviceId, channelId); + if (deviceChannel == null) { + deviceChannelMapper.add(channel); + }else { + deviceChannelMapper.update(channel); + } + } + + /** + * 鑾峰彇璁惧 + * + * @param deviceId 璁惧ID + * @return Device 璁惧瀵硅薄 + */ + @Override + public Device queryVideoDevice(String deviceId) { + return deviceMapper.getDeviceByDeviceId(deviceId); + } + + @Override + public PageInfo queryChannelsByDeviceId(String deviceId, String query, Boolean hasSubChannel, Boolean online, int page, int count) { + // 鑾峰彇鍒版墍鏈夋鍦ㄦ挱鏀剧殑娴� + PageHelper.startPage(page, count); + List<DeviceChannel> all = deviceChannelMapper.queryChannelsByDeviceId(deviceId, null, query, hasSubChannel, online); + return new PageInfo<>(all); + } + + + + @Override + public List<DeviceChannel> queryChannelsByDeviceId(String deviceId) { + return deviceChannelMapper.queryChannelsByDeviceId(deviceId, null,null, null, null); + } + + @Override + public PageInfo<DeviceChannel> querySubChannels(String deviceId, String parentChannelId, String query, Boolean hasSubChannel, String online, int page, int count) { + PageHelper.startPage(page, count); + List<DeviceChannel> all = deviceChannelMapper.queryChannelsByDeviceId(deviceId, parentChannelId, null, null, null); + return new PageInfo<>(all); + } + + @Override + public DeviceChannel queryChannel(String deviceId, String channelId) { + return deviceChannelMapper.queryChannel(deviceId, channelId); + } + + + /** + * 鑾峰彇澶氫釜璁惧 + * + * @param page 褰撳墠椤垫暟 + * @param count 姣忛〉鏁伴噺 + * @return PageInfo<Device> 鍒嗛〉璁惧瀵硅薄鏁扮粍 + */ + @Override + public PageInfo<Device> queryVideoDeviceList(int page, int count) { + PageHelper.startPage(page, count); + List<Device> all = deviceMapper.getDevices(); + return new PageInfo<>(all); + } + + /** + * 鑾峰彇澶氫釜璁惧 + * + * @return List<Device> 璁惧瀵硅薄鏁扮粍 + */ + @Override + public List<Device> queryVideoDeviceList() { + + List<Device> deviceList = deviceMapper.getDevices(); + return deviceList; + } + + /** + * 鍒犻櫎璁惧 + * + * @param deviceId 璁惧ID + * @return true锛氬垹闄ゆ垚鍔� false锛氬垹闄ゅけ璐� + */ + @Override + public boolean delete(String deviceId) { + int result = deviceMapper.del(deviceId); + + return result > 0; + } + + /** + * 鏇存柊璁惧鍦ㄧ嚎 + * + * @param deviceId 璁惧ID + * @return true锛氭洿鏂版垚鍔� false锛氭洿鏂板け璐� + */ + @Override + public synchronized boolean online(String deviceId) { + Device device = deviceMapper.getDeviceByDeviceId(deviceId); + device.setOnline(1); + System.out.println("鏇存柊璁惧鍦ㄧ嚎"); + if (device == null) { + return false; + } + return deviceMapper.update(device) > 0; + } + + /** + * 鏇存柊璁惧绂荤嚎 + * + * @param deviceId 璁惧ID + * @return true锛氭洿鏂版垚鍔� false锛氭洿鏂板け璐� + */ + @Override + public synchronized boolean outline(String deviceId) { + Device device = deviceMapper.getDeviceByDeviceId(deviceId); + device.setOnline(0); + System.out.println("鏇存柊璁惧绂荤嚎"); + return deviceMapper.update(device) > 0; + } + + + @Override + public void cleanChannelsForDevice(String deviceId) { + int result = deviceChannelMapper.cleanChannelsByDeviceId(deviceId); + } + + +} diff --git a/src/main/java/com/genersoft/iot/vmp/storager/jdbc/VideoManagerJdbcStoragerImpl.java b/src/main/java/com/genersoft/iot/vmp/storager/jdbc/VideoManagerJdbcStoragerImpl.java deleted file mode 100644 index 5e8ba1a..0000000 --- a/src/main/java/com/genersoft/iot/vmp/storager/jdbc/VideoManagerJdbcStoragerImpl.java +++ /dev/null @@ -1,237 +0,0 @@ -package com.genersoft.iot.vmp.storager.jdbc; - -import java.util.List; -import java.util.Map; - -import com.genersoft.iot.vmp.common.PageResult; -import com.genersoft.iot.vmp.common.StreamInfo; -import com.genersoft.iot.vmp.conf.MediaServerConfig; -import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel; -import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform; -import org.springframework.stereotype.Component; -import org.springframework.stereotype.Service; - -import com.genersoft.iot.vmp.common.VideoManagerConstants; -import com.genersoft.iot.vmp.gb28181.bean.Device; -import com.genersoft.iot.vmp.storager.IVideoManagerStorager; - -/** - * @Description:瑙嗛璁惧鏁版嵁瀛樺偍-jdbc瀹炵幇 - * @author: swwheihei - * @date: 2020骞�5鏈�6鏃� 涓嬪崍2:28:12 - */ -@Component("jdbcStorager") -public class VideoManagerJdbcStoragerImpl implements IVideoManagerStorager { - - @Override - public boolean updateMediaInfo(MediaServerConfig mediaServerConfig) { - return false; - } - - @Override - public MediaServerConfig getMediaInfo() { - return null; - } - - /** - * 鏍规嵁璁惧ID鍒ゆ柇璁惧鏄惁瀛樺湪 - * - * @param deviceId 璁惧ID - * @return true:瀛樺湪 false锛氫笉瀛樺湪 - */ - @Override - public boolean exists(String deviceId) { - // TODO Auto-generated method stub - return false; - } - - /** - * 瑙嗛璁惧鍒涘缓 - * - * @param device 璁惧瀵硅薄 - * @return true锛氬垱寤烘垚鍔� false锛氬垱寤哄け璐� - */ - @Override - public boolean create(Device device) { - // TODO Auto-generated method stub - return false; - } - - @Override - public boolean updateDevice(Device device) { - return false; - } - - @Override - public void updateChannel(String deviceId, DeviceChannel channel) { - - } - - - /** - * 鑾峰彇璁惧 - * - * @param deviceId 璁惧ID - * @return Device 璁惧瀵硅薄 - */ - @Override - public Device queryVideoDevice(String deviceId) { - // TODO Auto-generated method stub - return null; - } - - @Override - public PageResult queryChannelsByDeviceId(String deviceId, String query, Boolean hasSubChannel, String online, int page, int count) { - return null; - } - - - @Override - public List<DeviceChannel> queryChannelsByDeviceId(String deviceId) { - return null; - } - - @Override - public DeviceChannel queryChannel(String deviceId, String channelId) { - return null; - } - - @Override - public PageResult<Device> queryVideoDeviceList(String[] deviceIds, int page, int count) { - return null; - } - - /** - * 鑾峰彇澶氫釜璁惧 - * - * @param deviceIds 璁惧ID鏁扮粍 - * @return List<Device> 璁惧瀵硅薄鏁扮粍 - */ - @Override - public List<Device> queryVideoDeviceList(String[] deviceIds) { - // TODO Auto-generated method stub - return null; - } - - /** - * 鍒犻櫎璁惧 - * - * @param deviceId 璁惧ID - * @return true锛氬垹闄ゆ垚鍔� false锛氬垹闄ゅけ璐� - */ - @Override - public boolean delete(String deviceId) { - // TODO Auto-generated method stub - return false; - } - - /** - * 鏇存柊璁惧鍦ㄧ嚎 - * - * @param deviceId 璁惧ID - * @return true锛氭洿鏂版垚鍔� false锛氭洿鏂板け璐� - */ - @Override - public boolean online(String deviceId) { - // TODO Auto-generated method stub - return false; - } - - /** - * 鏇存柊璁惧绂荤嚎 - * - * @param deviceId 璁惧ID - * @return true锛氭洿鏂版垚鍔� false锛氭洿鏂板け璐� - */ - @Override - public boolean outline(String deviceId) { - // TODO Auto-generated method stub - return false; - } - - @Override - public boolean stopPlay(StreamInfo streamInfo) { - return false; - } - - @Override - public StreamInfo queryPlay(StreamInfo streamInfo) { - return null; - } - - @Override - public PageResult querySubChannels(String deviceId, String channelId, String query, Boolean hasSubChannel, String online, int page, int count) { - return null; - } - - @Override - public void updateCatch() { - System.out.println("##################"); - } - - @Override - public void cleanChannelsForDevice(String deviceId) { - - } - - @Override - public boolean startPlay(StreamInfo stream) { - return false; - } - - @Override - public StreamInfo queryPlayBySSRC(String ssrc) { - return null; - } - - @Override - public StreamInfo queryPlayByDevice(String deviceId, String code) { - return null; - } - - @Override - public Map<String, StreamInfo> queryPlayByDeviceId(String deviceId) { - - return null; - } - - @Override - public boolean startPlayback(StreamInfo streamInfo) { - return false; - } - - @Override - public boolean stopPlayback(StreamInfo streamInfo) { - return false; - } - - @Override - public StreamInfo queryPlaybackByDevice(String deviceId, String channelId) { - return null; - } - - @Override - public StreamInfo queryPlaybackBySSRC(String ssrc) { - return null; - } - - @Override - public boolean updateParentPlatform(ParentPlatform parentPlatform) { - return false; - } - - @Override - public boolean deleteParentPlatform(ParentPlatform parentPlatform) { - return false; - } - - @Override - public PageResult<ParentPlatform> queryParentPlatformList(int page, int count) { - return null; - } - - @Override - public ParentPlatform queryParentPlatById(String platformGbId) { - return null; - } -} diff --git a/src/main/java/com/genersoft/iot/vmp/storager/redis/VideoManagerRedisStoragerImpl.java b/src/main/java/com/genersoft/iot/vmp/storager/redis/VideoManagerRedisStoragerImpl.java deleted file mode 100644 index 99c7f06..0000000 --- a/src/main/java/com/genersoft/iot/vmp/storager/redis/VideoManagerRedisStoragerImpl.java +++ /dev/null @@ -1,600 +0,0 @@ -package com.genersoft.iot.vmp.storager.redis; - -import java.util.*; - -import com.alibaba.fastjson.JSON; -import com.alibaba.fastjson.JSONObject; -import com.genersoft.iot.vmp.common.PageResult; -import com.genersoft.iot.vmp.common.StreamInfo; -import com.genersoft.iot.vmp.conf.MediaServerConfig; -import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel; -import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; - -import com.genersoft.iot.vmp.common.VideoManagerConstants; -import com.genersoft.iot.vmp.gb28181.bean.Device; -import com.genersoft.iot.vmp.storager.IVideoManagerStorager; -import com.genersoft.iot.vmp.utils.redis.RedisUtil; -import org.springframework.util.StringUtils; - -/** - * @Description:瑙嗛璁惧鏁版嵁瀛樺偍-redis瀹炵幇 - * @author: swwheihei - * @date: 2020骞�5鏈�6鏃� 涓嬪崍2:31:42 - */ -@Component("redisStorager") -public class VideoManagerRedisStoragerImpl implements IVideoManagerStorager { - - @Autowired - private RedisUtil redis; - - private HashMap<String, HashMap<String, HashSet<String>>> deviceMap = new HashMap<>(); - - - /** - * 鏍规嵁璁惧ID鍒ゆ柇璁惧鏄惁瀛樺湪 - * - * @param deviceId 璁惧ID - * @return true:瀛樺湪 false锛氫笉瀛樺湪 - */ - @Override - public boolean exists(String deviceId) { - return redis.hasKey(VideoManagerConstants.DEVICE_PREFIX+deviceId); - } - - /** - * 瑙嗛璁惧鍒涘缓 - * - * @param device 璁惧瀵硅薄 - * @return true锛氬垱寤烘垚鍔� false锛氬垱寤哄け璐� - */ - @Override - public boolean create(Device device) { - return redis.set(VideoManagerConstants.DEVICE_PREFIX+device.getDeviceId(), device); - } - - - - /** - * 瑙嗛璁惧鏇存柊 - * - * @param device 璁惧瀵硅薄 - * @return true锛氭洿鏂版垚鍔� false锛氭洿鏂板け璐� - */ - @Override - public boolean updateDevice(Device device) { - if (deviceMap.get(device.getDeviceId()) == null) { - deviceMap.put(device.getDeviceId(), new HashMap<String, HashSet<String>>()); - } - // 鏇存柊device涓殑閫氶亾鏁伴噺 - device.setChannelCount(deviceMap.get(device.getDeviceId()).size()); - // 瀛樺偍device - return redis.set(VideoManagerConstants.DEVICE_PREFIX+device.getDeviceId(), device); - - - } - - @Override - public void updateChannel(String deviceId, DeviceChannel channel) { - String channelId = channel.getChannelId(); - HashMap<String, HashSet<String>> channelMap = deviceMap.get(deviceId); - if (channelMap == null) return; - // 浣滀负鐖惰澶�, 纭畾鑷繁鐨勫瓙鑺傜偣鏁� - if (channelMap.get(channelId) == null) { - channelMap.put(channelId, new HashSet<String>()); - }else if (channelMap.get(channelId).size() > 0) { - channel.setSubCount(channelMap.get(channelId).size()); - } - - // 瀛樺偍閫氶亾 - redis.set(VideoManagerConstants.CACHEKEY_PREFIX + deviceId + - "_" + channel.getChannelId() + - "_" + (channel.getStatus() == 1 ? "on":"off") + - "_" + (channelMap.get(channelId).size() > 0)+ - "_" + (StringUtils.isEmpty(channel.getParentId())?null:channel.getParentId()), - channel); - // 鏇存柊device涓殑閫氶亾鏁伴噺 - Device device = (Device)redis.get(VideoManagerConstants.DEVICE_PREFIX+deviceId); - device.setChannelCount(deviceMap.get(deviceId).size()); - redis.set(VideoManagerConstants.DEVICE_PREFIX+device.getDeviceId(), device); - - - // 濡傛灉鏈夌埗璁惧,鏇存柊鐖惰澶囧唴瀛愯妭鐐规暟 - String parentId = channel.getParentId(); - if (!StringUtils.isEmpty(parentId) && !parentId.equals(deviceId)) { - - if (channelMap.get(parentId) == null) { - channelMap.put(parentId, new HashSet<String>()); - } - channelMap.get(parentId).add(channelId); - - DeviceChannel deviceChannel = queryChannel(deviceId, parentId); - if (deviceChannel != null) { - deviceChannel.setSubCount(channelMap.get(parentId).size()); - redis.set(VideoManagerConstants.CACHEKEY_PREFIX + deviceId + - "_" + deviceChannel.getChannelId() + - "_" + (deviceChannel.getStatus() == 1 ? "on":"off") + - "_" + (channelMap.get(deviceChannel.getChannelId()).size() > 0)+ - "_" + (StringUtils.isEmpty(deviceChannel.getParentId())?null:deviceChannel.getParentId()), - deviceChannel); - - } - } - - } - - /** - * 鑾峰彇璁惧 - * - * @param deviceId 璁惧ID - * @return Device 璁惧瀵硅薄 - */ - @Override - public Device queryVideoDevice(String deviceId) { - return (Device)redis.get(VideoManagerConstants.DEVICE_PREFIX+deviceId); - } - - @Override - public PageResult queryChannelsByDeviceId(String deviceId, String query, Boolean hasSubChannel, String online, int page, int count) { - // 鑾峰彇鍒版墍鏈夋鍦ㄦ挱鏀剧殑娴� - Map<String, StreamInfo> stringStreamInfoMap = queryPlayByDeviceId(deviceId); - List<DeviceChannel> result = new ArrayList<>(); - PageResult pageResult = new PageResult<DeviceChannel>(); - String queryContent = "*"; - if (!StringUtils.isEmpty(query)) queryContent = String.format("*%S*",query); - String queryHasSubChannel = "*"; - if (hasSubChannel != null) queryHasSubChannel = hasSubChannel?"true":"false"; - String queryOnline = "*"; - if (!StringUtils.isEmpty(online)) queryOnline = online; - String queryStr = VideoManagerConstants.CACHEKEY_PREFIX + deviceId + - "_" + queryContent + // 鎼滅储缂栧彿鍜屽悕绉� - "_" + queryOnline + // 鎼滅储鏄惁鍦ㄧ嚎 - "_" + queryHasSubChannel + // 鎼滅储鏄惁鍚湁瀛愯妭鐐� - "_" + "*"; -// List<Object> deviceChannelList = redis.keys(queryStr); - List<Object> deviceChannelList = redis.scan(queryStr); - //瀵规煡璇㈢粨鏋滄帓搴忥紝閬垮厤鍑虹幇閫氶亾鎺掑垪椤哄簭涔卞簭鐨勬儏鍐� - Collections.sort(deviceChannelList,new Comparator<Object>(){ - @Override - public int compare(Object o1, Object o2) { - return o1.toString().compareToIgnoreCase(o2.toString()); - } - }); - pageResult.setPage(page); - pageResult.setCount(count); - pageResult.setTotal(deviceChannelList.size()); - int maxCount = (page + 1 ) * count; - if (deviceChannelList != null && deviceChannelList.size() > 0 ) { - for (int i = page * count; i < (pageResult.getTotal() > maxCount ? maxCount : pageResult.getTotal() ); i++) { - DeviceChannel deviceChannel = (DeviceChannel)redis.get((String)deviceChannelList.get(i)); - StreamInfo streamInfo = stringStreamInfoMap.get(deviceId + "_" + deviceChannel.getChannelId()); - deviceChannel.setPlay(streamInfo != null); - if (streamInfo != null) deviceChannel.setSsrc(streamInfo.getSsrc()); - result.add(deviceChannel); - } - pageResult.setData(result); - } - - return pageResult; - } - - - - @Override - public List<DeviceChannel> queryChannelsByDeviceId(String deviceId) { - List<DeviceChannel> result = new ArrayList<>(); -// List<Object> deviceChannelList = redis.keys(VideoManagerConstants.CACHEKEY_PREFIX + deviceId + "_" + "*"); - List<Object> deviceChannelList = redis.scan(VideoManagerConstants.CACHEKEY_PREFIX + deviceId + "_" + "*"); - - if (deviceChannelList != null && deviceChannelList.size() > 0 ) { - for (int i = 0; i < deviceChannelList.size(); i++) { - result.add((DeviceChannel)redis.get((String) deviceChannelList.get(i))); - } - } - return result; - } - - @Override - public PageResult querySubChannels(String deviceId, String parentChannelId, String query, Boolean hasSubChannel, String online, int page, int count) { - List<DeviceChannel> allDeviceChannels = new ArrayList<>(); - String queryContent = "*"; - if (!StringUtils.isEmpty(query)) queryContent = String.format("*%S*",query); - String queryHasSubChannel = "*"; - if (hasSubChannel != null) queryHasSubChannel = hasSubChannel?"true":"false"; - String queryOnline = "*"; - if (!StringUtils.isEmpty(online)) queryOnline = online; - String queryStr = VideoManagerConstants.CACHEKEY_PREFIX + deviceId + - "_" + queryContent + // 鎼滅储缂栧彿鍜屽悕绉� - "_" + queryOnline + // 鎼滅储鏄惁鍦ㄧ嚎 - "_" + queryHasSubChannel + // 鎼滅储鏄惁鍚湁瀛愯妭鐐� - "_" + parentChannelId; - -// List<Object> deviceChannelList = redis.keys(queryStr); - List<Object> deviceChannelList = redis.scan(queryStr); - - if (deviceChannelList != null && deviceChannelList.size() > 0 ) { - for (int i = 0; i < deviceChannelList.size(); i++) { - DeviceChannel deviceChannel = (DeviceChannel)redis.get((String)deviceChannelList.get(i)); - if (deviceChannel.getParentId() != null && deviceChannel.getParentId().equals(parentChannelId)) { - allDeviceChannels.add(deviceChannel); - } - } - } - int maxCount = (page + 1 ) * count; - PageResult pageResult = new PageResult<DeviceChannel>(); - pageResult.setPage(page); - pageResult.setCount(count); - pageResult.setTotal(allDeviceChannels.size()); - - if (allDeviceChannels.size() > 0) { - pageResult.setData(allDeviceChannels.subList( - page * count, pageResult.getTotal() > maxCount ? maxCount : pageResult.getTotal() - )); - } - return pageResult; - } - - public List<DeviceChannel> querySubChannels(String deviceId, String parentChannelId) { - List<DeviceChannel> allDeviceChannels = new ArrayList<>(); -// List<Object> deviceChannelList = redis.keys(VideoManagerConstants.CACHEKEY_PREFIX + deviceId + "_" + "*"); - List<Object> deviceChannelList = redis.scan(VideoManagerConstants.CACHEKEY_PREFIX + deviceId + "_" + "*"); - - if (deviceChannelList != null && deviceChannelList.size() > 0 ) { - for (int i = 0; i < deviceChannelList.size(); i++) { - DeviceChannel deviceChannel = (DeviceChannel)redis.get((String)deviceChannelList.get(i)); - if (deviceChannel.getParentId() != null && deviceChannel.getParentId().equals(parentChannelId)) { - allDeviceChannels.add(deviceChannel); - } - } - } - - return allDeviceChannels; - } - - @Override - public DeviceChannel queryChannel(String deviceId, String channelId) { - DeviceChannel deviceChannel = null; -// List<Object> deviceChannelList = redis.keys(VideoManagerConstants.CACHEKEY_PREFIX + deviceId + - List<Object> deviceChannelList = redis.scan(VideoManagerConstants.CACHEKEY_PREFIX + deviceId + - "_" + channelId + "*"); - if (deviceChannelList != null && deviceChannelList.size() > 0 ) { - deviceChannel = (DeviceChannel)redis.get((String)deviceChannelList.get(0)); - } - return deviceChannel; - } - - - /** - * 鑾峰彇澶氫釜璁惧 - * - * @param deviceIds 璁惧ID鏁扮粍 - * @return List<Device> 璁惧瀵硅薄鏁扮粍 - */ - @Override - public PageResult<Device> queryVideoDeviceList(String[] deviceIds, int page, int count) { - List<Device> devices = new ArrayList<>(); - PageResult pageResult = new PageResult<Device>(); - pageResult.setPage(page); - pageResult.setCount(count); - Device device = null; - - if (deviceIds == null || deviceIds.length == 0) { - -// List<Object> deviceIdList = redis.keys(VideoManagerConstants.DEVICE_PREFIX+"*"); - List<Object> deviceIdList = redis.scan(VideoManagerConstants.DEVICE_PREFIX+"*"); - pageResult.setTotal(deviceIdList.size()); - int maxCount = (page + 1)* count; - for (int i = page * count; i < (pageResult.getTotal() > maxCount ? maxCount : pageResult.getTotal() ); i++) { - // devices.add((Device)redis.get((String)deviceIdList.get(i))); - device =(Device)redis.get((String)deviceIdList.get(i)); - if (redis.scan(VideoManagerConstants.KEEPLIVEKEY_PREFIX+device.getDeviceId()).size() == 0){ - // outline(device.getDeviceId()); - } - devices.add(device); - } - } else { - for (int i = 0; i < deviceIds.length; i++) { - // devices.add((Device)redis.get(VideoManagerConstants.DEVICE_PREFIX+deviceIds[i])); - device = (Device)redis.get(VideoManagerConstants.DEVICE_PREFIX+deviceIds[i]); - if (redis.scan(VideoManagerConstants.KEEPLIVEKEY_PREFIX+device.getDeviceId()).size() == 0){ - // outline(device.getDeviceId()); - } - devices.add(device); - } - } - pageResult.setData(devices); - return pageResult; - } - - /** - * 鑾峰彇澶氫釜璁惧 - * - * @param deviceIds 璁惧ID鏁扮粍 - * @return List<Device> 璁惧瀵硅薄鏁扮粍 - */ - @Override - public List<Device> queryVideoDeviceList(String[] deviceIds) { - List<Device> devices = new ArrayList<>(); - Device device = null; - - if (deviceIds == null || deviceIds.length == 0) { -// List<Object> deviceIdList = redis.keys(VideoManagerConstants.DEVICE_PREFIX+"*"); - List<Object> deviceIdList = redis.scan(VideoManagerConstants.DEVICE_PREFIX+"*"); - for (int i = 0; i < deviceIdList.size(); i++) { - device =(Device)redis.get((String)deviceIdList.get(i)); - if (redis.scan(VideoManagerConstants.KEEPLIVEKEY_PREFIX+device.getDeviceId()).size() == 0){ - outline(device.getDeviceId()); - } - devices.add(device); - } - } else { - for (int i = 0; i < deviceIds.length; i++) { - device = (Device)redis.get(VideoManagerConstants.DEVICE_PREFIX+deviceIds[i]); - if (redis.scan(VideoManagerConstants.KEEPLIVEKEY_PREFIX+device.getDeviceId()).size() == 0){ - outline(device.getDeviceId()); - } - devices.add(device); - } - } - return devices; - } - - /** - * 鍒犻櫎璁惧 - * - * @param deviceId 璁惧ID - * @return true锛氬垹闄ゆ垚鍔� false锛氬垹闄ゅけ璐� - */ - @Override - public boolean delete(String deviceId) { - return redis.del(VideoManagerConstants.DEVICE_PREFIX+deviceId); - } - - /** - * 鏇存柊璁惧鍦ㄧ嚎 - * - * @param deviceId 璁惧ID - * @return true锛氭洿鏂版垚鍔� false锛氭洿鏂板け璐� - */ - @Override - public boolean online(String deviceId) { - Device device = (Device)redis.get(VideoManagerConstants.DEVICE_PREFIX+deviceId); - device.setOnline(1); - return redis.set(VideoManagerConstants.DEVICE_PREFIX+device.getDeviceId(), device); - } - - /** - * 鏇存柊璁惧绂荤嚎 - * - * @param deviceId 璁惧ID - * @return true锛氭洿鏂版垚鍔� false锛氭洿鏂板け璐� - */ - @Override - public boolean outline(String deviceId) { - Device device = (Device)redis.get(VideoManagerConstants.DEVICE_PREFIX+deviceId); - if (device == null) return false; - device.setOnline(0); - return redis.set(VideoManagerConstants.DEVICE_PREFIX+device.getDeviceId(), device); - } - - /** - * 寮�濮嬫挱鏀炬椂灏嗘祦瀛樺叆redis - * - * @return - */ - @Override - public boolean startPlay(StreamInfo stream) { - return redis.set(String.format("%S_%s_%s_%s", VideoManagerConstants.PLAYER_PREFIX, stream.getSsrc(),stream.getDeviceID(), stream.getCahnnelId()), - stream); - } - - /** - * 鍋滄鎾斁鏃朵粠redis鍒犻櫎 - * - * @return - */ - @Override - public boolean stopPlay(StreamInfo streamInfo) { - if (streamInfo == null) return false; - DeviceChannel deviceChannel = queryChannel(streamInfo.getDeviceID(), streamInfo.getCahnnelId()); - if (deviceChannel != null) { - deviceChannel.setSsrc(null); - deviceChannel.setPlay(false); - updateChannel(streamInfo.getDeviceID(), deviceChannel); - } - return redis.del(String.format("%S_%s_%s_%s", VideoManagerConstants.PLAYER_PREFIX, - streamInfo.getSsrc(), - streamInfo.getDeviceID(), - streamInfo.getCahnnelId())); - } - - /** - * 鏌ヨ鎾斁鍒楄〃 - * @return - */ - @Override - public StreamInfo queryPlay(StreamInfo streamInfo) { - return (StreamInfo)redis.get(String.format("%S_%s_%s_%s", - VideoManagerConstants.PLAYER_PREFIX, - streamInfo.getSsrc(), - streamInfo.getDeviceID(), - streamInfo.getCahnnelId())); - } - @Override - public StreamInfo queryPlayBySSRC(String ssrc) { -// List<Object> playLeys = redis.keys(String.format("%S_%s_*", VideoManagerConstants.PLAYER_PREFIX, ssrc)); - List<Object> playLeys = redis.scan(String.format("%S_%s_*", VideoManagerConstants.PLAYER_PREFIX, ssrc)); - if (playLeys == null || playLeys.size() == 0) return null; - return (StreamInfo)redis.get(playLeys.get(0).toString()); - } - - @Override - public StreamInfo queryPlaybackBySSRC(String ssrc) { -// List<Object> playLeys = redis.keys(String.format("%S_%s_*", VideoManagerConstants.PLAYER_PREFIX, ssrc)); - List<Object> playLeys = redis.scan(String.format("%S_%s_*", VideoManagerConstants.PLAY_BLACK_PREFIX, ssrc)); - if (playLeys == null || playLeys.size() == 0) return null; - return (StreamInfo)redis.get(playLeys.get(0).toString()); - } - - @Override - public StreamInfo queryPlayByDevice(String deviceId, String code) { -// List<Object> playLeys = redis.keys(String.format("%S_*_%s_%s", VideoManagerConstants.PLAYER_PREFIX, - List<Object> playLeys = redis.scan(String.format("%S_*_%s_%s", VideoManagerConstants.PLAYER_PREFIX, - deviceId, - code)); - if (playLeys == null || playLeys.size() == 0) return null; - return (StreamInfo)redis.get(playLeys.get(0).toString()); - } - - /** - * 鏇存柊娴佸獟浣撲俊鎭� - * @param mediaServerConfig - * @return - */ - @Override - public boolean updateMediaInfo(MediaServerConfig mediaServerConfig) { - return redis.set(VideoManagerConstants.MEDIA_SERVER_PREFIX,mediaServerConfig); - } - - /** - * 鑾峰彇娴佸獟浣撲俊鎭� - * @return - */ - @Override - public MediaServerConfig getMediaInfo() { - return (MediaServerConfig)redis.get(VideoManagerConstants.MEDIA_SERVER_PREFIX); - } - - @Override - public void updateCatch() { - deviceMap = new HashMap<>(); - // 鏇存柊璁惧 - List<Device> devices = queryVideoDeviceList(null); - if (devices == null && devices.size() == 0) return; - for (Device device : devices) { - // 鏇存柊璁惧涓嬬殑閫氶亾 - HashMap<String, HashSet<String>> channelMap = new HashMap<String, HashSet<String>>(); - List<Object> deviceChannelList = redis.scan(VideoManagerConstants.CACHEKEY_PREFIX + - device.getDeviceId() + "_" + "*"); - if (deviceChannelList != null && deviceChannelList.size() > 0 ) { - for (int i = 0; i < deviceChannelList.size(); i++) { - String key = (String)deviceChannelList.get(i); - String[] s = key.split("_"); - String channelId = s[3]; - HashSet<String> subChannel = channelMap.get(channelId); - if (subChannel == null) { - subChannel = new HashSet<>(); - } - System.out.println(key); - if (s.length == 6 && !"null".equals(s[5])) { - subChannel.add(s[5]); - } - channelMap.put(channelId, subChannel); - } - } - deviceMap.put(device.getDeviceId(),channelMap); - } - System.out.println(); - } - - @Override - public void cleanChannelsForDevice(String deviceId) { - List<DeviceChannel> result = new ArrayList<>(); -// List<Object> deviceChannelList = redis.keys(VideoManagerConstants.CACHEKEY_PREFIX + deviceId + "_" + "*"); - List<Object> deviceChannelList = redis.scan(VideoManagerConstants.CACHEKEY_PREFIX + deviceId + "_" + "*"); - if (deviceChannelList != null && deviceChannelList.size() > 0 ) { - for (int i = 0; i < deviceChannelList.size(); i++) { - redis.del((String)deviceChannelList.get(i)); - } - } - } - - @Override - public Map<String, StreamInfo> queryPlayByDeviceId(String deviceId) { - Map<String, StreamInfo> streamInfos = new HashMap<>(); -// List<Object> playLeys = redis.keys(String.format("%S_*_%S_*", VideoManagerConstants.PLAYER_PREFIX, deviceId)); - List<Object> playLeys = redis.scan(String.format("%S_*_%S_*", VideoManagerConstants.PLAYER_PREFIX, deviceId)); - if (playLeys.size() == 0) return streamInfos; - for (int i = 0; i < playLeys.size(); i++) { - String key = (String) playLeys.get(i); - StreamInfo streamInfo = (StreamInfo)redis.get(key); - streamInfos.put(streamInfo.getDeviceID() + "_" + streamInfo.getCahnnelId(), streamInfo); - } - return streamInfos; - } - - - @Override - public boolean startPlayback(StreamInfo stream) { - return redis.set(String.format("%S_%s_%s_%s", VideoManagerConstants.PLAY_BLACK_PREFIX, stream.getSsrc(),stream.getDeviceID(), stream.getCahnnelId()), - stream); - } - - - @Override - public boolean stopPlayback(StreamInfo streamInfo) { - if (streamInfo == null) return false; - DeviceChannel deviceChannel = queryChannel(streamInfo.getDeviceID(), streamInfo.getCahnnelId()); - if (deviceChannel != null) { - deviceChannel.setSsrc(null); - deviceChannel.setPlay(false); - updateChannel(streamInfo.getDeviceID(), deviceChannel); - } - return redis.del(String.format("%S_%s_%s_%s", VideoManagerConstants.PLAY_BLACK_PREFIX, - streamInfo.getSsrc(), - streamInfo.getDeviceID(), - streamInfo.getCahnnelId())); - } - - @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", VideoManagerConstants.PLAY_BLACK_PREFIX, - deviceId, - code)); - if (playLeys == null || playLeys.size() == 0) { - playLeys = redis.scan(String.format("%S_*_*_%s", VideoManagerConstants.PLAY_BLACK_PREFIX, - deviceId)); - } - if (playLeys == null || playLeys.size() == 0) return null; - return (StreamInfo)redis.get(playLeys.get(0).toString()); - } - - @Override - public boolean updateParentPlatform(ParentPlatform parentPlatform) { - - // 瀛樺偍device - return redis.set(VideoManagerConstants.PLATFORM_PREFIX + parentPlatform.getDeviceGBId(), parentPlatform); - } - - @Override - public boolean deleteParentPlatform(ParentPlatform parentPlatform) { - return redis.del(VideoManagerConstants.PLATFORM_PREFIX + parentPlatform.getDeviceGBId()); - } - - @Override - public PageResult<ParentPlatform> queryParentPlatformList(int page, int count) { - PageResult pageResult = new PageResult<Device>(); - pageResult.setPage(page); - pageResult.setCount(count); - List<ParentPlatform> resultData = new ArrayList<>(); - List<Object> parentPlatformList = redis.scan(VideoManagerConstants.PLATFORM_PREFIX + "*"); - pageResult.setTotal(parentPlatformList.size()); - int maxCount = (page + 1)* count; - for (int i = page * count; i < (pageResult.getTotal() > maxCount ? maxCount : pageResult.getTotal() ); i++) { - ParentPlatform parentPlatform =(ParentPlatform)redis.get((String)parentPlatformList.get(i)); - resultData.add(parentPlatform); - - } - pageResult.setData(resultData); - return pageResult; - } - - @Override - public ParentPlatform queryParentPlatById(String platformGbId) { - return (ParentPlatform)redis.get(VideoManagerConstants.PLATFORM_PREFIX + platformGbId); - } -} diff --git a/src/main/java/com/genersoft/iot/vmp/utils/SpringBeanFactory.java b/src/main/java/com/genersoft/iot/vmp/utils/SpringBeanFactory.java index 3fe7dcc..ccbe94d 100644 --- a/src/main/java/com/genersoft/iot/vmp/utils/SpringBeanFactory.java +++ b/src/main/java/com/genersoft/iot/vmp/utils/SpringBeanFactory.java @@ -34,6 +34,7 @@ * 鑾峰彇瀵硅薄 杩欓噷閲嶅啓浜哹ean鏂规硶锛岃捣涓昏浣滅敤 */ public static Object getBean(String beanId) throws BeansException { + if (applicationContext == null) return null; return applicationContext.getBean(beanId); } diff --git a/src/main/java/com/genersoft/iot/vmp/vmanager/device/DeviceController.java b/src/main/java/com/genersoft/iot/vmp/vmanager/device/DeviceController.java index 34a02ee..d64b632 100644 --- a/src/main/java/com/genersoft/iot/vmp/vmanager/device/DeviceController.java +++ b/src/main/java/com/genersoft/iot/vmp/vmanager/device/DeviceController.java @@ -1,14 +1,14 @@ package com.genersoft.iot.vmp.vmanager.device; -import java.util.List; - -import com.genersoft.iot.vmp.common.PageResult; import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel; +import com.genersoft.iot.vmp.gb28181.transmit.callback.RequestMessage; +import com.github.pagehelper.PageInfo; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; +import org.springframework.util.StringUtils; import org.springframework.web.bind.annotation.*; import org.springframework.web.context.request.async.DeferredResult; @@ -18,6 +18,8 @@ import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder; import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander; import com.genersoft.iot.vmp.storager.IVideoManagerStorager; + +import javax.sip.message.Response; @CrossOrigin @RestController @@ -50,13 +52,13 @@ } @GetMapping("/devices") - public PageResult<Device> devices(int page, int count){ + public PageInfo<Device> devices(int page, int count){ if (logger.isDebugEnabled()) { logger.debug("鏌ヨ鎵�鏈夎棰戣澶嘇PI璋冪敤"); } - return storager.queryVideoDeviceList(null, page, count); + return storager.queryVideoDeviceList(page, count); } /** @@ -66,18 +68,33 @@ * @param count 姣忛〉鏉℃暟 * @return 閫氶亾鍒楄〃 */ + /** + * 鍒嗛〉鏌ヨ閫氶亾鏁� + * + * @param deviceId 璁惧id + * @param page 褰撳墠椤� + * @param count 姣忛〉鏉℃暟 + * @param query 鏌ヨ鍐呭 + * @param online 鏄惁鍦ㄧ嚎 鍦ㄧ嚎 true / 绂荤嚎 false + * @param channelType 璁惧 false/瀛愮洰褰� true + * @return 閫氶亾鍒楄〃 + */ @GetMapping("/devices/{deviceId}/channels") - public ResponseEntity<PageResult> channels(@PathVariable String deviceId, + public ResponseEntity<PageInfo> channels(@PathVariable String deviceId, int page, int count, @RequestParam(required = false) String query, - @RequestParam(required = false) String online, + @RequestParam(required = false) Boolean online, @RequestParam(required = false) Boolean channelType ){ if (logger.isDebugEnabled()) { logger.debug("鏌ヨ鎵�鏈夎棰戣澶嘇PI璋冪敤"); } - PageResult pageResult = storager.queryChannelsByDeviceId(deviceId, query, channelType, online, page, count); + if (StringUtils.isEmpty(query)) { + query = null; + } + + PageInfo pageResult = storager.queryChannelsByDeviceId(deviceId, query, channelType, online, page, count); return new ResponseEntity<>(pageResult,HttpStatus.OK); } @@ -86,11 +103,25 @@ if (logger.isDebugEnabled()) { } - logger.debug("璁惧淇℃伅鍚屾API璋冪敤锛宒eviceId锛�" + deviceId); + logger.debug("璁惧閫氶亾淇℃伅鍚屾API璋冪敤锛宒eviceId锛�" + deviceId); Device device = storager.queryVideoDevice(deviceId); - cmder.catalogQuery(device); - DeferredResult<ResponseEntity<Device>> result = new DeferredResult<ResponseEntity<Device>>(); + cmder.catalogQuery(device, event -> { + Response response = event.getResponse(); + RequestMessage msg = new RequestMessage(); + msg.setId(DeferredResultHolder.CALLBACK_CMD_CATALOG+deviceId); + msg.setData(String.format("鍚屾閫氶亾澶辫触锛岄敊璇爜锛� %s, %s", response.getStatusCode(), response.getReasonPhrase())); + resultHolder.invokeResult(msg); + }); + DeferredResult<ResponseEntity<Device>> result = new DeferredResult<ResponseEntity<Device>>(2*1000L); + result.onTimeout(()->{ + logger.warn(String.format("璁惧閫氶亾淇℃伅鍚屾瓒呮椂")); + // 閲婃斁rtpserver + RequestMessage msg = new RequestMessage(); + msg.setId(DeferredResultHolder.CALLBACK_CMD_CATALOG+deviceId); + msg.setData("Timeout"); + resultHolder.invokeResult(msg); + }); resultHolder.put(DeferredResultHolder.CALLBACK_CMD_CATALOG+deviceId, result); return result; } @@ -124,7 +155,7 @@ * @return 瀛愰�氶亾鍒楄〃 */ @GetMapping("/subChannels/{deviceId}/{channelId}/channels") - public ResponseEntity<PageResult> subChannels(@PathVariable String deviceId, + public ResponseEntity<PageInfo> subChannels(@PathVariable String deviceId, @PathVariable String channelId, int page, int count, @@ -137,23 +168,23 @@ } DeviceChannel deviceChannel = storager.queryChannel(deviceId,channelId); if (deviceChannel == null) { - PageResult<DeviceChannel> deviceChannelPageResult = new PageResult<>(); + PageInfo<DeviceChannel> deviceChannelPageResult = new PageInfo<>(); return new ResponseEntity<>(deviceChannelPageResult,HttpStatus.OK); } - PageResult pageResult = storager.querySubChannels(deviceId, channelId, query, channelType, online, page, count); + PageInfo pageResult = storager.querySubChannels(deviceId, channelId, query, channelType, online, page, count); return new ResponseEntity<>(pageResult,HttpStatus.OK); } @PostMapping("/channel/update/{deviceId}") - public ResponseEntity<PageResult> updateChannel(@PathVariable String deviceId,DeviceChannel channel){ + public ResponseEntity<PageInfo> updateChannel(@PathVariable String deviceId,DeviceChannel channel){ storager.updateChannel(deviceId, channel); return new ResponseEntity<>(null,HttpStatus.OK); } @GetMapping("/devices/{deviceId}/transport/{streamMode}") @PostMapping("/devices/{deviceId}/transport/{streamMode}") - public ResponseEntity<PageResult> updateTransport(@PathVariable String deviceId, @PathVariable String streamMode){ + public ResponseEntity<PageInfo> updateTransport(@PathVariable String deviceId, @PathVariable String streamMode){ Device device = storager.queryVideoDevice(deviceId); device.setStreamMode(streamMode); storager.updateDevice(device); diff --git a/src/main/java/com/genersoft/iot/vmp/vmanager/device/entity/Device.java b/src/main/java/com/genersoft/iot/vmp/vmanager/device/entity/Device.java deleted file mode 100644 index e47f796..0000000 --- a/src/main/java/com/genersoft/iot/vmp/vmanager/device/entity/Device.java +++ /dev/null @@ -1,401 +0,0 @@ -package com.genersoft.iot.vmp.vmanager.device.entity; - -import java.util.List; - -import javax.persistence.Column; -import javax.persistence.Id; -import javax.persistence.Table; -import javax.persistence.Transient; -import javax.validation.constraints.Max; -import javax.validation.constraints.NotNull; -import javax.validation.constraints.Size; - -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; - -/** - * @Description:瑙嗛璁惧淇℃伅 - * @author: songww - * @date: 2020骞�5鏈�8鏃� 涓嬪崍2:05:56 - */ -@ApiModel(value = "瑙嗛璁惧淇℃伅", description = "瑙嗛璁惧淇℃伅") -@Table(name="VMP_VIDEODEVICES") -public class Device { - - /** - * 璁惧Id - */ - @ApiModelProperty("璁惧缂栧彿") - @Id - @Column(name="DEVICE_ID") - @NotNull(message = "deviceId 涓嶈兘涓� null") - @Size(min = 4, max = 32, message = "deviceId 蹇呴』澶т簬 4 浣嶅苟涓斿皬浜� 32 浣�") - private String deviceId; - - /** - * 璁惧鍚嶇О - */ - @ApiModelProperty("璁惧鍚嶇О") - @Column(name="DEVICE_NAME") - @Size(max = 32, message = "deviceName 蹇呴』灏忎簬 32 浣�") - private String deviceName; - - /** - * 鐢熶骇鍘傚晢 - */ - @ApiModelProperty("鐢熶骇鍘傚晢") - @Column(name="MANUFACTURER") - @Size(max = 64, message = "manufacturer 蹇呴』灏忎簬 64 浣�") - private String manufacturer; - - /** - * 鍨嬪彿 - */ - @ApiModelProperty("鍨嬪彿") - @Column(name="MODEL") - @Size(max = 64, message = "manufacturer 蹇呴』灏忎簬 64 浣�") - private String model; - - /** - * 鍥轰欢鐗堟湰 - */ - @ApiModelProperty("鍥轰欢鐗堟湰") - @Column(name="FIRMWARE") - @Size(max = 64, message = "firmware 蹇呴』灏忎簬 64 浣�") - private String firmware; - - /** - * 閫氫俊鍗忚 - * GB28181 ONVIF - */ - @ApiModelProperty("閫氫俊鍗忚") - @Column(name="PROTOCOL") - @NotNull(message = "protocol 涓嶈兘涓� null") - @Size(max = 16, message = "protocol 蹇呴』灏忎簬 16 浣�") - private String protocol; - - /** - * SIP 浼犺緭鍗忚 - * UDP/TCP - */ - @ApiModelProperty("SIP 浼犺緭鍗忚") - @Column(name="TRANSPORT") - @Size(min = 3,max = 3 ,message = "transport 蹇呴』涓� 3 浣�") - private String transport; - - /** - * 鏁版嵁娴佷紶杈撴ā寮� - * UDP:udp浼犺緭 - * TCP-ACTIVE锛歵cp涓诲姩妯″紡 - * TCP-PASSIVE锛歵cp琚姩妯″紡 - */ - @ApiModelProperty("鏁版嵁娴佷紶杈撴ā寮�") - @Column(name="STREAM_MODE") - @Size(max = 64, message = "streamMode 蹇呴』灏忎簬 16 浣�") - private String streamMode; - - /** - * IP鍦板潃 - */ - @ApiModelProperty("IP鍦板潃") - @Column(name="IP") - @Size(max = 15, message = "streamMode 蹇呴』灏忎簬 15 浣�") - private String ip; - - /** - * 绔彛鍙� - */ - @ApiModelProperty("绔彛鍙�") - @Column(name="PORT") - @Max(value = 65535,message = "port 鏈�澶у�间负 65535") - private Integer port; - - /** - * 鍦ㄧ嚎鐘舵�� 1鍦ㄧ嚎, 0绂荤嚎 - */ - @ApiModelProperty("鍦ㄧ嚎鐘舵��") - @Size(min = 1,max = 1 ,message = "online 蹇呴』涓� 1 浣�") - @Column(name="ONLINE") - private String online; - - /** - * 閫氶亾鏁伴噺 - */ - @ApiModelProperty("閫氶亾鏁伴噺") - @Column(name="CHANNEL_SUM") - @Max(value = 1000000000,message = "channelSum 鏈�澶у�间负 1000000000") - private Integer channelSum; - - @Override - public String toString() { - return "Device{" + - "deviceId='" + deviceId + '\'' + - ", deviceName='" + deviceName + '\'' + - ", manufacturer='" + manufacturer + '\'' + - ", model='" + model + '\'' + - ", firmware='" + firmware + '\'' + - ", protocol='" + protocol + '\'' + - ", transport='" + transport + '\'' + - ", streamMode='" + streamMode + '\'' + - ", ip='" + ip + '\'' + - ", port=" + port + - ", online='" + online + '\'' + - ", channelSum=" + channelSum + - ", createTime='" + createTime + '\'' + - ", registerTime='" + registerTime + '\'' + - ", heartbeatTime='" + heartbeatTime + '\'' + - ", updateTime='" + updateTime + '\'' + - ", updatePerson='" + updatePerson + '\'' + - ", syncTime='" + syncTime + '\'' + - ", syncPerson='" + syncPerson + '\'' + - ", username='" + username + '\'' + - ", password='" + password + '\'' + - ", channelList=" + channelList + - '}'; - } - - /** - * 鍒涘缓鏃堕棿 - */ - @ApiModelProperty("鍒涘缓鏃堕棿") - @Column(name="CREATE_TIME") - private String createTime; - - /** - * 娉ㄥ唽鏃堕棿 - */ - @ApiModelProperty("娉ㄥ唽鏃堕棿") - @Column(name="REGISTER_TIME") - private String registerTime; - - /** - * 蹇冭烦鏃堕棿 - */ - @ApiModelProperty("蹇冭烦鏃堕棿") - @Column(name="HEARTBEAT_TIME") - private String heartbeatTime; - - /** - * 淇敼鏃堕棿 - */ - @ApiModelProperty("鏇存柊鏃堕棿") - @Column(name="UPDATE_TIME") - private String updateTime; - - /** - * 淇敼浜� - */ - @ApiModelProperty("淇敼浜�") - @Column(name="UPDATE_PERSON") - private String updatePerson; - - /** - * 鍚屾鏃堕棿 - */ - @ApiModelProperty("鍚屾鏃堕棿") - @Column(name="SYNC_TIME") - private String syncTime; - - /** - * 鍚屾浜� - */ - @ApiModelProperty("鍚屾浜�") - @Column(name="SYNC_PERSON") - private String syncPerson; - - /** - * ONVIF鍗忚-鐢ㄦ埛鍚� - */ - @ApiModelProperty("鐢ㄦ埛鍚�") - @Column(name="USERNAME") - @Size(max = 32, message = "username 蹇呴』灏忎簬 32 浣�") - private String username; - - /** - * ONVIF鍗忚-瀵嗙爜 - */ - @ApiModelProperty("瀵嗙爜") - @Size(max = 32, message = "password 蹇呴』灏忎簬 32 浣�") - @Column(name="PASSWORD") - private String password; - - @Transient - private List<DeviceChannel> channelList; - - - public String getDeviceId() { - return deviceId; - } - - public void setDeviceId(String deviceId) { - this.deviceId = deviceId; - } - - public String getDeviceName() { - return deviceName; - } - - public void setDeviceName(String deviceName) { - this.deviceName = deviceName; - } - - public String getManufacturer() { - return manufacturer; - } - - public void setManufacturer(String manufacturer) { - this.manufacturer = manufacturer; - } - - public String getModel() { - return model; - } - - public void setModel(String model) { - this.model = model; - } - - public String getFirmware() { - return firmware; - } - - public void setFirmware(String firmware) { - this.firmware = firmware; - } - - public String getProtocol() { - return protocol; - } - - public void setProtocol(String protocol) { - this.protocol = protocol; - } - - public String getTransport() { - return transport; - } - - public void setTransport(String transport) { - this.transport = transport; - } - - public String getStreamMode() { - return streamMode; - } - - public void setStreamMode(String streamMode) { - this.streamMode = streamMode; - } - - public String getIp() { - return ip; - } - - public void setIp(String ip) { - this.ip = ip; - } - - public Integer getPort() { - return port; - } - - public void setPort(Integer port) { - this.port = port; - } - - public String getOnline() { - return online; - } - - public void setOnline(String online) { - this.online = online; - } - - public Integer getChannelSum() { - return channelSum; - } - - public void setChannelSum(Integer channelSum) { - this.channelSum = channelSum; - } - - public String getCreateTime() { - return createTime; - } - - public void setCreateTime(String createTime) { - this.createTime = createTime; - } - - public String getRegisterTime() { - return registerTime; - } - - public void setRegisterTime(String registerTime) { - this.registerTime = registerTime; - } - - public String getHeartbeatTime() { - return heartbeatTime; - } - - public void setHeartbeatTime(String heartbeatTime) { - this.heartbeatTime = heartbeatTime; - } - - public String getUpdateTime() { - return updateTime; - } - - public void setUpdateTime(String updateTime) { - this.updateTime = updateTime; - } - - public String getUpdatePerson() { - return updatePerson; - } - - public void setUpdatePerson(String updatePerson) { - this.updatePerson = updatePerson; - } - - public String getSyncTime() { - return syncTime; - } - - public void setSyncTime(String syncTime) { - this.syncTime = syncTime; - } - - public String getSyncPerson() { - return syncPerson; - } - - public void setSyncPerson(String syncPerson) { - this.syncPerson = syncPerson; - } - - public String getUsername() { - return username; - } - - public void setUsername(String username) { - this.username = username; - } - - public String getPassword() { - return password; - } - - public void setPassword(String password) { - this.password = password; - } - - public List<DeviceChannel> getChannelList() { - return channelList; - } - - public void setChannelList(List<DeviceChannel> channelList) { - this.channelList = channelList; - } -} diff --git a/src/main/java/com/genersoft/iot/vmp/vmanager/device/entity/DeviceChannel.java b/src/main/java/com/genersoft/iot/vmp/vmanager/device/entity/DeviceChannel.java deleted file mode 100644 index bedd075..0000000 --- a/src/main/java/com/genersoft/iot/vmp/vmanager/device/entity/DeviceChannel.java +++ /dev/null @@ -1,385 +0,0 @@ -package com.genersoft.iot.vmp.vmanager.device.entity; - -import javax.persistence.Column; -import javax.persistence.Id; -import javax.persistence.Table; - -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; - -/** - * @Description:璁惧閫氶亾淇℃伅 - * @author: songww - * @date: 2020骞�5鏈�20鏃� 涓嬪崍9:00:46 - */ -@ApiModel(value = "璁惧閫氶亾淇℃伅", description = "璁惧閫氶亾淇℃伅") -@Table(name="VMP_VIDEOCHANNELS") -public class DeviceChannel { - - /** - * 閫氶亾缂栧彿 - */ - @ApiModelProperty("閫氶亾缂栧彿") - @Id - @Column(name="CHANNEL_ID") - private String channelId; - - /** - * 璁惧缂栧彿 - */ - @ApiModelProperty("璁惧缂栧彿") - @Column(name="DEVICE_ID") - private String deviceId; - - /** - * 閫氶亾鍚� - */ - @ApiModelProperty("閫氶亾鍚�") - @Column(name="CHANNEL_NAME") - private String channelName; - - /** - * 鐢熶骇鍘傚晢 - */ - @ApiModelProperty("鐢熶骇鍘傚晢") - @Column(name="MANUFACTURER") - private String manufacture; - - /** - * 鍨嬪彿 - */ - @ApiModelProperty("鍨嬪彿") - @Column(name="MODEL") - private String model; - - /** - * 璁惧褰掑睘 - */ - @ApiModelProperty("璁惧褰掑睘") - @Column(name="OWNER") - private String owner; - - /** - * 琛屾斂鍖哄煙 - */ - @ApiModelProperty("琛屾斂鍖哄煙") - @Column(name="CIVIL_CODE") - private String civilCode; - - /** - * 璀﹀尯 - */ - @ApiModelProperty("璀﹀尯") - @Column(name="BLOCK") - private String block; - - /** - * 瀹夎鍦板潃 - */ - @ApiModelProperty("瀹夎鍦板潃") - @Column(name="ADDRESS") - private String address; - - /** - * 鏄惁鏈夊瓙璁惧 1鏈�, 0娌℃湁 - */ - @ApiModelProperty("鏄惁鏈夊瓙璁惧") - @Column(name="PARENTAL") - private String parental; - - /** - * 鐖剁骇id - */ - @ApiModelProperty("鐖剁骇缂栫爜") - @Column(name="PARENT_ID") - private String parentId; - - /** - * 淇′护瀹夊叏妯″紡 缂虹渷涓�0; 0:涓嶉噰鐢�; 2: S/MIME绛惧悕鏂瑰紡; 3: S/ MIME鍔犲瘑绛惧悕鍚屾椂閲囩敤鏂瑰紡; 4:鏁板瓧鎽樿鏂瑰紡 - */ - @ApiModelProperty("淇′护瀹夊叏妯″紡") - @Column(name="SAFETY_WAY") - private String safetyWay; - - /** - * 娉ㄥ唽鏂瑰紡 缂虹渷涓�1;1:绗﹀悎IETFRFC3261鏍囧噯鐨勮璇佹敞鍐屾ā 寮�; 2:鍩轰簬鍙d护鐨勫弻鍚戣璇佹敞鍐屾ā寮�; 3:鍩轰簬鏁板瓧璇佷功鐨勫弻鍚戣璇佹敞鍐屾ā寮� - */ - @ApiModelProperty("娉ㄥ唽鏂瑰紡") - @Column(name="REGISTER_WAY") - private String registerWay; - - /** - * 璇佷功搴忓垪鍙� - */ - @ApiModelProperty("璇佷功搴忓垪鍙�") - @Column(name="CERT_NUM") - private String certNum; - - /** - * 璇佷功鏈夋晥鏍囪瘑 缂虹渷涓�0;璇佷功鏈夋晥鏍囪瘑:0:鏃犳晥1: 鏈夋晥 - */ - @ApiModelProperty("璇佷功鏈夋晥鏍囪瘑") - @Column(name="CERT_VALID") - private String certValid; - - /** - * 璇佷功鏃犳晥鍘熷洜鐮� - */ - @ApiModelProperty("璇佷功鏃犳晥鍘熷洜鐮�") - @Column(name="CERT_ERRCODE") - private String certErrCode; - - /** - * 璇佷功缁堟鏈夋晥鏈� - */ - @ApiModelProperty("璇佷功缁堟鏈夋晥鏈�") - @Column(name="CERT_ENDTIME") - private String certEndTime; - - /** - * 淇濆瘑灞炴�� 缂虹渷涓�0; 0:涓嶆秹瀵�, 1:娑夊瘑 - */ - @ApiModelProperty("淇濆瘑灞炴��") - @Column(name="SECRECY") - private String secrecy; - - /** - * IP鍦板潃 - */ - @ApiModelProperty("IP鍦板潃") - @Column(name="IP") - private String ip; - - /** - * 绔彛鍙� - */ - @ApiModelProperty("绔彛鍙�") - @Column(name="PORT") - private Integer port; - - /** - * 瀵嗙爜 - */ - @ApiModelProperty("瀵嗙爜") - @Column(name="PASSWORD") - private String password; - - /** - * 鍦ㄧ嚎/绂荤嚎 - * 1鍦ㄧ嚎,0绂荤嚎 - * 榛樿鍦ㄧ嚎 - * 淇′护: - * <Status>ON</Status> - * <Status>OFF</Status> - * 閬囧埌杩嘚VR涓嬬殑IPC涓嬪彂淇′护鍙互鎺ㄦ祦锛� 浣嗘槸 Status 鍝嶅簲 OFF - */ - @ApiModelProperty("鐘舵��") - @Column(name="ONLINE") - private String online; - - /** - * 缁忓害 - */ - @ApiModelProperty("缁忓害") - @Column(name="LONGITUDE") - private double longitude; - - /** - * 绾害 - */ - @ApiModelProperty("绾害") - @Column(name="LATITUDE") - private double latitude; - - public String getChannelId() { - return channelId; - } - - public void setChannelId(String channelId) { - this.channelId = channelId; - } - - public String getDeviceId() { - return deviceId; - } - - public void setDeviceId(String deviceId) { - this.deviceId = deviceId; - } - - public String getChannelName() { - return channelName; - } - - public void setChannelName(String channelName) { - this.channelName = channelName; - } - - public String getManufacture() { - return manufacture; - } - - public void setManufacture(String manufacture) { - this.manufacture = manufacture; - } - - public String getModel() { - return model; - } - - public void setModel(String model) { - this.model = model; - } - - public String getOwner() { - return owner; - } - - public void setOwner(String owner) { - this.owner = owner; - } - - public String getCivilCode() { - return civilCode; - } - - public void setCivilCode(String civilCode) { - this.civilCode = civilCode; - } - - public String getBlock() { - return block; - } - - public void setBlock(String block) { - this.block = block; - } - - public String getAddress() { - return address; - } - - public void setAddress(String address) { - this.address = address; - } - - public String getParental() { - return parental; - } - - public void setParental(String parental) { - this.parental = parental; - } - - public String getParentId() { - return parentId; - } - - public void setParentId(String parentId) { - this.parentId = parentId; - } - - public String getSafetyWay() { - return safetyWay; - } - - public void setSafetyWay(String safetyWay) { - this.safetyWay = safetyWay; - } - - public String getRegisterWay() { - return registerWay; - } - - public void setRegisterWay(String registerWay) { - this.registerWay = registerWay; - } - - public String getCertNum() { - return certNum; - } - - public void setCertNum(String certNum) { - this.certNum = certNum; - } - - public String getCertValid() { - return certValid; - } - - public void setCertValid(String certValid) { - this.certValid = certValid; - } - - public String getCertErrCode() { - return certErrCode; - } - - public void setCertErrCode(String certErrCode) { - this.certErrCode = certErrCode; - } - - public String getCertEndTime() { - return certEndTime; - } - - public void setCertEndTime(String certEndTime) { - this.certEndTime = certEndTime; - } - - public String getSecrecy() { - return secrecy; - } - - public void setSecrecy(String secrecy) { - this.secrecy = secrecy; - } - - public String getIp() { - return ip; - } - - public void setIp(String ip) { - this.ip = ip; - } - - public Integer getPort() { - return port; - } - - public void setPort(Integer port) { - this.port = port; - } - - public String getPassword() { - return password; - } - - public void setPassword(String password) { - this.password = password; - } - - public String getOnline() { - return online; - } - - public void setOnline(String online) { - this.online = online; - } - - public double getLongitude() { - return longitude; - } - - public void setLongitude(double longitude) { - this.longitude = longitude; - } - - public double getLatitude() { - return latitude; - } - - public void setLatitude(double latitude) { - this.latitude = latitude; - } -} diff --git a/src/main/java/com/genersoft/iot/vmp/vmanager/play/PlayController.java b/src/main/java/com/genersoft/iot/vmp/vmanager/play/PlayController.java index e741b5a..59667d0 100644 --- a/src/main/java/com/genersoft/iot/vmp/vmanager/play/PlayController.java +++ b/src/main/java/com/genersoft/iot/vmp/vmanager/play/PlayController.java @@ -7,6 +7,8 @@ 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.ZLMRESTfulUtils; +import com.genersoft.iot.vmp.media.zlm.ZLMRTPServerFactory; +import com.genersoft.iot.vmp.storager.IRedisCatchStorage; import com.genersoft.iot.vmp.vmanager.service.IPlayService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -27,6 +29,7 @@ import com.genersoft.iot.vmp.storager.IVideoManagerStorager; import org.springframework.web.context.request.async.DeferredResult; +import javax.sip.message.Response; import java.text.DecimalFormat; import java.util.UUID; @@ -44,6 +47,9 @@ private IVideoManagerStorager storager; @Autowired + private IRedisCatchStorage redisCatchStorage; + + @Autowired private ZLMRESTfulUtils zlmresTfulUtils; @Autowired @@ -58,18 +64,11 @@ Device device = storager.queryVideoDevice(deviceId); - StreamInfo streamInfo = storager.queryPlayByDevice(deviceId, channelId); + StreamInfo streamInfo = redisCatchStorage.queryPlayByDevice(deviceId, channelId); UUID uuid = UUID.randomUUID(); DeferredResult<ResponseEntity<String>> result = new DeferredResult<ResponseEntity<String>>(); - // 瓒呮椂澶勭悊 - result.onTimeout(()->{ - logger.warn(String.format("璁惧鐐规挱瓒呮椂锛宒eviceId锛�%s 锛宑hannelId锛�%s", deviceId, channelId)); - RequestMessage msg = new RequestMessage(); - msg.setId(DeferredResultHolder.CALLBACK_CMD_PlAY + uuid); - msg.setData("Timeout"); - resultHolder.invokeResult(msg); - }); + // 褰曞儚鏌ヨ浠hannelId浣滀负deviceId鏌ヨ resultHolder.put(DeferredResultHolder.CALLBACK_CMD_PlAY + uuid, result); @@ -78,9 +77,15 @@ cmder.playStreamCmd(device, channelId, (JSONObject response) -> { logger.info("鏀跺埌璁㈤槄娑堟伅锛� " + response.toJSONString()); playService.onPublishHandlerForPlay(response, deviceId, channelId, uuid.toString()); + }, event -> { + RequestMessage msg = new RequestMessage(); + msg.setId(DeferredResultHolder.CALLBACK_CMD_PlAY + uuid); + Response response = event.getResponse(); + msg.setData(String.format("鐐规挱澶辫触锛� 閿欒鐮侊細 %s, %s", response.getStatusCode(), response.getReasonPhrase())); + resultHolder.invokeResult(msg); }); } else { - String streamId = String.format("%08x", Integer.parseInt(streamInfo.getSsrc())).toUpperCase(); + String streamId = streamInfo.getStreamId(); JSONObject rtpInfo = zlmresTfulUtils.getRtpInfo(streamId); if (rtpInfo.getBoolean("exist")) { RequestMessage msg = new RequestMessage(); @@ -88,58 +93,107 @@ msg.setData(JSON.toJSONString(streamInfo)); resultHolder.invokeResult(msg); } else { - storager.stopPlay(streamInfo); - // TODO playStreamCmd 瓒呮椂澶勭悊 + redisCatchStorage.stopPlay(streamInfo); cmder.playStreamCmd(device, channelId, (JSONObject response) -> { logger.info("鏀跺埌璁㈤槄娑堟伅锛� " + response.toJSONString()); playService.onPublishHandlerForPlay(response, deviceId, channelId, uuid.toString()); + }, event -> { + RequestMessage msg = new RequestMessage(); + msg.setId(DeferredResultHolder.CALLBACK_CMD_PlAY + uuid); + Response response = event.getResponse(); + msg.setData(String.format("鐐规挱澶辫触锛� 閿欒鐮侊細 %s, %s", response.getStatusCode(), response.getReasonPhrase())); + resultHolder.invokeResult(msg); }); } } + + // 瓒呮椂澶勭悊 + result.onTimeout(()->{ + logger.warn(String.format("璁惧鐐规挱瓒呮椂锛宒eviceId锛�%s 锛宑hannelId锛�%s", deviceId, channelId)); + // 閲婃斁rtpserver + cmder.closeRTPServer(device, channelId); + RequestMessage msg = new RequestMessage(); + msg.setId(DeferredResultHolder.CALLBACK_CMD_PlAY + uuid); + msg.setData("Timeout"); + resultHolder.invokeResult(msg); + }); return result; } - @PostMapping("/play/{ssrc}/stop") - public ResponseEntity<String> playStop(@PathVariable String ssrc) { + @PostMapping("/play/{streamId}/stop") + public DeferredResult<ResponseEntity<String>> playStop(@PathVariable String streamId) { - cmder.streamByeCmd(ssrc); - StreamInfo streamInfo = storager.queryPlayBySSRC(ssrc); - if (streamInfo == null) - return new ResponseEntity<String>("ssrc not found", HttpStatus.OK); - storager.stopPlay(streamInfo); - if (logger.isDebugEnabled()) { - logger.debug(String.format("璁惧棰勮鍋滄API璋冪敤锛宻src锛�%s", ssrc)); - } + logger.debug(String.format("璁惧棰勮/鍥炴斁鍋滄API璋冪敤锛宻treamId锛�%s", streamId)); - if (ssrc != null) { + UUID uuid = UUID.randomUUID(); + DeferredResult<ResponseEntity<String>> result = new DeferredResult<ResponseEntity<String>>(); + + // 褰曞儚鏌ヨ浠hannelId浣滀负deviceId鏌ヨ + resultHolder.put(DeferredResultHolder.CALLBACK_CMD_STOP + uuid, result); + + cmder.streamByeCmd(streamId, event -> { + StreamInfo streamInfo = redisCatchStorage.queryPlayByStreamId(streamId); + if (streamInfo == null) { + RequestMessage msg = new RequestMessage(); + msg.setId(DeferredResultHolder.CALLBACK_CMD_PlAY + uuid); + msg.setData("streamId not found"); + resultHolder.invokeResult(msg); + redisCatchStorage.stopPlay(streamInfo); + } + + RequestMessage msg = new RequestMessage(); + msg.setId(DeferredResultHolder.CALLBACK_CMD_STOP + uuid); + Response response = event.getResponse(); + msg.setData(String.format("success")); + resultHolder.invokeResult(msg); + }); + + + + if (streamId != null) { JSONObject json = new JSONObject(); - json.put("ssrc", ssrc); - return new ResponseEntity<String>(json.toString(), HttpStatus.OK); + json.put("streamId", streamId); + RequestMessage msg = new RequestMessage(); + msg.setId(DeferredResultHolder.CALLBACK_CMD_PlAY + uuid); + msg.setData(json.toString()); + resultHolder.invokeResult(msg); } else { - logger.warn("璁惧棰勮鍋滄API璋冪敤澶辫触锛�"); - return new ResponseEntity<String>(HttpStatus.INTERNAL_SERVER_ERROR); + logger.warn("璁惧棰勮/鍥炴斁鍋滄API璋冪敤澶辫触锛�"); + RequestMessage msg = new RequestMessage(); + msg.setId(DeferredResultHolder.CALLBACK_CMD_PlAY + uuid); + msg.setData("streamId null"); + resultHolder.invokeResult(msg); } + + // 瓒呮椂澶勭悊 + result.onTimeout(()->{ + logger.warn(String.format("璁惧棰勮/鍥炴斁鍋滄瓒呮椂锛宻treamId锛�%s ", streamId)); + RequestMessage msg = new RequestMessage(); + msg.setId(DeferredResultHolder.CALLBACK_CMD_STOP + uuid); + msg.setData("Timeout"); + resultHolder.invokeResult(msg); + }); + return result; } /** * 灏嗕笉鏄痟264鐨勮棰戦�氳繃ffmpeg 杞爜涓篽264 + aac - * @param ssrc + * @param streamId 娴両D * @return */ - @PostMapping("/play/{ssrc}/convert") - public ResponseEntity<String> playConvert(@PathVariable String ssrc) { - StreamInfo streamInfo = storager.queryPlayBySSRC(ssrc); + @PostMapping("/play/{streamId}/convert") + public ResponseEntity<String> playConvert(@PathVariable String streamId) { + StreamInfo streamInfo = redisCatchStorage.queryPlayByStreamId(streamId); if (streamInfo == null) { logger.warn("瑙嗛杞爜API璋冪敤澶辫触锛�, 瑙嗛娴佸凡缁忓仠姝�!"); return new ResponseEntity<String>("鏈壘鍒拌棰戞祦淇℃伅, 瑙嗛娴佸彲鑳藉凡缁忓仠姝�", HttpStatus.OK); } - String streamId = String.format("%08x", Integer.parseInt(ssrc)).toUpperCase(); JSONObject rtpInfo = zlmresTfulUtils.getRtpInfo(streamId); if (!rtpInfo.getBoolean("exist")) { logger.warn("瑙嗛杞爜API璋冪敤澶辫触锛�, 瑙嗛娴佸凡鍋滄鎺ㄦ祦!"); return new ResponseEntity<String>("鎺ㄦ祦淇℃伅鍦ㄦ祦濯掍綋涓笉瀛樺湪, 瑙嗛娴佸彲鑳藉凡鍋滄鎺ㄦ祦", HttpStatus.OK); } else { - MediaServerConfig mediaInfo = storager.getMediaInfo(); + MediaServerConfig mediaInfo = redisCatchStorage.getMediaInfo(); String dstUrl = String.format("rtmp://%s:%s/convert/%s", "127.0.0.1", mediaInfo.getRtmpPort(), streamId ); String srcUrl = String.format("rtsp://%s:%s/rtp/%s", "127.0.0.1", mediaInfo.getRtspPort(), streamId); diff --git a/src/main/java/com/genersoft/iot/vmp/vmanager/playback/PlaybackController.java b/src/main/java/com/genersoft/iot/vmp/vmanager/playback/PlaybackController.java index 2e32b1b..9449d26 100644 --- a/src/main/java/com/genersoft/iot/vmp/vmanager/playback/PlaybackController.java +++ b/src/main/java/com/genersoft/iot/vmp/vmanager/playback/PlaybackController.java @@ -6,6 +6,7 @@ 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.ZLMRESTfulUtils; +import com.genersoft.iot.vmp.storager.IRedisCatchStorage; import com.genersoft.iot.vmp.vmanager.service.IPlayService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -27,6 +28,7 @@ import com.genersoft.iot.vmp.storager.IVideoManagerStorager; import org.springframework.web.context.request.async.DeferredResult; +import javax.sip.message.Response; import java.util.UUID; @CrossOrigin @@ -41,6 +43,9 @@ @Autowired private IVideoManagerStorager storager; + + @Autowired + private IRedisCatchStorage redisCatchStorage; @Autowired private ZLMRESTfulUtils zlmresTfulUtils; @@ -69,15 +74,21 @@ resultHolder.invokeResult(msg); }); Device device = storager.queryVideoDevice(deviceId); - StreamInfo streamInfo = storager.queryPlaybackByDevice(deviceId, channelId); + StreamInfo streamInfo = redisCatchStorage.queryPlaybackByDevice(deviceId, channelId); if (streamInfo != null) { // 鍋滄涔嬪墠鐨勫洖鏀� - cmder.streamByeCmd(streamInfo.getSsrc()); + cmder.streamByeCmd(streamInfo.getStreamId()); } resultHolder.put(DeferredResultHolder.CALLBACK_CMD_PlAY + uuid, result); cmder.playbackStreamCmd(device, channelId, startTime, endTime, (JSONObject response) -> { logger.info("鏀跺埌璁㈤槄娑堟伅锛� " + response.toJSONString()); playService.onPublishHandlerForPlayBack(response, deviceId, channelId, uuid.toString()); + }, event -> { + Response response = event.getResponse(); + RequestMessage msg = new RequestMessage(); + msg.setId(DeferredResultHolder.CALLBACK_CMD_PlAY + uuid); + msg.setData(String.format("鍥炴斁澶辫触锛� 閿欒鐮侊細 %s, %s", response.getStatusCode(), response.getReasonPhrase())); + resultHolder.invokeResult(msg); }); return result; diff --git a/src/main/java/com/genersoft/iot/vmp/vmanager/ptz/PtzController.java b/src/main/java/com/genersoft/iot/vmp/vmanager/ptz/PtzController.java index 1a90977..4c41e16 100644 --- a/src/main/java/com/genersoft/iot/vmp/vmanager/ptz/PtzController.java +++ b/src/main/java/com/genersoft/iot/vmp/vmanager/ptz/PtzController.java @@ -29,15 +29,14 @@ private IVideoManagerStorager storager; /*** - * http://localhost:8080/api/ptz/34020000001320000002_34020000001320000008?leftRight=1&upDown=0&inOut=0&moveSpeed=50&zoomSpeed=0 - * @param deviceId - * @param channelId - * @param leftRight - * @param upDown - * @param inOut - * @param moveSpeed - * @param zoomSpeed - * @return + * 浜戝彴鎺у埗 + * @param deviceId 璁惧id + * @param channelId 閫氶亾id + * @param cmdCode 鎸囦护鐮� + * @param horizonSpeed 姘村钩绉诲姩閫熷害 + * @param verticalSpeed 鍨傜洿绉诲姩閫熷害 + * @param zoomSpeed 缂╂斁閫熷害 + * @return String 鎺у埗缁撴灉 */ @PostMapping("/ptz/{deviceId}/{channelId}") public ResponseEntity<String> ptz(@PathVariable String deviceId,@PathVariable String channelId,int cmdCode, int horizonSpeed, int verticalSpeed, int zoomSpeed){ diff --git a/src/main/java/com/genersoft/iot/vmp/vmanager/record/RecordController.java b/src/main/java/com/genersoft/iot/vmp/vmanager/record/RecordController.java index 502087e..519d299 100644 --- a/src/main/java/com/genersoft/iot/vmp/vmanager/record/RecordController.java +++ b/src/main/java/com/genersoft/iot/vmp/vmanager/record/RecordController.java @@ -1,5 +1,6 @@ package com.genersoft.iot.vmp.vmanager.record; +import com.genersoft.iot.vmp.gb28181.transmit.callback.RequestMessage; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -32,7 +33,7 @@ @Autowired private DeferredResultHolder resultHolder; - + @GetMapping("/record/{deviceId}/{channelId}") public DeferredResult<ResponseEntity<RecordInfo>> recordinfo(@PathVariable String deviceId,@PathVariable String channelId, String startTime, String endTime){ @@ -42,9 +43,17 @@ Device device = storager.queryVideoDevice(deviceId); cmder.recordInfoQuery(device, channelId, startTime, endTime); - DeferredResult<ResponseEntity<RecordInfo>> result = new DeferredResult<ResponseEntity<RecordInfo>>(); + // 鎸囧畾瓒呮椂鏃堕棿 1鍒嗛挓30绉� + DeferredResult<ResponseEntity<RecordInfo>> result = new DeferredResult<ResponseEntity<RecordInfo>>(90*1000L); // 褰曞儚鏌ヨ浠hannelId浣滀负deviceId鏌ヨ resultHolder.put(DeferredResultHolder.CALLBACK_CMD_RECORDINFO+channelId, result); + result.onTimeout(()->{ + RequestMessage msg = new RequestMessage(); + msg.setDeviceId(deviceId); + msg.setType(DeferredResultHolder.CALLBACK_CMD_RECORDINFO); + msg.setData("timeout"); + resultHolder.invokeResult(msg); + }); return result; } } diff --git a/src/main/java/com/genersoft/iot/vmp/vmanager/service/impl/PlayServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/vmanager/service/impl/PlayServiceImpl.java index e9528d1..f4bdd2b 100644 --- a/src/main/java/com/genersoft/iot/vmp/vmanager/service/impl/PlayServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/vmanager/service/impl/PlayServiceImpl.java @@ -4,8 +4,10 @@ import com.alibaba.fastjson.JSONObject; import com.genersoft.iot.vmp.common.StreamInfo; import com.genersoft.iot.vmp.conf.MediaServerConfig; +import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel; import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder; import com.genersoft.iot.vmp.gb28181.transmit.callback.RequestMessage; +import com.genersoft.iot.vmp.storager.IRedisCatchStorage; import com.genersoft.iot.vmp.storager.IVideoManagerStorager; import com.genersoft.iot.vmp.vmanager.play.PlayController; import com.genersoft.iot.vmp.vmanager.service.IPlayService; @@ -25,6 +27,9 @@ private IVideoManagerStorager storager; @Autowired + private IRedisCatchStorage redisCatchStorage; + + @Autowired private DeferredResultHolder resultHolder; @Override @@ -33,7 +38,13 @@ msg.setId(DeferredResultHolder.CALLBACK_CMD_PlAY + uuid); StreamInfo streamInfo = onPublishHandler(resonse, deviceId, channelId, uuid); if (streamInfo != null) { - storager.startPlay(streamInfo); + DeviceChannel deviceChannel = storager.queryChannel(deviceId, channelId); + if (deviceChannel != null) { + deviceChannel.setStreamId(streamInfo.getStreamId()); + storager.updateChannel(deviceId, deviceChannel); + } + + redisCatchStorage.startPlay(streamInfo); msg.setData(JSON.toJSONString(streamInfo)); resultHolder.invokeResult(msg); } else { @@ -49,7 +60,7 @@ msg.setId(DeferredResultHolder.CALLBACK_CMD_PlAY + uuid); StreamInfo streamInfo = onPublishHandler(resonse, deviceId, channelId, uuid); if (streamInfo != null) { - storager.startPlayback(streamInfo); + redisCatchStorage.startPlayback(streamInfo); msg.setData(JSON.toJSONString(streamInfo)); resultHolder.invokeResult(msg); } else { @@ -61,13 +72,11 @@ public StreamInfo onPublishHandler(JSONObject resonse, String deviceId, String channelId, String uuid) { String streamId = resonse.getString("id"); - String ssrc = new DecimalFormat("0000000000").format(Integer.parseInt(streamId, 16)); StreamInfo streamInfo = new StreamInfo(); - streamInfo.setSsrc(ssrc); streamInfo.setStreamId(streamId); streamInfo.setDeviceID(deviceId); streamInfo.setCahnnelId(channelId); - MediaServerConfig mediaServerConfig = storager.getMediaInfo(); + MediaServerConfig mediaServerConfig = redisCatchStorage.getMediaInfo(); streamInfo.setFlv(String.format("http://%s:%s/rtp/%s.flv", mediaServerConfig.getWanIp(), mediaServerConfig.getHttpPort(), streamId)); streamInfo.setWs_flv(String.format("ws://%s:%s/rtp/%s.flv", mediaServerConfig.getWanIp(), mediaServerConfig.getHttpPort(), streamId)); diff --git a/src/main/java/com/genersoft/iot/vmp/web/ApiDeviceController.java b/src/main/java/com/genersoft/iot/vmp/web/ApiDeviceController.java index ce3b7ec..199a9e6 100644 --- a/src/main/java/com/genersoft/iot/vmp/web/ApiDeviceController.java +++ b/src/main/java/com/genersoft/iot/vmp/web/ApiDeviceController.java @@ -1,22 +1,17 @@ package com.genersoft.iot.vmp.web; -import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; -import com.genersoft.iot.vmp.common.PageResult; import com.genersoft.iot.vmp.gb28181.bean.Device; import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel; import com.genersoft.iot.vmp.gb28181.event.DeviceOffLineDetector; import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder; import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander; import com.genersoft.iot.vmp.storager.IVideoManagerStorager; -import com.genersoft.iot.vmp.vmanager.device.DeviceController; +import com.github.pagehelper.PageInfo; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.*; import java.util.List; @@ -65,12 +60,12 @@ JSONObject result = new JSONObject(); List<Device> devices; if (start == null || limit ==null) { - devices = storager.queryVideoDeviceList(null); + devices = storager.queryVideoDeviceList(); result.put("DeviceCount", devices.size()); }else { - PageResult<Device> deviceList = storager.queryVideoDeviceList(null, start/limit, limit); + PageInfo<Device> deviceList = storager.queryVideoDeviceList(start/limit, limit); result.put("DeviceCount", deviceList.getTotal()); - devices = deviceList.getData(); + devices = deviceList.getList(); } JSONArray deviceJSONList = new JSONArray(); @@ -86,8 +81,8 @@ deviceJsonObject.put("Online", device.getOnline() == 1); deviceJsonObject.put("Password", ""); deviceJsonObject.put("MediaTransport", device.getTransport()); - deviceJsonObject.put("RemoteIP", device.getHost().getIp()); - deviceJsonObject.put("RemotePort", device.getHost().getPort()); + deviceJsonObject.put("RemoteIP", device.getIp()); + deviceJsonObject.put("RemotePort", device.getPort()); deviceJsonObject.put("LastRegisterAt", ""); deviceJsonObject.put("LastKeepaliveAt", ""); deviceJsonObject.put("UpdatedAt", ""); @@ -123,9 +118,9 @@ deviceChannels = storager.queryChannelsByDeviceId(serial); result.put("ChannelCount", deviceChannels.size()); }else { - PageResult<DeviceChannel> pageResult = storager.queryChannelsByDeviceId(serial, null, null, null,start/limit, limit); + PageInfo<DeviceChannel> pageResult = storager.queryChannelsByDeviceId(serial, null, null, null,start/limit, limit); result.put("ChannelCount", pageResult.getTotal()); - deviceChannels = pageResult.getData(); + deviceChannels = pageResult.getList(); } JSONArray channleJSONList = new JSONArray(); @@ -159,7 +154,7 @@ deviceJOSNChannel.put("PTZType ", deviceChannel.getPTZType()); // 浜戝彴绫诲瀷, 0 - 鏈煡, 1 - 鐞冩満, 2 - 鍗婄悆, // 3 - 鍥哄畾鏋満, 4 - 閬ユ帶鏋満 deviceJOSNChannel.put("CustomPTZType", ""); - deviceJOSNChannel.put("StreamID", deviceChannel.getSsrc()); // StreamID 鐩存挱娴両D, 鏈夊�艰〃绀烘鍦ㄧ洿鎾� + deviceJOSNChannel.put("StreamID", deviceChannel.getStreamId()); // StreamID 鐩存挱娴両D, 鏈夊�艰〃绀烘鍦ㄧ洿鎾� deviceJOSNChannel.put("NumOutputs ", -1); // 鐩存挱鍦ㄧ嚎浜烘暟 channleJSONList.add(deviceJOSNChannel); } diff --git a/src/main/java/com/genersoft/iot/vmp/web/ApiStreamController.java b/src/main/java/com/genersoft/iot/vmp/web/ApiStreamController.java index 6180fbb..8ebdf64 100644 --- a/src/main/java/com/genersoft/iot/vmp/web/ApiStreamController.java +++ b/src/main/java/com/genersoft/iot/vmp/web/ApiStreamController.java @@ -8,6 +8,7 @@ import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel; import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander; import com.genersoft.iot.vmp.media.zlm.ZLMRESTfulUtils; +import com.genersoft.iot.vmp.storager.IRedisCatchStorage; import com.genersoft.iot.vmp.storager.IVideoManagerStorager; import com.genersoft.iot.vmp.vmanager.play.PlayController; import org.slf4j.Logger; @@ -17,6 +18,7 @@ import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; +import org.springframework.web.context.request.async.DeferredResult; /** * 鍏煎LiveGBS鐨凙PI锛氬疄鏃剁洿鎾� @@ -34,11 +36,16 @@ @Autowired private IVideoManagerStorager storager; - private boolean closeWaitRTPInfo = false; + @Autowired + private IRedisCatchStorage redisCatchStorage; @Autowired private ZLMRESTfulUtils zlmresTfulUtils; + + + @Autowired + private PlayController playController; /** * 瀹炴椂鐩存挱 - 寮�濮嬬洿鎾� @@ -54,126 +61,54 @@ * @return */ @RequestMapping(value = "/start") - private JSONObject start(String serial , - @RequestParam(required = false)Integer channel , - @RequestParam(required = false)String code, - @RequestParam(required = false)String cdn, - @RequestParam(required = false)String audio, - @RequestParam(required = false)String transport, - @RequestParam(required = false)String checkchannelstatus , - @RequestParam(required = false)String transportmode, - @RequestParam(required = false)String timeout + private DeferredResult<JSONObject> start(String serial , + @RequestParam(required = false)Integer channel , + @RequestParam(required = false)String code, + @RequestParam(required = false)String cdn, + @RequestParam(required = false)String audio, + @RequestParam(required = false)String transport, + @RequestParam(required = false)String checkchannelstatus , + @RequestParam(required = false)String transportmode, + @RequestParam(required = false)String timeout ){ - int getEncoding = closeWaitRTPInfo? 1: 0; + DeferredResult<JSONObject> resultDeferredResult = new DeferredResult<JSONObject>(); Device device = storager.queryVideoDevice(serial); - if (device == null ) { JSONObject result = new JSONObject(); result.put("error","device[ " + serial + " ]鏈壘鍒�"); - return result; + resultDeferredResult.setResult(result); }else if (device.getOnline() == 0) { JSONObject result = new JSONObject(); result.put("error","device[ " + code + " ]offline"); - return result; + resultDeferredResult.setResult(result); } + resultDeferredResult.onTimeout(()->{ + logger.info("鎾斁绛夊緟瓒呮椂"); + JSONObject result = new JSONObject(); + result.put("error","timeout"); + resultDeferredResult.setResult(result); + + // 娓呯悊RTP server + }); DeviceChannel deviceChannel = storager.queryChannel(serial, code); if (deviceChannel == null) { JSONObject result = new JSONObject(); result.put("error","channel[ " + code + " ]鏈壘鍒�"); - return result; + resultDeferredResult.setResult(result); }else if (deviceChannel.getStatus() == 0) { JSONObject result = new JSONObject(); result.put("error","channel[ " + code + " ]offline"); - return result; + resultDeferredResult.setResult(result); } + DeferredResult<ResponseEntity<String>> play = playController.play(serial, code); - // 鏌ヨ鏄惁宸茬粡鍦ㄦ挱鏀� - StreamInfo streamInfo = storager.queryPlayByDevice(device.getDeviceId(), code); - if (streamInfo == null) { - logger.debug("streamInfo 绛変簬null, 閲嶆柊鐐规挱"); -// streamInfo = cmder.playStreamCmd(device, code); - }else { - logger.debug("streamInfo 涓嶇瓑浜巒ull, 鍚戞祦濯掍綋鏌ヨ鏄惁姝e湪鎺ㄦ祦"); - String streamId = String.format("%08x", Integer.parseInt(streamInfo.getSsrc())).toUpperCase(); - JSONObject rtpInfo = zlmresTfulUtils.getRtpInfo(streamId); - if (rtpInfo.getBoolean("exist")) { - logger.debug("鍚戞祦濯掍綋鏌ヨ姝e湪鎺ㄦ祦, 鐩存帴杩斿洖: " + streamInfo.getRtsp()); - JSONObject result = new JSONObject(); - result.put("StreamID", streamInfo.getSsrc()); - result.put("DeviceID", device.getDeviceId()); - result.put("ChannelID", code); - result.put("ChannelName", deviceChannel.getName()); - result.put("ChannelCustomName", ""); - result.put("FLV", streamInfo.getFlv()); - result.put("WS_FLV", streamInfo.getWs_flv()); - result.put("RTMP", streamInfo.getRtmp()); - result.put("HLS", streamInfo.getHls()); - result.put("RTSP", streamInfo.getRtsp()); - result.put("CDN", ""); - result.put("SnapURL", ""); - result.put("Transport", device.getTransport()); - result.put("StartAt", ""); - result.put("Duration", ""); - result.put("SourceVideoCodecName", ""); - result.put("SourceVideoWidth", ""); - result.put("SourceVideoHeight", ""); - result.put("SourceVideoFrameRate", ""); - result.put("SourceAudioCodecName", ""); - result.put("SourceAudioSampleRate", ""); - result.put("AudioEnable", ""); - result.put("Ondemand", ""); - result.put("InBytes", ""); - result.put("InBitRate", ""); - result.put("OutBytes", ""); - result.put("NumOutputs", ""); - result.put("CascadeSize", ""); - result.put("RelaySize", ""); - result.put("ChannelPTZType", 0); - return result; - } else { - logger.debug("鍚戞祦濯掍綋鏌ヨ娌℃湁鎺ㄦ祦, 閲嶆柊鐐规挱"); - storager.stopPlay(streamInfo); -// streamInfo = cmder.playStreamCmd(device, code); - } - } - - if (logger.isDebugEnabled()) { - logger.debug(String.format("璁惧棰勮 API璋冪敤锛宒eviceId锛�%s 锛宑hannelId锛�%s",serial, code)); - logger.debug("璁惧棰勮 API璋冪敤锛宻src锛�"+streamInfo.getSsrc()+",ZLMedia streamId:"+Integer.toHexString(Integer.parseInt(streamInfo.getSsrc()))); - } - boolean lockFlag = true; - long startTime = System.currentTimeMillis(); - while (lockFlag) { - try { - if (System.currentTimeMillis() - startTime > 10 * 1000) { - storager.stopPlay(streamInfo); - logger.info("鎾斁绛夊緟瓒呮椂"); - JSONObject result = new JSONObject(); - result.put("error","timeout"); - return result; - } else { - - StreamInfo streamInfoNow = storager.queryPlayByDevice(serial, code); - logger.debug("姝e湪鍚戞祦濯掍綋鏌ヨ"); - if (streamInfoNow != null && streamInfoNow.getFlv() != null) { - streamInfo = streamInfoNow; - logger.debug("鍚戞祦濯掍綋鏌ヨ鍒�: " + streamInfoNow.getRtsp()); - lockFlag = false; - continue; - } else { - Thread.sleep(2000); - continue; - } - } - } catch (InterruptedException e) { - e.printStackTrace(); - } - } - if(streamInfo!=null) { + play.setResultHandler((Object o)->{ + ResponseEntity<String> responseEntity = (ResponseEntity)o; + StreamInfo streamInfo = JSON.parseObject(responseEntity.getBody(), StreamInfo.class); JSONObject result = new JSONObject(); - result.put("StreamID", streamInfo.getSsrc()); + result.put("StreamID", streamInfo.getStreamId()); result.put("DeviceID", device.getDeviceId()); result.put("ChannelID", code); result.put("ChannelName", deviceChannel.getName()); @@ -203,13 +138,9 @@ result.put("CascadeSize", ""); result.put("RelaySize", ""); result.put("ChannelPTZType", 0); - return result; - } else { - logger.warn("璁惧棰勮API璋冪敤澶辫触锛�"); - JSONObject result = new JSONObject(); - result.put("error","璋冪敤澶辫触"); - return result; - } + resultDeferredResult.setResult(result); + }); + return resultDeferredResult; } /** @@ -228,14 +159,15 @@ @RequestParam(required = false)String check_outputs ){ - StreamInfo streamInfo = storager.queryPlayByDevice(serial, code); + + StreamInfo streamInfo = redisCatchStorage.queryPlayByDevice(serial, code); if (streamInfo == null) { JSONObject result = new JSONObject(); result.put("error","鏈壘鍒版祦淇℃伅"); return result; } - cmder.streamByeCmd(streamInfo.getSsrc()); - storager.stopPlay(streamInfo); + cmder.streamByeCmd(streamInfo.getStreamId()); + redisCatchStorage.stopPlay(streamInfo); return null; } diff --git a/src/main/resources/application-dev.yml b/src/main/resources/application-dev.yml index 638d5ae..7b98bd1 100644 --- a/src/main/resources/application-dev.yml +++ b/src/main/resources/application-dev.yml @@ -20,12 +20,20 @@ timeout: 10000 # [涓嶅彲鐢╙ jdbc鏁版嵁搴撻厤缃�, 鏆備笉鏀寔 datasource: + # name: eiot + # url: jdbc:mysql://127.0.0.1:3306/eiot?useUnicode=true&characterEncoding=UTF8&rewriteBatchedStatements=true + # username: + # password: + # type: com.alibaba.druid.pool.DruidDataSource + # driver-class-name: com.mysql.jdbc.Driver name: eiot - url: jdbc:mysql://127.0.0.1:3306/eiot?useUnicode=true&characterEncoding=UTF8&rewriteBatchedStatements=true + url: jdbc:sqlite::resource:wvp.sqlite username: password: type: com.alibaba.druid.pool.DruidDataSource - driver-class-name: com.mysql.jdbc.Driver + driver-class-name: org.sqlite.JDBC + max-active: 1 + min-idle: 1 # [鍙�塢 WVP鐩戝惉鐨凥TTP绔彛, 缃戦〉鍜屾帴鍙h皟鐢ㄩ兘鏄繖涓鍙� server: @@ -34,18 +42,18 @@ # 浣滀负28181鏈嶅姟鍣ㄧ殑閰嶇疆 sip: # [蹇呴』淇敼] 鏈満鐨処P, 蹇呴』鏄綉鍗′笂鐨処P - ip: 192.168.0.100 + ip: 192.168.1.44 # [鍙�塢 28181鏈嶅姟鐩戝惉鐨勭鍙� port: 5060 # 鏍规嵁鍥芥爣6.1.2涓瀹氾紝domain瀹滈噰鐢↖D缁熶竴缂栫爜鐨勫墠鍗佷綅缂栫爜銆傚浗鏍囬檮褰旸涓畾涔夊墠8浣嶄负涓績缂栫爜锛堢敱鐪佺骇銆佸競绾с�佸尯绾с�佸熀灞傜紪鍙风粍鎴愶紝鍙傜収GB/T 2260-2007锛� # 鍚庝袱浣嶄负琛屼笟缂栫爜锛屽畾涔夊弬鐓ч檮褰旸.3 # 3701020049鏍囪瘑灞变笢娴庡崡鍘嗕笅鍖� 淇℃伅琛屼笟鎺ュ叆 # [鍙�塢 - domain: 4401020049 + domain: 3402000000 # [鍙�塢 - id: 44010200492000000001 + id: 34020000002000000001 # [鍙�塢 榛樿璁惧璁よ瘉瀵嗙爜锛屽悗缁墿灞曚娇鐢ㄨ澶囧崟鐙瘑鐮� - password: admin123 + password: 12345678 # 鐧婚檰鐨勭敤鎴峰悕瀵嗙爜 auth: @@ -57,7 +65,7 @@ #zlm鏈嶅姟鍣ㄩ厤缃� media: # [蹇呴』淇敼] zlm鏈嶅姟鍣ㄧ殑鍐呯綉IP - ip: 192.168.0.100 + ip: 192.168.1.44 # [鍙�塢 zlm鏈嶅姟鍣ㄧ殑鍏綉IP, 鍐呯綉閮ㄧ讲缃┖鍗冲彲 wanIp: # [鍙�塢 zlm鏈嶅姟鍣ㄧ殑hook鎵�浣跨敤鐨処P, 榛樿浣跨敤sip.ip @@ -69,12 +77,12 @@ # [鍙�塢 zlm鏈嶅姟鍣ㄧ殑hook.admin_params=secret secret: 035c73f7-bb6b-4889-a715-d9eb2d1925cc # [鍙�塢 zlm鏈嶅姟鍣ㄧ殑general.streamNoneReaderDelayMS - streamNoneReaderDelayMS: 18000 # 鏃犱汉瑙傜湅澶氫箙鑷姩鍏抽棴娴� - # [鍙�塢 鍏抽棴绛夊緟鏀跺埌娴佺紪鐮佷俊鎭悗鍦ㄨ繑鍥�, - # 璁句负false鍙互鑾峰緱鏇村ソ鐨勫吋瀹规��,淇濊瘉杩斿洖鍚庢祦灏卞彲浠ユ挱鏀�, - # 璁句负true鍙互蹇�熸墦寮�鎾斁绐楀彛,鍙互鑾峰緱鏇村ソ鐨勪綋楠� - closeWaitRTPInfo: false - # 鍚敤udp澶氱鍙fā寮� + streamNoneReaderDelayMS: 600000 # 鏃犱汉瑙傜湅澶氫箙鑷姩鍏抽棴娴�, -1琛ㄧず姘镐笉鑷姩鍏抽棴,鍗� 鍏抽棴鎸夐渶鎷夋祦 + # [鍙�塢 鑷姩鐐规挱锛� 浣跨敤鍥哄畾娴佸湴鍧�杩涜鎾斁鏃讹紝濡傛灉鏈偣鎾垯鑷姩杩涜鐐规挱, 闇�瑕乺tp.enable=true + autoApplyPlay: true + # [鍙�塢 閮ㄥ垎璁惧闇�瑕佹墿灞昐DP锛岄渶瑕佹墦寮�姝よ缃� + seniorSdp: false + # 鍚敤udp澶氱鍙fā寮�, 璇︾粏瑙i噴鍙傝��: https://github.com/xia-chu/ZLMediaKit/wiki/GB28181%E6%8E%A8%E6%B5%81 涓嬬殑楂橀樁浣跨敤 rtp: # [鍙�塢 鏄惁鍚敤udp澶氱鍙fā寮�, 寮�鍚悗浼氬湪udpPortRange鑼冨洿鍐呴�夋嫨绔彛鐢ㄤ簬濯掍綋娴佷紶杈� enable: true diff --git a/src/main/resources/wvp.sqlite b/src/main/resources/wvp.sqlite new file mode 100644 index 0000000..023ea35 --- /dev/null +++ b/src/main/resources/wvp.sqlite Binary files differ diff --git a/web_src/src/components/channelList.vue b/web_src/src/components/channelList.vue index 4c39a3f..e221974 100644 --- a/web_src/src/components/channelList.vue +++ b/web_src/src/components/channelList.vue @@ -19,12 +19,12 @@ <el-option label="璁惧" value="false"></el-option> <el-option label="瀛愮洰褰�" value="true"></el-option> </el-select> - 鍦ㄧ嚎鐘舵��: <el-select size="mini" @change="search" v-model="online" placeholder="璇烽�夋嫨" default-first-option> + 鍦ㄧ嚎鐘舵��: <el-select size="mini" style="margin-right: 1rem;" @change="search" v-model="online" placeholder="璇烽�夋嫨" default-first-option> <el-option label="鍏ㄩ儴" value=""></el-option> - <el-option label="鍦ㄧ嚎" value="on"></el-option> - <el-option label="绂荤嚎" value="off"></el-option> + <el-option label="鍦ㄧ嚎" value="true"></el-option> + <el-option label="绂荤嚎" value="false"></el-option> </el-select> - + <el-checkbox size="mini" style="margin-right: 1rem; float: right;" v-model="autoList" @change="autoListChange">鑷姩鍒锋柊</el-checkbox> </div> <devicePlayer ref="devicePlayer" v-loading="isLoging"></devicePlayer> <!--璁惧鍒楄〃--> @@ -56,7 +56,7 @@ <el-button-group> <!-- <el-button size="mini" icon="el-icon-video-play" v-if="scope.row.parental == 0" @click="sendDevicePush(scope.row)">鎾斁</el-button> --> <el-button size="mini" icon="el-icon-video-play" @click="sendDevicePush(scope.row)">鎾斁</el-button> - <el-button size="mini" icon="el-icon-switch-button" type="danger" v-if="scope.row.play" @click="stopDevicePush(scope.row)">鍋滄</el-button> + <el-button size="mini" icon="el-icon-switch-button" type="danger" v-if="!!scope.row.streamId" @click="stopDevicePush(scope.row)">鍋滄</el-button> <el-button size="mini" icon="el-icon-s-open" type="primary" v-if="scope.row.parental == 1" @click="changeSubchannel(scope.row)">鏌ョ湅</el-button> <el-button size="mini" icon="el-icon-video-camera" type="primary" @click="queryRecords(scope.row)">璁惧褰曡薄</el-button> <!-- <el-button size="mini" @click="sendDevicePush(scope.row)">褰曞儚鏌ヨ</el-button> --> @@ -98,13 +98,17 @@ count: parseInt(this.$route.params.count), total: 0, beforeUrl: "/videoList", - isLoging: false + isLoging: false, + autoList: false }; }, mounted() { this.initData(); - this.updateLooper = setInterval(this.initData, 10000); + if (this.autoList) { + this.updateLooper = setInterval(this.initData, 1500); + } + }, destroyed() { this.$destroy('videojs'); @@ -161,7 +165,7 @@ .then(function (res) { console.log(res); that.total = res.data.total; - that.deviceChannelList = res.data.data; + that.deviceChannelList = res.data.list; // 闃叉鍑虹幇琛ㄦ牸閿欎綅 that.$nextTick(() => { that.$refs.channelListTable.doLayout(); @@ -179,17 +183,16 @@ let deviceId = this.deviceId; this.isLoging = true; let channelId = itemData.channelId; - let getEncoding = itemData.hasAudio ? '1' : '0' - console.log("閫氱煡璁惧鎺ㄦ祦1锛�" + deviceId + " : " + channelId + ":" + getEncoding); + console.log("閫氱煡璁惧鎺ㄦ祦1锛�" + deviceId + " : " + channelId ); let that = this; this.$axios({ method: 'get', - url: '/api/play/' + deviceId + '/' + channelId + '?getEncoding=' + getEncoding + url: '/api/play/' + deviceId + '/' + channelId }).then(function (res) { console.log(res.data) - let ssrc = res.data.ssrc; + let streamId = res.data.streamId; that.isLoging = false; - if (!!ssrc) { + if (!!streamId) { // that.$refs.devicePlayer.play(res.data, deviceId, channelId, itemData.hasAudio); that.$refs.devicePlayer.openDialog("media", deviceId, channelId, { streamInfo: res.data, @@ -212,7 +215,7 @@ var that = this; this.$axios({ method: 'post', - url: '/api/play/' + itemData.ssrc + '/stop' + url: '/api/play/' + itemData.streamId + '/stop' }).then(function (res) { console.log(JSON.stringify(res)); that.initData(); @@ -258,7 +261,7 @@ }) .then(function (res) { that.total = res.data.total; - that.deviceChannelList = res.data.data; + that.deviceChannelList = res.data.list; // 闃叉鍑虹幇琛ㄦ牸閿欎綅 that.$nextTick(() => { that.$refs.channelListTable.doLayout(); @@ -283,6 +286,13 @@ }).then(function (res) { console.log(JSON.stringify(res)); }); + }, + autoListChange: function () { + if (this.autoList) { + this.updateLooper = setInterval(this.initData, 1500); + }else{ + window.clearInterval(this.updateLooper); + } } } diff --git a/web_src/src/components/gb28181/devicePlayer.vue b/web_src/src/components/gb28181/devicePlayer.vue index 8442a82..babf0fe 100644 --- a/web_src/src/components/gb28181/devicePlayer.vue +++ b/web_src/src/components/gb28181/devicePlayer.vue @@ -1,6 +1,6 @@ <template> <div id="devicePlayer" v-loading="isLoging"> - + <el-dialog title="瑙嗛鎾斁" top="0" :close-on-click-modal="false" :visible.sync="showVideoDialog" :destroy-on-close="true" @close="close()"> <!-- <LivePlayer v-if="showVideoDialog" ref="videoPlayer" :videoUrl="videoUrl" :error="videoError" :message="videoError" :hasaudio="hasaudio" fluent autoplay live></LivePlayer> --> <player ref="videoPlayer" :visible.sync="showVideoDialog" :videoUrl="videoUrl" :error="videoError" :message="videoError" :hasaudio="hasaudio" fluent autoplay live></player> @@ -121,7 +121,7 @@ <p>閲囨牱鐜�: {{item.sample_rate}}</p> </div> </div> - + </div> </el-tab-pane> @@ -158,7 +158,6 @@ searchHistoryResult: [] //濯掍綋娴佸巻鍙茶褰曟悳绱㈢粨鏋� }, showVideoDialog: false, - ssrc: '', streamId: '', convertKey: '', deviceId: '', @@ -210,7 +209,6 @@ this.tabActiveName = tab; this.channelId = channelId; this.deviceId = deviceId; - this.ssrc = ""; this.streamId = ""; this.videoUrl = "" if (!!this.$refs.videoPlayer) { @@ -234,11 +232,10 @@ console.log(val) }, play: function (streamInfo, hasAudio) { - + this.hasaudio = hasAudio; this.isLoging = false; this.videoUrl = streamInfo.ws_flv; - this.ssrc = streamInfo.ssrc; this.streamId = streamInfo.streamId; this.playFromStreamInfo(false, streamInfo) }, @@ -248,7 +245,7 @@ this.$refs.videoPlayer.pause() that.$axios({ method: 'post', - url: '/api/play/' + that.ssrc + '/convert' + url: '/api/play/' + that.streamId + '/convert' }).then(function (res) { if (res.data.code == 0) { that.convertKey = res.data.key; @@ -317,7 +314,7 @@ } this.convertKey = '' }, - + copySharedInfo: function (data) { console.log('澶嶅埗鍐呭锛�' + data); this.coverPlaying = false; @@ -368,9 +365,9 @@ }, playRecord: function (row) { let that = this; - if (that.ssrc != "") { + if (that.streamId != "") { that.stopPlayRecord(function () { - that.ssrc = "", + that.streamId = "", that.playRecord(row); }) } else { @@ -380,7 +377,7 @@ row.endTime }).then(function (res) { var streamInfo = res.data; - that.ssrc = streamInfo.ssrc; + that.streamId = streamInfo.streamId; that.videoUrl = streamInfo.ws_flv; }); } @@ -390,7 +387,7 @@ this.videoUrl = ''; this.$axios({ method: 'get', - url: '/api/playback/' + this.ssrc + '/stop' + url: '/api/playback/' + this.streamId + '/stop' }).then(function (res) { if (callback) callback() }); diff --git a/web_src/src/components/videoList.vue b/web_src/src/components/videoList.vue index ad2f701..46b4aac 100644 --- a/web_src/src/components/videoList.vue +++ b/web_src/src/components/videoList.vue @@ -8,7 +8,7 @@ <div style="background-color: #FFFFFF; margin-bottom: 1rem; position: relative; padding: 0.5rem; text-align: left;"> <span style="font-size: 1rem; font-weight: bold;">璁惧鍒楄〃</span> <div style="position: absolute; right: 1rem; top: 0.3rem;"> - <el-button icon="el-icon-refresh-right" circle size="mini" @click="getDeviceList()"></el-button> + <el-button icon="el-icon-refresh-right" circle size="mini" :loading="getDeviceListLoading" @click="getDeviceList()"></el-button> </div> </div> <devicePlayer ref="devicePlayer"></devicePlayer> @@ -21,7 +21,7 @@ <el-table-column label="鍦板潃" width="180" align="center"> <template slot-scope="scope"> <div slot="reference" class="name-wrapper"> - <el-tag size="medium">{{ scope.row.host.address }}</el-tag> + <el-tag size="medium">{{ scope.row.hostAddress }}</el-tag> </div> </template> </el-table-column> @@ -51,7 +51,7 @@ <el-table-column label="鎿嶄綔" width="240" align="center" fixed="right"> <template slot-scope="scope"> - <el-button size="mini" icon="el-icon-refresh" @click="refDevice(scope.row)">鍒锋柊閫氶亾</el-button> + <el-button size="mini" :ref="scope.row.deviceId + 'refbtn' " icon="el-icon-refresh" @click="refDevice(scope.row)">鍒锋柊閫氶亾</el-button> <el-button size="mini" icon="el-icon-s-open" type="primary" @click="showChannelList(scope.row)">鏌ョ湅閫氶亾</el-button> </template> </el-table-column> @@ -90,7 +90,8 @@ winHeight: window.innerHeight - 200, currentPage:1, count:15, - total:0 + total:0, + getDeviceListLoading: false }; }, computed: { @@ -130,7 +131,7 @@ }, getDeviceList: function() { let that = this; - + this.getDeviceListLoading = true; this.$axios.get(`/api/devices`,{ params: { page: that.currentPage - 1, @@ -139,11 +140,14 @@ } ) .then(function (res) { console.log(res); + console.log(res.data.list); that.total = res.data.total; - that.deviceList = res.data.data; + that.deviceList = res.data.list; + that.getDeviceListLoading = false; }) .catch(function (error) { console.log(error); + that.getDeviceListLoading = false; }); }, @@ -158,17 +162,31 @@ refDevice: function(itemData) { ///api/devices/{deviceId}/sync console.log("鍒锋柊瀵瑰簲璁惧:" + itemData.deviceId); + var that = this; + that.$refs[itemData.deviceId + 'refbtn' ].loading = true; this.$axios({ method: 'post', url: '/api/devices/' + itemData.deviceId + '/sync' }).then(function(res) { - // console.log("鍒锋柊璁惧缁撴灉锛�"+JSON.stringify(res)); + console.log("鍒锋柊璁惧缁撴灉锛�"+JSON.stringify(res)); + if (!res.data.deviceId) { + that.$message({ + showClose: true, + message: res.data, + type: 'error' + }); + }else{ + that.$message({ + showClose: true, + message: '璇锋眰鎴愬姛', + type: 'success' + }); + } + that.initData() + that.$refs[itemData.deviceId + 'refbtn' ].loading = false; }).catch(function(e) { - that.$message({ - showClose: true, - message: '璇锋眰鎴愬姛', - type: 'success' - }); + console.error(e) + that.$refs[itemData.deviceId + 'refbtn' ].loading = false; });; }, //閫氱煡璁惧涓婁紶濯掍綋娴� -- Gitblit v1.8.0