Commit ecf4fbb68445cf412d5e946f67f92c9928df8273

Authored by 648540858
2 parents cb16cabb 042b28b2

Merge branch 'wvp-28181-2.0'

# Conflicts:
#	src/main/java/com/genersoft/iot/vmp/service/impl/MediaServerServiceImpl.java
#	src/main/java/com/genersoft/iot/vmp/service/impl/MediaServiceImpl.java
#	src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java
#	src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/play/PlayController.java
#	web_src/src/components/Login.vue
Showing 74 changed files with 1234 additions and 844 deletions

Too many changes to show.

To preserve performance only 74 of 146 files are displayed.

... ... @@ -6,7 +6,7 @@
6 6 <parent>
7 7 <groupId>org.springframework.boot</groupId>
8 8 <artifactId>spring-boot-starter-parent</artifactId>
9   - <version>2.3.5.RELEASE</version>
  9 + <version>2.7.2</version>
10 10 </parent>
11 11  
12 12 <groupId>com.genersoft</groupId>
... ... @@ -47,7 +47,6 @@
47 47 <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
48 48 <maven.build.timestamp.format>MMddHHmm</maven.build.timestamp.format>
49 49 <maven-jar-plugin.version>3.1.1</maven-jar-plugin.version>
50   - <jedis-version>3.1.0</jedis-version>
51 50  
52 51 <!-- 依赖版本 -->
53 52 <snippetsDirectory>${project.build.directory}/generated-snippets</snippetsDirectory>
... ... @@ -74,7 +73,7 @@
74 73 <dependency>
75 74 <groupId>org.mybatis.spring.boot</groupId>
76 75 <artifactId>mybatis-spring-boot-starter</artifactId>
77   - <version>2.1.4</version>
  76 + <version>2.2.2</version>
78 77 <exclusions>
79 78 <exclusion>
80 79 <groupId>com.zaxxer</groupId>
... ... @@ -91,37 +90,36 @@
91 90 <dependency>
92 91 <groupId>com.alibaba</groupId>
93 92 <artifactId>druid-spring-boot-starter</artifactId>
94   - <version>1.1.22</version>
  93 + <version>1.2.11</version>
95 94 </dependency>
96 95  
97 96 <!-- mysql数据库 -->
98 97 <dependency>
99 98 <groupId>mysql</groupId>
100 99 <artifactId>mysql-connector-java</artifactId>
101   - <version>8.0.22</version>
  100 + <version>8.0.30</version>
102 101 </dependency>
103 102  
104 103 <!--Mybatis分页插件 -->
105 104 <dependency>
106 105 <groupId>com.github.pagehelper</groupId>
107 106 <artifactId>pagehelper-spring-boot-starter</artifactId>
108   - <version>1.4.1</version>
  107 + <version>1.4.3</version>
109 108 </dependency>
110 109  
111   - <!--Swagger3 -->
112 110 <!--在线文档 -->
113 111 <dependency>
114   - <groupId>io.springfox</groupId>
115   - <artifactId>springfox-boot-starter</artifactId>
116   - <version>3.0.0</version>
  112 + <groupId>org.springdoc</groupId>
  113 + <artifactId>springdoc-openapi-ui</artifactId>
  114 + <version>1.6.10</version>
117 115 </dependency>
  116 +
118 117 <dependency>
119 118 <groupId>com.github.xiaoymin</groupId>
120   - <artifactId>knife4j-spring-boot-starter</artifactId>
121   - <version>3.0.2</version>
  119 + <artifactId>knife4j-springdoc-ui</artifactId>
  120 + <version>3.0.3</version>
122 121 </dependency>
123 122  
124   -
125 123 <!--参数校验 -->
126 124 <dependency>
127 125 <groupId>javax.validation</groupId>
... ... @@ -145,7 +143,7 @@
145 143 <dependency>
146 144 <groupId>org.slf4j</groupId>
147 145 <artifactId>log4j-over-slf4j</artifactId>
148   - <version>1.7.35</version>
  146 + <version>1.7.36</version>
149 147 </dependency>
150 148  
151 149 <!-- xml解析库 -->
... ... @@ -167,14 +165,14 @@
167 165 <dependency>
168 166 <groupId>com.squareup.okhttp3</groupId>
169 167 <artifactId>okhttp</artifactId>
170   - <version>4.9.0</version>
  168 + <version>4.10.0</version>
171 169 </dependency>
172 170  
173 171 <!-- okhttp 调试日志 -->
174 172 <dependency>
175 173 <groupId>com.squareup.okhttp3</groupId>
176 174 <artifactId>logging-interceptor</artifactId>
177   - <version>4.9.0</version>
  175 + <version>4.10.0</version>
178 176 </dependency>
179 177  
180 178  
... ... @@ -183,7 +181,7 @@
183 181 <dependency>
184 182 <groupId>io.github.rburgst</groupId>
185 183 <artifactId>okhttp-digest</artifactId>
186   - <version>2.5</version>
  184 + <version>2.7</version>
187 185 </dependency>
188 186  
189 187 <!-- https://mvnrepository.com/artifact/net.sf.kxml/kxml2 -->
... ... @@ -197,21 +195,21 @@
197 195 <dependency>
198 196 <groupId>org.mitre.dsmiley.httpproxy</groupId>
199 197 <artifactId>smiley-http-proxy-servlet</artifactId>
200   - <version>1.12</version>
  198 + <version>1.12.1</version>
201 199 </dependency>
202 200  
203 201 <!--excel解析库-->
204 202 <dependency>
205 203 <groupId>com.alibaba</groupId>
206 204 <artifactId>easyexcel</artifactId>
207   - <version>3.0.4</version>
  205 + <version>3.1.1</version>
208 206 </dependency>
209 207  
210 208 <!-- 获取系统信息 -->
211 209 <dependency>
212 210 <groupId>com.github.oshi</groupId>
213 211 <artifactId>oshi-core</artifactId>
214   - <version>6.1.0</version>
  212 + <version>6.2.2</version>
215 213 </dependency>
216 214  
217 215 <dependency>
... ... @@ -231,7 +229,7 @@
231 229 <dependency>
232 230 <groupId>com.google.guava</groupId>
233 231 <artifactId>guava</artifactId>
234   - <version>31.0.1-jre</version>
  232 + <version>31.1-jre</version>
235 233 </dependency>
236 234  
237 235  
... ...
src/main/java/com/genersoft/iot/vmp/VManageBootstrap.java
... ... @@ -8,7 +8,6 @@ import org.springframework.boot.autoconfigure.SpringBootApplication;
8 8 import org.springframework.boot.web.servlet.ServletComponentScan;
9 9 import org.springframework.context.ConfigurableApplicationContext;
10 10 import org.springframework.scheduling.annotation.EnableScheduling;
11   -import springfox.documentation.oas.annotations.EnableOpenApi;
12 11  
13 12 /**
14 13 * 启动类
... ... @@ -16,7 +15,6 @@ import springfox.documentation.oas.annotations.EnableOpenApi;
16 15 @ServletComponentScan("com.genersoft.iot.vmp.conf")
17 16 @SpringBootApplication
18 17 @EnableScheduling
19   -@EnableOpenApi
20 18 @EnableDruidSupport
21 19 public class VManageBootstrap extends LogManager {
22 20 private static String[] args;
... ...
src/main/java/com/genersoft/iot/vmp/common/StreamInfo.java
1 1 package com.genersoft.iot.vmp.common;
2 2  
3   -import com.alibaba.fastjson.JSONArray;
4 3  
5 4 public class StreamInfo {
6 5  
... ...
src/main/java/com/genersoft/iot/vmp/common/VideoManagerConstants.java
... ... @@ -91,6 +91,10 @@ public class VideoManagerConstants {
91 91 * 接收推流设备的GPS变化通知
92 92 */
93 93 public static final String VM_MSG_PUSH_STREAM_STATUS_CHANGE = "VM_MSG_PUSH_STREAM_STATUS_CHANGE";
  94 + /**
  95 + * 接收推流设备列表更新变化通知
  96 + */
  97 + public static final String VM_MSG_PUSH_STREAM_LIST_CHANGE = "VM_MSG_PUSH_STREAM_LIST_CHANGE";
94 98  
95 99 /**
96 100 * redis 消息通知设备推流到平台
... ...
src/main/java/com/genersoft/iot/vmp/conf/DynamicTask.java
... ... @@ -9,6 +9,7 @@ import org.springframework.scheduling.annotation.Scheduled;
9 9 import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
10 10 import org.springframework.stereotype.Component;
11 11  
  12 +import javax.annotation.PostConstruct;
12 13 import java.time.Instant;
13 14 import java.util.Map;
14 15 import java.util.Set;
... ... @@ -25,20 +26,18 @@ public class DynamicTask {
25 26  
26 27 private final Logger logger = LoggerFactory.getLogger(DynamicTask.class);
27 28  
28   - @Autowired
29 29 private ThreadPoolTaskScheduler threadPoolTaskScheduler;
30 30  
31 31 private final Map<String, ScheduledFuture<?>> futureMap = new ConcurrentHashMap<>();
32 32 private final Map<String, Runnable> runnableMap = new ConcurrentHashMap<>();
33 33  
34   - @Bean
35   - public ThreadPoolTaskScheduler threadPoolTaskScheduler() {
36   - ThreadPoolTaskScheduler schedulerPool = new ThreadPoolTaskScheduler();
37   - schedulerPool.setPoolSize(300);
38   - schedulerPool.setWaitForTasksToCompleteOnShutdown(true);
39   - schedulerPool.setAwaitTerminationSeconds(10);
40   - return schedulerPool;
41   -
  34 + @PostConstruct
  35 + public void DynamicTask() {
  36 + threadPoolTaskScheduler = new ThreadPoolTaskScheduler();
  37 + threadPoolTaskScheduler.setPoolSize(300);
  38 + threadPoolTaskScheduler.setWaitForTasksToCompleteOnShutdown(true);
  39 + threadPoolTaskScheduler.setAwaitTerminationSeconds(10);
  40 + threadPoolTaskScheduler.initialize();
42 41 }
43 42  
44 43 /**
... ...
src/main/java/com/genersoft/iot/vmp/conf/GlobalExceptionHandler.java 0 → 100644
  1 +package com.genersoft.iot.vmp.conf;
  2 +
  3 +import com.genersoft.iot.vmp.conf.exception.ControllerException;
  4 +import com.genersoft.iot.vmp.gb28181.event.alarm.AlarmEventListener;
  5 +import com.genersoft.iot.vmp.vmanager.bean.ErrorCode;
  6 +import com.genersoft.iot.vmp.vmanager.bean.WVPResult;
  7 +import org.slf4j.Logger;
  8 +import org.slf4j.LoggerFactory;
  9 +import org.springframework.http.HttpStatus;
  10 +import org.springframework.security.authentication.BadCredentialsException;
  11 +import org.springframework.web.bind.annotation.ExceptionHandler;
  12 +import org.springframework.web.bind.annotation.ResponseStatus;
  13 +import org.springframework.web.bind.annotation.RestControllerAdvice;
  14 +
  15 +/**
  16 + * 全局异常处理
  17 + */
  18 +@RestControllerAdvice
  19 +public class GlobalExceptionHandler {
  20 +
  21 + private final static Logger logger = LoggerFactory.getLogger(GlobalExceptionHandler.class);
  22 +
  23 + /**
  24 + * 默认异常处理
  25 + * @param e 异常
  26 + * @return 统一返回结果
  27 + */
  28 + @ExceptionHandler(Exception.class)
  29 + @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
  30 + public WVPResult<String> exceptionHandler(Exception e) {
  31 + logger.error("[全局异常]: ", e);
  32 + return WVPResult.fail(ErrorCode.ERROR500.getCode(), e.getMessage());
  33 + }
  34 +
  35 + /**
  36 + * 自定义异常处理, 处理controller中返回的错误
  37 + * @param e 异常
  38 + * @return 统一返回结果
  39 + */
  40 + @ExceptionHandler(ControllerException.class)
  41 + @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
  42 + public WVPResult<String> exceptionHandler(ControllerException e) {
  43 + return WVPResult.fail(e.getCode(), e.getMsg());
  44 + }
  45 +
  46 + /**
  47 + * 登陆失败
  48 + * @param e 异常
  49 + * @return 统一返回结果
  50 + */
  51 + @ExceptionHandler(BadCredentialsException.class)
  52 + @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
  53 + public WVPResult<String> exceptionHandler(BadCredentialsException e) {
  54 + return WVPResult.fail(ErrorCode.ERROR100.getCode(), e.getMessage());
  55 + }
  56 +}
... ...
src/main/java/com/genersoft/iot/vmp/conf/GlobalResponseAdvice.java 0 → 100644
  1 +package com.genersoft.iot.vmp.conf;
  2 +
  3 +import com.alibaba.fastjson.JSON;
  4 +import com.genersoft.iot.vmp.vmanager.bean.ErrorCode;
  5 +import com.genersoft.iot.vmp.vmanager.bean.WVPResult;
  6 +import org.jetbrains.annotations.NotNull;
  7 +import org.springframework.core.MethodParameter;
  8 +import org.springframework.http.MediaType;
  9 +import org.springframework.http.converter.HttpMessageConverter;
  10 +import org.springframework.http.server.ServerHttpRequest;
  11 +import org.springframework.http.server.ServerHttpResponse;
  12 +import org.springframework.web.bind.annotation.RestControllerAdvice;
  13 +import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;
  14 +
  15 +/**
  16 + * 全局统一返回结果
  17 + * @author lin
  18 + */
  19 +@RestControllerAdvice
  20 +public class GlobalResponseAdvice implements ResponseBodyAdvice<Object> {
  21 +
  22 +
  23 + @Override
  24 + public boolean supports(@NotNull MethodParameter returnType, @NotNull Class<? extends HttpMessageConverter<?>> converterType) {
  25 + return true;
  26 + }
  27 +
  28 + @Override
  29 + public Object beforeBodyWrite(Object body, @NotNull MethodParameter returnType, @NotNull MediaType selectedContentType, @NotNull Class<? extends HttpMessageConverter<?>> selectedConverterType, @NotNull ServerHttpRequest request, @NotNull ServerHttpResponse response) {
  30 + // 排除api文档的接口,这个接口不需要统一
  31 + String[] excludePath = {"/v3/api-docs","/api/v1","/index/hook"};
  32 + for (String path : excludePath) {
  33 + if (request.getURI().getPath().startsWith(path)) {
  34 + return body;
  35 + }
  36 + }
  37 +
  38 + if (body instanceof WVPResult) {
  39 + return body;
  40 + }
  41 +
  42 + if (body instanceof ErrorCode) {
  43 + ErrorCode errorCode = (ErrorCode) body;
  44 + return new WVPResult<>(errorCode.getCode(), errorCode.getMsg(), null);
  45 + }
  46 +
  47 + if (body instanceof String) {
  48 + return JSON.toJSONString(WVPResult.success(body));
  49 + }
  50 +
  51 + return WVPResult.success(body);
  52 + }
  53 +}
... ...
src/main/java/com/genersoft/iot/vmp/conf/MediaConfig.java
... ... @@ -4,6 +4,7 @@ import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
4 4 import com.genersoft.iot.vmp.utils.DateUtil;
5 5 import org.springframework.beans.factory.annotation.Value;
6 6 import org.springframework.context.annotation.Configuration;
  7 +import org.springframework.util.ObjectUtils;
7 8 import org.springframework.util.StringUtils;
8 9  
9 10 import java.net.InetAddress;
... ... @@ -88,7 +89,7 @@ public class MediaConfig{
88 89 }
89 90  
90 91 public String getHookIp() {
91   - if (StringUtils.isEmpty(hookIp)){
  92 + if (ObjectUtils.isEmpty(hookIp)){
92 93 return sipIp;
93 94 }else {
94 95 return hookIp;
... ... @@ -162,7 +163,7 @@ public class MediaConfig{
162 163 }
163 164  
164 165 public String getSdpIp() {
165   - if (StringUtils.isEmpty(sdpIp)){
  166 + if (ObjectUtils.isEmpty(sdpIp)){
166 167 return ip;
167 168 }else {
168 169 if (isValidIPAddress(sdpIp)) {
... ... @@ -181,7 +182,7 @@ public class MediaConfig{
181 182 }
182 183  
183 184 public String getStreamIp() {
184   - if (StringUtils.isEmpty(streamIp)){
  185 + if (ObjectUtils.isEmpty(streamIp)){
185 186 return ip;
186 187 }else {
187 188 return streamIp;
... ...
src/main/java/com/genersoft/iot/vmp/conf/ProxyServletConfig.java
... ... @@ -14,6 +14,7 @@ import org.springframework.beans.factory.annotation.Value;
14 14 import org.springframework.boot.web.servlet.ServletRegistrationBean;
15 15 import org.springframework.context.annotation.Bean;
16 16 import org.springframework.context.annotation.Configuration;
  17 +import org.springframework.util.ObjectUtils;
17 18 import org.springframework.util.StringUtils;
18 19  
19 20 import javax.servlet.ServletException;
... ... @@ -55,7 +56,7 @@ public class ProxyServletConfig {
55 56 String queryStr = super.rewriteQueryStringFromRequest(servletRequest, queryString);
56 57 MediaServerItem mediaInfo = getMediaInfoByUri(servletRequest.getRequestURI());
57 58 if (mediaInfo != null) {
58   - if (!StringUtils.isEmpty(queryStr)) {
  59 + if (!ObjectUtils.isEmpty(queryStr)) {
59 60 queryStr += "&secret=" + mediaInfo.getSecret();
60 61 }else {
61 62 queryStr = "secret=" + mediaInfo.getSecret();
... ... @@ -146,7 +147,7 @@ public class ProxyServletConfig {
146 147 logger.error("[ZLM服务访问代理],错误:处理url信息时未找到流媒体信息=>{}", requestURI);
147 148 return url;
148 149 }
149   - if (!StringUtils.isEmpty(mediaInfo.getId())) {
  150 + if (!ObjectUtils.isEmpty(mediaInfo.getId())) {
150 151 url = url.replace(mediaInfo.getId() + "/", "");
151 152 }
152 153 return url.replace("default/", "");
... ... @@ -173,7 +174,7 @@ public class ProxyServletConfig {
173 174 MediaServerItem mediaInfo = getMediaInfoByUri(servletRequest.getRequestURI());
174 175 String remoteHost = String.format("http://%s:%s", mediaInfo.getIp(), mediaInfo.getHttpPort());
175 176 if (mediaInfo != null) {
176   - if (!StringUtils.isEmpty(queryStr)) {
  177 + if (!ObjectUtils.isEmpty(queryStr)) {
177 178 queryStr += "&remoteHost=" + remoteHost;
178 179 }else {
179 180 queryStr = "remoteHost=" + remoteHost;
... ... @@ -265,7 +266,7 @@ public class ProxyServletConfig {
265 266 logger.error("[录像服务访问代理],错误:处理url信息时未找到流媒体信息=>{}", requestURI);
266 267 return url;
267 268 }
268   - if (!StringUtils.isEmpty(mediaInfo.getId())) {
  269 + if (!ObjectUtils.isEmpty(mediaInfo.getId())) {
269 270 url = url.replace(mediaInfo.getId() + "/", "");
270 271 }
271 272 return url.replace("default/", "");
... ...
src/main/java/com/genersoft/iot/vmp/conf/SpringDocConfig.java 0 → 100644
  1 +package com.genersoft.iot.vmp.conf;
  2 +
  3 +import io.swagger.v3.oas.models.ExternalDocumentation;
  4 +import io.swagger.v3.oas.models.OpenAPI;
  5 +import io.swagger.v3.oas.models.info.Contact;
  6 +import io.swagger.v3.oas.models.info.Info;
  7 +import io.swagger.v3.oas.models.info.License;
  8 +import io.swagger.v3.oas.models.media.StringSchema;
  9 +import io.swagger.v3.oas.models.parameters.HeaderParameter;
  10 +import org.springdoc.core.GroupedOpenApi;
  11 +import org.springdoc.core.SpringDocConfigProperties;
  12 +import org.springframework.beans.factory.annotation.Value;
  13 +import org.springframework.context.annotation.Bean;
  14 +import org.springframework.context.annotation.Configuration;
  15 +
  16 +/**
  17 + * @author lin
  18 + */
  19 +@Configuration
  20 +public class SpringDocConfig {
  21 +
  22 + @Value("${doc.enabled: true}")
  23 + private boolean enable;
  24 +
  25 + @Bean
  26 + public OpenAPI springShopOpenApi() {
  27 + Contact contact = new Contact();
  28 + contact.setName("pan");
  29 + contact.setEmail("648540858@qq.com");
  30 + return new OpenAPI()
  31 + .info(new Info().title("WVP-PRO 接口文档")
  32 + .contact(contact)
  33 + .description("开箱即用的28181协议视频平台")
  34 + .version("v2.0")
  35 + .license(new License().name("Apache 2.0").url("http://springdoc.org")));
  36 + }
  37 +
  38 + /**
  39 + * 添加分组
  40 + * @return
  41 + */
  42 + @Bean
  43 + public GroupedOpenApi publicApi() {
  44 + return GroupedOpenApi.builder()
  45 + .group("1. 全部")
  46 + .packagesToScan("com.genersoft.iot.vmp.vmanager")
  47 + .build();
  48 + }
  49 +
  50 + @Bean
  51 + public GroupedOpenApi publicApi2() {
  52 + return GroupedOpenApi.builder()
  53 + .group("2. 国标28181")
  54 + .packagesToScan("com.genersoft.iot.vmp.vmanager.gb28181")
  55 + .build();
  56 + }
  57 +
  58 + @Bean
  59 + public GroupedOpenApi publicApi3() {
  60 + return GroupedOpenApi.builder()
  61 + .group("3. 拉流转发")
  62 + .packagesToScan("com.genersoft.iot.vmp.vmanager.streamProxy")
  63 + .build();
  64 + }
  65 +
  66 + @Bean
  67 + public GroupedOpenApi publicApi4() {
  68 + return GroupedOpenApi.builder()
  69 + .group("4. 推流管理")
  70 + .packagesToScan("com.genersoft.iot.vmp.vmanager.streamPush")
  71 + .build();
  72 + }
  73 +
  74 + @Bean
  75 + public GroupedOpenApi publicApi5() {
  76 + return GroupedOpenApi.builder()
  77 + .group("4. 服务管理")
  78 + .packagesToScan("com.genersoft.iot.vmp.vmanager.server")
  79 + .build();
  80 + }
  81 +
  82 + @Bean
  83 + public GroupedOpenApi publicApi6() {
  84 + return GroupedOpenApi.builder()
  85 + .group("5. 用户管理")
  86 + .packagesToScan("com.genersoft.iot.vmp.vmanager.user")
  87 + .build();
  88 + }
  89 +}
... ...
src/main/java/com/genersoft/iot/vmp/conf/Swagger3Config.java deleted 100644 → 0
1   -package com.genersoft.iot.vmp.conf;
2   -
3   -import org.springframework.beans.factory.annotation.Value;
4   -import org.springframework.context.annotation.Bean;
5   -import org.springframework.context.annotation.Configuration;
6   -import springfox.documentation.builders.ApiInfoBuilder;
7   -import springfox.documentation.builders.PathSelectors;
8   -import springfox.documentation.builders.RequestHandlerSelectors;
9   -import springfox.documentation.service.ApiInfo;
10   -import springfox.documentation.service.Contact;
11   -import springfox.documentation.spi.DocumentationType;
12   -import springfox.documentation.spring.web.plugins.Docket;
13   -
14   -@Configuration
15   -public class Swagger3Config {
16   -
17   - @Value("${swagger-ui.enabled: true}")
18   - private boolean enable;
19   -
20   - @Bean
21   - public Docket createRestApi() {
22   - return new Docket(DocumentationType.OAS_30)
23   - .apiInfo(apiInfo())
24   - .groupName("1. 全部")
25   - .select()
26   - .apis(RequestHandlerSelectors.basePackage("com.genersoft.iot.vmp.vmanager"))
27   - .paths(PathSelectors.any())
28   - .build()
29   - .pathMapping("/")
30   - .enable(enable);
31   - }
32   - @Bean
33   - public Docket createRestGBApi() {
34   - return new Docket(DocumentationType.OAS_30)
35   - .apiInfo(apiInfo())
36   - .groupName("2. 国标28181")
37   - .select()
38   - .apis(RequestHandlerSelectors.basePackage("com.genersoft.iot.vmp.vmanager.gb28181"))
39   - .paths(PathSelectors.any())
40   - .build()
41   - .pathMapping("/")
42   - .enable(enable);
43   - }
44   -
45   - @Bean
46   - public Docket createRestONVIFApi() {
47   - return new Docket(DocumentationType.OAS_30)
48   - .apiInfo(apiInfo())
49   - .groupName("3. ONVIF")
50   - .select()
51   - .apis(RequestHandlerSelectors.basePackage("com.genersoft.iot.vmp.vmanager.onvif"))
52   - .paths(PathSelectors.any())
53   - .build()
54   - .pathMapping("/")
55   - .enable(enable);
56   - }
57   -
58   - @Bean
59   - public Docket createRestStreamProxyApi() {
60   - return new Docket(DocumentationType.OAS_30)
61   - .apiInfo(apiInfo())
62   - .groupName("4. 拉流转发")
63   - .select()
64   - .apis(RequestHandlerSelectors.basePackage("com.genersoft.iot.vmp.vmanager.streamProxy"))
65   - .paths(PathSelectors.any())
66   - .build()
67   - .pathMapping("/")
68   - .enable(enable);
69   - }
70   - @Bean
71   - public Docket createRestStreamPushApi() {
72   - return new Docket(DocumentationType.OAS_30)
73   - .apiInfo(apiInfo())
74   - .groupName("5. 推流管理")
75   - .select()
76   - .apis(RequestHandlerSelectors.basePackage("com.genersoft.iot.vmp.vmanager.streamPush"))
77   - .paths(PathSelectors.any())
78   - .build()
79   - .pathMapping("/")
80   - .enable(enable);
81   - }
82   -
83   -
84   - @Bean
85   - public Docket createServerApi() {
86   - return new Docket(DocumentationType.OAS_30)
87   - .apiInfo(apiInfo())
88   - .groupName("6. 服务管理")
89   - .select()
90   - .apis(RequestHandlerSelectors.basePackage("com.genersoft.iot.vmp.vmanager.server"))
91   - .paths(PathSelectors.any())
92   - .build()
93   - .pathMapping("/")
94   - .enable(enable);
95   - }
96   - @Bean
97   - public Docket createUserApi() {
98   - return new Docket(DocumentationType.OAS_30)
99   - .apiInfo(apiInfo())
100   - .groupName("7. 用户管理")
101   - .select()
102   - .apis(RequestHandlerSelectors.basePackage("com.genersoft.iot.vmp.vmanager.user"))
103   - .paths(PathSelectors.any())
104   - .build()
105   - .pathMapping("/")
106   - .enable(enable);
107   - }
108   -
109   - private ApiInfo apiInfo() {
110   - return new ApiInfoBuilder()
111   - .title("WVP-PRO 接口文档")
112   - .description("更多请咨询服务开发者(https://github.com/648540858/wvp-GB28181-pro)。")
113   - .contact(new Contact("648540858", "648540858", "648540858@qq.com"))
114   - .version("2.0")
115   - .build();
116   - }
117   -}
src/main/java/com/genersoft/iot/vmp/conf/exception/ControllerException.java 0 → 100644
  1 +package com.genersoft.iot.vmp.conf.exception;
  2 +
  3 +import com.genersoft.iot.vmp.vmanager.bean.ErrorCode;
  4 +
  5 +/**
  6 + * 自定义异常,controller出现错误时直接抛出异常由全局异常捕获并返回结果
  7 + */
  8 +public class ControllerException extends RuntimeException{
  9 +
  10 + private int code;
  11 + private String msg;
  12 +
  13 + public ControllerException(int code, String msg) {
  14 + this.code = code;
  15 + this.msg = msg;
  16 + }
  17 + public ControllerException(ErrorCode errorCode) {
  18 + this.code = errorCode.getCode();
  19 + this.msg = errorCode.getMsg();
  20 + }
  21 +
  22 + public int getCode() {
  23 + return code;
  24 + }
  25 +
  26 + public void setCode(int code) {
  27 + this.code = code;
  28 + }
  29 +
  30 + public String getMsg() {
  31 + return msg;
  32 + }
  33 +
  34 + public void setMsg(String msg) {
  35 + this.msg = msg;
  36 + }
  37 +}
... ...
src/main/java/com/genersoft/iot/vmp/conf/RedisConfig.java renamed to src/main/java/com/genersoft/iot/vmp/conf/redis/RedisConfig.java
1   -package com.genersoft.iot.vmp.conf;
2   -
3   -import com.alibaba.fastjson.parser.ParserConfig;
4   -import com.genersoft.iot.vmp.common.VideoManagerConstants;
5   -import com.genersoft.iot.vmp.service.impl.*;
6   -import org.apache.commons.lang3.StringUtils;
7   -import org.springframework.beans.factory.annotation.Autowired;
8   -import org.springframework.beans.factory.annotation.Value;
9   -import org.springframework.cache.annotation.CachingConfigurerSupport;
10   -import org.springframework.context.annotation.Bean;
11   -import org.springframework.context.annotation.Configuration;
12   -import org.springframework.data.redis.connection.RedisConnectionFactory;
13   -import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
14   -import org.springframework.data.redis.core.RedisTemplate;
15   -import org.springframework.data.redis.listener.PatternTopic;
16   -import org.springframework.data.redis.listener.RedisMessageListenerContainer;
17   -import org.springframework.data.redis.serializer.StringRedisSerializer;
18   -
19   -import com.genersoft.iot.vmp.utils.redis.FastJsonRedisSerializer;
20   -
21   -
22   -/**
23   - * @description:Redis中间件配置类,使用spring-data-redis集成,自动从application.yml中加载redis配置
24   - * @author: swwheihei
25   - * @date: 2019年5月30日 上午10:58:25
26   - *
27   - */
28   -@Configuration
29   -public class RedisConfig extends CachingConfigurerSupport {
30   -
31   - @Autowired
32   - private RedisGpsMsgListener redisGPSMsgListener;
33   -
34   - @Autowired
35   - private RedisAlarmMsgListener redisAlarmMsgListener;
36   -
37   - @Autowired
38   - private RedisStreamMsgListener redisStreamMsgListener;
39   -
40   - @Autowired
41   - private RedisGbPlayMsgListener redisGbPlayMsgListener;
42   -
43   - @Autowired
44   - private RedisPushStreamStatusMsgListener redisPushStreamStatusMsgListener;
45   -
46   - @Bean
47   - public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
48   - RedisTemplate<Object, Object> redisTemplate = new RedisTemplate<>();
49   - // 使用fastJson序列化
50   - FastJsonRedisSerializer fastJsonRedisSerializer = new FastJsonRedisSerializer(Object.class);
51   - // value值的序列化采用fastJsonRedisSerializer
52   - redisTemplate.setValueSerializer(fastJsonRedisSerializer);
53   - redisTemplate.setHashValueSerializer(fastJsonRedisSerializer);
54   - // 全局开启AutoType,不建议使用
55   - ParserConfig.getGlobalInstance().setAutoTypeSupport(true);
56   - // 建议使用这种方式,小范围指定白名单,需要序列化的类
57   -// ParserConfig.getGlobalInstance().addAccept("com.avatar");
58   - // key的序列化采用StringRedisSerializer
59   - redisTemplate.setKeySerializer(new StringRedisSerializer());
60   - redisTemplate.setHashKeySerializer(new StringRedisSerializer());
61   - redisTemplate.setConnectionFactory(redisConnectionFactory);
62   - return redisTemplate;
63   - }
64   -
65   -
66   - /**
67   - * redis消息监听器容器 可以添加多个监听不同话题的redis监听器,只需要把消息监听器和相应的消息订阅处理器绑定,该消息监听器
68   - * 通过反射技术调用消息订阅处理器的相关方法进行一些业务处理
69   - *
70   - * @param connectionFactory
71   - * @return
72   - */
73   - @Bean
74   - RedisMessageListenerContainer container(RedisConnectionFactory connectionFactory) {
75   -
76   - RedisMessageListenerContainer container = new RedisMessageListenerContainer();
77   - container.setConnectionFactory(connectionFactory);
78   - container.addMessageListener(redisGPSMsgListener, new PatternTopic(VideoManagerConstants.VM_MSG_GPS));
79   - container.addMessageListener(redisAlarmMsgListener, new PatternTopic(VideoManagerConstants.VM_MSG_SUBSCRIBE_ALARM_RECEIVE));
80   - container.addMessageListener(redisStreamMsgListener, new PatternTopic(VideoManagerConstants.WVP_MSG_STREAM_CHANGE_PREFIX + "PUSH"));
81   - container.addMessageListener(redisGbPlayMsgListener, new PatternTopic(RedisGbPlayMsgListener.WVP_PUSH_STREAM_KEY));
82   - container.addMessageListener(redisPushStreamStatusMsgListener, new PatternTopic(VideoManagerConstants.VM_MSG_PUSH_STREAM_STATUS_CHANGE));
83   - return container;
84   - }
85   -
86   -}
  1 +package com.genersoft.iot.vmp.conf.redis;
  2 +
  3 +
  4 +import com.alibaba.fastjson.parser.ParserConfig;
  5 +import com.genersoft.iot.vmp.common.VideoManagerConstants;
  6 +import com.genersoft.iot.vmp.service.impl.*;
  7 +import org.springframework.beans.factory.annotation.Autowired;
  8 +import org.springframework.cache.annotation.CachingConfigurerSupport;
  9 +import org.springframework.context.annotation.Bean;
  10 +import org.springframework.context.annotation.Configuration;
  11 +import org.springframework.data.redis.connection.RedisConnectionFactory;
  12 +import org.springframework.data.redis.core.RedisTemplate;
  13 +import org.springframework.data.redis.listener.PatternTopic;
  14 +import org.springframework.data.redis.listener.RedisMessageListenerContainer;
  15 +import org.springframework.data.redis.serializer.RedisSerializer;
  16 +import org.springframework.data.redis.serializer.StringRedisSerializer;
  17 +
  18 +import com.genersoft.iot.vmp.utils.redis.FastJsonRedisSerializer;
  19 +
  20 +
  21 +/**
  22 + * @description:Redis中间件配置类,使用spring-data-redis集成,自动从application.yml中加载redis配置
  23 + * @author: swwheihei
  24 + * @date: 2019年5月30日 上午10:58:25
  25 + *
  26 + */
  27 +@Configuration
  28 +public class RedisConfig extends CachingConfigurerSupport {
  29 +
  30 + @Autowired
  31 + private RedisGpsMsgListener redisGPSMsgListener;
  32 +
  33 + @Autowired
  34 + private RedisAlarmMsgListener redisAlarmMsgListener;
  35 +
  36 + @Autowired
  37 + private RedisStreamMsgListener redisStreamMsgListener;
  38 +
  39 + @Autowired
  40 + private RedisGbPlayMsgListener redisGbPlayMsgListener;
  41 +
  42 + @Autowired
  43 + private RedisPushStreamStatusMsgListener redisPushStreamStatusMsgListener;
  44 +
  45 + @Autowired
  46 + private RedisPushStreamListMsgListener redisPushStreamListMsgListener;
  47 +
  48 + @Bean
  49 + public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
  50 + RedisTemplate<Object, Object> redisTemplate = new RedisTemplate<>();
  51 + // 使用fastJson序列化
  52 + FastJsonRedisSerializer fastJsonRedisSerializer = new FastJsonRedisSerializer(Object.class);
  53 + // value值的序列化采用fastJsonRedisSerializer
  54 + redisTemplate.setValueSerializer(fastJsonRedisSerializer);
  55 + redisTemplate.setHashValueSerializer(fastJsonRedisSerializer);
  56 + // 全局开启AutoType,不建议使用
  57 + ParserConfig.getGlobalInstance().setAutoTypeSupport(true);
  58 + // key的序列化采用StringRedisSerializer
  59 + redisTemplate.setKeySerializer(new StringRedisSerializer());
  60 + redisTemplate.setHashKeySerializer(new StringRedisSerializer());
  61 + redisTemplate.setConnectionFactory(redisConnectionFactory);
  62 + return redisTemplate;
  63 + }
  64 +
  65 +
  66 + /**
  67 + * redis消息监听器容器 可以添加多个监听不同话题的redis监听器,只需要把消息监听器和相应的消息订阅处理器绑定,该消息监听器
  68 + * 通过反射技术调用消息订阅处理器的相关方法进行一些业务处理
  69 + *
  70 + * @param connectionFactory
  71 + * @return
  72 + */
  73 + @Bean
  74 + RedisMessageListenerContainer container(RedisConnectionFactory connectionFactory) {
  75 +
  76 + RedisMessageListenerContainer container = new RedisMessageListenerContainer();
  77 + container.setConnectionFactory(connectionFactory);
  78 + container.addMessageListener(redisGPSMsgListener, new PatternTopic(VideoManagerConstants.VM_MSG_GPS));
  79 + container.addMessageListener(redisAlarmMsgListener, new PatternTopic(VideoManagerConstants.VM_MSG_SUBSCRIBE_ALARM_RECEIVE));
  80 + container.addMessageListener(redisStreamMsgListener, new PatternTopic(VideoManagerConstants.WVP_MSG_STREAM_CHANGE_PREFIX + "PUSH"));
  81 + container.addMessageListener(redisGbPlayMsgListener, new PatternTopic(RedisGbPlayMsgListener.WVP_PUSH_STREAM_KEY));
  82 + container.addMessageListener(redisPushStreamStatusMsgListener, new PatternTopic(VideoManagerConstants.VM_MSG_PUSH_STREAM_STATUS_CHANGE));
  83 + container.addMessageListener(redisPushStreamListMsgListener, new PatternTopic(VideoManagerConstants.VM_MSG_PUSH_STREAM_LIST_CHANGE));
  84 + return container;
  85 + }
  86 +
  87 +}
... ...
src/main/java/com/genersoft/iot/vmp/conf/security/WebSecurityConfig.java
... ... @@ -91,6 +91,7 @@ public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
91 91 .antMatchers("/webjars/**")
92 92 .antMatchers("/swagger-resources/**")
93 93 .antMatchers("/v3/api-docs/**")
  94 + .antMatchers("/favicon.ico")
94 95 .antMatchers("/js/**");
95 96 List<String> interfaceAuthenticationExcludes = userSetting.getInterfaceAuthenticationExcludes();
96 97 for (String interfaceAuthenticationExclude : interfaceAuthenticationExcludes) {
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/bean/Device.java
1 1 package com.genersoft.iot.vmp.gb28181.bean;
2 2  
3 3  
  4 +import io.swagger.v3.oas.annotations.media.Schema;
  5 +
4 6 /**
5 7 * 国标设备/平台
6 8 * @author lin
7 9 */
  10 +@Schema(description = "国标设备/平台")
8 11 public class Device {
9 12  
10 13 /**
11   - * 设备Id
  14 + * 设备国标编号
12 15 */
  16 + @Schema(description = "设备国标编号")
13 17 private String deviceId;
14 18  
15 19 /**
16 20 * 设备名
17 21 */
  22 + @Schema(description = "名称")
18 23 private String name;
19 24  
20 25 /**
21 26 * 生产厂商
22 27 */
  28 + @Schema(description = "生产厂商")
23 29 private String manufacturer;
24 30  
25 31 /**
26 32 * 型号
27 33 */
  34 + @Schema(description = "型号")
28 35 private String model;
29 36  
30 37 /**
31 38 * 固件版本
32 39 */
  40 + @Schema(description = "固件版本")
33 41 private String firmware;
34 42  
35 43 /**
36 44 * 传输协议
37 45 * UDP/TCP
38 46 */
  47 + @Schema(description = "传输协议(UDP/TCP)")
39 48 private String transport;
40 49  
41 50 /**
... ... @@ -44,103 +53,123 @@ public class Device {
44 53 * TCP-ACTIVE:tcp主动模式
45 54 * TCP-PASSIVE:tcp被动模式
46 55 */
  56 + @Schema(description = "数据流传输模式")
47 57 private String streamMode;
48 58  
49 59 /**
50 60 * wan地址_ip
51 61 */
  62 + @Schema(description = "IP")
52 63 private String ip;
53 64  
54 65 /**
55 66 * wan地址_port
56 67 */
  68 + @Schema(description = "端口")
57 69 private int port;
58 70  
59 71 /**
60 72 * wan地址
61 73 */
  74 + @Schema(description = "wan地址")
62 75 private String hostAddress;
63 76  
64 77 /**
65 78 * 在线
66 79 */
  80 + @Schema(description = "是否在线,1为在线,0为离线")
67 81 private int online;
68 82  
69 83  
70 84 /**
71 85 * 注册时间
72 86 */
  87 + @Schema(description = "注册时间")
73 88 private String registerTime;
74 89  
75 90  
76 91 /**
77 92 * 心跳时间
78 93 */
  94 + @Schema(description = "心跳时间")
79 95 private String keepaliveTime;
80 96  
81 97 /**
82 98 * 通道个数
83 99 */
  100 + @Schema(description = "通道个数")
84 101 private int channelCount;
85 102  
86 103 /**
87 104 * 注册有效期
88 105 */
  106 + @Schema(description = "注册有效期")
89 107 private int expires;
90 108  
91 109 /**
92 110 * 创建时间
93 111 */
  112 + @Schema(description = "创建时间")
94 113 private String createTime;
95 114  
96 115 /**
97 116 * 更新时间
98 117 */
  118 + @Schema(description = "更新时间")
99 119 private String updateTime;
100 120  
101 121 /**
102 122 * 设备使用的媒体id, 默认为null
103 123 */
  124 + @Schema(description = "设备使用的媒体id, 默认为null")
104 125 private String mediaServerId;
105 126  
106 127 /**
107 128 * 字符集, 支持 UTF-8 与 GB2312
108 129 */
  130 + @Schema(description = "符集, 支持 UTF-8 与 GB2312")
109 131 private String charset ;
110 132  
111 133 /**
112 134 * 目录订阅周期,0为不订阅
113 135 */
  136 + @Schema(description = "目录订阅周期,0为不订阅")
114 137 private int subscribeCycleForCatalog;
115 138  
116 139 /**
117 140 * 移动设备位置订阅周期,0为不订阅
118 141 */
  142 + @Schema(description = "移动设备位置订阅周期,0为不订阅")
119 143 private int subscribeCycleForMobilePosition;
120 144  
121 145 /**
122 146 * 移动设备位置信息上报时间间隔,单位:秒,默认值5
123 147 */
  148 + @Schema(description = "移动设备位置信息上报时间间隔,单位:秒,默认值5")
124 149 private int mobilePositionSubmissionInterval = 5;
125 150  
126 151 /**
127 152 * 报警订阅周期,0为不订阅
128 153 */
  154 + @Schema(description = "报警心跳时间订阅周期,0为不订阅")
129 155 private int subscribeCycleForAlarm;
130 156  
131 157 /**
132 158 * 是否开启ssrc校验,默认关闭,开启可以防止串流
133 159 */
  160 + @Schema(description = "是否开启ssrc校验,默认关闭,开启可以防止串流")
134 161 private boolean ssrcCheck = true;
135 162  
136 163 /**
137   - * 地理坐标系, 目前支持 WGS84,GCJ02 TODO CGCS2000
  164 + * 地理坐标系, 目前支持 WGS84,GCJ02
138 165 */
  166 + @Schema(description = "地理坐标系, 目前支持 WGS84,GCJ02")
139 167 private String geoCoordSys;
140 168  
141 169 /**
142 170 * 树类型 国标规定了两种树的展现方式 行政区划:CivilCode 和业务分组:BusinessGroup
143 171 */
  172 + @Schema(description = "树类型 国标规定了两种树的展现方式 行政区划:CivilCode 和业务分组:BusinessGroup")
144 173 private String treeType;
145 174  
146 175  
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/bean/DeviceAlarm.java
1 1 package com.genersoft.iot.vmp.gb28181.bean;
2 2  
  3 +import io.swagger.v3.oas.annotations.media.Schema;
3 4  
  5 +/**
  6 + * @author lin
  7 + */
  8 +@Schema(description = "报警信息")
4 9 public class DeviceAlarm {
5 10  
6 11 /**
7 12 * 数据库id
8 13 */
  14 + @Schema(description = "数据库id")
9 15 private String id;
10 16  
11 17 /**
12 18 * 设备Id
13 19 */
  20 + @Schema(description = "设备的国标编号")
14 21 private String deviceId;
15 22  
16 23 /**
17 24 * 通道Id
18 25 */
  26 + @Schema(description = "通道的国标编号")
19 27 private String channelId;
20 28  
21 29 /**
22   - * 报警级别, 1为一级警情, 2为二级警情, 3为三级警情, 4为四级 警情-
  30 + * 报警级别, 1为一级警情, 2为二级警情, 3为三级警情, 4为四级警情
23 31 */
  32 + @Schema(description = "报警级别, 1为一级警情, 2为二级警情, 3为三级警情, 4为四级警情")
24 33 private String alarmPriority;
25 34  
26 35 /**
27 36 * 报警方式 , 1为电话报警, 2为设备报警, 3为短信报警, 4为 GPS报警, 5为视频报警, 6为设备故障报警,
28 37 * 7其他报警;可以为直接组合如12为电话报警或 设备报警-
29 38 */
  39 + @Schema(description = "报警方式 , 1为电话报警, 2为设备报警, 3为短信报警, 4为 GPS报警, 5为视频报警, 6为设备故障报警,\n" +
  40 + "\t * 7其他报警;可以为直接组合如12为电话报警或设备报警")
30 41 private String alarmMethod;
31 42  
32 43 /**
33 44 * 报警时间
34 45 */
  46 + @Schema(description = "报警时间")
35 47 private String alarmTime;
36 48  
37 49 /**
38 50 * 报警内容描述
39 51 */
  52 + @Schema(description = "报警内容描述")
40 53 private String alarmDescription;
41 54  
42 55 /**
43 56 * 经度
44 57 */
  58 + @Schema(description = "经度")
45 59 private double longitude;
46 60  
47 61 /**
48 62 * 纬度
49 63 */
  64 + @Schema(description = "纬度")
50 65 private double latitude;
51 66  
52 67 /**
... ... @@ -75,8 +90,10 @@ public class DeviceAlarm {
75 90 * 1-存储设备磁盘故障报警;
76 91 * 2-存储设备风扇故障报警。
77 92 */
  93 + @Schema(description = "报警类型")
78 94 private String alarmType;
79 95  
  96 + @Schema(description = "创建时间")
80 97 private String createTime;
81 98  
82 99  
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/bean/DeviceChannel.java
1 1 package com.genersoft.iot.vmp.gb28181.bean;
2 2  
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +
  5 +@Schema(description = "通道信息")
3 6 public class DeviceChannel {
4 7  
5 8  
6 9 /**
7 10 * 数据库自增ID
8 11 */
  12 + @Schema(description = "数据库自增ID")
9 13 private int id;
10 14  
11 15 /**
12   - * 通道id
  16 + * 通道国标编号
13 17 */
  18 + @Schema(description = "通道国标编号")
14 19 private String channelId;
15 20  
16 21 /**
17   - * 设备id
  22 + * 设备国标编号
18 23 */
  24 + @Schema(description = "设备国标编号")
19 25 private String deviceId;
20 26  
21 27 /**
22 28 * 通道名
23 29 */
  30 + @Schema(description = "名称")
24 31 private String name;
25 32  
26 33 /**
27 34 * 生产厂商
28 35 */
  36 + @Schema(description = "生产厂商")
29 37 private String manufacture;
30 38  
31 39 /**
32 40 * 型号
33 41 */
  42 + @Schema(description = "型号")
34 43 private String model;
35 44  
36 45 /**
37 46 * 设备归属
38 47 */
  48 + @Schema(description = "设备归属")
39 49 private String owner;
40 50  
41 51 /**
42 52 * 行政区域
43 53 */
  54 + @Schema(description = "行政区域")
44 55 private String civilCode;
45 56  
46 57 /**
47 58 * 警区
48 59 */
  60 + @Schema(description = "警区")
49 61 private String block;
50 62  
51 63 /**
52 64 * 安装地址
53 65 */
  66 + @Schema(description = "安装地址")
54 67 private String address;
55 68  
56 69 /**
57 70 * 是否有子设备 1有, 0没有
58 71 */
  72 + @Schema(description = "是否有子设备 1有, 0没有")
59 73 private int parental;
60 74  
61 75 /**
62 76 * 父级id
63 77 */
  78 + @Schema(description = "父级id")
64 79 private String parentId;
65 80  
66 81 /**
67 82 * 信令安全模式 缺省为0; 0:不采用; 2: S/MIME签名方式; 3: S/ MIME加密签名同时采用方式; 4:数字摘要方式
68 83 */
  84 + @Schema(description = "信令安全模式 缺省为0; 0:不采用; 2: S/MIME签名方式; 3: S/ MIME加密签名同时采用方式; 4:数字摘要方式")
69 85 private int safetyWay;
70 86  
71 87 /**
72 88 * 注册方式 缺省为1;1:符合IETFRFC3261标准的认证注册模 式; 2:基于口令的双向认证注册模式; 3:基于数字证书的双向认证注册模式
73 89 */
  90 + @Schema(description = "注册方式 缺省为1;1:符合IETFRFC3261标准的认证注册模 式; 2:基于口令的双向认证注册模式; 3:基于数字证书的双向认证注册模式")
74 91 private int registerWay;
75 92  
76 93 /**
77 94 * 证书序列号
78 95 */
  96 + @Schema(description = "证书序列号")
79 97 private String certNum;
80 98  
81 99 /**
82 100 * 证书有效标识 缺省为0;证书有效标识:0:无效1: 有效
83 101 */
  102 + @Schema(description = "证书有效标识 缺省为0;证书有效标识:0:无效1: 有效")
84 103 private int certifiable;
85 104  
86 105 /**
87 106 * 证书无效原因码
88 107 */
  108 + @Schema(description = "证书无效原因码")
89 109 private int errCode;
90 110  
91 111 /**
92 112 * 证书终止有效期
93 113 */
  114 + @Schema(description = "证书终止有效期")
94 115 private String endTime;
95 116  
96 117 /**
97 118 * 保密属性 缺省为0; 0:不涉密, 1:涉密
98 119 */
  120 + @Schema(description = "保密属性 缺省为0; 0:不涉密, 1:涉密")
99 121 private String secrecy;
100 122  
101 123 /**
102 124 * IP地址
103 125 */
  126 + @Schema(description = "IP地址")
104 127 private String ipAddress;
105 128  
106 129 /**
107 130 * 端口号
108 131 */
  132 + @Schema(description = "端口号")
109 133 private int port;
110 134  
111 135 /**
112 136 * 密码
113 137 */
  138 + @Schema(description = "密码")
114 139 private String password;
115 140  
116 141 /**
117 142 * 云台类型
118 143 */
  144 + @Schema(description = "云台类型")
119 145 private int PTZType;
120 146  
121 147 /**
122 148 * 云台类型描述字符串
123 149 */
  150 + @Schema(description = "云台类型描述字符串")
124 151 private String PTZTypeText;
125 152  
126 153 /**
127 154 * 创建时间
128 155 */
  156 + @Schema(description = "创建时间")
129 157 private String createTime;
130 158  
131 159 /**
132 160 * 更新时间
133 161 */
  162 + @Schema(description = "更新时间")
134 163 private String updateTime;
135 164  
136 165 /**
... ... @@ -142,66 +171,79 @@ public class DeviceChannel {
142 171 * <Status>OFF</Status>
143 172 * 遇到过NVR下的IPC下发信令可以推流, 但是 Status 响应 OFF
144 173 */
  174 + @Schema(description = "在线/离线, 1在线,0离线")
145 175 private int status;
146 176  
147 177 /**
148 178 * 经度
149 179 */
  180 + @Schema(description = "经度")
150 181 private double longitude;
151 182  
152 183 /**
153 184 * 纬度
154 185 */
  186 + @Schema(description = "纬度")
155 187 private double latitude;
156 188  
157 189 /**
158 190 * 经度 GCJ02
159 191 */
  192 + @Schema(description = "GCJ02坐标系经度")
160 193 private double longitudeGcj02;
161 194  
162 195 /**
163 196 * 纬度 GCJ02
164 197 */
  198 + @Schema(description = "GCJ02坐标系纬度")
165 199 private double latitudeGcj02;
166 200  
167 201 /**
168 202 * 经度 WGS84
169 203 */
  204 + @Schema(description = "WGS84坐标系经度")
170 205 private double longitudeWgs84;
171 206  
172 207 /**
173 208 * 纬度 WGS84
174 209 */
  210 + @Schema(description = "WGS84坐标系纬度")
175 211 private double latitudeWgs84;
176 212  
177 213 /**
178 214 * 子设备数
179 215 */
  216 + @Schema(description = "子设备数")
180 217 private int subCount;
181 218  
182 219 /**
183 220 * 流唯一编号,存在表示正在直播
184 221 */
  222 + @Schema(description = "流唯一编号,存在表示正在直播")
185 223 private String streamId;
186 224  
187 225 /**
188 226 * 是否含有音频
189 227 */
  228 + @Schema(description = "是否含有音频")
190 229 private boolean hasAudio;
191 230  
192 231 /**
193 232 * 标记通道的类型,0->国标通道 1->直播流通道 2->业务分组/虚拟组织/行政区划
194 233 */
  234 + @Schema(description = "标记通道的类型,0->国标通道 1->直播流通道 2->业务分组/虚拟组织/行政区划")
195 235 private int channelType;
196 236  
197 237 /**
198 238 * 业务分组
199 239 */
  240 + @Schema(description = "业务分组")
200 241 private String businessGroupId;
201 242  
202 243 /**
203 244 * GPS的更新时间
204 245 */
  246 + @Schema(description = "GPS的更新时间")
205 247 private String gpsTime;
206 248  
207 249 public int getId() {
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/bean/GbStream.java
1 1 package com.genersoft.iot.vmp.gb28181.bean;
2 2  
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +
3 5 /**
4 6 * 直播流关联国标上级平台
  7 + * @author lin
5 8 */
  9 +@Schema(description = "直播流关联国标上级平台")
6 10 public class GbStream extends PlatformGbStream{
7 11  
  12 + @Schema(description = "ID")
8 13 private Integer gbStreamId;
  14 + @Schema(description = "应用名")
9 15 private String app;
  16 + @Schema(description = "流ID")
10 17 private String stream;
  18 + @Schema(description = "国标ID")
11 19 private String gbId;
  20 + @Schema(description = "名称")
12 21 private String name;
  22 + @Schema(description = "流媒体ID")
13 23 private String mediaServerId;
  24 + @Schema(description = "经度")
14 25 private double longitude;
  26 + @Schema(description = "纬度")
15 27 private double latitude;
  28 + @Schema(description = "流类型(拉流/推流)")
16 29 private String streamType;
  30 + @Schema(description = "状态")
17 31 private boolean status;
18 32  
  33 + @Schema(description = "创建时间")
19 34 public String createTime;
20 35  
21 36 @Override
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/bean/ParentPlatform.java
1 1 package com.genersoft.iot.vmp.gb28181.bean;
2 2  
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +
  5 +/**
  6 + * @author lin
  7 + */
  8 +@Schema(description = "平台信息")
3 9 public class ParentPlatform {
4 10  
5 11 /**
6 12 * id
7 13 */
  14 + @Schema(description = "ID(数据库中)")
8 15 private Integer id;
9 16  
10 17 /**
11 18 * 是否启用
12 19 */
  20 + @Schema(description = "是否启用")
13 21 private boolean enable;
14 22  
15 23 /**
16 24 * 名称
17 25 */
  26 + @Schema(description = "名称")
18 27 private String name;
19 28  
20 29 /**
21 30 * SIP服务国标编码
22 31 */
  32 + @Schema(description = "SIP服务国标编码")
23 33 private String serverGBId;
24 34  
25 35 /**
26 36 * SIP服务国标域
27 37 */
  38 + @Schema(description = "SIP服务国标域")
28 39 private String serverGBDomain;
29 40  
30 41 /**
31 42 * SIP服务IP
32 43 */
  44 + @Schema(description = "SIP服务IP")
33 45 private String serverIP;
34 46  
35 47 /**
36 48 * SIP服务端口
37 49 */
  50 + @Schema(description = "SIP服务端口")
38 51 private int serverPort;
39 52  
40 53 /**
41 54 * 设备国标编号
42 55 */
  56 + @Schema(description = "11111")
43 57 private String deviceGBId;
44 58  
45 59 /**
46 60 * 设备ip
47 61 */
  62 + @Schema(description = "设备ip")
48 63 private String deviceIp;
49 64  
50 65 /**
51 66 * 设备端口
52 67 */
  68 + @Schema(description = "设备端口")
53 69 private String devicePort;
54 70  
55 71 /**
56 72 * SIP认证用户名(默认使用设备国标编号)
57 73 */
  74 + @Schema(description = "SIP认证用户名(默认使用设备国标编号)")
58 75 private String username;
59 76  
60 77 /**
61 78 * SIP认证密码
62 79 */
  80 + @Schema(description = "SIP认证密码")
63 81 private String password;
64 82  
65 83 /**
66 84 * 注册周期 (秒)
67 85 */
  86 + @Schema(description = "注册周期 (秒)")
68 87 private String expires;
69 88  
70 89 /**
71 90 * 心跳周期(秒)
72 91 */
  92 + @Schema(description = "心跳周期(秒)")
73 93 private String keepTimeout;
74 94  
75 95 /**
76 96 * 传输协议
77 97 * UDP/TCP
78 98 */
  99 + @Schema(description = "传输协议")
79 100 private String transport;
80 101  
81 102 /**
82 103 * 字符集
83 104 */
  105 + @Schema(description = "字符集")
84 106 private String characterSet;
85 107  
86 108 /**
87 109 * 允许云台控制
88 110 */
  111 + @Schema(description = "允许云台控制")
89 112 private boolean ptz;
90 113  
91 114 /**
92 115 * RTCP流保活
93 116 * TODO 预留, 暂不实现
94 117 */
  118 + @Schema(description = "RTCP流保活")
95 119 private boolean rtcp;
96 120  
97 121 /**
98 122 * 在线状态
99 123 */
  124 + @Schema(description = "在线状态")
100 125 private boolean status;
101 126  
102 127 /**
103 128 * 在线状态
104 129 */
  130 + @Schema(description = "在线状态")
105 131 private int channelCount;
106 132  
107 133 /**
108 134 * 默认目录Id,自动添加的通道多放在这个目录下
109 135 */
  136 + @Schema(description = "默认目录Id,自动添加的通道多放在这个目录下")
110 137 private String catalogId;
111 138  
112 139 /**
113 140 * 已被订阅目录信息
114 141 */
  142 + @Schema(description = "已被订阅目录信息")
115 143 private boolean catalogSubscribe;
116 144  
117 145 /**
118 146 * 已被订阅报警信息
119 147 */
  148 + @Schema(description = "已被订阅报警信息")
120 149 private boolean alarmSubscribe;
121 150  
122 151 /**
123 152 * 已被订阅移动位置信息
124 153 */
  154 + @Schema(description = "已被订阅移动位置信息")
125 155 private boolean mobilePositionSubscribe;
126 156  
127 157 /**
128 158 * 点播未推流的设备时是否使用redis通知拉起
129 159 */
  160 + @Schema(description = "点播未推流的设备时是否使用redis通知拉起")
130 161 private boolean startOfflinePush;
131 162  
132 163 /**
133 164 * 目录分组-每次向上级发送通道信息时单个包携带的通道数量,取值1,2,4,8
134 165 */
  166 + @Schema(description = "目录分组-每次向上级发送通道信息时单个包携带的通道数量,取值1,2,4,8")
135 167 private int catalogGroup;
136 168  
137 169 /**
138 170 * 行政区划
139 171 */
  172 + @Schema(description = "行政区划")
140 173 private String administrativeDivision;
141 174  
142 175 /**
143 176 * 更新时间
144 177 */
  178 + @Schema(description = "更新时间")
145 179 private String updateTime;
146 180  
147 181 /**
148 182 * 创建时间
149 183 */
  184 + @Schema(description = "创建时间")
150 185 private String createTime;
151 186  
152 187 /**
153 188 * 树类型 国标规定了两种树的展现方式 行政区划 CivilCode 和业务分组:BusinessGroup
154 189 */
  190 + @Schema(description = "树类型 国标规定了两种树的展现方式 行政区划 CivilCode 和业务分组:BusinessGrou")
155 191 private String treeType;
156 192  
157 193 public Integer getId() {
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/bean/PlatformCatalog.java
1 1 package com.genersoft.iot.vmp.gb28181.bean;
2 2  
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +
3 5 /**
4 6 * 国标级联-目录
5 7 * @author lin
6 8 */
  9 +@Schema(description = "目录信息")
7 10 public class PlatformCatalog {
  11 + @Schema(description = "ID")
8 12 private String id;
  13 +
  14 + @Schema(description = "名称")
9 15 private String name;
  16 +
  17 + @Schema(description = "平台ID")
10 18 private String platformId;
  19 +
  20 + @Schema(description = "父级目录ID")
11 21 private String parentId;
12 22  
  23 + @Schema(description = "行政区划")
13 24 private String civilCode;
14 25  
  26 + @Schema(description = "目录分组")
15 27 private String businessGroupId;
16 28  
17 29 /**
18 30 * 子节点数
19 31 */
  32 + @Schema(description = "子节点数")
20 33 private int childrenCount;
21 34  
22 35 /**
23 36 * 0 目录, 1 国标通道, 2 直播流
24 37 */
  38 + @Schema(description = "类型:0 目录, 1 国标通道, 2 直播流")
25 39 private int type;
26 40  
27 41 public String getId() {
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/bean/PlatformGbStream.java
1 1 package com.genersoft.iot.vmp.gb28181.bean;
2 2  
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +
3 5 public class PlatformGbStream {
  6 +
  7 + @Schema(description = "ID")
4 8 private Integer gbStreamId;
  9 +
  10 + @Schema(description = "平台ID")
5 11 private String platformId;
  12 +
  13 + @Schema(description = "目录ID")
6 14 private String catalogId;
7 15  
8 16 public Integer getGbStreamId() {
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/bean/SyncStatus.java
1 1 package com.genersoft.iot.vmp.gb28181.bean;
2 2  
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +
3 5 /**
4 6 * 摄像机同步状态
5 7 * @author lin
6 8 */
  9 +@Schema(description = "摄像机同步状态")
7 10 public class SyncStatus {
  11 + @Schema(description = "总数")
8 12 private int total;
  13 + @Schema(description = "当前更新多少")
9 14 private int current;
  15 + @Schema(description = "错误描述")
10 16 private String errorMsg;
11   -
  17 + @Schema(description = "是否同步中")
12 18 private boolean syncIng;
13 19  
14 20 public int getTotal() {
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/event/EventPublisher.java
... ... @@ -37,9 +37,9 @@ public class EventPublisher {
37 37 * @param platformGbId
38 38 */
39 39 public void platformKeepaliveExpireEventPublish(String platformGbId){
40   - PlatformKeepaliveExpireEvent platformNotRegisterEvent = new PlatformKeepaliveExpireEvent(this);
41   - platformNotRegisterEvent.setPlatformGbID(platformGbId);
42   - applicationEventPublisher.publishEvent(platformNotRegisterEvent);
  40 + PlatformKeepaliveExpireEvent platformKeepaliveExpireEvent = new PlatformKeepaliveExpireEvent(this);
  41 + platformKeepaliveExpireEvent.setPlatformGbID(platformGbId);
  42 + applicationEventPublisher.publishEvent(platformKeepaliveExpireEvent);
43 43 }
44 44  
45 45 /**
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/event/offline/KeepaliveTimeoutListenerForPlatform.java deleted 100644 → 0
1   -package com.genersoft.iot.vmp.gb28181.event.offline;
2   -
3   -import com.genersoft.iot.vmp.conf.RedisKeyExpirationEventMessageListener;
4   -import com.genersoft.iot.vmp.conf.UserSetting;
5   -import com.genersoft.iot.vmp.gb28181.bean.Device;
6   -import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform;
7   -import com.genersoft.iot.vmp.gb28181.event.SipSubscribe;
8   -import com.genersoft.iot.vmp.storager.IVideoManagerStorage;
9   -import org.slf4j.Logger;
10   -import org.slf4j.LoggerFactory;
11   -import org.springframework.beans.factory.annotation.Autowired;
12   -import org.springframework.data.redis.connection.Message;
13   -import org.springframework.data.redis.listener.RedisMessageListenerContainer;
14   -import org.springframework.stereotype.Component;
15   -
16   -import com.genersoft.iot.vmp.common.VideoManagerConstants;
17   -import com.genersoft.iot.vmp.gb28181.event.EventPublisher;
18   -
19   -/**
20   - * 设备心跳超时监听,借助redis过期特性,进行监听,监听到说明设备心跳超时,发送离线事件
21   - * @author swwheihei
22   - */
23   -@Component
24   -public class KeepaliveTimeoutListenerForPlatform extends RedisKeyExpirationEventMessageListener {
25   -
26   - private Logger logger = LoggerFactory.getLogger(KeepaliveTimeoutListenerForPlatform.class);
27   -
28   - @Autowired
29   - private EventPublisher publisher;
30   -
31   - @Autowired
32   - private UserSetting userSetting;
33   -
34   - @Autowired
35   - private SipSubscribe sipSubscribe;
36   -
37   - @Autowired
38   - private IVideoManagerStorage storager;
39   -
40   - public KeepaliveTimeoutListenerForPlatform(RedisMessageListenerContainer listenerContainer, UserSetting userSetting) {
41   - super(listenerContainer, userSetting);
42   - }
43   -
44   -
45   - /**
46   - * 监听失效的key
47   - * @param message
48   - * @param pattern
49   - */
50   - @Override
51   - public void onMessage(Message message, byte[] pattern) {
52   - // 获取失效的key
53   - String expiredKey = message.toString();
54   - // 平台心跳到期,需要重发, 判断是否已经多次未收到心跳回复, 多次未收到,则重新发起注册, 注册尝试多次未得到回复,则认为平台离线
55   - String PLATFORM_KEEPLIVEKEY_PREFIX = VideoManagerConstants.PLATFORM_KEEPALIVE_PREFIX + userSetting.getServerId() + "_";
56   - String PLATFORM_REGISTER_PREFIX = VideoManagerConstants.PLATFORM_REGISTER_PREFIX + userSetting.getServerId() + "_";
57   - String REGISTER_INFO_PREFIX = VideoManagerConstants.PLATFORM_REGISTER_INFO_PREFIX + userSetting.getServerId() + "_";
58   - if (expiredKey.startsWith(PLATFORM_KEEPLIVEKEY_PREFIX)) {
59   - String platformGbId = expiredKey.substring(PLATFORM_KEEPLIVEKEY_PREFIX.length());
60   - ParentPlatform platform = storager.queryParentPlatByServerGBId(platformGbId);
61   - if (platform != null) {
62   - publisher.platformKeepaliveExpireEventPublish(platformGbId);
63   - }
64   - }else if (expiredKey.startsWith(PLATFORM_REGISTER_PREFIX)) {
65   - String platformGbId = expiredKey.substring(PLATFORM_REGISTER_PREFIX.length(),expiredKey.length());
66   - ParentPlatform platform = storager.queryParentPlatByServerGBId(platformGbId);
67   - if (platform != null) {
68   - publisher.platformRegisterCycleEventPublish(platformGbId);
69   - }
70   - }else if (expiredKey.startsWith(REGISTER_INFO_PREFIX)) {
71   - String callId = expiredKey.substring(REGISTER_INFO_PREFIX.length());
72   - if (sipSubscribe.getErrorSubscribe(callId) != null) {
73   - SipSubscribe.EventResult eventResult = new SipSubscribe.EventResult();
74   - eventResult.callId = callId;
75   - eventResult.msg = "注册超时";
76   - eventResult.type = "register timeout";
77   - sipSubscribe.getErrorSubscribe(callId).response(eventResult);
78   - }
79   - }
80   - }
81   -}
src/main/java/com/genersoft/iot/vmp/gb28181/event/subscribe/catalog/CatalogEventLister.java
... ... @@ -15,6 +15,7 @@ import org.slf4j.LoggerFactory;
15 15 import org.springframework.beans.factory.annotation.Autowired;
16 16 import org.springframework.context.ApplicationListener;
17 17 import org.springframework.stereotype.Component;
  18 +import org.springframework.util.ObjectUtils;
18 19 import org.springframework.util.StringUtils;
19 20  
20 21 import java.util.*;
... ... @@ -58,7 +59,7 @@ public class CatalogEventLister implements ApplicationListener&lt;CatalogEvent&gt; {
58 59 ParentPlatform parentPlatform = null;
59 60  
60 61 Map<String, List<ParentPlatform>> parentPlatformMap = new HashMap<>();
61   - if (!StringUtils.isEmpty(event.getPlatformId())) {
  62 + if (!ObjectUtils.isEmpty(event.getPlatformId())) {
62 63 subscribe = subscribeHolder.getCatalogSubscribe(event.getPlatformId());
63 64 if (subscribe == null) {
64 65 return;
... ... @@ -81,7 +82,7 @@ public class CatalogEventLister implements ApplicationListener&lt;CatalogEvent&gt; {
81 82 }else if (event.getGbStreams() != null) {
82 83 if (platforms.size() > 0) {
83 84 for (GbStream gbStream : event.getGbStreams()) {
84   - if (gbStream == null || StringUtils.isEmpty(gbStream.getGbId())) {
  85 + if (gbStream == null || ObjectUtils.isEmpty(gbStream.getGbId())) {
85 86 continue;
86 87 }
87 88 List<ParentPlatform> parentPlatformsForGB = storager.queryPlatFormListForStreamWithGBId(gbStream.getApp(),gbStream.getStream(), platforms);
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/session/RecordDataCatch.java
... ... @@ -60,16 +60,12 @@ public class RecordDataCatch {
60 60 // 处理录像数据, 返回给前端
61 61 String msgKey = DeferredResultHolder.CALLBACK_CMD_RECORDINFO + recordInfo.getDeviceId() + recordInfo.getSn();
62 62  
63   - WVPResult<RecordInfo> wvpResult = new WVPResult<>();
64   - wvpResult.setCode(0);
65   - wvpResult.setMsg("success");
66 63 // 对数据进行排序
67 64 Collections.sort(recordInfo.getRecordList());
68   - wvpResult.setData(recordInfo);
69 65  
70 66 RequestMessage msg = new RequestMessage();
71 67 msg.setKey(msgKey);
72   - msg.setData(wvpResult);
  68 + msg.setData(recordInfo);
73 69 deferredResultHolder.invokeAllResult(msg);
74 70 data.remove(key);
75 71 }
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/session/SsrcConfig.java
1 1 package com.genersoft.iot.vmp.gb28181.session;
2 2  
3 3 import com.genersoft.iot.vmp.utils.ConfigConst;
  4 +import io.swagger.v3.oas.annotations.media.Schema;
4 5  
5 6 import java.util.ArrayList;
6 7 import java.util.List;
7 8 import java.util.Random;
8 9 import java.util.Set;
9 10  
  11 +@Schema(description = "ssrc信息")
10 12 public class SsrcConfig {
11 13  
12 14 /**
13 15 * zlm流媒体服务器Id
14 16 */
  17 + @Schema(description = "流媒体服务器Id")
15 18 private String mediaServerId;
16 19  
  20 + @Schema(description = "SSRC前缀")
17 21 private String ssrcPrefix;
  22 +
18 23 /**
19 24 * zlm流媒体服务器已用会话句柄
20 25 */
  26 + @Schema(description = "zlm流媒体服务器已用会话句柄")
21 27 private List<String> isUsed;
  28 +
22 29 /**
23 30 * zlm流媒体服务器可用会话句柄
24 31 */
  32 + @Schema(description = "zlm流媒体服务器可用会话句柄")
25 33 private List<String> notUsed;
26 34  
27 35 public SsrcConfig() {
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/session/VideoStreamSessionManager.java
... ... @@ -14,6 +14,7 @@ import com.genersoft.iot.vmp.utils.redis.RedisUtil;
14 14 import gov.nist.javax.sip.stack.SIPDialog;
15 15 import org.springframework.beans.factory.annotation.Autowired;
16 16 import org.springframework.stereotype.Component;
  17 +import org.springframework.util.ObjectUtils;
17 18 import org.springframework.util.StringUtils;
18 19  
19 20 /**
... ... @@ -25,9 +26,6 @@ import org.springframework.util.StringUtils;
25 26 public class VideoStreamSessionManager {
26 27  
27 28 @Autowired
28   - private RedisUtil redisUtil;
29   -
30   - @Autowired
31 29 private UserSetting userSetting;
32 30  
33 31 public enum SessionType {
... ... @@ -58,9 +56,9 @@ public class VideoStreamSessionManager {
58 56 ssrcTransaction.setMediaServerId(mediaServerId);
59 57 ssrcTransaction.setType(type);
60 58  
61   - redisUtil.set(VideoManagerConstants.MEDIA_TRANSACTION_USED_PREFIX + userSetting.getServerId()
  59 + RedisUtil.set(VideoManagerConstants.MEDIA_TRANSACTION_USED_PREFIX + userSetting.getServerId()
62 60 + "_" + deviceId + "_" + channelId + "_" + callId + "_" + stream, ssrcTransaction);
63   - redisUtil.set(VideoManagerConstants.MEDIA_TRANSACTION_USED_PREFIX + userSetting.getServerId()
  61 + RedisUtil.set(VideoManagerConstants.MEDIA_TRANSACTION_USED_PREFIX + userSetting.getServerId()
64 62 + "_" + deviceId + "_" + channelId + "_" + callId + "_" + stream, ssrcTransaction);
65 63 }
66 64  
... ... @@ -70,7 +68,7 @@ public class VideoStreamSessionManager {
70 68 byte[] dialogByteArray = SerializeUtils.serialize(dialog);
71 69 ssrcTransaction.setDialog(dialogByteArray);
72 70 }
73   - redisUtil.set(VideoManagerConstants.MEDIA_TRANSACTION_USED_PREFIX + userSetting.getServerId()
  71 + RedisUtil.set(VideoManagerConstants.MEDIA_TRANSACTION_USED_PREFIX + userSetting.getServerId()
74 72 + "_" + deviceId + "_" + channelId + "_" + ssrcTransaction.getCallId() + "_"
75 73 + ssrcTransaction.getStream(), ssrcTransaction);
76 74 }
... ... @@ -113,47 +111,47 @@ public class VideoStreamSessionManager {
113 111  
114 112 public SsrcTransaction getSsrcTransaction(String deviceId, String channelId, String callId, String stream){
115 113  
116   - if (StringUtils.isEmpty(deviceId)) {
  114 + if (ObjectUtils.isEmpty(deviceId)) {
117 115 deviceId ="*";
118 116 }
119   - if (StringUtils.isEmpty(channelId)) {
  117 + if (ObjectUtils.isEmpty(channelId)) {
120 118 channelId ="*";
121 119 }
122   - if (StringUtils.isEmpty(callId)) {
  120 + if (ObjectUtils.isEmpty(callId)) {
123 121 callId ="*";
124 122 }
125   - if (StringUtils.isEmpty(stream)) {
  123 + if (ObjectUtils.isEmpty(stream)) {
126 124 stream ="*";
127 125 }
128 126 String key = VideoManagerConstants.MEDIA_TRANSACTION_USED_PREFIX + userSetting.getServerId() + "_" + deviceId + "_" + channelId + "_" + callId+ "_" + stream;
129   - List<Object> scanResult = redisUtil.scan(key);
  127 + List<Object> scanResult = RedisUtil.scan(key);
130 128 if (scanResult.size() == 0) {
131 129 return null;
132 130 }
133   - return (SsrcTransaction)redisUtil.get((String) scanResult.get(0));
  131 + return (SsrcTransaction)RedisUtil.get((String) scanResult.get(0));
134 132 }
135 133  
136 134 public List<SsrcTransaction> getSsrcTransactionForAll(String deviceId, String channelId, String callId, String stream){
137   - if (StringUtils.isEmpty(deviceId)) {
  135 + if (ObjectUtils.isEmpty(deviceId)) {
138 136 deviceId ="*";
139 137 }
140   - if (StringUtils.isEmpty(channelId)) {
  138 + if (ObjectUtils.isEmpty(channelId)) {
141 139 channelId ="*";
142 140 }
143   - if (StringUtils.isEmpty(callId)) {
  141 + if (ObjectUtils.isEmpty(callId)) {
144 142 callId ="*";
145 143 }
146   - if (StringUtils.isEmpty(stream)) {
  144 + if (ObjectUtils.isEmpty(stream)) {
147 145 stream ="*";
148 146 }
149 147 String key = VideoManagerConstants.MEDIA_TRANSACTION_USED_PREFIX + userSetting.getServerId() + "_" + deviceId + "_" + channelId + "_" + callId+ "_" + stream;
150   - List<Object> scanResult = redisUtil.scan(key);
  148 + List<Object> scanResult = RedisUtil.scan(key);
151 149 if (scanResult.size() == 0) {
152 150 return null;
153 151 }
154 152 List<SsrcTransaction> result = new ArrayList<>();
155 153 for (Object keyObj : scanResult) {
156   - result.add((SsrcTransaction)redisUtil.get((String) keyObj));
  154 + result.add((SsrcTransaction)RedisUtil.get((String) keyObj));
157 155 }
158 156 return result;
159 157 }
... ... @@ -179,17 +177,17 @@ public class VideoStreamSessionManager {
179 177 if (ssrcTransaction == null) {
180 178 return;
181 179 }
182   - redisUtil.del(VideoManagerConstants.MEDIA_TRANSACTION_USED_PREFIX + userSetting.getServerId() + "_"
  180 + RedisUtil.del(VideoManagerConstants.MEDIA_TRANSACTION_USED_PREFIX + userSetting.getServerId() + "_"
183 181 + deviceId + "_" + channelId + "_" + ssrcTransaction.getCallId() + "_" + ssrcTransaction.getStream());
184 182 }
185 183  
186 184  
187 185 public List<SsrcTransaction> getAllSsrc() {
188   - List<Object> ssrcTransactionKeys = redisUtil.scan(String.format("%s_*_*_*_*", VideoManagerConstants.MEDIA_TRANSACTION_USED_PREFIX+ userSetting.getServerId()));
  186 + List<Object> ssrcTransactionKeys = RedisUtil.scan(String.format("%s_*_*_*_*", VideoManagerConstants.MEDIA_TRANSACTION_USED_PREFIX+ userSetting.getServerId()));
189 187 List<SsrcTransaction> result= new ArrayList<>();
190 188 for (int i = 0; i < ssrcTransactionKeys.size(); i++) {
191 189 String key = (String)ssrcTransactionKeys.get(i);
192   - SsrcTransaction ssrcTransaction = (SsrcTransaction)redisUtil.get(key);
  190 + SsrcTransaction ssrcTransaction = (SsrcTransaction)RedisUtil.get(key);
193 191 result.add(ssrcTransaction);
194 192 }
195 193 return result;
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPProcessorObserver.java
... ... @@ -3,8 +3,6 @@ package com.genersoft.iot.vmp.gb28181.transmit;
3 3 import com.genersoft.iot.vmp.gb28181.event.EventPublisher;
4 4 import com.genersoft.iot.vmp.gb28181.event.SipSubscribe;
5 5 import com.genersoft.iot.vmp.gb28181.transmit.event.request.ISIPRequestProcessor;
6   -import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.RegisterRequestProcessor;
7   -import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.notify.cmd.KeepaliveNotifyMessageHandler;
8 6 import com.genersoft.iot.vmp.gb28181.transmit.event.response.ISIPResponseProcessor;
9 7 import com.genersoft.iot.vmp.gb28181.transmit.event.timeout.ITimeoutProcessor;
10 8 import org.slf4j.Logger;
... ... @@ -14,13 +12,10 @@ import org.springframework.scheduling.annotation.Async;
14 12 import org.springframework.stereotype.Component;
15 13  
16 14 import javax.sip.*;
17   -import javax.sip.address.SipURI;
18   -import javax.sip.address.URI;
19 15 import javax.sip.header.*;
20 16 import javax.sip.message.Request;
21 17 import javax.sip.message.Response;
22 18 import java.util.Map;
23   -import java.util.Objects;
24 19 import java.util.concurrent.ConcurrentHashMap;
25 20  
26 21 /**
... ... @@ -43,9 +38,6 @@ public class SIPProcessorObserver implements ISIPProcessorObserver {
43 38 @Autowired
44 39 private EventPublisher eventPublisher;
45 40  
46   -
47   -
48   -
49 41 /**
50 42 * 添加 request订阅
51 43 * @param method 方法名
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/callback/DeferredResultHolder.java
... ... @@ -96,7 +96,7 @@ public class DeferredResultHolder {
96 96 if (result == null) {
97 97 return;
98 98 }
99   - result.setResult(new ResponseEntity<>(msg.getData(),HttpStatus.OK));
  99 + result.setResult(msg.getData());
100 100 deferredResultMap.remove(msg.getId());
101 101 if (deferredResultMap.size() == 0) {
102 102 map.remove(msg.getKey());
... ... @@ -118,9 +118,8 @@ public class DeferredResultHolder {
118 118 if (result == null) {
119 119 return;
120 120 }
121   - result.setResult(ResponseEntity.ok().body(msg.getData()));
  121 + result.setResult(msg.getData());
122 122 }
123 123 map.remove(msg.getKey());
124   -
125 124 }
126 125 }
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java
... ... @@ -32,6 +32,7 @@ import org.springframework.beans.factory.annotation.Autowired;
32 32 import org.springframework.beans.factory.annotation.Qualifier;
33 33 import org.springframework.context.annotation.DependsOn;
34 34 import org.springframework.stereotype.Component;
  35 +import org.springframework.util.ObjectUtils;
35 36 import org.springframework.util.StringUtils;
36 37  
37 38 import javax.sip.*;
... ... @@ -819,7 +820,7 @@ public class SIPCommander implements ISIPCommander {
819 820 cmdXml.append("<Control>\r\n");
820 821 cmdXml.append("<CmdType>DeviceControl</CmdType>\r\n");
821 822 cmdXml.append("<SN>" + (int)((Math.random()*9+1)*100000) + "</SN>\r\n");
822   - if (StringUtils.isEmpty(channelId)) {
  823 + if (ObjectUtils.isEmpty(channelId)) {
823 824 cmdXml.append("<DeviceID>" + device.getDeviceId() + "</DeviceID>\r\n");
824 825 } else {
825 826 cmdXml.append("<DeviceID>" + channelId + "</DeviceID>\r\n");
... ... @@ -922,16 +923,16 @@ public class SIPCommander implements ISIPCommander {
922 923 cmdXml.append("<SN>" + (int)((Math.random()*9+1)*100000) + "</SN>\r\n");
923 924 cmdXml.append("<DeviceID>" + device.getDeviceId() + "</DeviceID>\r\n");
924 925 cmdXml.append("<AlarmCmd>ResetAlarm</AlarmCmd>\r\n");
925   - if (!StringUtils.isEmpty(alarmMethod) || !StringUtils.isEmpty(alarmType)) {
  926 + if (!ObjectUtils.isEmpty(alarmMethod) || !ObjectUtils.isEmpty(alarmType)) {
926 927 cmdXml.append("<Info>\r\n");
927 928 }
928   - if (!StringUtils.isEmpty(alarmMethod)) {
  929 + if (!ObjectUtils.isEmpty(alarmMethod)) {
929 930 cmdXml.append("<AlarmMethod>" + alarmMethod + "</AlarmMethod>\r\n");
930 931 }
931   - if (!StringUtils.isEmpty(alarmType)) {
  932 + if (!ObjectUtils.isEmpty(alarmType)) {
932 933 cmdXml.append("<AlarmType>" + alarmType + "</AlarmType>\r\n");
933 934 }
934   - if (!StringUtils.isEmpty(alarmMethod) || !StringUtils.isEmpty(alarmType)) {
  935 + if (!ObjectUtils.isEmpty(alarmMethod) || !ObjectUtils.isEmpty(alarmType)) {
935 936 cmdXml.append("</Info>\r\n");
936 937 }
937 938 cmdXml.append("</Control>\r\n");
... ... @@ -965,7 +966,7 @@ public class SIPCommander implements ISIPCommander {
965 966 cmdXml.append("<Control>\r\n");
966 967 cmdXml.append("<CmdType>DeviceControl</CmdType>\r\n");
967 968 cmdXml.append("<SN>" + (int)((Math.random()*9+1)*100000) + "</SN>\r\n");
968   - if (StringUtils.isEmpty(channelId)) {
  969 + if (ObjectUtils.isEmpty(channelId)) {
969 970 cmdXml.append("<DeviceID>" + device.getDeviceId() + "</DeviceID>\r\n");
970 971 } else {
971 972 cmdXml.append("<DeviceID>" + channelId + "</DeviceID>\r\n");
... ... @@ -1004,7 +1005,7 @@ public class SIPCommander implements ISIPCommander {
1004 1005 cmdXml.append("<Control>\r\n");
1005 1006 cmdXml.append("<CmdType>DeviceControl</CmdType>\r\n");
1006 1007 cmdXml.append("<SN>" + (int)((Math.random()*9+1)*100000) + "</SN>\r\n");
1007   - if (StringUtils.isEmpty(channelId)) {
  1008 + if (ObjectUtils.isEmpty(channelId)) {
1008 1009 cmdXml.append("<DeviceID>" + device.getDeviceId() + "</DeviceID>\r\n");
1009 1010 } else {
1010 1011 cmdXml.append("<DeviceID>" + channelId + "</DeviceID>\r\n");
... ... @@ -1073,13 +1074,13 @@ public class SIPCommander implements ISIPCommander {
1073 1074 cmdXml.append("<Control>\r\n");
1074 1075 cmdXml.append("<CmdType>DeviceConfig</CmdType>\r\n");
1075 1076 cmdXml.append("<SN>" + (int)((Math.random()*9+1)*100000) + "</SN>\r\n");
1076   - if (StringUtils.isEmpty(channelId)) {
  1077 + if (ObjectUtils.isEmpty(channelId)) {
1077 1078 cmdXml.append("<DeviceID>" + device.getDeviceId() + "</DeviceID>\r\n");
1078 1079 } else {
1079 1080 cmdXml.append("<DeviceID>" + channelId + "</DeviceID>\r\n");
1080 1081 }
1081 1082 cmdXml.append("<BasicParam>\r\n");
1082   - if (!StringUtils.isEmpty(name)) {
  1083 + if (!ObjectUtils.isEmpty(name)) {
1083 1084 cmdXml.append("<Name>" + name + "</Name>\r\n");
1084 1085 }
1085 1086 if (NumericUtil.isInteger(expiration)) {
... ... @@ -1289,22 +1290,22 @@ public class SIPCommander implements ISIPCommander {
1289 1290 cmdXml.append("<CmdType>Alarm</CmdType>\r\n");
1290 1291 cmdXml.append("<SN>" + (int)((Math.random()*9+1)*100000) + "</SN>\r\n");
1291 1292 cmdXml.append("<DeviceID>" + device.getDeviceId() + "</DeviceID>\r\n");
1292   - if (!StringUtils.isEmpty(startPriority)) {
  1293 + if (!ObjectUtils.isEmpty(startPriority)) {
1293 1294 cmdXml.append("<StartAlarmPriority>" + startPriority + "</StartAlarmPriority>\r\n");
1294 1295 }
1295   - if (!StringUtils.isEmpty(endPriority)) {
  1296 + if (!ObjectUtils.isEmpty(endPriority)) {
1296 1297 cmdXml.append("<EndAlarmPriority>" + endPriority + "</EndAlarmPriority>\r\n");
1297 1298 }
1298   - if (!StringUtils.isEmpty(alarmMethod)) {
  1299 + if (!ObjectUtils.isEmpty(alarmMethod)) {
1299 1300 cmdXml.append("<AlarmMethod>" + alarmMethod + "</AlarmMethod>\r\n");
1300 1301 }
1301   - if (!StringUtils.isEmpty(alarmType)) {
  1302 + if (!ObjectUtils.isEmpty(alarmType)) {
1302 1303 cmdXml.append("<AlarmType>" + alarmType + "</AlarmType>\r\n");
1303 1304 }
1304   - if (!StringUtils.isEmpty(startTime)) {
  1305 + if (!ObjectUtils.isEmpty(startTime)) {
1305 1306 cmdXml.append("<StartAlarmTime>" + startTime + "</StartAlarmTime>\r\n");
1306 1307 }
1307   - if (!StringUtils.isEmpty(endTime)) {
  1308 + if (!ObjectUtils.isEmpty(endTime)) {
1308 1309 cmdXml.append("<EndAlarmTime>" + endTime + "</EndAlarmTime>\r\n");
1309 1310 }
1310 1311 cmdXml.append("</Query>\r\n");
... ... @@ -1339,7 +1340,7 @@ public class SIPCommander implements ISIPCommander {
1339 1340 cmdXml.append("<Query>\r\n");
1340 1341 cmdXml.append("<CmdType>ConfigDownload</CmdType>\r\n");
1341 1342 cmdXml.append("<SN>" + (int)((Math.random()*9+1)*100000) + "</SN>\r\n");
1342   - if (StringUtils.isEmpty(channelId)) {
  1343 + if (ObjectUtils.isEmpty(channelId)) {
1343 1344 cmdXml.append("<DeviceID>" + device.getDeviceId() + "</DeviceID>\r\n");
1344 1345 } else {
1345 1346 cmdXml.append("<DeviceID>" + channelId + "</DeviceID>\r\n");
... ... @@ -1375,7 +1376,7 @@ public class SIPCommander implements ISIPCommander {
1375 1376 cmdXml.append("<Query>\r\n");
1376 1377 cmdXml.append("<CmdType>PresetQuery</CmdType>\r\n");
1377 1378 cmdXml.append("<SN>" + (int)((Math.random()*9+1)*100000) + "</SN>\r\n");
1378   - if (StringUtils.isEmpty(channelId)) {
  1379 + if (ObjectUtils.isEmpty(channelId)) {
1379 1380 cmdXml.append("<DeviceID>" + device.getDeviceId() + "</DeviceID>\r\n");
1380 1381 } else {
1381 1382 cmdXml.append("<DeviceID>" + channelId + "</DeviceID>\r\n");
... ... @@ -1506,22 +1507,22 @@ public class SIPCommander implements ISIPCommander {
1506 1507 cmdXml.append("<CmdType>Alarm</CmdType>\r\n");
1507 1508 cmdXml.append("<SN>" + (int)((Math.random()*9+1)*100000) + "</SN>\r\n");
1508 1509 cmdXml.append("<DeviceID>" + device.getDeviceId() + "</DeviceID>\r\n");
1509   - if (!StringUtils.isEmpty(startPriority)) {
  1510 + if (!ObjectUtils.isEmpty(startPriority)) {
1510 1511 cmdXml.append("<StartAlarmPriority>" + startPriority + "</StartAlarmPriority>\r\n");
1511 1512 }
1512   - if (!StringUtils.isEmpty(endPriority)) {
  1513 + if (!ObjectUtils.isEmpty(endPriority)) {
1513 1514 cmdXml.append("<EndAlarmPriority>" + endPriority + "</EndAlarmPriority>\r\n");
1514 1515 }
1515   - if (!StringUtils.isEmpty(alarmMethod)) {
  1516 + if (!ObjectUtils.isEmpty(alarmMethod)) {
1516 1517 cmdXml.append("<AlarmMethod>" + alarmMethod + "</AlarmMethod>\r\n");
1517 1518 }
1518   - if (!StringUtils.isEmpty(alarmType)) {
  1519 + if (!ObjectUtils.isEmpty(alarmType)) {
1519 1520 cmdXml.append("<AlarmType>" + alarmType + "</AlarmType>\r\n");
1520 1521 }
1521   - if (!StringUtils.isEmpty(startTime)) {
  1522 + if (!ObjectUtils.isEmpty(startTime)) {
1522 1523 cmdXml.append("<StartAlarmTime>" + startTime + "</StartAlarmTime>\r\n");
1523 1524 }
1524   - if (!StringUtils.isEmpty(endTime)) {
  1525 + if (!ObjectUtils.isEmpty(endTime)) {
1525 1526 cmdXml.append("<EndAlarmTime>" + endTime + "</EndAlarmTime>\r\n");
1526 1527 }
1527 1528 cmdXml.append("</Query>\r\n");
... ... @@ -1602,7 +1603,7 @@ public class SIPCommander implements ISIPCommander {
1602 1603 dragXml.append("<Control>\r\n");
1603 1604 dragXml.append("<CmdType>DeviceControl</CmdType>\r\n");
1604 1605 dragXml.append("<SN>" + (int) ((Math.random() * 9 + 1) * 100000) + "</SN>\r\n");
1605   - if (StringUtils.isEmpty(channelId)) {
  1606 + if (ObjectUtils.isEmpty(channelId)) {
1606 1607 dragXml.append("<DeviceID>" + device.getDeviceId() + "</DeviceID>\r\n");
1607 1608 } else {
1608 1609 dragXml.append("<DeviceID>" + channelId + "</DeviceID>\r\n");
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommanderFroPlatform.java
... ... @@ -23,6 +23,7 @@ import org.springframework.context.annotation.DependsOn;
23 23 import org.springframework.context.annotation.Lazy;
24 24 import org.springframework.lang.Nullable;
25 25 import org.springframework.stereotype.Component;
  26 +import org.springframework.util.ObjectUtils;
26 27 import org.springframework.util.StringUtils;
27 28  
28 29  
... ... @@ -728,10 +729,10 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform {
728 729 recordXml.append("<EndTime>" + DateUtil.yyyy_MM_dd_HH_mm_ssToISO8601(recordItem.getEndTime()) + "</EndTime>\r\n");
729 730 recordXml.append("<Secrecy>" + recordItem.getSecrecy() + "</Secrecy>\r\n");
730 731 recordXml.append("<Type>" + recordItem.getType() + "</Type>\r\n");
731   - if (!StringUtils.isEmpty(recordItem.getFileSize())) {
  732 + if (!ObjectUtils.isEmpty(recordItem.getFileSize())) {
732 733 recordXml.append("<FileSize>" + recordItem.getFileSize() + "</FileSize>\r\n");
733 734 }
734   - if (!StringUtils.isEmpty(recordItem.getFilePath())) {
  735 + if (!ObjectUtils.isEmpty(recordItem.getFilePath())) {
735 736 recordXml.append("<FilePath>" + recordItem.getFilePath() + "</FilePath>\r\n");
736 737 }
737 738 }
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/SIPRequestProcessorParent.java
... ... @@ -231,6 +231,9 @@ public abstract class SIPRequestProcessorParent {
231 231 byte destBye = (byte) despChar;
232 232 List<Byte> result = new ArrayList<>();
233 233 byte[] rawContent = request.getRawContent();
  234 + if (rawContent == null) {
  235 + return null;
  236 + }
234 237 for (int i = 0; i < rawContent.length; i++) {
235 238 if (rawContent[i] == destBye) {
236 239 boolean resul = false;
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/NotifyRequestProcessor.java
... ... @@ -29,6 +29,7 @@ import org.springframework.beans.factory.annotation.Autowired;
29 29 import org.springframework.beans.factory.annotation.Qualifier;
30 30 import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
31 31 import org.springframework.stereotype.Component;
  32 +import org.springframework.util.ObjectUtils;
32 33 import org.springframework.util.StringUtils;
33 34  
34 35 import javax.sip.InvalidArgumentException;
... ... @@ -41,7 +42,7 @@ import java.util.Iterator;
41 42 import java.util.concurrent.ConcurrentLinkedQueue;
42 43  
43 44 /**
44   - * SIP命令类型: NOTIFY请求
  45 + * SIP命令类型: NOTIFY请求,这是作为上级发送订阅请求后,设备才会响应的
45 46 */
46 47 @Component
47 48 public class NotifyRequestProcessor extends SIPRequestProcessorParent implements InitializingBean, ISIPRequestProcessor {
... ... @@ -101,6 +102,10 @@ public class NotifyRequestProcessor extends SIPRequestProcessorParent implements
101 102 try {
102 103 HandlerCatchData take = taskQueue.poll();
103 104 Element rootElement = getRootElement(take.getEvt());
  105 + if (rootElement == null) {
  106 + logger.error("处理NOTIFY消息时未获取到消息体,{}", take.getEvt().getRequest());
  107 + continue;
  108 + }
104 109 String cmd = XmlUtil.getText(rootElement, "CmdType");
105 110  
106 111 if (CmdType.CATALOG.equals(cmd)) {
... ... @@ -116,14 +121,17 @@ public class NotifyRequestProcessor extends SIPRequestProcessorParent implements
116 121 logger.info("接收到消息:" + cmd);
117 122 }
118 123 } catch (DocumentException e) {
119   - throw new RuntimeException(e);
  124 + logger.error("处理NOTIFY消息时错误", e);
  125 + } finally {
  126 + taskQueueHandlerRun = false;
120 127 }
121 128 }
122   - taskQueueHandlerRun = false;
123 129 });
124 130 }
125 131 } catch (SipException | InvalidArgumentException | ParseException e) {
126 132 e.printStackTrace();
  133 + } finally {
  134 + taskQueueHandlerRun = false;
127 135 }
128 136 }
129 137  
... ... @@ -139,6 +147,10 @@ public class NotifyRequestProcessor extends SIPRequestProcessorParent implements
139 147  
140 148 // 回复 200 OK
141 149 Element rootElement = getRootElement(evt);
  150 + if (rootElement == null) {
  151 + logger.error("处理MobilePosition移动位置Notify时未获取到消息体,{}", evt.getRequest());
  152 + return;
  153 + }
142 154  
143 155 MobilePosition mobilePosition = new MobilePosition();
144 156 mobilePosition.setCreateTime(DateUtil.getNow());
... ... @@ -146,7 +158,7 @@ public class NotifyRequestProcessor extends SIPRequestProcessorParent implements
146 158 String channelId = deviceIdElement.getTextTrim().toString();
147 159 Device device = redisCatchStorage.getDevice(deviceId);
148 160 if (device != null) {
149   - if (!StringUtils.isEmpty(device.getName())) {
  161 + if (!ObjectUtils.isEmpty(device.getName())) {
150 162 mobilePosition.setDeviceName(device.getName());
151 163 }
152 164 }
... ... @@ -195,6 +207,7 @@ public class NotifyRequestProcessor extends SIPRequestProcessorParent implements
195 207 }
196 208  
197 209 storager.updateChannelPosition(deviceChannel);
  210 +
198 211 // 发送redis消息。 通知位置信息的变化
199 212 JSONObject jsonObject = new JSONObject();
200 213 jsonObject.put("time", time);
... ... @@ -225,6 +238,10 @@ public class NotifyRequestProcessor extends SIPRequestProcessorParent implements
225 238 String deviceId = SipUtils.getUserIdFromFromHeader(fromHeader);
226 239  
227 240 Element rootElement = getRootElement(evt);
  241 + if (rootElement == null) {
  242 + logger.error("处理alarm设备报警Notify时未获取到消息体{}", evt.getRequest());
  243 + return;
  244 + }
228 245 Element deviceIdElement = rootElement.element("DeviceID");
229 246 String channelId = deviceIdElement.getText().toString();
230 247  
... ... @@ -234,6 +251,10 @@ public class NotifyRequestProcessor extends SIPRequestProcessorParent implements
234 251 return;
235 252 }
236 253 rootElement = getRootElement(evt, device.getCharset());
  254 + if (rootElement == null) {
  255 + logger.warn("[ NotifyAlarm ] content cannot be null, {}", evt.getRequest());
  256 + return;
  257 + }
237 258 DeviceAlarm deviceAlarm = new DeviceAlarm();
238 259 deviceAlarm.setDeviceId(deviceId);
239 260 deviceAlarm.setAlarmPriority(XmlUtil.getText(rootElement, "AlarmPriority"));
... ... @@ -269,8 +290,6 @@ public class NotifyRequestProcessor extends SIPRequestProcessorParent implements
269 290 mobilePosition.setLatitude(deviceAlarm.getLatitude());
270 291 mobilePosition.setReportSource("GPS Alarm");
271 292  
272   -
273   -
274 293 // 更新device channel 的经纬度
275 294 DeviceChannel deviceChannel = new DeviceChannel();
276 295 deviceChannel.setDeviceId(device.getDeviceId());
... ... @@ -291,6 +310,18 @@ public class NotifyRequestProcessor extends SIPRequestProcessorParent implements
291 310 }
292 311  
293 312 storager.updateChannelPosition(deviceChannel);
  313 + // 发送redis消息。 通知位置信息的变化
  314 + JSONObject jsonObject = new JSONObject();
  315 + jsonObject.put("time", mobilePosition.getTime());
  316 + jsonObject.put("serial", deviceChannel.getDeviceId());
  317 + jsonObject.put("code", deviceChannel.getChannelId());
  318 + jsonObject.put("longitude", mobilePosition.getLongitude());
  319 + jsonObject.put("latitude", mobilePosition.getLatitude());
  320 + jsonObject.put("altitude", mobilePosition.getAltitude());
  321 + jsonObject.put("direction", mobilePosition.getDirection());
  322 + jsonObject.put("speed", mobilePosition.getSpeed());
  323 + redisCatchStorage.sendMobilePositionMsg(jsonObject);
  324 +
294 325 }
295 326 // TODO: 需要实现存储报警信息、报警分类
296 327  
... ... @@ -319,6 +350,10 @@ public class NotifyRequestProcessor extends SIPRequestProcessorParent implements
319 350 return;
320 351 }
321 352 Element rootElement = getRootElement(evt, device.getCharset());
  353 + if (rootElement == null) {
  354 + logger.warn("[ 收到目录订阅 ] content cannot be null, {}", evt.getRequest());
  355 + return;
  356 + }
322 357 Element deviceListElement = rootElement.element("DeviceList");
323 358 if (deviceListElement == null) {
324 359 return;
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/RegisterRequestProcessor.java
... ... @@ -19,6 +19,7 @@ import org.slf4j.LoggerFactory;
19 19 import org.springframework.beans.factory.InitializingBean;
20 20 import org.springframework.beans.factory.annotation.Autowired;
21 21 import org.springframework.stereotype.Component;
  22 +import org.springframework.util.ObjectUtils;
22 23 import org.springframework.util.StringUtils;
23 24  
24 25 import javax.sip.InvalidArgumentException;
... ... @@ -81,7 +82,7 @@ public class RegisterRequestProcessor extends SIPRequestProcessorParent implemen
81 82 String deviceId = uri.getUser();
82 83  
83 84 AuthorizationHeader authHead = (AuthorizationHeader) request.getHeader(AuthorizationHeader.NAME);
84   - if (authHead == null && !StringUtils.isEmpty(sipConfig.getPassword())) {
  85 + if (authHead == null && !ObjectUtils.isEmpty(sipConfig.getPassword())) {
85 86 logger.info("[注册请求] 未携带授权头 回复401: {}", requestAddress);
86 87 response = getMessageFactory().createResponse(Response.UNAUTHORIZED, request);
87 88 new DigestServerAuthenticationHelper().generateChallenge(getHeaderFactory(), response, sipConfig.getDomain());
... ... @@ -90,7 +91,7 @@ public class RegisterRequestProcessor extends SIPRequestProcessorParent implemen
90 91 }
91 92  
92 93 // 校验密码是否正确
93   - passwordCorrect = StringUtils.isEmpty(sipConfig.getPassword()) ||
  94 + passwordCorrect = ObjectUtils.isEmpty(sipConfig.getPassword()) ||
94 95 new DigestServerAuthenticationHelper().doAuthenticatePlainTextPassword(request, sipConfig.getPassword());
95 96  
96 97 if (!passwordCorrect) {
... ... @@ -132,7 +133,7 @@ public class RegisterRequestProcessor extends SIPRequestProcessorParent implemen
132 133 String received = viaHeader.getReceived();
133 134 int rPort = viaHeader.getRPort();
134 135 // 解析本地地址替代
135   - if (StringUtils.isEmpty(received) || rPort == -1) {
  136 + if (ObjectUtils.isEmpty(received) || rPort == -1) {
136 137 received = viaHeader.getHost();
137 138 rPort = viaHeader.getPort();
138 139 }
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/SubscribeRequestProcessor.java
... ... @@ -84,6 +84,10 @@ public class SubscribeRequestProcessor extends SIPRequestProcessorParent impleme
84 84 Request request = evt.getRequest();
85 85 try {
86 86 Element rootElement = getRootElement(evt);
  87 + if (rootElement == null) {
  88 + logger.error("处理SUBSCRIBE请求 未获取到消息体{}", evt.getRequest());
  89 + return;
  90 + }
87 91 String cmd = XmlUtil.getText(rootElement, "CmdType");
88 92 if (CmdType.MOBILE_POSITION.equals(cmd)) {
89 93 processNotifyMobilePosition(evt, rootElement);
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/MessageRequestProcessor.java
... ... @@ -108,6 +108,11 @@ public class MessageRequestProcessor extends SIPRequestProcessorParent implement
108 108 Element rootElement = null;
109 109 try {
110 110 rootElement = getRootElement(evt);
  111 + if (rootElement == null) {
  112 + logger.error("处理MESSAGE请求 未获取到消息体{}", evt.getRequest());
  113 + responseAck(evt, Response.BAD_REQUEST, "content is null");
  114 + return;
  115 + }
111 116 } catch (DocumentException e) {
112 117 logger.warn("解析XML消息内容异常", e);
113 118 // 不存在则回复404
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/control/cmd/DeviceControlQueryMessageHandler.java
... ... @@ -17,6 +17,7 @@ import org.slf4j.LoggerFactory;
17 17 import org.springframework.beans.factory.InitializingBean;
18 18 import org.springframework.beans.factory.annotation.Autowired;
19 19 import org.springframework.stereotype.Component;
  20 +import org.springframework.util.ObjectUtils;
20 21 import org.springframework.util.StringUtils;
21 22  
22 23 import javax.sip.*;
... ... @@ -64,7 +65,7 @@ public class DeviceControlQueryMessageHandler extends SIPRequestProcessorParent
64 65 String targetGBId = ((SipURI) ((HeaderAddress) evt.getRequest().getHeader(ToHeader.NAME)).getAddress().getURI()).getUser();
65 66 String channelId = getText(rootElement, "DeviceID");
66 67 // 远程启动功能
67   - if (!StringUtils.isEmpty(getText(rootElement, "TeleBoot"))) {
  68 + if (!ObjectUtils.isEmpty(getText(rootElement, "TeleBoot"))) {
68 69 if (parentPlatform.getServerGBId().equals(targetGBId)) {
69 70 // 远程启动本平台:需要在重新启动程序后先对SipStack解绑
70 71 logger.info("执行远程启动本平台命令");
... ... @@ -101,7 +102,7 @@ public class DeviceControlQueryMessageHandler extends SIPRequestProcessorParent
101 102 }
102 103 }
103 104 // 云台/前端控制命令
104   - if (!StringUtils.isEmpty(getText(rootElement,"PTZCmd")) && !parentPlatform.getServerGBId().equals(targetGBId)) {
  105 + if (!ObjectUtils.isEmpty(getText(rootElement,"PTZCmd")) && !parentPlatform.getServerGBId().equals(targetGBId)) {
105 106 String cmdString = getText(rootElement,"PTZCmd");
106 107 Device deviceForPlatform = storager.queryVideoDeviceByPlatformIdAndChannelId(parentPlatform.getServerGBId(), channelId);
107 108 if (deviceForPlatform == null) {
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/NotifyMessageHandler.java
... ... @@ -7,7 +7,7 @@ import org.springframework.beans.factory.annotation.Autowired;
7 7 import org.springframework.stereotype.Component;
8 8  
9 9 /**
10   - * 命令类型: 通知命令
  10 + * 命令类型: 通知命令, 参看 A.2.5 通知命令
11 11 * 命令类型: 状态信息(心跳)报送, 报警通知, 媒体通知, 移动设备位置数据,语音广播通知(TODO), 设备预置位(TODO)
12 12 * @author lin
13 13 */
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/AlarmNotifyMessageHandler.java
1 1 package com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.notify.cmd;
2 2  
  3 +import com.alibaba.fastjson.JSONObject;
3 4 import com.genersoft.iot.vmp.conf.SipConfig;
4 5 import com.genersoft.iot.vmp.conf.UserSetting;
5 6 import com.genersoft.iot.vmp.gb28181.bean.*;
... ... @@ -21,6 +22,7 @@ import org.slf4j.LoggerFactory;
21 22 import org.springframework.beans.factory.InitializingBean;
22 23 import org.springframework.beans.factory.annotation.Autowired;
23 24 import org.springframework.stereotype.Component;
  25 +import org.springframework.util.ObjectUtils;
24 26 import org.springframework.util.StringUtils;
25 27  
26 28 import javax.sip.InvalidArgumentException;
... ... @@ -32,6 +34,9 @@ import java.text.ParseException;
32 34  
33 35 import static com.genersoft.iot.vmp.gb28181.utils.XmlUtil.*;
34 36  
  37 +/**
  38 + * 报警事件的处理,参考:9.4
  39 + */
35 40 @Component
36 41 public class AlarmNotifyMessageHandler extends SIPRequestProcessorParent implements InitializingBean, IMessageHandler {
37 42  
... ... @@ -73,12 +78,8 @@ public class AlarmNotifyMessageHandler extends SIPRequestProcessorParent impleme
73 78 // 回复200 OK
74 79 try {
75 80 responseAck(evt, Response.OK);
76   - } catch (SipException e) {
77   - throw new RuntimeException(e);
78   - } catch (InvalidArgumentException e) {
79   - throw new RuntimeException(e);
80   - } catch (ParseException e) {
81   - throw new RuntimeException(e);
  81 + } catch (SipException | InvalidArgumentException | ParseException e) {
  82 + logger.error("[收到报警通知], 回复200OK失败", e);
82 83 }
83 84  
84 85 Element deviceIdElement = rootElement.element("DeviceID");
... ... @@ -114,7 +115,7 @@ public class AlarmNotifyMessageHandler extends SIPRequestProcessorParent impleme
114 115 deviceAlarm.setLatitude(0.00);
115 116 }
116 117  
117   - if (!StringUtils.isEmpty(deviceAlarm.getAlarmMethod())) {
  118 + if (!ObjectUtils.isEmpty(deviceAlarm.getAlarmMethod())) {
118 119 if ( deviceAlarm.getAlarmMethod().contains(DeviceAlarmMethod.GPS.getVal() + "")) {
119 120 MobilePosition mobilePosition = new MobilePosition();
120 121 mobilePosition.setCreateTime(DateUtil.getNow());
... ... @@ -124,7 +125,6 @@ public class AlarmNotifyMessageHandler extends SIPRequestProcessorParent impleme
124 125 mobilePosition.setLatitude(deviceAlarm.getLatitude());
125 126 mobilePosition.setReportSource("GPS Alarm");
126 127  
127   -
128 128 // 更新device channel 的经纬度
129 129 DeviceChannel deviceChannel = new DeviceChannel();
130 130 deviceChannel.setDeviceId(device.getDeviceId());
... ... @@ -144,9 +144,21 @@ public class AlarmNotifyMessageHandler extends SIPRequestProcessorParent impleme
144 144 storager.insertMobilePosition(mobilePosition);
145 145 }
146 146 storager.updateChannelPosition(deviceChannel);
  147 +
  148 + // 发送redis消息。 通知位置信息的变化
  149 + JSONObject jsonObject = new JSONObject();
  150 + jsonObject.put("time", mobilePosition.getTime());
  151 + jsonObject.put("serial", deviceChannel.getDeviceId());
  152 + jsonObject.put("code", deviceChannel.getChannelId());
  153 + jsonObject.put("longitude", mobilePosition.getLongitude());
  154 + jsonObject.put("latitude", mobilePosition.getLatitude());
  155 + jsonObject.put("altitude", mobilePosition.getAltitude());
  156 + jsonObject.put("direction", mobilePosition.getDirection());
  157 + jsonObject.put("speed", mobilePosition.getSpeed());
  158 + redisCatchStorage.sendMobilePositionMsg(jsonObject);
147 159 }
148 160 }
149   - if (!StringUtils.isEmpty(deviceAlarm.getDeviceId())) {
  161 + if (!ObjectUtils.isEmpty(deviceAlarm.getDeviceId())) {
150 162 if (deviceAlarm.getAlarmMethod().contains(DeviceAlarmMethod.Video.getVal() + "")) {
151 163 deviceAlarm.setAlarmType(getText(rootElement.element("Info"), "AlarmType"));
152 164 }
... ... @@ -159,7 +171,6 @@ public class AlarmNotifyMessageHandler extends SIPRequestProcessorParent impleme
159 171 alarmChannelMessage.setAlarmDescription(deviceAlarm.getAlarmDescription());
160 172 alarmChannelMessage.setGbId(channelId);
161 173 redisCatchStorage.sendAlarmMsg(alarmChannelMessage);
162   -
163 174 return;
164 175 }
165 176  
... ... @@ -169,7 +180,6 @@ public class AlarmNotifyMessageHandler extends SIPRequestProcessorParent impleme
169 180 deviceAlarmService.add(deviceAlarm);
170 181 }
171 182  
172   -
173 183 if (redisCatchStorage.deviceIsOnline(device.getDeviceId())) {
174 184 publisher.deviceAlarmEventPublish(deviceAlarm);
175 185 }
... ... @@ -222,7 +232,7 @@ public class AlarmNotifyMessageHandler extends SIPRequestProcessorParent impleme
222 232 deviceAlarm.setLatitude(0.00);
223 233 }
224 234  
225   - if (!StringUtils.isEmpty(deviceAlarm.getAlarmMethod())) {
  235 + if (!ObjectUtils.isEmpty(deviceAlarm.getAlarmMethod())) {
226 236  
227 237 if (deviceAlarm.getAlarmMethod().contains(DeviceAlarmMethod.Video.getVal() + "")) {
228 238 deviceAlarm.setAlarmType(getText(rootElement.element("Info"), "AlarmType"));
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/CatalogNotifyMessageHandler.java deleted 100644 → 0
1   -package com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.notify.cmd;
2   -
3   -import com.genersoft.iot.vmp.gb28181.bean.*;
4   -import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder;
5   -import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommanderFroPlatform;
6   -import com.genersoft.iot.vmp.gb28181.transmit.event.request.SIPRequestProcessorParent;
7   -import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.IMessageHandler;
8   -import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.notify.NotifyMessageHandler;
9   -import com.genersoft.iot.vmp.storager.IVideoManagerStorage;
10   -import org.dom4j.Element;
11   -import org.springframework.beans.factory.InitializingBean;
12   -import org.springframework.beans.factory.annotation.Autowired;
13   -import org.springframework.stereotype.Component;
14   -
15   -import javax.sip.InvalidArgumentException;
16   -import javax.sip.RequestEvent;
17   -import javax.sip.SipException;
18   -import javax.sip.header.FromHeader;
19   -import javax.sip.message.Response;
20   -import java.text.ParseException;
21   -import java.util.ArrayList;
22   -import java.util.List;
23   -
24   -@Component
25   -public class CatalogNotifyMessageHandler extends SIPRequestProcessorParent implements InitializingBean, IMessageHandler {
26   -
27   - private final String cmdType = "Catalog";
28   -
29   - @Autowired
30   - private NotifyMessageHandler notifyMessageHandler;
31   -
32   - @Autowired
33   - private IVideoManagerStorage storage;
34   -
35   - @Autowired
36   - private SIPCommanderFroPlatform cmderFroPlatform;
37   -
38   - @Override
39   - public void afterPropertiesSet() throws Exception {
40   - notifyMessageHandler.addHandler(cmdType, this);
41   - }
42   -
43   - @Override
44   - public void handForDevice(RequestEvent evt, Device device, Element element) {
45   -
46   - }
47   -
48   - @Override
49   - public void handForPlatform(RequestEvent evt, ParentPlatform parentPlatform, Element rootElement) {
50   -
51   - String key = DeferredResultHolder.CALLBACK_CMD_CATALOG + parentPlatform.getServerGBId();
52   - FromHeader fromHeader = (FromHeader) evt.getRequest().getHeader(FromHeader.NAME);
53   - try {
54   - // 回复200 OK
55   - responseAck(evt, Response.OK);
56   - Element snElement = rootElement.element("SN");
57   - String sn = snElement.getText();
58   - // 准备回复通道信息
59   - List<DeviceChannelInPlatform> deviceChannels = storage.queryChannelListInParentPlatform(parentPlatform.getServerGBId());
60   - // 查询关联的直播通道
61   - List<DeviceChannel> gbStreams = storage.queryGbStreamListInPlatform(parentPlatform.getServerGBId());
62   - // 回复目录信息
63   - List<DeviceChannel> catalogs = storage.queryCatalogInPlatform(parentPlatform.getServerGBId());
64   -
65   - List<DeviceChannel> allChannels = new ArrayList<>();
66   - if (catalogs.size() > 0) {
67   - allChannels.addAll(catalogs);
68   - }
69   - // 回复级联的通道
70   - if (deviceChannels.size() > 0) {
71   - allChannels.addAll(deviceChannels);
72   - }
73   - // 回复直播的通道
74   - if (gbStreams.size() > 0) {
75   - allChannels.addAll(gbStreams);
76   - }
77   - if (allChannels.size() > 0) {
78   - cmderFroPlatform.catalogQuery(allChannels, parentPlatform, sn, fromHeader.getTag());
79   - }else {
80   - // 回复无通道
81   - cmderFroPlatform.catalogQuery(null, parentPlatform, sn, fromHeader.getTag(), 0);
82   - }
83   - } catch (SipException | InvalidArgumentException | ParseException e) {
84   - e.printStackTrace();
85   - }
86   -
87   - }
88   -}
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/KeepaliveNotifyMessageHandler.java
... ... @@ -16,6 +16,7 @@ import org.slf4j.LoggerFactory;
16 16 import org.springframework.beans.factory.InitializingBean;
17 17 import org.springframework.beans.factory.annotation.Autowired;
18 18 import org.springframework.stereotype.Component;
  19 +import org.springframework.util.ObjectUtils;
19 20 import org.springframework.util.StringUtils;
20 21  
21 22 import javax.sip.InvalidArgumentException;
... ... @@ -25,6 +26,9 @@ import javax.sip.header.ViaHeader;
25 26 import javax.sip.message.Response;
26 27 import java.text.ParseException;
27 28  
  29 +/**
  30 + * 状态信息(心跳)报送
  31 + */
28 32 @Component
29 33 public class KeepaliveNotifyMessageHandler extends SIPRequestProcessorParent implements InitializingBean, IMessageHandler {
30 34  
... ... @@ -55,7 +59,7 @@ public class KeepaliveNotifyMessageHandler extends SIPRequestProcessorParent imp
55 59 String received = viaHeader.getReceived();
56 60 int rPort = viaHeader.getRPort();
57 61 // 解析本地地址替代
58   - if (StringUtils.isEmpty(received) || rPort == -1) {
  62 + if (ObjectUtils.isEmpty(received) || rPort == -1) {
59 63 received = viaHeader.getHost();
60 64 rPort = viaHeader.getPort();
61 65 }
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/MediaStatusNotifyMessageHandler.java
... ... @@ -29,6 +29,9 @@ import java.text.ParseException;
29 29  
30 30 import static com.genersoft.iot.vmp.gb28181.utils.XmlUtil.getText;
31 31  
  32 +/**
  33 + * 媒体通知
  34 + */
32 35 @Component
33 36 public class MediaStatusNotifyMessageHandler extends SIPRequestProcessorParent implements InitializingBean, IMessageHandler {
34 37  
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/MobilePositionNotifyMessageHandler.java
1 1 package com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.notify.cmd;
2 2  
  3 +import com.alibaba.fastjson.JSONObject;
3 4 import com.genersoft.iot.vmp.conf.UserSetting;
4 5 import com.genersoft.iot.vmp.gb28181.bean.*;
5 6 import com.genersoft.iot.vmp.gb28181.transmit.event.request.SIPRequestProcessorParent;
6 7 import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.IMessageHandler;
7 8 import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.notify.NotifyMessageHandler;
8   -import com.genersoft.iot.vmp.gb28181.utils.Coordtransform;
9 9 import com.genersoft.iot.vmp.gb28181.utils.NumericUtil;
10 10 import com.genersoft.iot.vmp.service.IDeviceChannelService;
  11 +import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
11 12 import com.genersoft.iot.vmp.storager.IVideoManagerStorage;
12 13 import com.genersoft.iot.vmp.utils.DateUtil;
13   -import com.genersoft.iot.vmp.utils.GpsUtil;
14 14 import org.dom4j.DocumentException;
15 15 import org.dom4j.Element;
16 16 import org.slf4j.Logger;
... ... @@ -18,6 +18,7 @@ import org.slf4j.LoggerFactory;
18 18 import org.springframework.beans.factory.InitializingBean;
19 19 import org.springframework.beans.factory.annotation.Autowired;
20 20 import org.springframework.stereotype.Component;
  21 +import org.springframework.util.ObjectUtils;
21 22 import org.springframework.util.StringUtils;
22 23  
23 24 import javax.sip.InvalidArgumentException;
... ... @@ -28,6 +29,9 @@ import java.text.ParseException;
28 29  
29 30 import static com.genersoft.iot.vmp.gb28181.utils.XmlUtil.getText;
30 31  
  32 +/**
  33 + * 移动设备位置数据通知,设备主动发起,不需要上级订阅
  34 + */
31 35 @Component
32 36 public class MobilePositionNotifyMessageHandler extends SIPRequestProcessorParent implements InitializingBean, IMessageHandler {
33 37  
... ... @@ -44,6 +48,9 @@ public class MobilePositionNotifyMessageHandler extends SIPRequestProcessorParen
44 48 private IVideoManagerStorage storager;
45 49  
46 50 @Autowired
  51 + private IRedisCatchStorage redisCatchStorage;
  52 +
  53 + @Autowired
47 54 private IDeviceChannelService deviceChannelService;
48 55  
49 56 @Override
... ... @@ -56,10 +63,14 @@ public class MobilePositionNotifyMessageHandler extends SIPRequestProcessorParen
56 63  
57 64 try {
58 65 rootElement = getRootElement(evt, device.getCharset());
59   -
  66 + if (rootElement == null) {
  67 + logger.warn("[ 移动设备位置数据通知 ] content cannot be null, {}", evt.getRequest());
  68 + responseAck(evt, Response.BAD_REQUEST);
  69 + return;
  70 + }
60 71 MobilePosition mobilePosition = new MobilePosition();
61 72 mobilePosition.setCreateTime(DateUtil.getNow());
62   - if (!StringUtils.isEmpty(device.getName())) {
  73 + if (!ObjectUtils.isEmpty(device.getName())) {
63 74 mobilePosition.setDeviceName(device.getName());
64 75 }
65 76 mobilePosition.setDeviceId(device.getDeviceId());
... ... @@ -106,6 +117,19 @@ public class MobilePositionNotifyMessageHandler extends SIPRequestProcessorParen
106 117 storager.updateChannelPosition(deviceChannel);
107 118 //回复 200 OK
108 119 responseAck(evt, Response.OK);
  120 +
  121 + // 发送redis消息。 通知位置信息的变化
  122 + JSONObject jsonObject = new JSONObject();
  123 + jsonObject.put("time", mobilePosition.getTime());
  124 + jsonObject.put("serial", deviceChannel.getDeviceId());
  125 + jsonObject.put("code", deviceChannel.getChannelId());
  126 + jsonObject.put("longitude", mobilePosition.getLongitude());
  127 + jsonObject.put("latitude", mobilePosition.getLatitude());
  128 + jsonObject.put("altitude", mobilePosition.getAltitude());
  129 + jsonObject.put("direction", mobilePosition.getDirection());
  130 + jsonObject.put("speed", mobilePosition.getSpeed());
  131 + redisCatchStorage.sendMobilePositionMsg(jsonObject);
  132 +
109 133 } catch (DocumentException | SipException | InvalidArgumentException | ParseException e) {
110 134 e.printStackTrace();
111 135 }
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/response/cmd/CatalogResponseMessageHandler.java
... ... @@ -35,6 +35,9 @@ import java.util.Iterator;
35 35 import java.util.List;
36 36 import java.util.concurrent.ConcurrentLinkedQueue;
37 37  
  38 +/**
  39 + * 目录查询的回复
  40 + */
38 41 @Component
39 42 public class CatalogResponseMessageHandler extends SIPRequestProcessorParent implements InitializingBean, IMessageHandler {
40 43  
... ... @@ -85,82 +88,88 @@ public class CatalogResponseMessageHandler extends SIPRequestProcessorParent imp
85 88 // 回复200 OK
86 89 try {
87 90 responseAck(evt, Response.OK);
  91 + if (!taskQueueHandlerRun) {
  92 + taskQueueHandlerRun = true;
  93 + taskExecutor.execute(()-> {
  94 + while (!taskQueue.isEmpty()) {
  95 + HandlerCatchData take = taskQueue.poll();
  96 + try {
  97 + Element rootElement = getRootElement(take.getEvt(), take.getDevice().getCharset());
  98 + if (rootElement == null) {
  99 + logger.warn("[ 收到通道 ] content cannot be null, {}", evt.getRequest());
  100 + continue;
  101 + }
  102 + Element deviceListElement = rootElement.element("DeviceList");
  103 + Element sumNumElement = rootElement.element("SumNum");
  104 + Element snElement = rootElement.element("SN");
  105 + if (snElement == null || sumNumElement == null || deviceListElement == null) {
  106 + responseAck(take.getEvt(), Response.BAD_REQUEST, "xml error");
  107 + continue;
  108 + }
  109 + int sumNum = Integer.parseInt(sumNumElement.getText());
  110 +
  111 + if (sumNum == 0) {
  112 + logger.info("[收到通道]设备:{}的: 0个", take.getDevice().getDeviceId());
  113 + // 数据已经完整接收
  114 + storager.cleanChannelsForDevice(take.getDevice().getDeviceId());
  115 + catalogDataCatch.setChannelSyncEnd(take.getDevice().getDeviceId(), null);
  116 + }else {
  117 + Iterator<Element> deviceListIterator = deviceListElement.elementIterator();
  118 + if (deviceListIterator != null) {
  119 + List<DeviceChannel> channelList = new ArrayList<>();
  120 + // 遍历DeviceList
  121 + while (deviceListIterator.hasNext()) {
  122 + Element itemDevice = deviceListIterator.next();
  123 + Element channelDeviceElement = itemDevice.element("DeviceID");
  124 + if (channelDeviceElement == null) {
  125 + continue;
  126 + }
  127 + DeviceChannel deviceChannel = XmlUtil.channelContentHander(itemDevice, device, null);
  128 + deviceChannel.setDeviceId(take.getDevice().getDeviceId());
  129 +
  130 + channelList.add(deviceChannel);
  131 + }
  132 + int sn = Integer.parseInt(snElement.getText());
  133 + catalogDataCatch.put(take.getDevice().getDeviceId(), sn, sumNum, take.getDevice(), channelList);
  134 + logger.info("[收到通道]设备: {} -> {}个,{}/{}", take.getDevice().getDeviceId(), channelList.size(), catalogDataCatch.get(take.getDevice().getDeviceId()) == null ? 0 :catalogDataCatch.get(take.getDevice().getDeviceId()).size(), sumNum);
  135 + if (catalogDataCatch.get(take.getDevice().getDeviceId()).size() == sumNum) {
  136 + // 数据已经完整接收, 此时可能存在某个设备离线变上线的情况,但是考虑到性能,此处不做处理,
  137 + // 目前支持设备通道上线通知时和设备上线时向上级通知
  138 + boolean resetChannelsResult = storager.resetChannels(take.getDevice().getDeviceId(), catalogDataCatch.get(take.getDevice().getDeviceId()));
  139 + if (!resetChannelsResult) {
  140 + String errorMsg = "接收成功,写入失败,共" + sumNum + "条,已接收" + catalogDataCatch.get(take.getDevice().getDeviceId()).size() + "条";
  141 + catalogDataCatch.setChannelSyncEnd(take.getDevice().getDeviceId(), errorMsg);
  142 + }else {
  143 + catalogDataCatch.setChannelSyncEnd(take.getDevice().getDeviceId(), null);
  144 + }
  145 + }
  146 + }
  147 +
  148 + }
  149 + } catch (DocumentException e) {
  150 + e.printStackTrace();
  151 + } catch (InvalidArgumentException e) {
  152 + e.printStackTrace();
  153 + } catch (ParseException e) {
  154 + e.printStackTrace();
  155 + } catch (SipException e) {
  156 + e.printStackTrace();
  157 + } finally {
  158 + taskQueueHandlerRun = false;
  159 + }
  160 + }
  161 + });
  162 + }
88 163 } catch (SipException e) {
89 164 throw new RuntimeException(e);
90 165 } catch (InvalidArgumentException e) {
91 166 throw new RuntimeException(e);
92 167 } catch (ParseException e) {
93 168 throw new RuntimeException(e);
  169 + } finally {
  170 + taskQueueHandlerRun = false;
94 171 }
95   - if (!taskQueueHandlerRun) {
96   - taskQueueHandlerRun = true;
97   - taskExecutor.execute(()-> {
98   - while (!taskQueue.isEmpty()) {
99   - HandlerCatchData take = taskQueue.poll();
100   - String key = DeferredResultHolder.CALLBACK_CMD_CATALOG + take.getDevice().getDeviceId();
101   - Element rootElement = null;
102   - try {
103   - rootElement = getRootElement(take.getEvt(), take.getDevice().getCharset());
104   - Element deviceListElement = rootElement.element("DeviceList");
105   - Element sumNumElement = rootElement.element("SumNum");
106   - Element snElement = rootElement.element("SN");
107   - if (snElement == null || sumNumElement == null || deviceListElement == null) {
108   - responseAck(take.getEvt(), Response.BAD_REQUEST, "xml error");
109   - return;
110   - }
111   - int sumNum = Integer.parseInt(sumNumElement.getText());
112   -
113   - if (sumNum == 0) {
114   - logger.info("[收到通道]设备:{}的: 0个", take.getDevice().getDeviceId());
115   - // 数据已经完整接收
116   - storager.cleanChannelsForDevice(take.getDevice().getDeviceId());
117   - catalogDataCatch.setChannelSyncEnd(take.getDevice().getDeviceId(), null);
118   - }else {
119   - Iterator<Element> deviceListIterator = deviceListElement.elementIterator();
120   - if (deviceListIterator != null) {
121   - List<DeviceChannel> channelList = new ArrayList<>();
122   - // 遍历DeviceList
123   - while (deviceListIterator.hasNext()) {
124   - Element itemDevice = deviceListIterator.next();
125   - Element channelDeviceElement = itemDevice.element("DeviceID");
126   - if (channelDeviceElement == null) {
127   - continue;
128   - }
129   - DeviceChannel deviceChannel = XmlUtil.channelContentHander(itemDevice, device, null);
130   - deviceChannel.setDeviceId(take.getDevice().getDeviceId());
131   -
132   - channelList.add(deviceChannel);
133   - }
134   - int sn = Integer.parseInt(snElement.getText());
135   - catalogDataCatch.put(take.getDevice().getDeviceId(), sn, sumNum, take.getDevice(), channelList);
136   - logger.info("[收到通道]设备: {} -> {}个,{}/{}", take.getDevice().getDeviceId(), channelList.size(), catalogDataCatch.get(take.getDevice().getDeviceId()) == null ? 0 :catalogDataCatch.get(take.getDevice().getDeviceId()).size(), sumNum);
137   - if (catalogDataCatch.get(take.getDevice().getDeviceId()).size() == sumNum) {
138   - // 数据已经完整接收
139   - boolean resetChannelsResult = storager.resetChannels(take.getDevice().getDeviceId(), catalogDataCatch.get(take.getDevice().getDeviceId()));
140   - if (!resetChannelsResult) {
141   - String errorMsg = "接收成功,写入失败,共" + sumNum + "条,已接收" + catalogDataCatch.get(take.getDevice().getDeviceId()).size() + "条";
142   - catalogDataCatch.setChannelSyncEnd(take.getDevice().getDeviceId(), errorMsg);
143   - }else {
144   - catalogDataCatch.setChannelSyncEnd(take.getDevice().getDeviceId(), null);
145   - }
146   - }
147   - }
148 172  
149   - }
150   - } catch (DocumentException e) {
151   - e.printStackTrace();
152   - } catch (InvalidArgumentException e) {
153   - e.printStackTrace();
154   - } catch (ParseException e) {
155   - e.printStackTrace();
156   - } catch (SipException e) {
157   - e.printStackTrace();
158   - }
159   - }
160   - taskQueueHandlerRun = false;
161   - });
162   -
163   - }
164 173 }
165 174  
166 175 @Override
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/response/cmd/DeviceInfoResponseMessageHandler.java
... ... @@ -20,6 +20,7 @@ import org.slf4j.LoggerFactory;
20 20 import org.springframework.beans.factory.InitializingBean;
21 21 import org.springframework.beans.factory.annotation.Autowired;
22 22 import org.springframework.stereotype.Component;
  23 +import org.springframework.util.ObjectUtils;
23 24 import org.springframework.util.StringUtils;
24 25  
25 26 import javax.sip.InvalidArgumentException;
... ... @@ -75,6 +76,11 @@ public class DeviceInfoResponseMessageHandler extends SIPRequestProcessorParent
75 76 }
76 77 try {
77 78 rootElement = getRootElement(evt, device.getCharset());
  79 + if (rootElement == null) {
  80 + logger.warn("[ 接收到DeviceInfo应答消息 ] content cannot be null, {}", evt.getRequest());
  81 + responseAck(evt, Response.BAD_REQUEST);
  82 + return;
  83 + }
78 84 Element deviceIdElement = rootElement.element("DeviceID");
79 85 String channelId = deviceIdElement.getTextTrim();
80 86 String key = DeferredResultHolder.CALLBACK_CMD_DEVICEINFO + device.getDeviceId() + channelId;
... ... @@ -83,7 +89,7 @@ public class DeviceInfoResponseMessageHandler extends SIPRequestProcessorParent
83 89 device.setManufacturer(getText(rootElement, "Manufacturer"));
84 90 device.setModel(getText(rootElement, "Model"));
85 91 device.setFirmware(getText(rootElement, "Firmware"));
86   - if (StringUtils.isEmpty(device.getStreamMode())) {
  92 + if (ObjectUtils.isEmpty(device.getStreamMode())) {
87 93 device.setStreamMode("UDP");
88 94 }
89 95 deviceService.updateDevice(device);
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/response/cmd/MobilePositionResponseMessageHandler.java
1 1 package com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.response.cmd;
2 2  
  3 +import com.alibaba.fastjson.JSONObject;
3 4 import com.genersoft.iot.vmp.conf.UserSetting;
4 5 import com.genersoft.iot.vmp.gb28181.bean.*;
5 6 import com.genersoft.iot.vmp.gb28181.transmit.event.request.SIPRequestProcessorParent;
... ... @@ -8,6 +9,7 @@ import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.respons
8 9 import com.genersoft.iot.vmp.gb28181.utils.Coordtransform;
9 10 import com.genersoft.iot.vmp.gb28181.utils.NumericUtil;
10 11 import com.genersoft.iot.vmp.service.IDeviceChannelService;
  12 +import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
11 13 import com.genersoft.iot.vmp.storager.IVideoManagerStorage;
12 14 import com.genersoft.iot.vmp.utils.DateUtil;
13 15 import com.genersoft.iot.vmp.utils.GpsUtil;
... ... @@ -18,6 +20,7 @@ import org.slf4j.LoggerFactory;
18 20 import org.springframework.beans.factory.InitializingBean;
19 21 import org.springframework.beans.factory.annotation.Autowired;
20 22 import org.springframework.stereotype.Component;
  23 +import org.springframework.util.ObjectUtils;
21 24 import org.springframework.util.StringUtils;
22 25  
23 26 import javax.sip.InvalidArgumentException;
... ... @@ -28,6 +31,10 @@ import java.text.ParseException;
28 31  
29 32 import static com.genersoft.iot.vmp.gb28181.utils.XmlUtil.getText;
30 33  
  34 +/**
  35 + * 移动设备位置数据查询回复
  36 + * @author lin
  37 + */
31 38 @Component
32 39 public class MobilePositionResponseMessageHandler extends SIPRequestProcessorParent implements InitializingBean, IMessageHandler {
33 40  
... ... @@ -44,6 +51,9 @@ public class MobilePositionResponseMessageHandler extends SIPRequestProcessorPar
44 51 private IVideoManagerStorage storager;
45 52  
46 53 @Autowired
  54 + private IRedisCatchStorage redisCatchStorage;
  55 +
  56 + @Autowired
47 57 private IDeviceChannelService deviceChannelService;
48 58  
49 59 @Override
... ... @@ -56,10 +66,14 @@ public class MobilePositionResponseMessageHandler extends SIPRequestProcessorPar
56 66  
57 67 try {
58 68 rootElement = getRootElement(evt, device.getCharset());
59   -
  69 + if (rootElement == null) {
  70 + logger.warn("[ 移动设备位置数据查询回复 ] content cannot be null, {}", evt.getRequest());
  71 + responseAck(evt, Response.BAD_REQUEST);
  72 + return;
  73 + }
60 74 MobilePosition mobilePosition = new MobilePosition();
61 75 mobilePosition.setCreateTime(DateUtil.getNow());
62   - if (!StringUtils.isEmpty(device.getName())) {
  76 + if (!ObjectUtils.isEmpty(device.getName())) {
63 77 mobilePosition.setDeviceName(device.getName());
64 78 }
65 79 mobilePosition.setDeviceId(device.getDeviceId());
... ... @@ -103,6 +117,18 @@ public class MobilePositionResponseMessageHandler extends SIPRequestProcessorPar
103 117 storager.insertMobilePosition(mobilePosition);
104 118 }
105 119 storager.updateChannelPosition(deviceChannel);
  120 +
  121 + // 发送redis消息。 通知位置信息的变化
  122 + JSONObject jsonObject = new JSONObject();
  123 + jsonObject.put("time", mobilePosition.getTime());
  124 + jsonObject.put("serial", deviceChannel.getDeviceId());
  125 + jsonObject.put("code", deviceChannel.getChannelId());
  126 + jsonObject.put("longitude", mobilePosition.getLongitude());
  127 + jsonObject.put("latitude", mobilePosition.getLatitude());
  128 + jsonObject.put("altitude", mobilePosition.getAltitude());
  129 + jsonObject.put("direction", mobilePosition.getDirection());
  130 + jsonObject.put("speed", mobilePosition.getSpeed());
  131 + redisCatchStorage.sendMobilePositionMsg(jsonObject);
106 132 //回复 200 OK
107 133 responseAck(evt, Response.OK);
108 134 } catch (DocumentException | SipException | InvalidArgumentException | ParseException e) {
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/response/cmd/PresetQueryResponseMessageHandler.java
... ... @@ -26,6 +26,9 @@ import java.util.List;
26 26  
27 27 import static com.genersoft.iot.vmp.gb28181.utils.XmlUtil.getText;
28 28  
  29 +/**
  30 + * 设备预置位查询应答
  31 + */
29 32 @Component
30 33 public class PresetQueryResponseMessageHandler extends SIPRequestProcessorParent implements InitializingBean, IMessageHandler {
31 34  
... ... @@ -49,7 +52,11 @@ public class PresetQueryResponseMessageHandler extends SIPRequestProcessorParent
49 52 Element rootElement = null;
50 53 try {
51 54 rootElement = getRootElement(evt, device.getCharset());
52   -
  55 + if (rootElement == null) {
  56 + logger.warn("[ 设备预置位查询应答 ] content cannot be null, {}", evt.getRequest());
  57 + responseAck(evt, Response.BAD_REQUEST);
  58 + return;
  59 + }
53 60 Element presetListNumElement = rootElement.element("PresetList");
54 61 Element snElement = rootElement.element("SN");
55 62 //该字段可能为通道或则设备的id
... ... @@ -61,11 +68,7 @@ public class PresetQueryResponseMessageHandler extends SIPRequestProcessorParent
61 68 }
62 69 int sumNum = Integer.parseInt(presetListNumElement.attributeValue("Num"));
63 70 List<PresetQuerySipReq> presetQuerySipReqList = new ArrayList<>();
64   - if (sumNum == 0) {
65   - // 数据无预置位信息
66   -
67   -
68   - }else {
  71 + if (sumNum > 0) {
69 72 for (Iterator<Element> presetIterator = presetListNumElement.elementIterator();presetIterator.hasNext();){
70 73 Element itemListElement = presetIterator.next();
71 74 PresetQuerySipReq presetQuerySipReq = new PresetQuerySipReq();
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/response/cmd/RecordInfoResponseMessageHandler.java
... ... @@ -19,6 +19,7 @@ import org.springframework.beans.factory.annotation.Autowired;
19 19 import org.springframework.beans.factory.annotation.Qualifier;
20 20 import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
21 21 import org.springframework.stereotype.Component;
  22 +import org.springframework.util.ObjectUtils;
22 23 import org.springframework.util.StringUtils;
23 24  
24 25 import javax.sip.InvalidArgumentException;
... ... @@ -39,7 +40,7 @@ import static com.genersoft.iot.vmp.gb28181.utils.XmlUtil.getText;
39 40 @Component
40 41 public class RecordInfoResponseMessageHandler extends SIPRequestProcessorParent implements InitializingBean, IMessageHandler {
41 42  
42   - private Logger logger = LoggerFactory.getLogger(RecordInfoResponseMessageHandler.class);
  43 + private final Logger logger = LoggerFactory.getLogger(RecordInfoResponseMessageHandler.class);
43 44 private final String cmdType = "RecordInfo";
44 45  
45 46 private ConcurrentLinkedQueue<HandlerCatchData> taskQueue = new ConcurrentLinkedQueue<>();
... ... @@ -76,10 +77,14 @@ public class RecordInfoResponseMessageHandler extends SIPRequestProcessorParent
76 77 if (!taskQueueHandlerRun) {
77 78 taskQueueHandlerRun = true;
78 79 taskExecutor.execute(()->{
79   - try {
80   - while (!taskQueue.isEmpty()) {
  80 + while (!taskQueue.isEmpty()) {
  81 + try {
81 82 HandlerCatchData take = taskQueue.poll();
82 83 Element rootElementForCharset = getRootElement(take.getEvt(), take.getDevice().getCharset());
  84 + if (rootElement == null) {
  85 + logger.warn("[ 国标录像 ] content cannot be null, {}", evt.getRequest());
  86 + continue;
  87 + }
83 88 String sn = getText(rootElementForCharset, "SN");
84 89 String channelId = getText(rootElementForCharset, "DeviceID");
85 90 RecordInfo recordInfo = new RecordInfo();
... ... @@ -89,7 +94,7 @@ public class RecordInfoResponseMessageHandler extends SIPRequestProcessorParent
89 94 recordInfo.setName(getText(rootElementForCharset, "Name"));
90 95 String sumNumStr = getText(rootElementForCharset, "SumNum");
91 96 int sumNum = 0;
92   - if (!StringUtils.isEmpty(sumNumStr)) {
  97 + if (!ObjectUtils.isEmpty(sumNumStr)) {
93 98 sumNum = Integer.parseInt(sumNumStr);
94 99 }
95 100 recordInfo.setSumNum(sumNum);
... ... @@ -141,10 +146,11 @@ public class RecordInfoResponseMessageHandler extends SIPRequestProcessorParent
141 146 releaseRequest(take.getDevice().getDeviceId(), sn);
142 147 }
143 148 }
  149 + } catch (DocumentException e) {
  150 + throw new RuntimeException(e);
  151 + } finally {
  152 + taskQueueHandlerRun = false;
144 153 }
145   - taskQueueHandlerRun = false;
146   - }catch (DocumentException e) {
147   - throw new RuntimeException(e);
148 154 }
149 155 });
150 156 }
... ... @@ -155,6 +161,8 @@ public class RecordInfoResponseMessageHandler extends SIPRequestProcessorParent
155 161 e.printStackTrace();
156 162 } catch (ParseException e) {
157 163 e.printStackTrace();
  164 + }finally {
  165 + taskQueueHandlerRun = false;
158 166 }
159 167 }
160 168  
... ... @@ -165,16 +173,12 @@ public class RecordInfoResponseMessageHandler extends SIPRequestProcessorParent
165 173  
166 174 public void releaseRequest(String deviceId, String sn){
167 175 String key = DeferredResultHolder.CALLBACK_CMD_RECORDINFO + deviceId + sn;
168   - WVPResult<RecordInfo> wvpResult = new WVPResult<>();
169   - wvpResult.setCode(0);
170   - wvpResult.setMsg("success");
171 176 // 对数据进行排序
172 177 Collections.sort(recordDataCatch.getRecordInfo(deviceId, sn).getRecordList());
173   - wvpResult.setData(recordDataCatch.getRecordInfo(deviceId, sn));
174 178  
175 179 RequestMessage msg = new RequestMessage();
176 180 msg.setKey(key);
177   - msg.setData(wvpResult);
  181 + msg.setData(recordDataCatch.getRecordInfo(deviceId, sn));
178 182 deferredResultHolder.invokeAllResult(msg);
179 183 recordDataCatch.remove(deviceId, sn);
180 184 }
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/utils/XmlUtil.java
... ... @@ -14,6 +14,7 @@ import org.dom4j.Element;
14 14 import org.dom4j.io.SAXReader;
15 15 import org.slf4j.Logger;
16 16 import org.slf4j.LoggerFactory;
  17 +import org.springframework.util.ObjectUtils;
17 18 import org.springframework.util.StringUtils;
18 19  
19 20 import javax.sip.RequestEvent;
... ... @@ -118,12 +119,12 @@ public class XmlUtil {
118 119 // 如果是属性
119 120 for (Object o : element.attributes()) {
120 121 Attribute attr = (Attribute) o;
121   - if (!StringUtils.isEmpty(attr.getValue())) {
  122 + if (!ObjectUtils.isEmpty(attr.getValue())) {
122 123 json.put("@" + attr.getName(), attr.getValue());
123 124 }
124 125 }
125 126 List<Element> chdEl = element.elements();
126   - if (chdEl.isEmpty() && !StringUtils.isEmpty(element.getText())) {// 如果没有子元素,只有一个值
  127 + if (chdEl.isEmpty() && !ObjectUtils.isEmpty(element.getText())) {// 如果没有子元素,只有一个值
127 128 json.put(element.getName(), element.getText());
128 129 }
129 130  
... ... @@ -154,7 +155,7 @@ public class XmlUtil {
154 155 } else { // 子元素没有子元素
155 156 for (Object o : element.attributes()) {
156 157 Attribute attr = (Attribute) o;
157   - if (!StringUtils.isEmpty(attr.getValue())) {
  158 + if (!ObjectUtils.isEmpty(attr.getValue())) {
158 159 json.put("@" + attr.getName(), attr.getValue());
159 160 }
160 161 }
... ... @@ -197,7 +198,7 @@ public class XmlUtil {
197 198 return null;
198 199 }
199 200 String channelId = channdelIdElement.getTextTrim();
200   - if (StringUtils.isEmpty(channelId)) {
  201 + if (ObjectUtils.isEmpty(channelId)) {
201 202 logger.warn("解析Catalog消息时发现缺少 DeviceID");
202 203 return null;
203 204 }
... ... @@ -316,7 +317,7 @@ public class XmlUtil {
316 317 // 识别自带的目录标识
317 318 String parental = XmlUtil.getText(itemDevice, "Parental");
318 319 // 由于海康会错误的发送65535作为这里的取值,所以这里除非是0否则认为是1
319   - if (!StringUtils.isEmpty(parental) && parental.length() == 1 && Integer.parseInt(parental) == 0) {
  320 + if (!ObjectUtils.isEmpty(parental) && parental.length() == 1 && Integer.parseInt(parental) == 0) {
320 321 deviceChannel.setParental(0);
321 322 }else {
322 323 deviceChannel.setParental(1);
... ... @@ -332,14 +333,14 @@ public class XmlUtil {
332 333 deviceChannel.setPassword(XmlUtil.getText(itemDevice, "Password"));
333 334  
334 335 String safetyWay = XmlUtil.getText(itemDevice, "SafetyWay");
335   - if (StringUtils.isEmpty(safetyWay)) {
  336 + if (ObjectUtils.isEmpty(safetyWay)) {
336 337 deviceChannel.setSafetyWay(0);
337 338 } else {
338 339 deviceChannel.setSafetyWay(Integer.parseInt(safetyWay));
339 340 }
340 341  
341 342 String registerWay = XmlUtil.getText(itemDevice, "RegisterWay");
342   - if (StringUtils.isEmpty(registerWay)) {
  343 + if (ObjectUtils.isEmpty(registerWay)) {
343 344 deviceChannel.setRegisterWay(1);
344 345 } else {
345 346 deviceChannel.setRegisterWay(Integer.parseInt(registerWay));
... ...
src/main/java/com/genersoft/iot/vmp/media/zlm/AssistRESTfulUtils.java
... ... @@ -9,6 +9,7 @@ import org.jetbrains.annotations.NotNull;
9 9 import org.slf4j.Logger;
10 10 import org.slf4j.LoggerFactory;
11 11 import org.springframework.stereotype.Component;
  12 +import org.springframework.util.ObjectUtils;
12 13 import org.springframework.util.StringUtils;
13 14  
14 15 import java.io.File;
... ... @@ -49,7 +50,7 @@ public class AssistRESTfulUtils {
49 50 if (mediaServerItem == null) {
50 51 return null;
51 52 }
52   - if (StringUtils.isEmpty(mediaServerItem.getRecordAssistPort())) {
  53 + if (ObjectUtils.isEmpty(mediaServerItem.getRecordAssistPort())) {
53 54 logger.warn("未启用Assist服务");
54 55 return null;
55 56 }
... ...
src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java
... ... @@ -22,6 +22,7 @@ import org.slf4j.LoggerFactory;
22 22 import org.springframework.beans.factory.annotation.Autowired;
23 23 import org.springframework.http.HttpStatus;
24 24 import org.springframework.http.ResponseEntity;
  25 +import org.springframework.util.ObjectUtils;
25 26 import org.springframework.util.StringUtils;
26 27 import org.springframework.web.bind.annotation.PostMapping;
27 28 import org.springframework.web.bind.annotation.RequestBody;
... ... @@ -633,7 +634,7 @@ public class ZLMHttpHookListener {
633 634  
634 635 private Map<String, String> urlParamToMap(String params) {
635 636 HashMap<String, String> map = new HashMap<>();
636   - if (StringUtils.isEmpty(params)) {
  637 + if (ObjectUtils.isEmpty(params)) {
637 638 return map;
638 639 }
639 640 String[] paramsArray = params.split("&");
... ...
src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRTPServerFactory.java
... ... @@ -9,6 +9,7 @@ import org.slf4j.Logger;
9 9 import org.slf4j.LoggerFactory;
10 10 import org.springframework.beans.factory.annotation.Autowired;
11 11 import org.springframework.stereotype.Component;
  12 +import org.springframework.util.ObjectUtils;
12 13 import org.springframework.util.StringUtils;
13 14  
14 15 import java.util.*;
... ... @@ -187,7 +188,7 @@ public class ZLMRTPServerFactory {
187 188  
188 189 // 使用RTPServer 功能找一个可用的端口
189 190 String sendRtpPortRange = serverItem.getSendRtpPortRange();
190   - if (StringUtils.isEmpty(sendRtpPortRange)) {
  191 + if (ObjectUtils.isEmpty(sendRtpPortRange)) {
191 192 return null;
192 193 }
193 194 String[] portRangeStrArray = serverItem.getSendRtpPortRange().split(",");
... ... @@ -229,7 +230,7 @@ public class ZLMRTPServerFactory {
229 230 public SendRtpItem createSendRtpItem(MediaServerItem serverItem, String ip, int port, String ssrc, String platformId, String app, String stream, String channelId, boolean tcp){
230 231 // 使用RTPServer 功能找一个可用的端口
231 232 String sendRtpPortRange = serverItem.getSendRtpPortRange();
232   - if (StringUtils.isEmpty(sendRtpPortRange)) {
  233 + if (ObjectUtils.isEmpty(sendRtpPortRange)) {
233 234 return null;
234 235 }
235 236 String[] portRangeStrArray = serverItem.getSendRtpPortRange().split(",");
... ...
src/main/java/com/genersoft/iot/vmp/media/zlm/dto/MediaServerItem.java
... ... @@ -3,64 +3,94 @@ package com.genersoft.iot.vmp.media.zlm.dto;
3 3  
4 4 import com.genersoft.iot.vmp.gb28181.session.SsrcConfig;
5 5 import com.genersoft.iot.vmp.media.zlm.ZLMServerConfig;
  6 +import io.swagger.v3.oas.annotations.media.Schema;
  7 +import org.springframework.util.ObjectUtils;
6 8 import org.springframework.util.StringUtils;
7 9  
8 10 import java.util.HashMap;
9 11  
  12 +@Schema(description = "流媒体服务信息")
10 13 public class MediaServerItem{
11 14  
  15 + @Schema(description = "ID")
12 16 private String id;
13 17  
  18 + @Schema(description = "IP")
14 19 private String ip;
15 20  
  21 + @Schema(description = "hook使用的IP(zlm访问WVP使用的IP)")
16 22 private String hookIp;
17 23  
  24 + @Schema(description = "SDP IP")
18 25 private String sdpIp;
19 26  
  27 + @Schema(description = "流IP")
20 28 private String streamIp;
21 29  
  30 + @Schema(description = "HTTP端口")
22 31 private int httpPort;
23 32  
  33 + @Schema(description = "HTTPS端口")
24 34 private int httpSSlPort;
25 35  
  36 + @Schema(description = "RTMP端口")
26 37 private int rtmpPort;
27 38  
  39 + @Schema(description = "RTMPS端口")
28 40 private int rtmpSSlPort;
29 41  
  42 + @Schema(description = "RTP收流端口(单端口模式有用)")
30 43 private int rtpProxyPort;
31 44  
  45 + @Schema(description = "RTSP端口")
32 46 private int rtspPort;
33 47  
  48 + @Schema(description = "RTSPS端口")
34 49 private int rtspSSLPort;
35 50  
  51 + @Schema(description = "是否开启自动配置ZLM")
36 52 private boolean autoConfig;
37 53  
  54 + @Schema(description = "ZLM鉴权参数")
38 55 private String secret;
39 56  
  57 + @Schema(description = "某个流无人观看时,触发hook.on_stream_none_reader事件的最大等待时间,单位毫秒")
40 58 private int streamNoneReaderDelayMS;
41 59  
  60 + @Schema(description = "keepalive hook触发间隔,单位秒")
42 61 private int hookAliveInterval;
43 62  
  63 + @Schema(description = "是否使用多端口模式")
44 64 private boolean rtpEnable;
45 65  
  66 + @Schema(description = "状态")
46 67 private boolean status;
47 68  
  69 + @Schema(description = "多端口RTP收流端口范围")
48 70 private String rtpPortRange;
49 71  
  72 + @Schema(description = "RTP发流端口范围")
50 73 private String sendRtpPortRange;
51 74  
  75 + @Schema(description = "assist服务端口")
52 76 private int recordAssistPort;
53 77  
  78 + @Schema(description = "创建时间")
54 79 private String createTime;
55 80  
  81 + @Schema(description = "更新时间")
56 82 private String updateTime;
57 83  
  84 + @Schema(description = "上次心跳时间")
58 85 private String lastKeepaliveTime;
59 86  
  87 + @Schema(description = "是否是默认ZLM")
60 88 private boolean defaultServer;
61 89  
  90 + @Schema(description = "SSRC信息")
62 91 private SsrcConfig ssrcConfig;
63 92  
  93 + @Schema(description = "当前使用到的端口")
64 94 private int currentPort;
65 95  
66 96  
... ... @@ -68,6 +98,7 @@ public class MediaServerItem{
68 98 * 每一台ZLM都有一套独立的SSRC列表
69 99 * 在ApplicationCheckRunner里对mediaServerSsrcMap进行初始化
70 100 */
  101 + @Schema(description = "ID")
71 102 private HashMap<String, SsrcConfig> mediaServerSsrcMap;
72 103  
73 104 public MediaServerItem() {
... ... @@ -76,9 +107,9 @@ public class MediaServerItem{
76 107 public MediaServerItem(ZLMServerConfig zlmServerConfig, String sipIp) {
77 108 id = zlmServerConfig.getGeneralMediaServerId();
78 109 ip = zlmServerConfig.getIp();
79   - hookIp = StringUtils.isEmpty(zlmServerConfig.getHookIp())? sipIp: zlmServerConfig.getHookIp();
80   - sdpIp = StringUtils.isEmpty(zlmServerConfig.getSdpIp())? zlmServerConfig.getIp(): zlmServerConfig.getSdpIp();
81   - streamIp = StringUtils.isEmpty(zlmServerConfig.getStreamIp())? zlmServerConfig.getIp(): zlmServerConfig.getStreamIp();
  110 + hookIp = ObjectUtils.isEmpty(zlmServerConfig.getHookIp())? sipIp: zlmServerConfig.getHookIp();
  111 + sdpIp = ObjectUtils.isEmpty(zlmServerConfig.getSdpIp())? zlmServerConfig.getIp(): zlmServerConfig.getSdpIp();
  112 + streamIp = ObjectUtils.isEmpty(zlmServerConfig.getStreamIp())? zlmServerConfig.getIp(): zlmServerConfig.getStreamIp();
82 113 httpPort = zlmServerConfig.getHttpPort();
83 114 httpSSlPort = zlmServerConfig.getHttpSSLport();
84 115 rtmpPort = zlmServerConfig.getRtmpPort();
... ...
src/main/java/com/genersoft/iot/vmp/media/zlm/dto/StreamProxyItem.java
1 1 package com.genersoft.iot.vmp.media.zlm.dto;
2 2  
3 3 import com.genersoft.iot.vmp.gb28181.bean.GbStream;
  4 +import io.swagger.v3.oas.annotations.media.Schema;
4 5  
  6 +/**
  7 + * @author lin
  8 + */
  9 +@Schema(description = "拉流代理的信息")
5 10 public class StreamProxyItem extends GbStream {
6 11  
  12 + @Schema(description = "类型")
7 13 private String type;
  14 + @Schema(description = "应用名")
8 15 private String app;
  16 + @Schema(description = "流ID")
9 17 private String stream;
  18 + @Schema(description = "流媒体服务ID")
10 19 private String mediaServerId;
  20 + @Schema(description = "拉流地址")
11 21 private String url;
  22 + @Schema(description = "拉流地址")
12 23 private String src_url;
  24 + @Schema(description = "目标地址")
13 25 private String dst_url;
  26 + @Schema(description = "超时时间")
14 27 private int timeout_ms;
  28 + @Schema(description = "ffmpeg模板KEY")
15 29 private String ffmpeg_cmd_key;
  30 + @Schema(description = "rtsp拉流时,拉流方式,0:tcp,1:udp,2:组播")
16 31 private String rtp_type;
  32 + @Schema(description = "是否启用")
17 33 private boolean enable;
  34 + @Schema(description = "是否启用HLS")
18 35 private boolean enable_hls;
  36 + @Schema(description = "是否启用MP4")
19 37 private boolean enable_mp4;
20   - private boolean enable_remove_none_reader; // 无人观看时删除
  38 + @Schema(description = "是否 无人观看时删除")
  39 + private boolean enable_remove_none_reader;
  40 + @Schema(description = "上级平台国标ID")
21 41 private String platformGbId;
  42 + @Schema(description = "创建时间")
22 43 private String createTime;
23 44  
24 45 public String getType() {
... ...
src/main/java/com/genersoft/iot/vmp/media/zlm/dto/StreamPushItem.java
... ... @@ -2,37 +2,43 @@ package com.genersoft.iot.vmp.media.zlm.dto;
2 2  
3 3 import com.genersoft.iot.vmp.gb28181.bean.GbStream;
4 4 import com.genersoft.iot.vmp.utils.DateUtil;
  5 +import io.swagger.v3.oas.annotations.media.Schema;
5 6 import org.jetbrains.annotations.NotNull;
6 7 import org.springframework.util.unit.DataUnit;
7 8  
8 9 import java.util.List;
9 10  
10   -
  11 +@Schema(description = "推流信息")
11 12 public class StreamPushItem extends GbStream implements Comparable<StreamPushItem>{
12 13  
13 14 /**
14 15 * id
15 16 */
  17 + @Schema(description = "id")
16 18 private Integer id;
17 19  
18 20 /**
19 21 * 应用名
20 22 */
  23 + @Schema(description = "应用名")
21 24 private String app;
22 25  
23 26 /**
24 27 * 流id
25 28 */
  29 + @Schema(description = "流id")
26 30 private String stream;
27 31  
28 32 /**
29 33 * 观看总人数,包括hls/rtsp/rtmp/http-flv/ws-flv
30 34 */
  35 + @Schema(description = "观看总人数")
31 36 private String totalReaderCount;
32 37  
33 38 /**
34 39 * 协议 包括hls/rtsp/rtmp/http-flv/ws-flv
35 40 */
  41 + @Schema(description = "协议 包括hls/rtsp/rtmp/http-flv/ws-flv")
36 42 private List<MediaSchema> schemas;
37 43  
38 44 /**
... ... @@ -46,71 +52,85 @@ public class StreamPushItem extends GbStream implements Comparable&lt;StreamPushIte
46 52 * mp4_vod=6,
47 53 * device_chn=7
48 54 */
  55 + @Schema(description = "产生源类型")
49 56 private int originType;
50 57  
51 58 /**
52 59 * 客户端和服务器网络信息,可能为null类型
53 60 */
  61 + @Schema(description = "客户端和服务器网络信息,可能为null类型")
54 62 private MediaItem.OriginSock originSock;
55 63  
56 64 /**
57 65 * 产生源类型的字符串描述
58 66 */
  67 + @Schema(description = "产生源类型的字符串描述")
59 68 private String originTypeStr;
60 69  
61 70 /**
62 71 * 产生源的url
63 72 */
  73 + @Schema(description = "产生源的url")
64 74 private String originUrl;
65 75  
66 76 /**
67 77 * 存活时间,单位秒
68 78 */
  79 + @Schema(description = "存活时间,单位秒")
69 80 private Long aliveSecond;
70 81  
71 82 /**
72 83 * 音视频轨道
73 84 */
  85 + @Schema(description = "音视频轨道")
74 86 private List<MediaItem.MediaTrack> tracks;
75 87  
76 88 /**
77 89 * 音视频轨道
78 90 */
  91 + @Schema(description = "音视频轨道")
79 92 private String vhost;
80 93  
81 94 /**
82 95 * 使用的流媒体ID
83 96 */
  97 + @Schema(description = "使用的流媒体ID")
84 98 private String mediaServerId;
85 99  
86 100 /**
87 101 * 使用的服务ID
88 102 */
  103 + @Schema(description = "使用的服务ID")
89 104 private String serverId;
90 105  
91 106 /**
92 107 * 推流时间
93 108 */
  109 + @Schema(description = "推流时间")
94 110 private String pushTime;
95 111  
96 112 /**
97 113 * 更新时间
98 114 */
  115 + @Schema(description = "更新时间")
99 116 private String updateTime;
100 117  
101 118 /**
102 119 * 创建时间
103 120 */
  121 + @Schema(description = "创建时间")
104 122 private String createTime;
105 123  
106 124 /**
107 125 * 是否正在推流
108 126 */
  127 + @Schema(description = "是否正在推流")
109 128 private boolean pushIng;
110 129  
111 130 /**
112 131 * 是否自己平台的推流
113 132 */
  133 + @Schema(description = "是否自己平台的推流")
114 134 private boolean self;
115 135  
116 136  
... ...
src/main/java/com/genersoft/iot/vmp/service/IGbStreamService.java
... ... @@ -3,6 +3,7 @@ package com.genersoft.iot.vmp.service;
3 3 import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel;
4 4 import com.genersoft.iot.vmp.gb28181.bean.GbStream;
5 5 import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform;
  6 +import com.genersoft.iot.vmp.media.zlm.dto.StreamPushItem;
6 7 import com.github.pagehelper.PageInfo;
7 8  
8 9 import java.util.List;
... ... @@ -45,4 +46,11 @@ public interface IGbStreamService {
45 46  
46 47 void sendCatalogMsg(GbStream gbStream, String type);
47 48 void sendCatalogMsgs(List<GbStream> gbStreams, String type);
  49 +
  50 + /**
  51 + * 修改gbId或name
  52 + * @param streamPushItemForUpdate
  53 + * @return
  54 + */
  55 + int updateGbIdOrName(List<StreamPushItem> streamPushItemForUpdate);
48 56 }
... ...
src/main/java/com/genersoft/iot/vmp/service/IMediaServerService.java
... ... @@ -63,7 +63,7 @@ public interface IMediaServerService {
63 63  
64 64 void clearMediaServerForOnline();
65 65  
66   - WVPResult<String> add(MediaServerItem mediaSerItem);
  66 + void add(MediaServerItem mediaSerItem);
67 67  
68 68 int addToDatabase(MediaServerItem mediaSerItem);
69 69  
... ... @@ -71,7 +71,7 @@ public interface IMediaServerService {
71 71  
72 72 void resetOnlineServerItem(MediaServerItem serverItem);
73 73  
74   - WVPResult<MediaServerItem> checkMediaServer(String ip, int port, String secret);
  74 + MediaServerItem checkMediaServer(String ip, int port, String secret);
75 75  
76 76 boolean checkMediaRecordServer(String ip, int port);
77 77  
... ...
src/main/java/com/genersoft/iot/vmp/service/IPlayService.java
... ... @@ -32,13 +32,13 @@ public interface IPlayService {
32 32  
33 33 void onPublishHandlerForDownload(InviteStreamInfo inviteStreamInfo, String deviceId, String channelId, String toString);
34 34  
35   - DeferredResult<ResponseEntity<String>> playBack(String deviceId, String channelId, String startTime, String endTime, InviteStreamCallback infoCallBack, PlayBackCallback hookCallBack);
36   - DeferredResult<ResponseEntity<String>> playBack(MediaServerItem mediaServerItem, SSRCInfo ssrcInfo,String deviceId, String channelId, String startTime, String endTime, InviteStreamCallback infoCallBack, PlayBackCallback hookCallBack);
  35 + DeferredResult<String> playBack(String deviceId, String channelId, String startTime, String endTime, InviteStreamCallback infoCallBack, PlayBackCallback hookCallBack);
  36 + DeferredResult<String> playBack(MediaServerItem mediaServerItem, SSRCInfo ssrcInfo,String deviceId, String channelId, String startTime, String endTime, InviteStreamCallback infoCallBack, PlayBackCallback hookCallBack);
37 37  
38 38 void zlmServerOffline(String mediaServerId);
39 39  
40   - DeferredResult<ResponseEntity<String>> download(String deviceId, String channelId, String startTime, String endTime, int downloadSpeed, InviteStreamCallback infoCallBack, PlayBackCallback hookCallBack);
41   - DeferredResult<ResponseEntity<String>> download(MediaServerItem mediaServerItem, SSRCInfo ssrcInfo,String deviceId, String channelId, String startTime, String endTime, int downloadSpeed, InviteStreamCallback infoCallBack, PlayBackCallback hookCallBack);
  40 + DeferredResult<String> download(String deviceId, String channelId, String startTime, String endTime, int downloadSpeed, InviteStreamCallback infoCallBack, PlayBackCallback hookCallBack);
  41 + DeferredResult<String> download(MediaServerItem mediaServerItem, SSRCInfo ssrcInfo,String deviceId, String channelId, String startTime, String endTime, int downloadSpeed, InviteStreamCallback infoCallBack, PlayBackCallback hookCallBack);
42 42  
43 43 StreamInfo getDownLoadInfo(String deviceId, String channelId, String stream);
44 44  
... ...
src/main/java/com/genersoft/iot/vmp/service/IStreamProxyService.java
... ... @@ -2,12 +2,8 @@ package com.genersoft.iot.vmp.service;
2 2  
3 3 import com.alibaba.fastjson.JSONObject;
4 4 import com.genersoft.iot.vmp.common.StreamInfo;
5   -import com.genersoft.iot.vmp.media.zlm.ZLMServerConfig;
6   -import com.genersoft.iot.vmp.media.zlm.dto.MediaItem;
7 5 import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
8 6 import com.genersoft.iot.vmp.media.zlm.dto.StreamProxyItem;
9   -import com.genersoft.iot.vmp.media.zlm.dto.StreamPushItem;
10   -import com.genersoft.iot.vmp.vmanager.bean.WVPResult;
11 7 import com.github.pagehelper.PageInfo;
12 8  
13 9 public interface IStreamProxyService {
... ... @@ -16,7 +12,7 @@ public interface IStreamProxyService {
16 12 * 保存视频代理
17 13 * @param param
18 14 */
19   - WVPResult<StreamInfo> save(StreamProxyItem param);
  15 + StreamInfo save(StreamProxyItem param);
20 16  
21 17 /**
22 18 * 添加视频代理到zlm
... ...
src/main/java/com/genersoft/iot/vmp/service/IStreamPushService.java
... ... @@ -100,4 +100,10 @@ public interface IStreamPushService {
100 100 * 增加推流
101 101 */
102 102 boolean add(StreamPushItem stream);
  103 +
  104 + /**
  105 + * 获取全部的app+Streanm 用于判断推流列表是新增还是修改
  106 + * @return
  107 + */
  108 + List<String> getAllAppAndStream();
103 109 }
... ...
src/main/java/com/genersoft/iot/vmp/service/bean/PlayBackResult.java
... ... @@ -4,14 +4,18 @@ import com.alibaba.fastjson.JSONObject;
4 4 import com.genersoft.iot.vmp.gb28181.event.SipSubscribe;
5 5 import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
6 6  
7   -import javax.sip.RequestEvent;
  7 +import java.util.EventObject;
8 8  
  9 +
  10 +/**
  11 + * @author lin
  12 + */
9 13 public class PlayBackResult<T> {
10 14 private int code;
11 15 private T data;
12 16 private MediaServerItem mediaServerItem;
13 17 private JSONObject response;
14   - private SipSubscribe.EventResult event;
  18 + private SipSubscribe.EventResult<EventObject> event;
15 19  
16 20 public int getCode() {
17 21 return code;
... ... @@ -45,11 +49,11 @@ public class PlayBackResult&lt;T&gt; {
45 49 this.response = response;
46 50 }
47 51  
48   - public SipSubscribe.EventResult getEvent() {
  52 + public SipSubscribe.EventResult<EventObject> getEvent() {
49 53 return event;
50 54 }
51 55  
52   - public void setEvent(SipSubscribe.EventResult event) {
  56 + public void setEvent(SipSubscribe.EventResult<EventObject> event) {
53 57 this.event = event;
54 58 }
55 59 }
... ...
src/main/java/com/genersoft/iot/vmp/service/impl/DeviceServiceImpl.java
... ... @@ -23,6 +23,7 @@ import org.slf4j.LoggerFactory;
23 23 import org.springframework.beans.factory.annotation.Autowired;
24 24 import org.springframework.jdbc.support.incrementer.AbstractIdentityColumnMaxValueIncrementer;
25 25 import org.springframework.stereotype.Service;
  26 +import org.springframework.util.ObjectUtils;
26 27 import org.springframework.util.StringUtils;
27 28  
28 29 import java.time.Instant;
... ... @@ -105,6 +106,7 @@ public class DeviceServiceImpl implements IDeviceService {
105 106 redisCatchStorage.updateDevice(device);
106 107 commander.deviceInfoQuery(device);
107 108 sync(device);
  109 + // TODO 如果设备下的通道级联到了其他平台,那么需要发送事件或者notify给上级平台
108 110 }else {
109 111 deviceMapper.update(device);
110 112 redisCatchStorage.updateDevice(device);
... ... @@ -281,13 +283,13 @@ public class DeviceServiceImpl implements IDeviceService {
281 283 logger.warn("更新设备时未找到设备信息");
282 284 return;
283 285 }
284   - if (!StringUtils.isEmpty(device.getName())) {
  286 + if (!ObjectUtils.isEmpty(device.getName())) {
285 287 deviceInStore.setName(device.getName());
286 288 }
287   - if (!StringUtils.isEmpty(device.getCharset())) {
  289 + if (!ObjectUtils.isEmpty(device.getCharset())) {
288 290 deviceInStore.setCharset(device.getCharset());
289 291 }
290   - if (!StringUtils.isEmpty(device.getMediaServerId())) {
  292 + if (!ObjectUtils.isEmpty(device.getMediaServerId())) {
291 293 deviceInStore.setMediaServerId(device.getMediaServerId());
292 294 }
293 295  
... ...
src/main/java/com/genersoft/iot/vmp/service/impl/GbStreamServiceImpl.java
1 1 package com.genersoft.iot.vmp.service.impl;
2 2  
3   -import com.genersoft.iot.vmp.conf.SipConfig;
4 3 import com.genersoft.iot.vmp.gb28181.bean.*;
5 4 import com.genersoft.iot.vmp.gb28181.event.EventPublisher;
6 5 import com.genersoft.iot.vmp.gb28181.event.subscribe.catalog.CatalogEvent;
7   -import com.genersoft.iot.vmp.media.zlm.dto.StreamProxyItem;
  6 +import com.genersoft.iot.vmp.media.zlm.dto.StreamPushItem;
8 7 import com.genersoft.iot.vmp.storager.dao.GbStreamMapper;
9 8 import com.genersoft.iot.vmp.storager.dao.ParentPlatformMapper;
10 9 import com.genersoft.iot.vmp.storager.dao.PlatformCatalogMapper;
... ... @@ -19,6 +18,7 @@ import org.springframework.jdbc.datasource.DataSourceTransactionManager;
19 18 import org.springframework.stereotype.Service;
20 19 import org.springframework.transaction.TransactionDefinition;
21 20 import org.springframework.transaction.TransactionStatus;
  21 +import org.springframework.util.ObjectUtils;
22 22 import org.springframework.util.StringUtils;
23 23  
24 24 import java.util.ArrayList;
... ... @@ -169,7 +169,7 @@ public class GbStreamServiceImpl implements IGbStreamService {
169 169 public void sendCatalogMsgs(List<GbStream> gbStreams, String type) {
170 170 if (gbStreams.size() > 0) {
171 171 for (GbStream gs : gbStreams) {
172   - if (StringUtils.isEmpty(gs.getGbId())){
  172 + if (ObjectUtils.isEmpty(gs.getGbId())){
173 173 continue;
174 174 }
175 175 List<ParentPlatform> parentPlatforms = platformGbStreamMapper.selectByAppAndStream(gs.getApp(), gs.getStream());
... ... @@ -183,4 +183,9 @@ public class GbStreamServiceImpl implements IGbStreamService {
183 183 }
184 184 }
185 185 }
  186 +
  187 + @Override
  188 + public int updateGbIdOrName(List<StreamPushItem> streamPushItemForUpdate) {
  189 + return gbStreamMapper.updateGbIdOrName(streamPushItemForUpdate);
  190 + }
186 191 }
... ...
src/main/java/com/genersoft/iot/vmp/service/impl/MediaServerServiceImpl.java
... ... @@ -11,6 +11,8 @@ import java.util.Set;
11 11 import com.genersoft.iot.vmp.media.zlm.ZLMRunner;
12 12 import com.genersoft.iot.vmp.service.IStreamProxyService;
13 13 import com.genersoft.iot.vmp.storager.IVideoManagerStorage;
  14 +import com.genersoft.iot.vmp.conf.exception.ControllerException;
  15 +import com.genersoft.iot.vmp.vmanager.bean.ErrorCode;
14 16 import org.slf4j.Logger;
15 17 import org.slf4j.LoggerFactory;
16 18 import org.springframework.beans.factory.annotation.Autowired;
... ... @@ -19,6 +21,7 @@ import org.springframework.jdbc.datasource.DataSourceTransactionManager;
19 21 import org.springframework.stereotype.Service;
20 22 import org.springframework.transaction.TransactionDefinition;
21 23 import org.springframework.transaction.TransactionStatus;
  24 +import org.springframework.util.ObjectUtils;
22 25 import org.springframework.util.StringUtils;
23 26  
24 27 import com.alibaba.fastjson.JSON;
... ... @@ -58,9 +61,6 @@ public class MediaServerServiceImpl implements IMediaServerService {
58 61 @Autowired
59 62 private SipConfig sipConfig;
60 63  
61   - @Autowired
62   - private ZLMRunner zlmRunner;
63   -
64 64 @Value("${server.ssl.enabled:false}")
65 65 private boolean sslEnabled;
66 66  
... ... @@ -88,8 +88,6 @@ public class MediaServerServiceImpl implements IMediaServerService {
88 88 @Autowired
89 89 private ZLMRTPServerFactory zlmrtpServerFactory;
90 90  
91   - @Autowired
92   - private RedisUtil redisUtil;
93 91  
94 92 @Autowired
95 93 private IVideoManagerStorage storager;
... ... @@ -107,19 +105,19 @@ public class MediaServerServiceImpl implements IMediaServerService {
107 105 public void updateVmServer(List<MediaServerItem> mediaServerItemList) {
108 106 logger.info("[zlm] 缓存初始化 ");
109 107 for (MediaServerItem mediaServerItem : mediaServerItemList) {
110   - if (StringUtils.isEmpty(mediaServerItem.getId())) {
  108 + if (ObjectUtils.isEmpty(mediaServerItem.getId())) {
111 109 continue;
112 110 }
113 111 // 更新
114 112 if (mediaServerItem.getSsrcConfig() == null) {
115 113 SsrcConfig ssrcConfig = new SsrcConfig(mediaServerItem.getId(), null, sipConfig.getDomain());
116 114 mediaServerItem.setSsrcConfig(ssrcConfig);
117   - redisUtil.set(VideoManagerConstants.MEDIA_SERVER_PREFIX + userSetting.getServerId() + "_" + mediaServerItem.getId(), mediaServerItem);
  115 + RedisUtil.set(VideoManagerConstants.MEDIA_SERVER_PREFIX + userSetting.getServerId() + "_" + mediaServerItem.getId(), mediaServerItem);
118 116 }
119 117 // 查询redis是否存在此mediaServer
120 118 String key = VideoManagerConstants.MEDIA_SERVER_PREFIX + userSetting.getServerId() + "_" + mediaServerItem.getId();
121   - if (!redisUtil.hasKey(key)) {
122   - redisUtil.set(key, mediaServerItem);
  119 + if (!RedisUtil.hasKey(key)) {
  120 + RedisUtil.set(key, mediaServerItem);
123 121 }
124 122  
125 123 }
... ... @@ -161,7 +159,7 @@ public class MediaServerServiceImpl implements IMediaServerService {
161 159 if (mediaServerItem.isRtpEnable()) {
162 160 rtpServerPort = zlmrtpServerFactory.createRTPServer(mediaServerItem, streamId, ssrcCheck?Integer.parseInt(ssrc):0, port);
163 161 }
164   - redisUtil.set(key, mediaServerItem);
  162 + RedisUtil.set(key, mediaServerItem);
165 163 return new SSRCInfo(rtpServerPort, ssrc, streamId);
166 164 }
167 165 }
... ... @@ -194,7 +192,7 @@ public class MediaServerServiceImpl implements IMediaServerService {
194 192 ssrcConfig.releaseSsrc(ssrc);
195 193 mediaServerItem.setSsrcConfig(ssrcConfig);
196 194 String key = VideoManagerConstants.MEDIA_SERVER_PREFIX + userSetting.getServerId() + "_" + mediaServerItem.getId();
197   - redisUtil.set(key, mediaServerItem);
  195 + RedisUtil.set(key, mediaServerItem);
198 196 }
199 197  
200 198 /**
... ... @@ -203,7 +201,7 @@ public class MediaServerServiceImpl implements IMediaServerService {
203 201 @Override
204 202 public void clearRTPServer(MediaServerItem mediaServerItem) {
205 203 mediaServerItem.setSsrcConfig(new SsrcConfig(mediaServerItem.getId(), null, sipConfig.getDomain()));
206   - redisUtil.zAdd(VideoManagerConstants.MEDIA_SERVERS_ONLINE_PREFIX + userSetting.getServerId(), mediaServerItem.getId(), 0);
  204 + RedisUtil.zAdd(VideoManagerConstants.MEDIA_SERVERS_ONLINE_PREFIX + userSetting.getServerId(), mediaServerItem.getId(), 0);
207 205  
208 206 }
209 207  
... ... @@ -225,19 +223,19 @@ public class MediaServerServiceImpl implements IMediaServerService {
225 223 );
226 224 }
227 225 String key = VideoManagerConstants.MEDIA_SERVER_PREFIX + userSetting.getServerId() + "_" + mediaServerItemInDataBase.getId();
228   - redisUtil.set(key, mediaServerItemInDataBase);
  226 + RedisUtil.set(key, mediaServerItemInDataBase);
229 227 }
230 228  
231 229 @Override
232 230 public List<MediaServerItem> getAll() {
233 231 List<MediaServerItem> result = new ArrayList<>();
234   - List<Object> mediaServerKeys = redisUtil.scan(String.format("%S*", VideoManagerConstants.MEDIA_SERVER_PREFIX+ userSetting.getServerId() + "_" ));
  232 + List<Object> mediaServerKeys = RedisUtil.scan(String.format("%S*", VideoManagerConstants.MEDIA_SERVER_PREFIX+ userSetting.getServerId() + "_" ));
235 233 String onlineKey = VideoManagerConstants.MEDIA_SERVERS_ONLINE_PREFIX + userSetting.getServerId();
236 234 for (Object mediaServerKey : mediaServerKeys) {
237 235 String key = (String) mediaServerKey;
238   - MediaServerItem mediaServerItem = (MediaServerItem) redisUtil.get(key);
  236 + MediaServerItem mediaServerItem = (MediaServerItem) RedisUtil.get(key);
239 237 // 检查状态
240   - Double aDouble = redisUtil.zScore(onlineKey, mediaServerItem.getId());
  238 + Double aDouble = RedisUtil.zScore(onlineKey, mediaServerItem.getId());
241 239 if (aDouble != null) {
242 240 mediaServerItem.setStatus(true);
243 241 }
... ... @@ -263,13 +261,13 @@ public class MediaServerServiceImpl implements IMediaServerService {
263 261 @Override
264 262 public List<MediaServerItem> getAllOnline() {
265 263 String key = VideoManagerConstants.MEDIA_SERVERS_ONLINE_PREFIX + userSetting.getServerId();
266   - Set<String> mediaServerIdSet = redisUtil.zRevRange(key, 0, -1);
  264 + Set<String> mediaServerIdSet = RedisUtil.zRevRange(key, 0, -1);
267 265  
268 266 List<MediaServerItem> result = new ArrayList<>();
269 267 if (mediaServerIdSet != null && mediaServerIdSet.size() > 0) {
270 268 for (String mediaServerId : mediaServerIdSet) {
271 269 String serverKey = VideoManagerConstants.MEDIA_SERVER_PREFIX + userSetting.getServerId() + "_" + mediaServerId;
272   - result.add((MediaServerItem) redisUtil.get(serverKey));
  270 + result.add((MediaServerItem) RedisUtil.get(serverKey));
273 271 }
274 272 }
275 273 Collections.reverse(result);
... ... @@ -287,7 +285,7 @@ public class MediaServerServiceImpl implements IMediaServerService {
287 285 return null;
288 286 }
289 287 String key = VideoManagerConstants.MEDIA_SERVER_PREFIX + userSetting.getServerId() + "_" + mediaServerId;
290   - return (MediaServerItem)redisUtil.get(key);
  288 + return (MediaServerItem)RedisUtil.get(key);
291 289 }
292 290  
293 291 @Override
... ... @@ -299,12 +297,11 @@ public class MediaServerServiceImpl implements IMediaServerService {
299 297 @Override
300 298 public void clearMediaServerForOnline() {
301 299 String key = VideoManagerConstants.MEDIA_SERVERS_ONLINE_PREFIX + userSetting.getServerId();
302   - redisUtil.del(key);
  300 + RedisUtil.del(key);
303 301 }
304 302  
305 303 @Override
306   - public WVPResult<String> add(MediaServerItem mediaServerItem) {
307   - WVPResult<String> result = new WVPResult<>();
  304 + public void add(MediaServerItem mediaServerItem) {
308 305 mediaServerItem.setCreateTime(DateUtil.getNow());
309 306 mediaServerItem.setUpdateTime(DateUtil.getNow());
310 307 mediaServerItem.setHookAliveInterval(120);
... ... @@ -314,26 +311,19 @@ public class MediaServerServiceImpl implements IMediaServerService {
314 311 if (data != null && data.size() > 0) {
315 312 ZLMServerConfig zlmServerConfig= JSON.parseObject(JSON.toJSONString(data.get(0)), ZLMServerConfig.class);
316 313 if (mediaServerMapper.queryOne(zlmServerConfig.getGeneralMediaServerId()) != null) {
317   - result.setCode(-1);
318   - result.setMsg("保存失败,媒体服务ID [ " + zlmServerConfig.getGeneralMediaServerId() + " ] 已存在,请修改媒体服务器配置");
319   - return result;
  314 + throw new ControllerException(ErrorCode.ERROR100.getCode(),"保存失败,媒体服务ID [ " + zlmServerConfig.getGeneralMediaServerId() + " ] 已存在,请修改媒体服务器配置");
320 315 }
321 316 mediaServerItem.setId(zlmServerConfig.getGeneralMediaServerId());
322 317 zlmServerConfig.setIp(mediaServerItem.getIp());
323 318 mediaServerMapper.add(mediaServerItem);
324 319 zlmServerOnline(zlmServerConfig);
325   - result.setCode(0);
326   - result.setMsg("success");
327 320 }else {
328   - result.setCode(-1);
329   - result.setMsg("连接失败");
  321 + throw new ControllerException(ErrorCode.ERROR100.getCode(),"连接失败");
330 322 }
331 323  
332 324 }else {
333   - result.setCode(-1);
334   - result.setMsg("连接失败");
  325 + throw new ControllerException(ErrorCode.ERROR100.getCode(),"连接失败");
335 326 }
336   - return result;
337 327 }
338 328  
339 329 @Override
... ... @@ -401,20 +391,20 @@ public class MediaServerServiceImpl implements IMediaServerService {
401 391 }
402 392 serverItem.setStatus(true);
403 393  
404   - if (StringUtils.isEmpty(serverItem.getId())) {
  394 + if (ObjectUtils.isEmpty(serverItem.getId())) {
405 395 logger.warn("[未注册的zlm] serverItem缺少ID, 无法接入:{}:{}", zlmServerConfig.getIp(),zlmServerConfig.getHttpPort() );
406 396 return;
407 397 }
408 398 mediaServerMapper.update(serverItem);
409 399 String key = VideoManagerConstants.MEDIA_SERVER_PREFIX + userSetting.getServerId() + "_" + zlmServerConfig.getGeneralMediaServerId();
410   - if (redisUtil.get(key) == null) {
  400 + if (RedisUtil.get(key) == null) {
411 401 SsrcConfig ssrcConfig = new SsrcConfig(zlmServerConfig.getGeneralMediaServerId(), null, sipConfig.getDomain());
412 402 serverItem.setSsrcConfig(ssrcConfig);
413 403 }else {
414   - MediaServerItem mediaServerItemInRedis = (MediaServerItem)redisUtil.get(key);
  404 + MediaServerItem mediaServerItemInRedis = (MediaServerItem)RedisUtil.get(key);
415 405 serverItem.setSsrcConfig(mediaServerItemInRedis.getSsrcConfig());
416 406 }
417   - redisUtil.set(key, serverItem);
  407 + RedisUtil.set(key, serverItem);
418 408 resetOnlineServerItem(serverItem);
419 409 if (serverItem.isAutoConfig()) {
420 410 setZLMConfig(serverItem, "0".equals(zlmServerConfig.getHookEnable()));
... ... @@ -435,15 +425,15 @@ public class MediaServerServiceImpl implements IMediaServerService {
435 425 // 更新缓存
436 426 String key = VideoManagerConstants.MEDIA_SERVERS_ONLINE_PREFIX + userSetting.getServerId();
437 427 // 使用zset的分数作为当前并发量, 默认值设置为0
438   - if (redisUtil.zScore(key, serverItem.getId()) == null) { // 不存在则设置默认值 已存在则重置
439   - redisUtil.zAdd(key, serverItem.getId(), 0L);
  428 + if (RedisUtil.zScore(key, serverItem.getId()) == null) { // 不存在则设置默认值 已存在则重置
  429 + RedisUtil.zAdd(key, serverItem.getId(), 0L);
440 430 // 查询服务流数量
441 431 zlmresTfulUtils.getMediaList(serverItem, null, null, "rtmp",(mediaList ->{
442 432 Integer code = mediaList.getInteger("code");
443 433 if (code == 0) {
444 434 JSONArray data = mediaList.getJSONArray("data");
445 435 if (data != null) {
446   - redisUtil.zAdd(key, serverItem.getId(), data.size());
  436 + RedisUtil.zAdd(key, serverItem.getId(), data.size());
447 437 }
448 438 }
449 439 }));
... ... @@ -460,14 +450,14 @@ public class MediaServerServiceImpl implements IMediaServerService {
460 450 return;
461 451 }
462 452 String key = VideoManagerConstants.MEDIA_SERVERS_ONLINE_PREFIX + userSetting.getServerId();
463   - redisUtil.zIncrScore(key, mediaServerId, 1);
  453 + RedisUtil.zIncrScore(key, mediaServerId, 1);
464 454  
465 455 }
466 456  
467 457 @Override
468 458 public void removeCount(String mediaServerId) {
469 459 String key = VideoManagerConstants.MEDIA_SERVERS_ONLINE_PREFIX + userSetting.getServerId();
470   - redisUtil.zIncrScore(key, mediaServerId, - 1);
  460 + RedisUtil.zIncrScore(key, mediaServerId, - 1);
471 461 }
472 462  
473 463 /**
... ... @@ -478,15 +468,15 @@ public class MediaServerServiceImpl implements IMediaServerService {
478 468 public MediaServerItem getMediaServerForMinimumLoad() {
479 469 String key = VideoManagerConstants.MEDIA_SERVERS_ONLINE_PREFIX + userSetting.getServerId();
480 470  
481   - if (redisUtil.zSize(key) == null || redisUtil.zSize(key) == 0) {
482   - if (redisUtil.zSize(key) == null || redisUtil.zSize(key) == 0) {
  471 + if (RedisUtil.zSize(key) == null || RedisUtil.zSize(key) == 0) {
  472 + if (RedisUtil.zSize(key) == null || RedisUtil.zSize(key) == 0) {
483 473 logger.info("获取负载最低的节点时无在线节点");
484 474 return null;
485 475 }
486 476 }
487 477  
488 478 // 获取分数最低的,及并发最低的
489   - Set<Object> objects = redisUtil.ZRange(key, 0, -1);
  479 + Set<Object> objects = RedisUtil.ZRange(key, 0, -1);
490 480 ArrayList<Object> mediaServerObjectS = new ArrayList<>(objects);
491 481  
492 482 String mediaServerId = (String)mediaServerObjectS.get(0);
... ... @@ -536,7 +526,7 @@ public class MediaServerServiceImpl implements IMediaServerService {
536 526 // 最多等待未初始化的Track时间,单位毫秒,超时之后会忽略未初始化的Track, 设置此选项优化那些音频错误的不规范流,
537 527 // 等zlm支持给每个rtpServer设置关闭音频的时候可以不设置此选项
538 528 // param.put("general.wait_track_ready_ms", "3000" );
539   - if (mediaServerItem.isRtpEnable() && !StringUtils.isEmpty(mediaServerItem.getRtpPortRange())) {
  529 + if (mediaServerItem.isRtpEnable() && !ObjectUtils.isEmpty(mediaServerItem.getRtpPortRange())) {
540 530 param.put("rtp_proxy.port_range", mediaServerItem.getRtpPortRange().replace(",", "-"));
541 531 }
542 532  
... ... @@ -563,12 +553,9 @@ public class MediaServerServiceImpl implements IMediaServerService {
563 553  
564 554  
565 555 @Override
566   - public WVPResult<MediaServerItem> checkMediaServer(String ip, int port, String secret) {
567   - WVPResult<MediaServerItem> result = new WVPResult<>();
  556 + public MediaServerItem checkMediaServer(String ip, int port, String secret) {
568 557 if (mediaServerMapper.queryOneByHostAndPort(ip, port) != null) {
569   - result.setCode(-1);
570   - result.setMsg("此连接已存在");
571   - return result;
  558 + throw new ControllerException(ErrorCode.ERROR100.getCode(), "此连接已存在");
572 559 }
573 560 MediaServerItem mediaServerItem = new MediaServerItem();
574 561 mediaServerItem.setIp(ip);
... ... @@ -576,21 +563,15 @@ public class MediaServerServiceImpl implements IMediaServerService {
576 563 mediaServerItem.setSecret(secret);
577 564 JSONObject responseJSON = zlmresTfulUtils.getMediaServerConfig(mediaServerItem);
578 565 if (responseJSON == null) {
579   - result.setCode(-1);
580   - result.setMsg("连接失败");
581   - return result;
  566 + throw new ControllerException(ErrorCode.ERROR100.getCode(), "连接失败");
582 567 }
583 568 JSONArray data = responseJSON.getJSONArray("data");
584 569 ZLMServerConfig zlmServerConfig = JSON.parseObject(JSON.toJSONString(data.get(0)), ZLMServerConfig.class);
585 570 if (zlmServerConfig == null) {
586   - result.setCode(-1);
587   - result.setMsg("读取配置失败");
588   - return result;
  571 + throw new ControllerException(ErrorCode.ERROR100.getCode(), "读取配置失败");
589 572 }
590 573 if (mediaServerMapper.queryOne(zlmServerConfig.getGeneralMediaServerId()) != null) {
591   - result.setCode(-1);
592   - result.setMsg("媒体服务ID [" + zlmServerConfig.getGeneralMediaServerId() + " ] 已存在,请修改媒体服务器配置");
593   - return result;
  574 + throw new ControllerException(ErrorCode.ERROR100.getCode(), "媒体服务ID [" + zlmServerConfig.getGeneralMediaServerId() + " ] 已存在,请修改媒体服务器配置");
594 575 }
595 576 mediaServerItem.setHttpSSlPort(zlmServerConfig.getHttpPort());
596 577 mediaServerItem.setRtmpPort(zlmServerConfig.getRtmpPort());
... ... @@ -602,10 +583,7 @@ public class MediaServerServiceImpl implements IMediaServerService {
602 583 mediaServerItem.setHookIp(sipConfig.getIp());
603 584 mediaServerItem.setSdpIp(ip);
604 585 mediaServerItem.setStreamNoneReaderDelayMS(zlmServerConfig.getGeneralStreamNoneReaderDelayMS());
605   - result.setCode(0);
606   - result.setMsg("成功");
607   - result.setData(mediaServerItem);
608   - return result;
  586 + return mediaServerItem;
609 587 }
610 588  
611 589 @Override
... ... @@ -629,9 +607,9 @@ public class MediaServerServiceImpl implements IMediaServerService {
629 607  
630 608 @Override
631 609 public void delete(String id) {
632   - redisUtil.zRemove(VideoManagerConstants.MEDIA_SERVERS_ONLINE_PREFIX + userSetting.getServerId(), id);
  610 + RedisUtil.zRemove(VideoManagerConstants.MEDIA_SERVERS_ONLINE_PREFIX + userSetting.getServerId(), id);
633 611 String key = VideoManagerConstants.MEDIA_SERVER_PREFIX + userSetting.getServerId() + "_" + id;
634   - redisUtil.del(key);
  612 + RedisUtil.del(key);
635 613 }
636 614 @Override
637 615 public void deleteDb(String id){
... ... @@ -650,7 +628,7 @@ public class MediaServerServiceImpl implements IMediaServerService {
650 628 }
651 629 // zlm连接重试
652 630 logger.warn("[更新ZLM 保活信息]失败,未找到流媒体信息,尝试重连zlm");
653   - reloadZlm();
  631 +// reloadZlm();
654 632 mediaServerItem = getOne(mediaServerId);
655 633 if (mediaServerItem == null) {
656 634 // zlm连接重试
... ... @@ -660,7 +638,7 @@ public class MediaServerServiceImpl implements IMediaServerService {
660 638 }
661 639 String key = VideoManagerConstants.MEDIA_SERVER_KEEPALIVE_PREFIX + userSetting.getServerId() + "_" + mediaServerId;
662 640 int hookAliveInterval = mediaServerItem.getHookAliveInterval() + 2;
663   - redisUtil.set(key, data, hookAliveInterval);
  641 + RedisUtil.set(key, data, hookAliveInterval);
664 642 }
665 643  
666 644 private MediaServerItem getOneFromDatabase(String mediaServerId) {
... ... @@ -682,13 +660,4 @@ public class MediaServerServiceImpl implements IMediaServerService {
682 660 }
683 661 }
684 662 }
685   -
686   - public void reloadZlm(){
687   - try {
688   - zlmRunner.run();
689   - Thread.sleep(500);//延迟0.5秒缓冲时间
690   - } catch (Exception e) {
691   - logger.warn("尝试重连zlm失败!",e);
692   - }
693   - }
694 663 }
... ...
src/main/java/com/genersoft/iot/vmp/service/impl/MediaServiceImpl.java
... ... @@ -15,6 +15,7 @@ import com.genersoft.iot.vmp.storager.IVideoManagerStorage;
15 15 import com.genersoft.iot.vmp.service.IMediaService;
16 16 import org.springframework.beans.factory.annotation.Autowired;
17 17 import org.springframework.stereotype.Service;
  18 +import org.springframework.util.ObjectUtils;
18 19 import org.springframework.util.StringUtils;
19 20  
20 21 @Service
... ... @@ -94,7 +95,7 @@ public class MediaServiceImpl implements IMediaService {
94 95 }
95 96 streamInfoResult.setIp(addr);
96 97 streamInfoResult.setMediaServerId(mediaInfo.getId());
97   - String callIdParam = StringUtils.isEmpty(callId)?"":"?callId=" + callId;
  98 + String callIdParam = ObjectUtils.isEmpty(callId)?"":"?callId=" + callId;
98 99 streamInfoResult.setRtmp(String.format("rtmp://%s:%s/%s/%s%s", addr, mediaInfo.getRtmpPort(), app, stream, callIdParam));
99 100 if (mediaInfo.getRtmpSSlPort() != 0) {
100 101 streamInfoResult.setRtmps(String.format("rtmps://%s:%s/%s/%s%s", addr, mediaInfo.getRtmpSSlPort(), app, stream, callIdParam));
... ... @@ -121,7 +122,7 @@ public class MediaServiceImpl implements IMediaService {
121 122 streamInfoResult.setHttps_ts(String.format("https://%s:%s/%s/%s.live.ts%s", addr, mediaInfo.getHttpSSlPort(), app, stream, callIdParam));
122 123 streamInfoResult.setWss_ts(String.format("wss://%s:%s/%s/%s.live.ts%s", addr, mediaInfo.getHttpSSlPort(), app, stream, callIdParam));
123 124 streamInfoResult.setWss_ts(String.format("wss://%s:%s/%s/%s.live.ts%s", addr, mediaInfo.getHttpSSlPort(), app, stream, callIdParam));
124   - streamInfoResult.setRtc(String.format("https://%s:%s/index/api/webrtc?app=%s&stream=%s&type=%s%s", mediaInfo.getStreamIp(), mediaInfo.getHttpSSlPort(), app, stream, isPlay?"play":"push", StringUtils.isEmpty(callId)?"":"&callId=" + callId));
  125 + streamInfoResult.setRtc(String.format("https://%s:%s/index/api/webrtc?app=%s&stream=%s&type=%s%s", mediaInfo.getStreamIp(), mediaInfo.getHttpSSlPort(), app, stream, isPlay?"play":"push", ObjectUtils.isEmpty(callId)?"":"&callId=" + callId));
125 126 }
126 127  
127 128 streamInfoResult.setTracks(tracks);
... ...
src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java
... ... @@ -7,12 +7,12 @@ import java.util.*;
7 7 import javax.sip.ResponseEvent;
8 8  
9 9 import com.genersoft.iot.vmp.gb28181.bean.*;
  10 +import com.genersoft.iot.vmp.conf.exception.ControllerException;
  11 +import com.genersoft.iot.vmp.vmanager.bean.ErrorCode;
10 12 import org.slf4j.Logger;
11 13 import org.slf4j.LoggerFactory;
12 14 import org.springframework.beans.factory.annotation.Autowired;
13 15 import org.springframework.beans.factory.annotation.Qualifier;
14   -import org.springframework.http.HttpStatus;
15   -import org.springframework.http.ResponseEntity;
16 16 import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
17 17 import org.springframework.stereotype.Service;
18 18 import org.springframework.web.context.request.async.DeferredResult;
... ... @@ -34,7 +34,6 @@ import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommanderFroPlatform;
34 34 import com.genersoft.iot.vmp.media.zlm.ZLMRTPServerFactory;
35 35 import com.genersoft.iot.vmp.media.zlm.dto.HookSubscribeFactory;
36 36 import com.genersoft.iot.vmp.media.zlm.dto.HookSubscribeForStreamChange;
37   -import com.genersoft.iot.vmp.media.zlm.dto.HookType;
38 37 import com.genersoft.iot.vmp.utils.DateUtil;
39 38 import com.genersoft.iot.vmp.media.zlm.AssistRESTfulUtils;
40 39 import com.genersoft.iot.vmp.media.zlm.ZLMHttpHookSubscribe;
... ... @@ -141,6 +140,9 @@ public class PlayServiceImpl implements IPlayService {
141 140 public PlayResult play(MediaServerItem mediaServerItem, String deviceId, String channelId,
142 141 ZLMHttpHookSubscribe.Event hookEvent, SipSubscribe.Event errorEvent,
143 142 Runnable timeoutCallback) {
  143 + if (mediaServerItem == null) {
  144 + throw new ControllerException(ErrorCode.ERROR100.getCode(), "未找到可用的zlm");
  145 + }
144 146 PlayResult playResult = new PlayResult();
145 147 RequestMessage msg = new RequestMessage();
146 148 String key = DeferredResultHolder.CALLBACK_CMD_PLAY + deviceId + channelId;
... ... @@ -148,18 +150,11 @@ public class PlayServiceImpl implements IPlayService {
148 150 String uuid = UUID.randomUUID().toString();
149 151 msg.setId(uuid);
150 152 playResult.setUuid(uuid);
151   - DeferredResult<ResponseEntity<String>> result = new DeferredResult<>(userSetting.getPlayTimeout().longValue());
  153 + DeferredResult<WVPResult<String>> result = new DeferredResult<>(userSetting.getPlayTimeout().longValue());
152 154 playResult.setResult(result);
153 155 // 录像查询以channelId作为deviceId查询
154 156 resultHolder.put(key, uuid, result);
155   - if (mediaServerItem == null) {
156   - WVPResult wvpResult = new WVPResult();
157   - wvpResult.setCode(-1);
158   - wvpResult.setMsg("未找到可用的zlm");
159   - msg.setData(wvpResult);
160   - resultHolder.invokeResult(msg);
161   - return playResult;
162   - }
  157 +
163 158 Device device = redisCatchStorage.getDevice(deviceId);
164 159 StreamInfo streamInfo = redisCatchStorage.queryPlayByDevice(deviceId, channelId);
165 160 playResult.setDevice(device);
... ... @@ -170,17 +165,14 @@ public class PlayServiceImpl implements IPlayService {
170 165 // TODO 应该在上流时调用更好,结束也可能是错误结束
171 166 String path = "snap";
172 167 String fileName = deviceId + "_" + channelId + ".jpg";
173   - ResponseEntity responseEntity = (ResponseEntity)result.getResult();
174   - if (responseEntity != null && responseEntity.getStatusCode() == HttpStatus.OK) {
175   - WVPResult wvpResult = (WVPResult)responseEntity.getBody();
176   - if (Objects.requireNonNull(wvpResult).getCode() == 0) {
177   - StreamInfo streamInfoForSuccess = (StreamInfo)wvpResult.getData();
178   - MediaServerItem mediaInfo = mediaServerService.getOne(streamInfoForSuccess.getMediaServerId());
179   - String streamUrl = streamInfoForSuccess.getFmp4();
180   - // 请求截图
181   - logger.info("[请求截图]: " + fileName);
182   - zlmresTfulUtils.getSnap(mediaInfo, streamUrl, 15, 1, path, fileName);
183   - }
  168 + WVPResult wvpResult = (WVPResult)result.getResult();
  169 + if (Objects.requireNonNull(wvpResult).getCode() == 0) {
  170 + StreamInfo streamInfoForSuccess = (StreamInfo)wvpResult.getData();
  171 + MediaServerItem mediaInfo = mediaServerService.getOne(streamInfoForSuccess.getMediaServerId());
  172 + String streamUrl = streamInfoForSuccess.getFmp4();
  173 + // 请求截图
  174 + logger.info("[请求截图]: " + fileName);
  175 + zlmresTfulUtils.getSnap(mediaInfo, streamUrl, 15, 1, path, fileName);
184 176 }
185 177 });
186 178 });
... ... @@ -188,7 +180,7 @@ public class PlayServiceImpl implements IPlayService {
188 180 String streamId = streamInfo.getStream();
189 181 if (streamId == null) {
190 182 WVPResult wvpResult = new WVPResult();
191   - wvpResult.setCode(-1);
  183 + wvpResult.setCode(ErrorCode.ERROR100.getCode());
192 184 wvpResult.setMsg("点播失败, redis缓存streamId等于null");
193 185 msg.setData(wvpResult);
194 186 resultHolder.invokeAllResult(msg);
... ... @@ -202,8 +194,8 @@ public class PlayServiceImpl implements IPlayService {
202 194 if (rtpInfo.getBoolean("exist")) {
203 195  
204 196 WVPResult wvpResult = new WVPResult();
205   - wvpResult.setCode(0);
206   - wvpResult.setMsg("success");
  197 + wvpResult.setCode(ErrorCode.SUCCESS.getCode());
  198 + wvpResult.setMsg(ErrorCode.SUCCESS.getMsg());
207 199 wvpResult.setData(streamInfo);
208 200 msg.setData(wvpResult);
209 201  
... ... @@ -236,7 +228,7 @@ public class PlayServiceImpl implements IPlayService {
236 228 }, event -> {
237 229 // sip error错误
238 230 WVPResult wvpResult = new WVPResult();
239   - wvpResult.setCode(-1);
  231 + wvpResult.setCode(ErrorCode.ERROR100.getCode());
240 232 wvpResult.setMsg(String.format("点播失败, 错误码: %s, %s", event.statusCode, event.msg));
241 233 msg.setData(wvpResult);
242 234 resultHolder.invokeAllResult(msg);
... ... @@ -246,7 +238,7 @@ public class PlayServiceImpl implements IPlayService {
246 238 }, (code, msgStr)->{
247 239 // invite点播超时
248 240 WVPResult wvpResult = new WVPResult();
249   - wvpResult.setCode(-1);
  241 + wvpResult.setCode(ErrorCode.ERROR100.getCode());
250 242 if (code == 0) {
251 243 wvpResult.setMsg("点播超时,请稍候重试");
252 244 }else if (code == 1) {
... ... @@ -386,15 +378,15 @@ public class PlayServiceImpl implements IPlayService {
386 378 redisCatchStorage.startPlay(streamInfo);
387 379  
388 380 WVPResult wvpResult = new WVPResult();
389   - wvpResult.setCode(0);
390   - wvpResult.setMsg("success");
  381 + wvpResult.setCode(ErrorCode.SUCCESS.getCode());
  382 + wvpResult.setMsg(ErrorCode.SUCCESS.getMsg());
391 383 wvpResult.setData(streamInfo);
392 384 msg.setData(wvpResult);
393 385  
394 386 resultHolder.invokeAllResult(msg);
395 387 } else {
396 388 logger.warn("设备预览API调用失败!");
397   - msg.setData("设备预览API调用失败!");
  389 + msg.setData(WVPResult.fail(ErrorCode.ERROR100.getCode(), "设备预览API调用失败!"));
398 390 resultHolder.invokeAllResult(msg);
399 391 }
400 392 }
... ... @@ -418,7 +410,7 @@ public class PlayServiceImpl implements IPlayService {
418 410 }
419 411  
420 412 @Override
421   - public DeferredResult<ResponseEntity<String>> playBack(String deviceId, String channelId, String startTime,
  413 + public DeferredResult<String> playBack(String deviceId, String channelId, String startTime,
422 414 String endTime,InviteStreamCallback inviteStreamCallback,
423 415 PlayBackCallback callback) {
424 416 Device device = storager.queryVideoDevice(deviceId);
... ... @@ -432,7 +424,7 @@ public class PlayServiceImpl implements IPlayService {
432 424 }
433 425  
434 426 @Override
435   - public DeferredResult<ResponseEntity<String>> playBack(MediaServerItem mediaServerItem, SSRCInfo ssrcInfo,
  427 + public DeferredResult<String> playBack(MediaServerItem mediaServerItem, SSRCInfo ssrcInfo,
436 428 String deviceId, String channelId, String startTime,
437 429 String endTime, InviteStreamCallback infoCallBack,
438 430 PlayBackCallback playBackCallback) {
... ... @@ -441,24 +433,21 @@ public class PlayServiceImpl implements IPlayService {
441 433 }
442 434 String uuid = UUID.randomUUID().toString();
443 435 String key = DeferredResultHolder.CALLBACK_CMD_PLAYBACK + deviceId + channelId;
444   - DeferredResult<ResponseEntity<String>> result = new DeferredResult<>(30000L);
445 436 Device device = storager.queryVideoDevice(deviceId);
446 437 if (device == null) {
447   - result.setResult(new ResponseEntity<>(HttpStatus.BAD_REQUEST));
448   - return result;
  438 + throw new ControllerException(ErrorCode.ERROR100.getCode(), "设备: " + deviceId + "不存在");
449 439 }
450   -
  440 + DeferredResult<String> result = new DeferredResult<>(30000L);
451 441 resultHolder.put(DeferredResultHolder.CALLBACK_CMD_PLAYBACK + deviceId + channelId, uuid, result);
452   - RequestMessage msg = new RequestMessage();
453   - msg.setId(uuid);
454   - msg.setKey(key);
  442 + RequestMessage requestMessage = new RequestMessage();
  443 + requestMessage.setId(uuid);
  444 + requestMessage.setKey(key);
455 445 PlayBackResult<RequestMessage> playBackResult = new PlayBackResult<>();
456   - String playBackTimeOutTaskKey = UUID.randomUUID().toString();
  446 + String playBackTimeOutTaskKey = UUID.randomUUID().toString();
457 447 dynamicTask.startDelay(playBackTimeOutTaskKey, ()->{
458 448 logger.warn(String.format("设备回放超时,deviceId:%s ,channelId:%s", deviceId, channelId));
459 449 playBackResult.setCode(-1);
460   - playBackResult.setData(msg);
461   - playBackCallback.call(playBackResult);
  450 + playBackResult.setData(requestMessage);
462 451 SIPDialog dialog = streamSession.getDialogByStream(deviceId, channelId, ssrcInfo.getStream());
463 452 // 点播超时回复BYE 同时释放ssrc以及此次点播的资源
464 453 if (dialog != null) {
... ... @@ -481,24 +470,23 @@ public class PlayServiceImpl implements IPlayService {
481 470 StreamInfo streamInfo = onPublishHandler(inviteStreamInfo.getMediaServerItem(), inviteStreamInfo.getResponse(), deviceId, channelId);
482 471 if (streamInfo == null) {
483 472 logger.warn("设备回放API调用失败!");
484   - msg.setData("设备回放API调用失败!");
485 473 playBackResult.setCode(-1);
486   - playBackResult.setData(msg);
487 474 playBackCallback.call(playBackResult);
488 475 return;
489 476 }
490 477 redisCatchStorage.startPlayback(streamInfo, inviteStreamInfo.getCallId());
491   - msg.setData(JSON.toJSONString(streamInfo));
  478 + WVPResult<StreamInfo> success = WVPResult.success(streamInfo);
  479 + requestMessage.setData(success);
492 480 playBackResult.setCode(0);
493   - playBackResult.setData(msg);
  481 + playBackResult.setData(requestMessage);
494 482 playBackResult.setMediaServerItem(inviteStreamInfo.getMediaServerItem());
495 483 playBackResult.setResponse(inviteStreamInfo.getResponse());
496 484 playBackCallback.call(playBackResult);
497 485 }, event -> {
498 486 dynamicTask.stop(playBackTimeOutTaskKey);
499   - msg.setData(String.format("回放失败, 错误码: %s, %s", event.statusCode, event.msg));
  487 + requestMessage.setData(WVPResult.fail(ErrorCode.ERROR100.getCode(), String.format("回放失败, 错误码: %s, %s", event.statusCode, event.msg)));
500 488 playBackResult.setCode(-1);
501   - playBackResult.setData(msg);
  489 + playBackResult.setData(requestMessage);
502 490 playBackResult.setEvent(event);
503 491 playBackCallback.call(playBackResult);
504 492 streamSession.remove(device.getDeviceId(), channelId, ssrcInfo.getStream());
... ... @@ -507,7 +495,7 @@ public class PlayServiceImpl implements IPlayService {
507 495 }
508 496  
509 497 @Override
510   - public DeferredResult<ResponseEntity<String>> download(String deviceId, String channelId, String startTime, String endTime, int downloadSpeed, InviteStreamCallback infoCallBack, PlayBackCallback hookCallBack) {
  498 + public DeferredResult<String> download(String deviceId, String channelId, String startTime, String endTime, int downloadSpeed, InviteStreamCallback infoCallBack, PlayBackCallback hookCallBack) {
511 499 Device device = storager.queryVideoDevice(deviceId);
512 500 if (device == null) {
513 501 return null;
... ... @@ -519,32 +507,31 @@ public class PlayServiceImpl implements IPlayService {
519 507 }
520 508  
521 509 @Override
522   - public DeferredResult<ResponseEntity<String>> download(MediaServerItem mediaServerItem, SSRCInfo ssrcInfo, String deviceId, String channelId, String startTime, String endTime, int downloadSpeed, InviteStreamCallback infoCallBack, PlayBackCallback hookCallBack) {
  510 + public DeferredResult<String> download(MediaServerItem mediaServerItem, SSRCInfo ssrcInfo, String deviceId, String channelId, String startTime, String endTime, int downloadSpeed, InviteStreamCallback infoCallBack, PlayBackCallback hookCallBack) {
523 511 if (mediaServerItem == null || ssrcInfo == null) {
524 512 return null;
525 513 }
526 514 String uuid = UUID.randomUUID().toString();
527 515 String key = DeferredResultHolder.CALLBACK_CMD_DOWNLOAD + deviceId + channelId;
528   - DeferredResult<ResponseEntity<String>> result = new DeferredResult<>(30000L);
  516 + DeferredResult<String> result = new DeferredResult<>(30000L);
529 517 Device device = storager.queryVideoDevice(deviceId);
530 518 if (device == null) {
531   - result.setResult(new ResponseEntity<>(HttpStatus.BAD_REQUEST));
532   - return result;
  519 + throw new ControllerException(ErrorCode.ERROR400.getCode(), "设备:" + deviceId + "不存在");
533 520 }
534 521  
535 522 resultHolder.put(key, uuid, result);
536   - RequestMessage msg = new RequestMessage();
537   - msg.setId(uuid);
538   - msg.setKey(key);
  523 + RequestMessage requestMessage = new RequestMessage();
  524 + requestMessage.setId(uuid);
  525 + requestMessage.setKey(key);
539 526 WVPResult<StreamInfo> wvpResult = new WVPResult<>();
540   - msg.setData(wvpResult);
  527 + requestMessage.setData(wvpResult);
541 528 PlayBackResult<RequestMessage> downloadResult = new PlayBackResult<>();
542   - downloadResult.setData(msg);
  529 + downloadResult.setData(requestMessage);
543 530  
544 531 String downLoadTimeOutTaskKey = UUID.randomUUID().toString();
545 532 dynamicTask.startDelay(downLoadTimeOutTaskKey, ()->{
546 533 logger.warn(String.format("录像下载请求超时,deviceId:%s ,channelId:%s", deviceId, channelId));
547   - wvpResult.setCode(-1);
  534 + wvpResult.setCode(ErrorCode.ERROR100.getCode());
548 535 wvpResult.setMsg("录像下载请求超时");
549 536 downloadResult.setCode(-1);
550 537 hookCallBack.call(downloadResult);
... ... @@ -578,8 +565,8 @@ public class PlayServiceImpl implements IPlayService {
578 565 return ;
579 566 }
580 567 redisCatchStorage.startDownload(streamInfo, inviteStreamInfo.getCallId());
581   - wvpResult.setCode(0);
582   - wvpResult.setMsg("success");
  568 + wvpResult.setCode(ErrorCode.SUCCESS.getCode());
  569 + wvpResult.setMsg(ErrorCode.SUCCESS.getMsg());
583 570 wvpResult.setData(streamInfo);
584 571 downloadResult.setCode(0);
585 572 downloadResult.setMediaServerItem(inviteStreamInfo.getMediaServerItem());
... ... @@ -588,7 +575,7 @@ public class PlayServiceImpl implements IPlayService {
588 575 }, event -> {
589 576 dynamicTask.stop(downLoadTimeOutTaskKey);
590 577 downloadResult.setCode(-1);
591   - wvpResult.setCode(-1);
  578 + wvpResult.setCode(ErrorCode.ERROR100.getCode());
592 579 wvpResult.setMsg(String.format("录像下载失败, 错误码: %s, %s", event.statusCode, event.msg));
593 580 downloadResult.setEvent(event);
594 581 hookCallBack.call(downloadResult);
... ... @@ -649,7 +636,7 @@ public class PlayServiceImpl implements IPlayService {
649 636 resultHolder.invokeResult(msg);
650 637 } else {
651 638 logger.warn("设备预览API调用失败!");
652   - msg.setData("设备预览API调用失败!");
  639 + msg.setData(WVPResult.fail(ErrorCode.ERROR100.getCode(), "设备预览API调用失败!"));
653 640 resultHolder.invokeResult(msg);
654 641 }
655 642 }
... ...
src/main/java/com/genersoft/iot/vmp/service/impl/RedisGbPlayMsgListener.java
... ... @@ -66,8 +66,6 @@ public class RedisGbPlayMsgListener implements MessageListener {
66 66 @Autowired
67 67 private UserSetting userSetting;
68 68  
69   - @Autowired
70   - private RedisUtil redis;
71 69  
72 70 @Autowired
73 71 private ZLMMediaListManager zlmMediaListManager;
... ... @@ -227,7 +225,7 @@ public class RedisGbPlayMsgListener implements MessageListener {
227 225 WvpRedisMsg response = WvpRedisMsg.getResponseInstance(userSetting.getServerId(), toId,
228 226 WvpRedisMsgCmd.REQUEST_PUSH_STREAM, serial, result);
229 227 JSONObject jsonObject = (JSONObject)JSON.toJSON(response);
230   - redis.convertAndSend(WVP_PUSH_STREAM_KEY, jsonObject);
  228 + RedisUtil.convertAndSend(WVP_PUSH_STREAM_KEY, jsonObject);
231 229 }
232 230  
233 231 /**
... ... @@ -246,7 +244,7 @@ public class RedisGbPlayMsgListener implements MessageListener {
246 244 WvpRedisMsgCmd.GET_SEND_ITEM, serial, result);
247 245  
248 246 JSONObject jsonObject = (JSONObject)JSON.toJSON(response);
249   - redis.convertAndSend(WVP_PUSH_STREAM_KEY, jsonObject);
  247 + RedisUtil.convertAndSend(WVP_PUSH_STREAM_KEY, jsonObject);
250 248 return;
251 249 }
252 250 // 确定流是否在线
... ... @@ -269,7 +267,7 @@ public class RedisGbPlayMsgListener implements MessageListener {
269 267 userSetting.getServerId(), toId, WvpRedisMsgCmd.GET_SEND_ITEM, serial, result
270 268 );
271 269 JSONObject jsonObject = (JSONObject)JSON.toJSON(response);
272   - redis.convertAndSend(WVP_PUSH_STREAM_KEY, jsonObject);
  270 + RedisUtil.convertAndSend(WVP_PUSH_STREAM_KEY, jsonObject);
273 271 }, userSetting.getPlatformPlayTimeout());
274 272  
275 273 // 添加订阅
... ... @@ -308,7 +306,7 @@ public class RedisGbPlayMsgListener implements MessageListener {
308 306 userSetting.getServerId(), toId, WvpRedisMsgCmd.GET_SEND_ITEM, serial, result
309 307 );
310 308 JSONObject jsonObject = (JSONObject)JSON.toJSON(response);
311   - redis.convertAndSend(WVP_PUSH_STREAM_KEY, jsonObject);
  309 + RedisUtil.convertAndSend(WVP_PUSH_STREAM_KEY, jsonObject);
312 310 }
313 311  
314 312 /**
... ... @@ -345,7 +343,7 @@ public class RedisGbPlayMsgListener implements MessageListener {
345 343 wvpResult.setMsg("timeout");
346 344 errorCallback.handler(wvpResult);
347 345 }, userSetting.getPlatformPlayTimeout());
348   - redis.convertAndSend(WVP_PUSH_STREAM_KEY, jsonObject);
  346 + RedisUtil.convertAndSend(WVP_PUSH_STREAM_KEY, jsonObject);
349 347 }
350 348  
351 349 /**
... ... @@ -370,6 +368,6 @@ public class RedisGbPlayMsgListener implements MessageListener {
370 368 callbacksForStartSendRtpStream.remove(key);
371 369 callbacksForError.remove(key);
372 370 });
373   - redis.convertAndSend(WVP_PUSH_STREAM_KEY, jsonObject);
  371 + RedisUtil.convertAndSend(WVP_PUSH_STREAM_KEY, jsonObject);
374 372 }
375 373 }
... ...
src/main/java/com/genersoft/iot/vmp/service/impl/RedisPushStreamListMsgListener.java 0 → 100644
  1 +package com.genersoft.iot.vmp.service.impl;
  2 +
  3 +import com.alibaba.fastjson.JSON;
  4 +import com.alibaba.fastjson.JSONObject;
  5 +import com.genersoft.iot.vmp.media.zlm.dto.StreamPushItem;
  6 +import com.genersoft.iot.vmp.service.IGbStreamService;
  7 +import com.genersoft.iot.vmp.service.IMediaServerService;
  8 +import com.genersoft.iot.vmp.service.IStreamPushService;
  9 +import com.genersoft.iot.vmp.utils.DateUtil;
  10 +import org.slf4j.Logger;
  11 +import org.slf4j.LoggerFactory;
  12 +import org.springframework.beans.factory.annotation.Autowired;
  13 +import org.springframework.data.redis.connection.Message;
  14 +import org.springframework.data.redis.connection.MessageListener;
  15 +import org.springframework.stereotype.Component;
  16 +
  17 +import javax.annotation.Resource;
  18 +import java.util.*;
  19 +
  20 +/**
  21 + * @Auther: JiangFeng
  22 + * @Date: 2022/8/16 11:32
  23 + * @Description: 接收redis发送的推流设备列表更新通知
  24 + */
  25 +@Component
  26 +public class RedisPushStreamListMsgListener implements MessageListener {
  27 +
  28 + private final static Logger logger = LoggerFactory.getLogger(RedisPushStreamListMsgListener.class);
  29 + @Resource
  30 + private IMediaServerService mediaServerService;
  31 +
  32 + @Resource
  33 + private IStreamPushService streamPushService;
  34 + @Resource
  35 + private IGbStreamService gbStreamService;
  36 +
  37 + @Override
  38 + public void onMessage(Message message, byte[] bytes) {
  39 + //
  40 + logger.warn("[REDIS消息-推流设备列表更新]: {}", new String(message.getBody()));
  41 + List<StreamPushItem> streamPushItems = JSON.parseArray(new String(message.getBody()), StreamPushItem.class);
  42 + //查询全部的app+stream 用于判断是添加还是修改
  43 + List<String> allAppAndStream = streamPushService.getAllAppAndStream();
  44 +
  45 + /**
  46 + * 用于存储更具APP+Stream过滤后的数据,可以直接存入stream_push表与gb_stream表
  47 + */
  48 + List<StreamPushItem> streamPushItemForSave = new ArrayList<>();
  49 + List<StreamPushItem> streamPushItemForUpdate = new ArrayList<>();
  50 + for (StreamPushItem streamPushItem : streamPushItems) {
  51 + String app = streamPushItem.getApp();
  52 + String stream = streamPushItem.getStream();
  53 + boolean contains = allAppAndStream.contains(app + stream);
  54 + //不存在就添加
  55 + if (!contains) {
  56 + streamPushItem.setStatus(false);
  57 + streamPushItem.setStreamType("push");
  58 + streamPushItem.setCreateTime(DateUtil.getNow());
  59 + streamPushItem.setMediaServerId(mediaServerService.getDefaultMediaServer().getId());
  60 + streamPushItem.setOriginType(2);
  61 + streamPushItem.setOriginTypeStr("rtsp_push");
  62 + streamPushItem.setTotalReaderCount("0");
  63 + streamPushItemForSave.add(streamPushItem);
  64 + } else {
  65 + //存在就只修改 name和gbId
  66 + streamPushItemForUpdate.add(streamPushItem);
  67 + }
  68 + }
  69 + if (streamPushItemForSave.size() > 0) {
  70 +
  71 + logger.info("添加{}条",streamPushItemForSave.size());
  72 + logger.info(JSONObject.toJSONString(streamPushItemForSave));
  73 + streamPushService.batchAdd(streamPushItemForSave);
  74 +
  75 + }
  76 + if(streamPushItemForUpdate.size()>0){
  77 + logger.info("修改{}条",streamPushItemForUpdate.size());
  78 + logger.info(JSONObject.toJSONString(streamPushItemForUpdate));
  79 + gbStreamService.updateGbIdOrName(streamPushItemForUpdate);
  80 + }
  81 +
  82 + }
  83 +}
... ...
src/main/java/com/genersoft/iot/vmp/service/impl/RedisStreamMsgListener.java
... ... @@ -27,15 +27,6 @@ public class RedisStreamMsgListener implements MessageListener {
27 27 private final static Logger logger = LoggerFactory.getLogger(RedisStreamMsgListener.class);
28 28  
29 29 @Autowired
30   - private ISIPCommander commander;
31   -
32   - @Autowired
33   - private ISIPCommanderForPlatform commanderForPlatform;
34   -
35   - @Autowired
36   - private IVideoManagerStorage storage;
37   -
38   - @Autowired
39 30 private UserSetting userSetting;
40 31  
41 32 @Autowired
... ...
src/main/java/com/genersoft/iot/vmp/service/impl/StreamProxyServiceImpl.java
... ... @@ -4,6 +4,7 @@ import com.alibaba.fastjson.JSONArray;
4 4 import com.alibaba.fastjson.JSONObject;
5 5 import com.genersoft.iot.vmp.common.StreamInfo;
6 6 import com.genersoft.iot.vmp.conf.UserSetting;
  7 +import com.genersoft.iot.vmp.conf.exception.ControllerException;
7 8 import com.genersoft.iot.vmp.gb28181.bean.GbStream;
8 9 import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform;
9 10 import com.genersoft.iot.vmp.gb28181.bean.TreeType;
... ... @@ -24,6 +25,7 @@ import com.genersoft.iot.vmp.storager.dao.PlatformGbStreamMapper;
24 25 import com.genersoft.iot.vmp.storager.dao.StreamProxyMapper;
25 26 import com.genersoft.iot.vmp.service.IStreamProxyService;
26 27 import com.genersoft.iot.vmp.utils.DateUtil;
  28 +import com.genersoft.iot.vmp.vmanager.bean.ErrorCode;
27 29 import com.genersoft.iot.vmp.vmanager.bean.WVPResult;
28 30 import com.github.pagehelper.PageInfo;
29 31 import org.slf4j.Logger;
... ... @@ -33,6 +35,7 @@ import org.springframework.jdbc.datasource.DataSourceTransactionManager;
33 35 import org.springframework.stereotype.Service;
34 36 import org.springframework.transaction.TransactionDefinition;
35 37 import org.springframework.transaction.TransactionStatus;
  38 +import org.springframework.util.ObjectUtils;
36 39 import org.springframework.util.StringUtils;
37 40  
38 41 import java.net.InetAddress;
... ... @@ -93,10 +96,8 @@ public class StreamProxyServiceImpl implements IStreamProxyService {
93 96  
94 97  
95 98 @Override
96   - public WVPResult<StreamInfo> save(StreamProxyItem param) {
  99 + public StreamInfo save(StreamProxyItem param) {
97 100 MediaServerItem mediaInfo;
98   - WVPResult<StreamInfo> wvpResult = new WVPResult<>();
99   - wvpResult.setCode(0);
100 101 if (param.getMediaServerId() == null || "auto".equals(param.getMediaServerId())){
101 102 mediaInfo = mediaServerService.getMediaServerForMinimumLoad();
102 103 }else {
... ... @@ -104,14 +105,12 @@ public class StreamProxyServiceImpl implements IStreamProxyService {
104 105 }
105 106 if (mediaInfo == null) {
106 107 logger.warn("保存代理未找到在线的ZLM...");
107   - wvpResult.setMsg("保存失败");
108   - return wvpResult;
  108 + throw new ControllerException(ErrorCode.ERROR100.getCode(), "保存代理未找到在线的ZLM");
109 109 }
110   -
111 110 String dstUrl = String.format("rtmp://%s:%s/%s/%s", "127.0.0.1", mediaInfo.getRtmpPort(), param.getApp(),
112 111 param.getStream() );
113 112 param.setDst_url(dstUrl);
114   - StringBuffer result = new StringBuffer();
  113 + StringBuffer resultMsg = new StringBuffer();
115 114 boolean streamLive = false;
116 115 param.setMediaServerId(mediaInfo.getId());
117 116 boolean saveResult;
... ... @@ -121,43 +120,47 @@ public class StreamProxyServiceImpl implements IStreamProxyService {
121 120 }else { // 新增
122 121 saveResult = addStreamProxy(param);
123 122 }
124   - if (saveResult) {
125   - result.append("保存成功");
126   - if (param.isEnable()) {
127   - JSONObject jsonObject = addStreamProxyToZlm(param);
128   - if (jsonObject == null || jsonObject.getInteger("code") != 0) {
129   - streamLive = false;
130   - result.append(", 但是启用失败,请检查流地址是否可用");
131   - param.setEnable(false);
132   - // 直接移除
133   - if (param.isEnable_remove_none_reader()) {
134   - del(param.getApp(), param.getStream());
135   - }else {
136   - updateStreamProxy(param);
137   - }
138   -
  123 + if (!saveResult) {
  124 + throw new ControllerException(ErrorCode.ERROR100.getCode(),"保存失败");
  125 + }
  126 + StreamInfo resultForStreamInfo = null;
  127 + resultMsg.append("保存成功");
  128 + if (param.isEnable()) {
  129 + JSONObject jsonObject = addStreamProxyToZlm(param);
  130 + if (jsonObject == null || jsonObject.getInteger("code") != 0) {
  131 + streamLive = false;
  132 + resultMsg.append(", 但是启用失败,请检查流地址是否可用");
  133 + param.setEnable(false);
  134 + // 直接移除
  135 + if (param.isEnable_remove_none_reader()) {
  136 + del(param.getApp(), param.getStream());
139 137 }else {
140   - streamLive = true;
141   - StreamInfo streamInfo = mediaService.getStreamInfoByAppAndStream(
142   - mediaInfo, param.getApp(), param.getStream(), null, null);
143   - wvpResult.setData(streamInfo);
144   -
  138 + updateStreamProxy(param);
145 139 }
  140 +
  141 +
  142 + }else {
  143 + streamLive = true;
  144 + resultForStreamInfo = mediaService.getStreamInfoByAppAndStream(
  145 + mediaInfo, param.getApp(), param.getStream(), null, null);
  146 +
146 147 }
147   - }else {
148   - result.append("保存失败");
149 148 }
150   - if ( !StringUtils.isEmpty(param.getPlatformGbId()) && streamLive) {
  149 + if ( !ObjectUtils.isEmpty(param.getPlatformGbId()) && streamLive) {
151 150 List<GbStream> gbStreams = new ArrayList<>();
152 151 gbStreams.add(param);
153 152 if (gbStreamService.addPlatformInfo(gbStreams, param.getPlatformGbId(), param.getCatalogId())){
154   - result.append(", 关联国标平台[ " + param.getPlatformGbId() + " ]成功");
  153 + return resultForStreamInfo;
155 154 }else {
156   - result.append(", 关联国标平台[ " + param.getPlatformGbId() + " ]失败");
  155 + resultMsg.append(", 关联国标平台[ " + param.getPlatformGbId() + " ]失败");
  156 + throw new ControllerException(ErrorCode.ERROR100.getCode(), resultMsg.toString());
  157 + }
  158 + }else {
  159 + if (!streamLive) {
  160 + throw new ControllerException(ErrorCode.ERROR100.getCode(), resultMsg.toString());
157 161 }
158 162 }
159   - wvpResult.setMsg(result.toString());
160   - return wvpResult;
  163 + return resultForStreamInfo;
161 164 }
162 165  
163 166 /**
... ... @@ -174,7 +177,7 @@ public class StreamProxyServiceImpl implements IStreamProxyService {
174 177 streamProxyItem.setCreateTime(now);
175 178 try {
176 179 if (streamProxyMapper.add(streamProxyItem) > 0) {
177   - if (!StringUtils.isEmpty(streamProxyItem.getGbId())) {
  180 + if (!ObjectUtils.isEmpty(streamProxyItem.getGbId())) {
178 181 if (gbStreamMapper.add(streamProxyItem) < 0) {
179 182 //事务回滚
180 183 dataSourceTransactionManager.rollback(transactionStatus);
... ... @@ -209,7 +212,7 @@ public class StreamProxyServiceImpl implements IStreamProxyService {
209 212 streamProxyItem.setStreamType("proxy");
210 213 try {
211 214 if (streamProxyMapper.update(streamProxyItem) > 0) {
212   - if (!StringUtils.isEmpty(streamProxyItem.getGbId())) {
  215 + if (!ObjectUtils.isEmpty(streamProxyItem.getGbId())) {
213 216 if (gbStreamMapper.updateByAppAndStream(streamProxyItem) == 0) {
214 217 //事务回滚
215 218 dataSourceTransactionManager.rollback(transactionStatus);
... ...
src/main/java/com/genersoft/iot/vmp/service/impl/StreamPushServiceImpl.java
... ... @@ -27,6 +27,7 @@ import org.springframework.jdbc.datasource.DataSourceTransactionManager;
27 27 import org.springframework.stereotype.Service;
28 28 import org.springframework.transaction.TransactionDefinition;
29 29 import org.springframework.transaction.TransactionStatus;
  30 +import org.springframework.util.ObjectUtils;
30 31 import org.springframework.util.StringUtils;
31 32  
32 33 import java.util.*;
... ... @@ -208,7 +209,7 @@ public class StreamPushServiceImpl implements IStreamPushService {
208 209 Map<String, MediaItem> streamInfoPushItemMap = new HashMap<>();
209 210 if (pushList.size() > 0) {
210 211 for (StreamPushItem streamPushItem : pushList) {
211   - if (StringUtils.isEmpty(streamPushItem.getGbId())) {
  212 + if (ObjectUtils.isEmpty(streamPushItem.getGbId())) {
212 213 pushItemMap.put(streamPushItem.getApp() + streamPushItem.getStream(), streamPushItem);
213 214 }
214 215 }
... ... @@ -340,6 +341,7 @@ public class StreamPushServiceImpl implements IStreamPushService {
340 341 gbStreamMapper.batchAdd(streamPushItems);
341 342 }
342 343  
  344 +
343 345 @Override
344 346 public void batchAddForUpload(List<StreamPushItem> streamPushItems, Map<String, List<String[]>> streamPushItemsForAll ) {
345 347 // 存储数据到stream_push表
... ... @@ -491,7 +493,7 @@ public class StreamPushServiceImpl implements IStreamPushService {
491 493 TransactionStatus transactionStatus = dataSourceTransactionManager.getTransaction(transactionDefinition);
492 494 try {
493 495 int addStreamResult = streamPushMapper.add(stream);
494   - if (!StringUtils.isEmpty(stream.getGbId())) {
  496 + if (!ObjectUtils.isEmpty(stream.getGbId())) {
495 497 stream.setStreamType("push");
496 498 gbStreamMapper.add(stream);
497 499 }
... ... @@ -503,4 +505,9 @@ public class StreamPushServiceImpl implements IStreamPushService {
503 505 }
504 506 return result;
505 507 }
  508 +
  509 + @Override
  510 + public List<String> getAllAppAndStream() {
  511 + return streamPushMapper.getAllAppAndStream();
  512 + }
506 513 }
... ...
src/main/java/com/genersoft/iot/vmp/service/impl/StreamPushUploadFileHandler.java
... ... @@ -8,6 +8,7 @@ import com.genersoft.iot.vmp.utils.DateUtil;
8 8 import com.genersoft.iot.vmp.vmanager.bean.StreamPushExcelDto;
9 9 import com.google.common.collect.BiMap;
10 10 import com.google.common.collect.HashBiMap;
  11 +import org.springframework.util.ObjectUtils;
11 12 import org.springframework.util.StringUtils;
12 13  
13 14 import java.util.*;
... ... @@ -82,9 +83,9 @@ public class StreamPushUploadFileHandler extends AnalysisEventListener&lt;StreamPus
82 83  
83 84 @Override
84 85 public void invoke(StreamPushExcelDto streamPushExcelDto, AnalysisContext analysisContext) {
85   - if (StringUtils.isEmpty(streamPushExcelDto.getApp())
86   - || StringUtils.isEmpty(streamPushExcelDto.getStream())
87   - || StringUtils.isEmpty(streamPushExcelDto.getGbId())) {
  86 + if (ObjectUtils.isEmpty(streamPushExcelDto.getApp())
  87 + || ObjectUtils.isEmpty(streamPushExcelDto.getStream())
  88 + || ObjectUtils.isEmpty(streamPushExcelDto.getGbId())) {
88 89 return;
89 90 }
90 91  
... ... @@ -130,7 +131,7 @@ public class StreamPushUploadFileHandler extends AnalysisEventListener&lt;StreamPus
130 131 streamPushItems.add(streamPushItem);
131 132 streamPushItemForSave.put(streamPushItem.getApp() + streamPushItem.getStream(), streamPushItem);
132 133  
133   - if (!StringUtils.isEmpty(streamPushExcelDto.getPlatformId())) {
  134 + if (!ObjectUtils.isEmpty(streamPushExcelDto.getPlatformId())) {
134 135 List<String[]> platformList = streamPushItemsForPlatform.get(streamPushItem.getApp() + streamPushItem.getStream());
135 136 if (platformList == null) {
136 137 platformList = new ArrayList<>();
... ... @@ -138,7 +139,7 @@ public class StreamPushUploadFileHandler extends AnalysisEventListener&lt;StreamPus
138 139 }
139 140 String platformId = streamPushExcelDto.getPlatformId();
140 141 String catalogId = streamPushExcelDto.getCatalogId();
141   - if (StringUtils.isEmpty(streamPushExcelDto.getCatalogId())) {
  142 + if (ObjectUtils.isEmpty(streamPushExcelDto.getCatalogId())) {
142 143 catalogId = null;
143 144 }
144 145 String[] platFormInfoArray = new String[]{platformId, catalogId};
... ...
src/main/java/com/genersoft/iot/vmp/service/impl/UserServiceImpl.java
... ... @@ -7,6 +7,7 @@ import com.github.pagehelper.PageHelper;
7 7 import com.github.pagehelper.PageInfo;
8 8 import org.springframework.beans.factory.annotation.Autowired;
9 9 import org.springframework.stereotype.Service;
  10 +import org.springframework.util.ObjectUtils;
10 11 import org.springframework.util.StringUtils;
11 12  
12 13 import java.util.List;
... ... @@ -60,7 +61,7 @@ public class UserServiceImpl implements IUserService {
60 61  
61 62 @Override
62 63 public boolean checkPushAuthority(String callId, String sign) {
63   - if (StringUtils.isEmpty(callId)) {
  64 + if (ObjectUtils.isEmpty(callId)) {
64 65 return userMapper.checkPushAuthorityByCallId(sign).size() > 0;
65 66 }else {
66 67 return userMapper.checkPushAuthorityByCallIdAndSign(callId, sign).size() > 0;
... ...