Commit e5370bbd6e74b7746db12ced5302ef97ef58a4ce

Authored by mrjackwang
Committed by GitHub
2 parents f65d2730 28d7fd3b

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

Showing 87 changed files with 1117 additions and 611 deletions
.gitignore
@@ -3,7 +3,7 @@ @@ -3,7 +3,7 @@
3 3
4 # Log file 4 # Log file
5 *.log 5 *.log
6 - 6 +logs/*
7 # BlueJ files 7 # BlueJ files
8 *.ctxt 8 *.ctxt
9 9
README.md
@@ -105,6 +105,10 @@ https://gitee.com/pan648540858/wvp-GB28181-pro.git @@ -105,6 +105,10 @@ https://gitee.com/pan648540858/wvp-GB28181-pro.git
105 - [X] WEB端支持播放H264与H265,音频支持G.711A/G.711U/AAC,覆盖国标常用编码格式。 105 - [X] WEB端支持播放H264与H265,音频支持G.711A/G.711U/AAC,覆盖国标常用编码格式。
106 106
107 # docker快速体验 107 # docker快速体验
  108 +目前作者的docker-compose因为时间有限维护不及时,这里提供第三方提供的供大家使用,维护不易,大家记得给这位小伙伴点个star。
  109 +https://github.com/SaltFish001/wvp_pro_compose
  110 +[https://github.com/SaltFish001/wvp_pro_compose](https://github.com/SaltFish001/wvp_pro_compose)
  111 +这是作者维护的一个镜像,可能存在不及时的问题。
108 ```shell 112 ```shell
109 docker pull 648540858/wvp_pro 113 docker pull 648540858/wvp_pro
110 114
@@ -90,8 +90,8 @@ @@ -90,8 +90,8 @@
90 <!-- druid数据库连接池 --> 90 <!-- druid数据库连接池 -->
91 <dependency> 91 <dependency>
92 <groupId>com.alibaba</groupId> 92 <groupId>com.alibaba</groupId>
93 - <artifactId>druid</artifactId>  
94 - <version>1.2.3</version> 93 + <artifactId>druid-spring-boot-starter</artifactId>
  94 + <version>1.1.22</version>
95 </dependency> 95 </dependency>
96 96
97 <!-- mysql数据库 --> 97 <!-- mysql数据库 -->
@@ -183,6 +183,15 @@ @@ -183,6 +183,15 @@
183 <version>4.9.0</version> 183 <version>4.9.0</version>
184 </dependency> 184 </dependency>
185 185
  186 + <!-- okhttp 调试日志 -->
  187 + <dependency>
  188 + <groupId>com.squareup.okhttp3</groupId>
  189 + <artifactId>logging-interceptor</artifactId>
  190 + <version>4.9.0</version>
  191 + </dependency>
  192 +
  193 +
  194 +
186 <!-- okhttp-digest --> 195 <!-- okhttp-digest -->
187 <dependency> 196 <dependency>
188 <groupId>com.burgstaller</groupId> 197 <groupId>com.burgstaller</groupId>
sql/mysql.sql
@@ -44,7 +44,7 @@ CREATE TABLE `device` ( @@ -44,7 +44,7 @@ CREATE TABLE `device` (
44 `charset` varchar(50) COLLATE utf8mb4_general_ci NOT NULL, 44 `charset` varchar(50) COLLATE utf8mb4_general_ci NOT NULL,
45 PRIMARY KEY (`id`), 45 PRIMARY KEY (`id`),
46 UNIQUE KEY `device_deviceId_uindex` (`deviceId`) 46 UNIQUE KEY `device_deviceId_uindex` (`deviceId`)
47 -) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; 47 +) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
48 /*!40101 SET character_set_client = @saved_cs_client */; 48 /*!40101 SET character_set_client = @saved_cs_client */;
49 49
50 -- 50 --
@@ -95,39 +95,41 @@ DROP TABLE IF EXISTS `device_channel`; @@ -95,39 +95,41 @@ DROP TABLE IF EXISTS `device_channel`;
95 /*!40101 SET @saved_cs_client = @@character_set_client */; 95 /*!40101 SET @saved_cs_client = @@character_set_client */;
96 /*!50503 SET character_set_client = utf8mb4 */; 96 /*!50503 SET character_set_client = utf8mb4 */;
97 CREATE TABLE `device_channel` ( 97 CREATE TABLE `device_channel` (
98 - `channelId` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,  
99 - `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,  
100 - `manufacture` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,  
101 - `model` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,  
102 - `owner` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,  
103 - `civilCode` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,  
104 - `block` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,  
105 - `address` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,  
106 - `parentId` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, 98 + `id` int NOT NULL AUTO_INCREMENT,
  99 + `channelId` varchar(50) COLLATE utf8mb4_general_ci NOT NULL,
  100 + `name` varchar(255) COLLATE utf8mb4_general_ci DEFAULT NULL,
  101 + `manufacture` varchar(50) COLLATE utf8mb4_general_ci DEFAULT NULL,
  102 + `model` varchar(50) COLLATE utf8mb4_general_ci DEFAULT NULL,
  103 + `owner` varchar(50) COLLATE utf8mb4_general_ci DEFAULT NULL,
  104 + `civilCode` varchar(50) COLLATE utf8mb4_general_ci DEFAULT NULL,
  105 + `block` varchar(50) COLLATE utf8mb4_general_ci DEFAULT NULL,
  106 + `address` varchar(50) COLLATE utf8mb4_general_ci DEFAULT NULL,
  107 + `parentId` varchar(50) COLLATE utf8mb4_general_ci DEFAULT NULL,
107 `safetyWay` int DEFAULT NULL, 108 `safetyWay` int DEFAULT NULL,
108 `registerWay` int DEFAULT NULL, 109 `registerWay` int DEFAULT NULL,
109 - `certNum` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, 110 + `certNum` varchar(50) COLLATE utf8mb4_general_ci DEFAULT NULL,
110 `certifiable` int DEFAULT NULL, 111 `certifiable` int DEFAULT NULL,
111 `errCode` int DEFAULT NULL, 112 `errCode` int DEFAULT NULL,
112 - `endTime` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,  
113 - `secrecy` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,  
114 - `ipAddress` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, 113 + `endTime` varchar(50) COLLATE utf8mb4_general_ci DEFAULT NULL,
  114 + `secrecy` varchar(50) COLLATE utf8mb4_general_ci DEFAULT NULL,
  115 + `ipAddress` varchar(50) COLLATE utf8mb4_general_ci DEFAULT NULL,
115 `port` int DEFAULT NULL, 116 `port` int DEFAULT NULL,
116 - `password` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, 117 + `password` varchar(255) COLLATE utf8mb4_general_ci DEFAULT NULL,
117 `PTZType` int DEFAULT NULL, 118 `PTZType` int DEFAULT NULL,
118 `status` int DEFAULT NULL, 119 `status` int DEFAULT NULL,
119 `longitude` double DEFAULT NULL, 120 `longitude` double DEFAULT NULL,
120 `latitude` double DEFAULT NULL, 121 `latitude` double DEFAULT NULL,
121 - `streamId` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,  
122 - `deviceId` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,  
123 - `parental` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, 122 + `streamId` varchar(50) COLLATE utf8mb4_general_ci DEFAULT NULL,
  123 + `deviceId` varchar(50) COLLATE utf8mb4_general_ci NOT NULL,
  124 + `parental` varchar(50) COLLATE utf8mb4_general_ci DEFAULT NULL,
124 `hasAudio` bit(1) DEFAULT NULL, 125 `hasAudio` bit(1) DEFAULT NULL,
125 - `createTime` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,  
126 - `updateTime` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, 126 + `createTime` varchar(50) COLLATE utf8mb4_general_ci NOT NULL,
  127 + `updateTime` varchar(50) COLLATE utf8mb4_general_ci NOT NULL,
127 `subCount` int DEFAULT '0', 128 `subCount` int DEFAULT '0',
128 - PRIMARY KEY (`channelId`,`deviceId`) USING BTREE, 129 + PRIMARY KEY (`id`),
  130 + UNIQUE KEY `device_channel_id_uindex` (`id`),
129 UNIQUE KEY `device_channel_pk` (`channelId`,`deviceId`) 131 UNIQUE KEY `device_channel_pk` (`channelId`,`deviceId`)
130 -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC; 132 +) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
131 /*!40101 SET character_set_client = @saved_cs_client */; 133 /*!40101 SET character_set_client = @saved_cs_client */;
132 134
133 -- 135 --
@@ -196,7 +198,7 @@ CREATE TABLE `gb_stream` ( @@ -196,7 +198,7 @@ CREATE TABLE `gb_stream` (
196 PRIMARY KEY (`gbStreamId`) USING BTREE, 198 PRIMARY KEY (`gbStreamId`) USING BTREE,
197 UNIQUE KEY `app` (`app`,`stream`) USING BTREE, 199 UNIQUE KEY `app` (`app`,`stream`) USING BTREE,
198 UNIQUE KEY `gbId` (`gbId`) USING BTREE 200 UNIQUE KEY `gbId` (`gbId`) USING BTREE
199 -) ENGINE=InnoDB AUTO_INCREMENT=291 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC; 201 +) ENGINE=InnoDB AUTO_INCREMENT=375 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC;
200 /*!40101 SET character_set_client = @saved_cs_client */; 202 /*!40101 SET character_set_client = @saved_cs_client */;
201 203
202 -- 204 --
@@ -226,7 +228,7 @@ CREATE TABLE `log` ( @@ -226,7 +228,7 @@ CREATE TABLE `log` (
226 `username` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, 228 `username` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
227 `createTime` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, 229 `createTime` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
228 PRIMARY KEY (`id`) USING BTREE 230 PRIMARY KEY (`id`) USING BTREE
229 -) ENGINE=InnoDB AUTO_INCREMENT=245 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC; 231 +) ENGINE=InnoDB AUTO_INCREMENT=313 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC;
230 /*!40101 SET character_set_client = @saved_cs_client */; 232 /*!40101 SET character_set_client = @saved_cs_client */;
231 233
232 -- 234 --
@@ -315,7 +317,7 @@ CREATE TABLE `parent_platform` ( @@ -315,7 +317,7 @@ CREATE TABLE `parent_platform` (
315 PRIMARY KEY (`id`), 317 PRIMARY KEY (`id`),
316 UNIQUE KEY `parent_platform_id_uindex` (`id`), 318 UNIQUE KEY `parent_platform_id_uindex` (`id`),
317 UNIQUE KEY `parent_platform_pk` (`serverGBId`) 319 UNIQUE KEY `parent_platform_pk` (`serverGBId`)
318 -) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC; 320 +) ENGINE=InnoDB AUTO_INCREMENT=14 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC;
319 /*!40101 SET character_set_client = @saved_cs_client */; 321 /*!40101 SET character_set_client = @saved_cs_client */;
320 322
321 -- 323 --
@@ -361,13 +363,11 @@ DROP TABLE IF EXISTS `platform_gb_channel`; @@ -361,13 +363,11 @@ DROP TABLE IF EXISTS `platform_gb_channel`;
361 /*!50503 SET character_set_client = utf8mb4 */; 363 /*!50503 SET character_set_client = utf8mb4 */;
362 CREATE TABLE `platform_gb_channel` ( 364 CREATE TABLE `platform_gb_channel` (
363 `id` int NOT NULL AUTO_INCREMENT, 365 `id` int NOT NULL AUTO_INCREMENT,
364 - `channelId` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,  
365 - `deviceId` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,  
366 - `platformId` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,  
367 - `deviceAndChannelId` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,  
368 - `catalogId` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, 366 + `platformId` varchar(50) COLLATE utf8mb4_general_ci NOT NULL,
  367 + `catalogId` varchar(50) COLLATE utf8mb4_general_ci NOT NULL,
  368 + `deviceChannelId` int NOT NULL,
369 PRIMARY KEY (`id`) 369 PRIMARY KEY (`id`)
370 -) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC; 370 +) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
371 /*!40101 SET character_set_client = @saved_cs_client */; 371 /*!40101 SET character_set_client = @saved_cs_client */;
372 372
373 -- 373 --
@@ -393,7 +393,7 @@ CREATE TABLE `platform_gb_stream` ( @@ -393,7 +393,7 @@ CREATE TABLE `platform_gb_stream` (
393 `id` int NOT NULL AUTO_INCREMENT, 393 `id` int NOT NULL AUTO_INCREMENT,
394 PRIMARY KEY (`id`), 394 PRIMARY KEY (`id`),
395 UNIQUE KEY `platform_gb_stream_pk` (`platformId`,`catalogId`,`gbStreamId`) 395 UNIQUE KEY `platform_gb_stream_pk` (`platformId`,`catalogId`,`gbStreamId`)
396 -) ENGINE=InnoDB AUTO_INCREMENT=256 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC; 396 +) ENGINE=InnoDB AUTO_INCREMENT=406 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC;
397 /*!40101 SET character_set_client = @saved_cs_client */; 397 /*!40101 SET character_set_client = @saved_cs_client */;
398 398
399 -- 399 --
@@ -415,6 +415,7 @@ DROP TABLE IF EXISTS `stream_proxy`; @@ -415,6 +415,7 @@ DROP TABLE IF EXISTS `stream_proxy`;
415 CREATE TABLE `stream_proxy` ( 415 CREATE TABLE `stream_proxy` (
416 `id` int NOT NULL AUTO_INCREMENT, 416 `id` int NOT NULL AUTO_INCREMENT,
417 `type` varchar(50) COLLATE utf8mb4_general_ci NOT NULL, 417 `type` varchar(50) COLLATE utf8mb4_general_ci NOT NULL,
  418 + `name` varchar(255) COLLATE utf8mb4_general_ci NOT NULL,
418 `app` varchar(255) COLLATE utf8mb4_general_ci NOT NULL, 419 `app` varchar(255) COLLATE utf8mb4_general_ci NOT NULL,
419 `name` varchar(255) COLLATE utf8mb4_general_ci NOT NULL, 420 `name` varchar(255) COLLATE utf8mb4_general_ci NOT NULL,
420 `stream` varchar(255) COLLATE utf8mb4_general_ci NOT NULL, 421 `stream` varchar(255) COLLATE utf8mb4_general_ci NOT NULL,
@@ -464,7 +465,7 @@ CREATE TABLE `stream_push` ( @@ -464,7 +465,7 @@ CREATE TABLE `stream_push` (
464 `mediaServerId` varchar(50) COLLATE utf8mb4_general_ci DEFAULT NULL, 465 `mediaServerId` varchar(50) COLLATE utf8mb4_general_ci DEFAULT NULL,
465 PRIMARY KEY (`id`), 466 PRIMARY KEY (`id`),
466 UNIQUE KEY `stream_push_pk` (`app`,`stream`) 467 UNIQUE KEY `stream_push_pk` (`app`,`stream`)
467 -) ENGINE=InnoDB AUTO_INCREMENT=310 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; 468 +) ENGINE=InnoDB AUTO_INCREMENT=394 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
468 /*!40101 SET character_set_client = @saved_cs_client */; 469 /*!40101 SET character_set_client = @saved_cs_client */;
469 470
470 -- 471 --
@@ -541,4 +542,4 @@ UNLOCK TABLES; @@ -541,4 +542,4 @@ UNLOCK TABLES;
541 /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; 542 /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
542 /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; 543 /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
543 544
544 --- Dump completed on 2022-02-24 16:52:12 545 +-- Dump completed on 2022-02-25 20:32:21
src/main/java/com/genersoft/iot/vmp/VManageBootstrap.java
@@ -2,6 +2,7 @@ package com.genersoft.iot.vmp; @@ -2,6 +2,7 @@ package com.genersoft.iot.vmp;
2 2
3 import java.util.logging.LogManager; 3 import java.util.logging.LogManager;
4 4
  5 +import com.genersoft.iot.vmp.conf.druid.EnableDruidSupport;
5 import org.springframework.boot.SpringApplication; 6 import org.springframework.boot.SpringApplication;
6 import org.springframework.boot.autoconfigure.SpringBootApplication; 7 import org.springframework.boot.autoconfigure.SpringBootApplication;
7 import org.springframework.boot.web.servlet.ServletComponentScan; 8 import org.springframework.boot.web.servlet.ServletComponentScan;
@@ -17,6 +18,7 @@ import springfox.documentation.oas.annotations.EnableOpenApi; @@ -17,6 +18,7 @@ import springfox.documentation.oas.annotations.EnableOpenApi;
17 @SpringBootApplication 18 @SpringBootApplication
18 @EnableScheduling 19 @EnableScheduling
19 @EnableOpenApi 20 @EnableOpenApi
  21 +@EnableDruidSupport
20 public class VManageBootstrap extends LogManager { 22 public class VManageBootstrap extends LogManager {
21 private static String[] args; 23 private static String[] args;
22 private static ConfigurableApplicationContext context; 24 private static ConfigurableApplicationContext context;
src/main/java/com/genersoft/iot/vmp/common/StreamInfo.java
@@ -5,7 +5,7 @@ import com.alibaba.fastjson.JSONArray; @@ -5,7 +5,7 @@ import com.alibaba.fastjson.JSONArray;
5 public class StreamInfo { 5 public class StreamInfo {
6 6
7 private String app; 7 private String app;
8 - private String streamId; 8 + private String stream;
9 private String deviceID; 9 private String deviceID;
10 private String channelId; 10 private String channelId;
11 private String flv; 11 private String flv;
@@ -153,12 +153,12 @@ public class StreamInfo { @@ -153,12 +153,12 @@ public class StreamInfo {
153 this.ws_ts = ws_ts; 153 this.ws_ts = ws_ts;
154 } 154 }
155 155
156 - public String getStreamId() {  
157 - return streamId; 156 + public String getStream() {
  157 + return stream;
158 } 158 }
159 159
160 - public void setStreamId(String streamId) {  
161 - this.streamId = streamId; 160 + public void setStream(String stream) {
  161 + this.stream = stream;
162 } 162 }
163 163
164 public String getRtc() { 164 public String getRtc() {
src/main/java/com/genersoft/iot/vmp/common/VideoManagerConstants.java
@@ -29,6 +29,7 @@ public class VideoManagerConstants { @@ -29,6 +29,7 @@ public class VideoManagerConstants {
29 // 此处多了一个_,暂不修改 29 // 此处多了一个_,暂不修改
30 public static final String PLAYER_PREFIX = "VMP_PLAYER_"; 30 public static final String PLAYER_PREFIX = "VMP_PLAYER_";
31 public static final String PLAY_BLACK_PREFIX = "VMP_PLAYBACK_"; 31 public static final String PLAY_BLACK_PREFIX = "VMP_PLAYBACK_";
  32 + public static final String PLAY_INFO_PREFIX = "VMP_PLAY_INFO_";
32 33
33 public static final String DOWNLOAD_PREFIX = "VMP_DOWNLOAD_"; 34 public static final String DOWNLOAD_PREFIX = "VMP_DOWNLOAD_";
34 35
src/main/java/com/genersoft/iot/vmp/conf/SipPlatformRunner.java
@@ -3,6 +3,7 @@ package com.genersoft.iot.vmp.conf; @@ -3,6 +3,7 @@ package com.genersoft.iot.vmp.conf;
3 import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform; 3 import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform;
4 import com.genersoft.iot.vmp.gb28181.bean.ParentPlatformCatch; 4 import com.genersoft.iot.vmp.gb28181.bean.ParentPlatformCatch;
5 import com.genersoft.iot.vmp.gb28181.event.EventPublisher; 5 import com.genersoft.iot.vmp.gb28181.event.EventPublisher;
  6 +import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform;
6 import com.genersoft.iot.vmp.media.zlm.ZLMRTPServerFactory; 7 import com.genersoft.iot.vmp.media.zlm.ZLMRTPServerFactory;
7 import com.genersoft.iot.vmp.storager.IRedisCatchStorage; 8 import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
8 import com.genersoft.iot.vmp.storager.IVideoManagerStorager; 9 import com.genersoft.iot.vmp.storager.IVideoManagerStorager;
@@ -30,7 +31,7 @@ public class SipPlatformRunner implements CommandLineRunner { @@ -30,7 +31,7 @@ public class SipPlatformRunner implements CommandLineRunner {
30 private EventPublisher publisher; 31 private EventPublisher publisher;
31 32
32 @Autowired 33 @Autowired
33 - private ZLMRTPServerFactory zlmrtpServerFactory; 34 + private ISIPCommanderForPlatform sipCommanderForPlatform;
34 35
35 36
36 @Override 37 @Override
@@ -57,6 +58,9 @@ public class SipPlatformRunner implements CommandLineRunner { @@ -57,6 +58,9 @@ public class SipPlatformRunner implements CommandLineRunner {
57 parentPlatformCatch.setId(parentPlatform.getServerGBId()); 58 parentPlatformCatch.setId(parentPlatform.getServerGBId());
58 redisCatchStorage.updatePlatformCatchInfo(parentPlatformCatch); 59 redisCatchStorage.updatePlatformCatchInfo(parentPlatformCatch);
59 60
  61 + // 取消订阅
  62 + sipCommanderForPlatform.unregister(parentPlatform, null, null);
  63 + Thread.sleep(500);
60 // 发送平台未注册消息 64 // 发送平台未注册消息
61 publisher.platformNotRegisterEventPublish(parentPlatform.getServerGBId()); 65 publisher.platformNotRegisterEventPublish(parentPlatform.getServerGBId());
62 } 66 }
src/main/java/com/genersoft/iot/vmp/conf/Swagger3Config.java
@@ -14,7 +14,7 @@ import springfox.documentation.spring.web.plugins.Docket; @@ -14,7 +14,7 @@ import springfox.documentation.spring.web.plugins.Docket;
14 @Configuration 14 @Configuration
15 public class Swagger3Config { 15 public class Swagger3Config {
16 16
17 - @Value("${swagger-ui.enabled}") 17 + @Value("${swagger-ui.enabled: true}")
18 private boolean enable; 18 private boolean enable;
19 19
20 @Bean 20 @Bean
src/main/java/com/genersoft/iot/vmp/conf/druid/DruidConfiguration.java 0 → 100644
  1 +package com.genersoft.iot.vmp.conf.druid;
  2 +
  3 +import com.alibaba.druid.support.http.StatViewServlet;
  4 +import com.alibaba.druid.support.http.WebStatFilter;
  5 +import org.springframework.beans.factory.annotation.Value;
  6 +import org.springframework.boot.web.servlet.FilterRegistrationBean;
  7 +import org.springframework.boot.web.servlet.ServletRegistrationBean;
  8 +import org.springframework.context.annotation.Bean;
  9 +
  10 +import javax.servlet.Filter;
  11 +import javax.servlet.Servlet;
  12 +
  13 +/**
  14 + * druid监控配置
  15 + * @author
  16 + */
  17 +public class DruidConfiguration {
  18 +
  19 + @Value("${rj-druid-manage.allow:127.0.0.1}")
  20 + private String allow;
  21 +
  22 + @Value("${rj-druid-manage.deny:}")
  23 + private String deny;
  24 +
  25 + @Value("${rj-druid-manage.loginUsername:admin}")
  26 + private String loginUsername;
  27 +
  28 + @Value("${rj-druid-manage.loginPassword:admin}")
  29 + private String loginPassword;
  30 +
  31 + @Value("${rj-druid-manage.resetEnable:false}")
  32 + private String resetEnable;
  33 +
  34 + /**
  35 + * druid监控页面开启
  36 + */
  37 + @Bean
  38 + public ServletRegistrationBean druidServlet() {
  39 + ServletRegistrationBean<Servlet> servletRegistrationBean = new ServletRegistrationBean<>(new StatViewServlet(), "/druid/*");
  40 + // IP白名单
  41 + servletRegistrationBean.addInitParameter("allow", allow);
  42 + // IP黑名单(共同存在时,deny优先于allow)
  43 + servletRegistrationBean.addInitParameter("deny", deny);
  44 + //控制台管理用户
  45 + servletRegistrationBean.addInitParameter("loginUsername", loginUsername);
  46 + servletRegistrationBean.addInitParameter("loginPassword", loginPassword);
  47 + //是否能够重置数据 禁用HTML页面上的“Reset All”功能
  48 + servletRegistrationBean.addInitParameter("resetEnable", resetEnable);
  49 + return servletRegistrationBean;
  50 + }
  51 +
  52 + /**
  53 + * druid url监控配置
  54 + */
  55 + @Bean
  56 + public FilterRegistrationBean filterRegistrationBean() {
  57 + FilterRegistrationBean<Filter> filterRegistrationBean = new FilterRegistrationBean<>(new WebStatFilter());
  58 + filterRegistrationBean.addUrlPatterns("/*");
  59 + filterRegistrationBean.addInitParameter("exclusions", "*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*");
  60 + return filterRegistrationBean;
  61 + }
  62 +
  63 +
  64 +}
0 \ No newline at end of file 65 \ No newline at end of file
src/main/java/com/genersoft/iot/vmp/conf/druid/EnableDruidSupport.java 0 → 100644
  1 +package com.genersoft.iot.vmp.conf.druid;
  2 +
  3 +import org.springframework.boot.web.servlet.ServletComponentScan;
  4 +import org.springframework.context.annotation.Import;
  5 +
  6 +import java.lang.annotation.*;
  7 +
  8 +/**
  9 + * druid监控支持注解
  10 + *
  11 + * @author
  12 + * {@link DruidConfiguration} druid监控页面安全配置支持
  13 + * {@link ServletComponentScan} druid监控页面需要扫描servlet
  14 + */
  15 +@Target(ElementType.TYPE)
  16 +@Retention(RetentionPolicy.RUNTIME)
  17 +@Documented
  18 +@Inherited
  19 +@Import({
  20 + DruidConfiguration.class,
  21 +})
  22 +@ServletComponentScan
  23 +public @interface EnableDruidSupport {
  24 +}
src/main/java/com/genersoft/iot/vmp/gb28181/bean/DeviceChannel.java
@@ -3,6 +3,10 @@ package com.genersoft.iot.vmp.gb28181.bean; @@ -3,6 +3,10 @@ package com.genersoft.iot.vmp.gb28181.bean;
3 public class DeviceChannel { 3 public class DeviceChannel {
4 4
5 5
  6 + /**
  7 + * 数据库自赠ID
  8 + */
  9 + private int id;
6 10
7 /** 11 /**
8 * 通道id 12 * 通道id
@@ -165,6 +169,14 @@ public class DeviceChannel { @@ -165,6 +169,14 @@ public class DeviceChannel {
165 */ 169 */
166 private boolean hasAudio; 170 private boolean hasAudio;
167 171
  172 + public int getId() {
  173 + return id;
  174 + }
  175 +
  176 + public void setId(int id) {
  177 + this.id = id;
  178 + }
  179 +
168 public String getDeviceId() { 180 public String getDeviceId() {
169 return deviceId; 181 return deviceId;
170 } 182 }
src/main/java/com/genersoft/iot/vmp/gb28181/bean/SsrcTransaction.java
@@ -4,11 +4,12 @@ public class SsrcTransaction { @@ -4,11 +4,12 @@ public class SsrcTransaction {
4 4
5 private String deviceId; 5 private String deviceId;
6 private String channelId; 6 private String channelId;
7 - private String ssrc;  
8 - private String streamId; 7 + private String callId;
  8 + private String stream;
9 private byte[] transaction; 9 private byte[] transaction;
10 private byte[] dialog; 10 private byte[] dialog;
11 private String mediaServerId; 11 private String mediaServerId;
  12 + private String ssrc;
12 13
13 public String getDeviceId() { 14 public String getDeviceId() {
14 return deviceId; 15 return deviceId;
@@ -26,20 +27,20 @@ public class SsrcTransaction { @@ -26,20 +27,20 @@ public class SsrcTransaction {
26 this.channelId = channelId; 27 this.channelId = channelId;
27 } 28 }
28 29
29 - public String getSsrc() {  
30 - return ssrc; 30 + public String getCallId() {
  31 + return callId;
31 } 32 }
32 33
33 - public void setSsrc(String ssrc) {  
34 - this.ssrc = ssrc; 34 + public void setCallId(String callId) {
  35 + this.callId = callId;
35 } 36 }
36 37
37 - public String getStreamId() {  
38 - return streamId; 38 + public String getStream() {
  39 + return stream;
39 } 40 }
40 41
41 - public void setStreamId(String streamId) {  
42 - this.streamId = streamId; 42 + public void setStream(String stream) {
  43 + this.stream = stream;
43 } 44 }
44 45
45 public byte[] getTransaction() { 46 public byte[] getTransaction() {
@@ -65,4 +66,12 @@ public class SsrcTransaction { @@ -65,4 +66,12 @@ public class SsrcTransaction {
65 public void setMediaServerId(String mediaServerId) { 66 public void setMediaServerId(String mediaServerId) {
66 this.mediaServerId = mediaServerId; 67 this.mediaServerId = mediaServerId;
67 } 68 }
  69 +
  70 + public String getSsrc() {
  71 + return ssrc;
  72 + }
  73 +
  74 + public void setSsrc(String ssrc) {
  75 + this.ssrc = ssrc;
  76 + }
68 } 77 }
src/main/java/com/genersoft/iot/vmp/gb28181/bean/SubscribeInfo.java
@@ -18,15 +18,21 @@ public class SubscribeInfo { @@ -18,15 +18,21 @@ public class SubscribeInfo {
18 this.fromTag = fromHeader.getTag(); 18 this.fromTag = fromHeader.getTag();
19 ExpiresHeader expiresHeader = (ExpiresHeader)request.getHeader(ExpiresHeader.NAME); 19 ExpiresHeader expiresHeader = (ExpiresHeader)request.getHeader(ExpiresHeader.NAME);
20 this.expires = expiresHeader.getExpires(); 20 this.expires = expiresHeader.getExpires();
21 - this.event = ((EventHeader)request.getHeader(EventHeader.NAME)).getName(); 21 + EventHeader eventHeader = (EventHeader)request.getHeader(EventHeader.NAME);
  22 + this.eventId = eventHeader.getEventId();
  23 + this.eventType = eventHeader.getEventType();
  24 + ViaHeader viaHeader = (ViaHeader)request.getHeader(ViaHeader.NAME);
  25 + this.branch = viaHeader.getBranch();
22 } 26 }
23 27
24 private String id; 28 private String id;
25 private int expires; 29 private int expires;
26 private String callId; 30 private String callId;
27 - private String event; 31 + private String eventId;
  32 + private String eventType;
28 private String fromTag; 33 private String fromTag;
29 private String toTag; 34 private String toTag;
  35 + private String branch;
30 36
31 public String getId() { 37 public String getId() {
32 return id; 38 return id;
@@ -68,11 +74,27 @@ public class SubscribeInfo { @@ -68,11 +74,27 @@ public class SubscribeInfo {
68 this.fromTag = fromTag; 74 this.fromTag = fromTag;
69 } 75 }
70 76
71 - public String getEvent() {  
72 - return event; 77 + public String getEventId() {
  78 + return eventId;
73 } 79 }
74 80
75 - public void setEvent(String event) {  
76 - this.event = event; 81 + public void setEventId(String eventId) {
  82 + this.eventId = eventId;
  83 + }
  84 +
  85 + public String getEventType() {
  86 + return eventType;
  87 + }
  88 +
  89 + public void setEventType(String eventType) {
  90 + this.eventType = eventType;
  91 + }
  92 +
  93 + public String getBranch() {
  94 + return branch;
  95 + }
  96 +
  97 + public void setBranch(String branch) {
  98 + this.branch = branch;
77 } 99 }
78 } 100 }
src/main/java/com/genersoft/iot/vmp/gb28181/event/EventPublisher.java
@@ -101,14 +101,14 @@ public class EventPublisher { @@ -101,14 +101,14 @@ public class EventPublisher {
101 applicationEventPublisher.publishEvent(outEvent); 101 applicationEventPublisher.publishEvent(outEvent);
102 } 102 }
103 103
104 - @Async 104 +
105 public void catalogEventPublish(String platformId, DeviceChannel deviceChannel, String type) { 105 public void catalogEventPublish(String platformId, DeviceChannel deviceChannel, String type) {
106 List<DeviceChannel> deviceChannelList = new ArrayList<>(); 106 List<DeviceChannel> deviceChannelList = new ArrayList<>();
107 deviceChannelList.add(deviceChannel); 107 deviceChannelList.add(deviceChannel);
108 catalogEventPublish(platformId, deviceChannelList, type); 108 catalogEventPublish(platformId, deviceChannelList, type);
109 } 109 }
110 110
111 - @Async 111 +
112 public void catalogEventPublish(String platformId, List<DeviceChannel> deviceChannels, String type) { 112 public void catalogEventPublish(String platformId, List<DeviceChannel> deviceChannels, String type) {
113 CatalogEvent outEvent = new CatalogEvent(this); 113 CatalogEvent outEvent = new CatalogEvent(this);
114 List<DeviceChannel> channels = new ArrayList<>(); 114 List<DeviceChannel> channels = new ArrayList<>();
@@ -130,8 +130,8 @@ public class EventPublisher { @@ -130,8 +130,8 @@ public class EventPublisher {
130 applicationEventPublisher.publishEvent(outEvent); 130 applicationEventPublisher.publishEvent(outEvent);
131 } 131 }
132 132
133 - @Async  
134 - public void catalogEventPublishForStream(String platformId, GbStream[] gbStreams, String type) { 133 +
  134 + public void catalogEventPublishForStream(String platformId, List<GbStream> gbStreams, String type) {
135 CatalogEvent outEvent = new CatalogEvent(this); 135 CatalogEvent outEvent = new CatalogEvent(this);
136 outEvent.setGbStreams(gbStreams); 136 outEvent.setGbStreams(gbStreams);
137 outEvent.setType(type); 137 outEvent.setType(type);
@@ -139,9 +139,10 @@ public class EventPublisher { @@ -139,9 +139,10 @@ public class EventPublisher {
139 applicationEventPublisher.publishEvent(outEvent); 139 applicationEventPublisher.publishEvent(outEvent);
140 } 140 }
141 141
142 - @Async 142 +
143 public void catalogEventPublishForStream(String platformId, GbStream gbStream, String type) { 143 public void catalogEventPublishForStream(String platformId, GbStream gbStream, String type) {
144 - GbStream[] gbStreams = {gbStream};  
145 - catalogEventPublishForStream(platformId, gbStreams, type); 144 + List<GbStream> gbStreamList = new ArrayList<>();
  145 + gbStreamList.add(gbStream);
  146 + catalogEventPublishForStream(platformId, gbStreamList, type);
146 } 147 }
147 } 148 }
src/main/java/com/genersoft/iot/vmp/gb28181/event/SipSubscribe.java
@@ -23,24 +23,36 @@ public class SipSubscribe { @@ -23,24 +23,36 @@ public class SipSubscribe {
23 23
24 private Map<String, SipSubscribe.Event> okSubscribes = new ConcurrentHashMap<>(); 24 private Map<String, SipSubscribe.Event> okSubscribes = new ConcurrentHashMap<>();
25 25
26 - private Map<String, Date> timeSubscribes = new ConcurrentHashMap<>(); 26 + private Map<String, Date> okTimeSubscribes = new ConcurrentHashMap<>();
  27 + private Map<String, Date> errorTimeSubscribes = new ConcurrentHashMap<>();
27 28
28 -// @Scheduled(cron="*/5 * * * * ?") //每五秒执行一次 29 + // @Scheduled(cron="*/5 * * * * ?") //每五秒执行一次
29 // @Scheduled(fixedRate= 100 * 60 * 60 ) 30 // @Scheduled(fixedRate= 100 * 60 * 60 )
30 - @Scheduled(cron="0 0 * * * ?") //每小时执行一次, 每个整点 31 + @Scheduled(cron="0 0/5 * * * ?") //每5分钟执行一次
31 public void execute(){ 32 public void execute(){
32 logger.info("[定时任务] 清理过期的订阅信息"); 33 logger.info("[定时任务] 清理过期的订阅信息");
33 Calendar calendar = Calendar.getInstance(); 34 Calendar calendar = Calendar.getInstance();
34 calendar.setTime(new Date()); 35 calendar.setTime(new Date());
35 - calendar.set(Calendar.HOUR, calendar.get(Calendar.HOUR) - 1);  
36 - for (String key : timeSubscribes.keySet()) {  
37 - if (timeSubscribes.get(key).before(calendar.getTime())){  
38 - logger.info("[定时任务] 清理过期的订阅信息: {}", key);  
39 - errorSubscribes.remove(key); 36 + calendar.set(Calendar.MINUTE, calendar.get(Calendar.MINUTE) - 5);
  37 +
  38 + for (String key : okTimeSubscribes.keySet()) {
  39 + if (okTimeSubscribes.get(key).before(calendar.getTime())){
  40 +// logger.info("[定时任务] 清理过期的订阅信息: {}", key);
40 okSubscribes.remove(key); 41 okSubscribes.remove(key);
41 - timeSubscribes.remove(key); 42 + okTimeSubscribes.remove(key);
  43 + }
  44 + }
  45 + for (String key : errorTimeSubscribes.keySet()) {
  46 + if (errorTimeSubscribes.get(key).before(calendar.getTime())){
  47 +// logger.info("[定时任务] 清理过期的订阅信息: {}", key);
  48 + errorSubscribes.remove(key);
  49 + errorTimeSubscribes.remove(key);
42 } 50 }
43 } 51 }
  52 + logger.info("okTimeSubscribes.size:{}",okTimeSubscribes.size());
  53 + logger.info("okSubscribes.size:{}",okSubscribes.size());
  54 + logger.info("errorTimeSubscribes.size:{}",errorTimeSubscribes.size());
  55 + logger.info("errorSubscribes.size:{}",errorSubscribes.size());
44 } 56 }
45 57
46 public interface Event { 58 public interface Event {
@@ -105,12 +117,12 @@ public class SipSubscribe { @@ -105,12 +117,12 @@ public class SipSubscribe {
105 117
106 public void addErrorSubscribe(String key, SipSubscribe.Event event) { 118 public void addErrorSubscribe(String key, SipSubscribe.Event event) {
107 errorSubscribes.put(key, event); 119 errorSubscribes.put(key, event);
108 - timeSubscribes.put(key, new Date()); 120 + errorTimeSubscribes.put(key, new Date());
109 } 121 }
110 122
111 public void addOkSubscribe(String key, SipSubscribe.Event event) { 123 public void addOkSubscribe(String key, SipSubscribe.Event event) {
112 okSubscribes.put(key, event); 124 okSubscribes.put(key, event);
113 - timeSubscribes.put(key, new Date()); 125 + okTimeSubscribes.put(key, new Date());
114 } 126 }
115 127
116 public SipSubscribe.Event getErrorSubscribe(String key) { 128 public SipSubscribe.Event getErrorSubscribe(String key) {
@@ -119,7 +131,7 @@ public class SipSubscribe { @@ -119,7 +131,7 @@ public class SipSubscribe {
119 131
120 public void removeErrorSubscribe(String key) { 132 public void removeErrorSubscribe(String key) {
121 errorSubscribes.remove(key); 133 errorSubscribes.remove(key);
122 - timeSubscribes.remove(key); 134 + errorTimeSubscribes.remove(key);
123 } 135 }
124 136
125 public SipSubscribe.Event getOkSubscribe(String key) { 137 public SipSubscribe.Event getOkSubscribe(String key) {
@@ -128,7 +140,7 @@ public class SipSubscribe { @@ -128,7 +140,7 @@ public class SipSubscribe {
128 140
129 public void removeOkSubscribe(String key) { 141 public void removeOkSubscribe(String key) {
130 okSubscribes.remove(key); 142 okSubscribes.remove(key);
131 - timeSubscribes.remove(key); 143 + okTimeSubscribes.remove(key);
132 } 144 }
133 public int getErrorSubscribesSize(){ 145 public int getErrorSubscribesSize(){
134 return errorSubscribes.size(); 146 return errorSubscribes.size();
src/main/java/com/genersoft/iot/vmp/gb28181/event/subscribe/catalog/CatalogEvent.java
@@ -20,7 +20,7 @@ public class CatalogEvent extends ApplicationEvent { @@ -20,7 +20,7 @@ public class CatalogEvent extends ApplicationEvent {
20 public static final String UPDATE = "UPDATE"; // 更新 20 public static final String UPDATE = "UPDATE"; // 更新
21 21
22 private List<DeviceChannel> deviceChannels; 22 private List<DeviceChannel> deviceChannels;
23 - private GbStream[] gbStreams; 23 + private List<GbStream> gbStreams;
24 private String type; 24 private String type;
25 private String platformId; 25 private String platformId;
26 26
@@ -48,11 +48,11 @@ public class CatalogEvent extends ApplicationEvent { @@ -48,11 +48,11 @@ public class CatalogEvent extends ApplicationEvent {
48 this.platformId = platformId; 48 this.platformId = platformId;
49 } 49 }
50 50
51 - public GbStream[] getGbStreams() { 51 + public List<GbStream> getGbStreams() {
52 return gbStreams; 52 return gbStreams;
53 } 53 }
54 54
55 - public void setGbStreams(GbStream[] gbStreams) { 55 + public void setGbStreams(List<GbStream> gbStreams) {
56 this.gbStreams = gbStreams; 56 this.gbStreams = gbStreams;
57 } 57 }
58 } 58 }
src/main/java/com/genersoft/iot/vmp/gb28181/event/subscribe/catalog/CatalogEventLister.java
@@ -60,10 +60,14 @@ public class CatalogEventLister implements ApplicationListener&lt;CatalogEvent&gt; { @@ -60,10 +60,14 @@ public class CatalogEventLister implements ApplicationListener&lt;CatalogEvent&gt; {
60 Map<String, List<ParentPlatform>> parentPlatformMap = new HashMap<>(); 60 Map<String, List<ParentPlatform>> parentPlatformMap = new HashMap<>();
61 if (event.getPlatformId() != null) { 61 if (event.getPlatformId() != null) {
62 parentPlatform = storager.queryParentPlatByServerGBId(event.getPlatformId()); 62 parentPlatform = storager.queryParentPlatByServerGBId(event.getPlatformId());
63 - if (!parentPlatform.isStatus())return; 63 + if (parentPlatform != null && !parentPlatform.isStatus())return;
64 String key = VideoManagerConstants.SIP_SUBSCRIBE_PREFIX + userSetup.getServerId() + "_Catalog_" + event.getPlatformId(); 64 String key = VideoManagerConstants.SIP_SUBSCRIBE_PREFIX + userSetup.getServerId() + "_Catalog_" + event.getPlatformId();
65 subscribe = redisCatchStorage.getSubscribe(key); 65 subscribe = redisCatchStorage.getSubscribe(key);
66 - if (subscribe == null) return; 66 +
  67 + if (subscribe == null) {
  68 + logger.debug("发送订阅消息时发现订阅信息已经不存在");
  69 + return;
  70 + }
67 }else { 71 }else {
68 // 获取所用订阅 72 // 获取所用订阅
69 List<String> platforms = redisCatchStorage.getAllSubscribePlatform(); 73 List<String> platforms = redisCatchStorage.getAllSubscribePlatform();
@@ -94,7 +98,7 @@ public class CatalogEventLister implements ApplicationListener&lt;CatalogEvent&gt; { @@ -94,7 +98,7 @@ public class CatalogEventLister implements ApplicationListener&lt;CatalogEvent&gt; {
94 if (event.getDeviceChannels() != null) { 98 if (event.getDeviceChannels() != null) {
95 deviceChannelList.addAll(event.getDeviceChannels()); 99 deviceChannelList.addAll(event.getDeviceChannels());
96 } 100 }
97 - if (event.getGbStreams() != null && event.getGbStreams().length > 0){ 101 + if (event.getGbStreams() != null && event.getGbStreams().size() > 0){
98 for (GbStream gbStream : event.getGbStreams()) { 102 for (GbStream gbStream : event.getGbStreams()) {
99 DeviceChannel deviceChannelByStream = gbStreamService.getDeviceChannelListByStream(gbStream, gbStream.getCatalogId(), parentPlatform.getDeviceGBId()); 103 DeviceChannel deviceChannelByStream = gbStreamService.getDeviceChannelListByStream(gbStream, gbStream.getCatalogId(), parentPlatform.getDeviceGBId());
100 deviceChannelList.add(deviceChannelByStream); 104 deviceChannelList.add(deviceChannelByStream);
@@ -102,7 +106,7 @@ public class CatalogEventLister implements ApplicationListener&lt;CatalogEvent&gt; { @@ -102,7 +106,7 @@ public class CatalogEventLister implements ApplicationListener&lt;CatalogEvent&gt; {
102 } 106 }
103 if (deviceChannelList.size() > 0) { 107 if (deviceChannelList.size() > 0) {
104 logger.info("[Catalog事件: {}]平台:{},影响通道{}个", event.getType(), event.getPlatformId(), deviceChannelList.size()); 108 logger.info("[Catalog事件: {}]平台:{},影响通道{}个", event.getType(), event.getPlatformId(), deviceChannelList.size());
105 - sipCommanderFroPlatform.sendNotifyForCatalogOther(event.getType(), parentPlatform, deviceChannelList, subscribe); 109 + sipCommanderFroPlatform.sendNotifyForCatalogOther(event.getType(), parentPlatform, deviceChannelList, subscribe, null);
106 } 110 }
107 }else if (parentPlatformMap.keySet().size() > 0) { 111 }else if (parentPlatformMap.keySet().size() > 0) {
108 for (String gbId : parentPlatformMap.keySet()) { 112 for (String gbId : parentPlatformMap.keySet()) {
@@ -117,7 +121,7 @@ public class CatalogEventLister implements ApplicationListener&lt;CatalogEvent&gt; { @@ -117,7 +121,7 @@ public class CatalogEventLister implements ApplicationListener&lt;CatalogEvent&gt; {
117 DeviceChannel deviceChannel = new DeviceChannel(); 121 DeviceChannel deviceChannel = new DeviceChannel();
118 deviceChannel.setChannelId(gbId); 122 deviceChannel.setChannelId(gbId);
119 deviceChannelList.add(deviceChannel); 123 deviceChannelList.add(deviceChannel);
120 - sipCommanderFroPlatform.sendNotifyForCatalogOther(event.getType(), platform, deviceChannelList, subscribeInfo); 124 + sipCommanderFroPlatform.sendNotifyForCatalogOther(event.getType(), platform, deviceChannelList, subscribeInfo, null);
121 } 125 }
122 } 126 }
123 } 127 }
@@ -134,7 +138,7 @@ public class CatalogEventLister implements ApplicationListener&lt;CatalogEvent&gt; { @@ -134,7 +138,7 @@ public class CatalogEventLister implements ApplicationListener&lt;CatalogEvent&gt; {
134 if (event.getDeviceChannels() != null) { 138 if (event.getDeviceChannels() != null) {
135 deviceChannelList.addAll(event.getDeviceChannels()); 139 deviceChannelList.addAll(event.getDeviceChannels());
136 } 140 }
137 - if (event.getGbStreams() != null && event.getGbStreams().length > 0){ 141 + if (event.getGbStreams() != null && event.getGbStreams().size() > 0){
138 for (GbStream gbStream : event.getGbStreams()) { 142 for (GbStream gbStream : event.getGbStreams()) {
139 DeviceChannel deviceChannelByStream = gbStreamService.getDeviceChannelListByStream(gbStream, gbStream.getCatalogId(), parentPlatform.getDeviceGBId()); 143 DeviceChannel deviceChannelByStream = gbStreamService.getDeviceChannelListByStream(gbStream, gbStream.getCatalogId(), parentPlatform.getDeviceGBId());
140 deviceChannelList.add(deviceChannelByStream); 144 deviceChannelList.add(deviceChannelByStream);
@@ -142,7 +146,7 @@ public class CatalogEventLister implements ApplicationListener&lt;CatalogEvent&gt; { @@ -142,7 +146,7 @@ public class CatalogEventLister implements ApplicationListener&lt;CatalogEvent&gt; {
142 } 146 }
143 if (deviceChannelList.size() > 0) { 147 if (deviceChannelList.size() > 0) {
144 logger.info("[Catalog事件: {}]平台:{},影响通道{}个", event.getType(), event.getPlatformId(), deviceChannelList.size()); 148 logger.info("[Catalog事件: {}]平台:{},影响通道{}个", event.getType(), event.getPlatformId(), deviceChannelList.size());
145 - sipCommanderFroPlatform.sendNotifyForCatalogAddOrUpdate(event.getType(), parentPlatform, deviceChannelList, subscribe); 149 + sipCommanderFroPlatform.sendNotifyForCatalogAddOrUpdate(event.getType(), parentPlatform, deviceChannelList, subscribe, null);
146 } 150 }
147 }else if (parentPlatformMap.keySet().size() > 0) { 151 }else if (parentPlatformMap.keySet().size() > 0) {
148 for (String gbId : parentPlatformMap.keySet()) { 152 for (String gbId : parentPlatformMap.keySet()) {
@@ -159,7 +163,7 @@ public class CatalogEventLister implements ApplicationListener&lt;CatalogEvent&gt; { @@ -159,7 +163,7 @@ public class CatalogEventLister implements ApplicationListener&lt;CatalogEvent&gt; {
159 GbStream gbStream = storager.queryStreamInParentPlatform(platform.getServerGBId(), gbId); 163 GbStream gbStream = storager.queryStreamInParentPlatform(platform.getServerGBId(), gbId);
160 DeviceChannel deviceChannelByStream = gbStreamService.getDeviceChannelListByStream(gbStream, gbStream.getCatalogId(), platform.getDeviceGBId()); 164 DeviceChannel deviceChannelByStream = gbStreamService.getDeviceChannelListByStream(gbStream, gbStream.getCatalogId(), platform.getDeviceGBId());
161 deviceChannelList.add(deviceChannelByStream); 165 deviceChannelList.add(deviceChannelByStream);
162 - sipCommanderFroPlatform.sendNotifyForCatalogOther(event.getType(), platform, deviceChannelList, subscribeInfo); 166 + sipCommanderFroPlatform.sendNotifyForCatalogOther(event.getType(), platform, deviceChannelList, subscribeInfo, null);
163 } 167 }
164 } 168 }
165 } 169 }
src/main/java/com/genersoft/iot/vmp/gb28181/session/VideoStreamSessionManager.java
@@ -14,6 +14,7 @@ import com.genersoft.iot.vmp.utils.redis.RedisUtil; @@ -14,6 +14,7 @@ import com.genersoft.iot.vmp.utils.redis.RedisUtil;
14 import gov.nist.javax.sip.stack.SIPDialog; 14 import gov.nist.javax.sip.stack.SIPDialog;
15 import org.springframework.beans.factory.annotation.Autowired; 15 import org.springframework.beans.factory.annotation.Autowired;
16 import org.springframework.stereotype.Component; 16 import org.springframework.stereotype.Component;
  17 +import org.springframework.util.StringUtils;
17 18
18 /** 19 /**
19 * @description:视频流session管理器,管理视频预览、预览回放的通信句柄 20 * @description:视频流session管理器,管理视频预览、预览回放的通信句柄
@@ -29,39 +30,55 @@ public class VideoStreamSessionManager { @@ -29,39 +30,55 @@ public class VideoStreamSessionManager {
29 @Autowired 30 @Autowired
30 private UserSetup userSetup; 31 private UserSetup userSetup;
31 32
32 - public void put(String deviceId, String channelId ,String ssrc, String streamId, String mediaServerId, ClientTransaction transaction){ 33 + /**
  34 + * 添加一个点播/回放的事务信息
  35 + * 后续可以通过流Id/callID
  36 + * @param deviceId 设备ID
  37 + * @param channelId 通道ID
  38 + * @param callId 一次请求的CallID
  39 + * @param stream 流名称
  40 + * @param mediaServerId 所使用的流媒体ID
  41 + * @param transaction 事务
  42 + */
  43 + public void put(String deviceId, String channelId, String callId, String stream, String ssrc, String mediaServerId, ClientTransaction transaction){
33 SsrcTransaction ssrcTransaction = new SsrcTransaction(); 44 SsrcTransaction ssrcTransaction = new SsrcTransaction();
34 ssrcTransaction.setDeviceId(deviceId); 45 ssrcTransaction.setDeviceId(deviceId);
35 ssrcTransaction.setChannelId(channelId); 46 ssrcTransaction.setChannelId(channelId);
36 - ssrcTransaction.setStreamId(streamId); 47 + ssrcTransaction.setStream(stream);
37 byte[] transactionByteArray = SerializeUtils.serialize(transaction); 48 byte[] transactionByteArray = SerializeUtils.serialize(transaction);
38 ssrcTransaction.setTransaction(transactionByteArray); 49 ssrcTransaction.setTransaction(transactionByteArray);
  50 + ssrcTransaction.setCallId(callId);
39 ssrcTransaction.setSsrc(ssrc); 51 ssrcTransaction.setSsrc(ssrc);
40 ssrcTransaction.setMediaServerId(mediaServerId); 52 ssrcTransaction.setMediaServerId(mediaServerId);
41 53
42 - redisUtil.set(VideoManagerConstants.MEDIA_TRANSACTION_USED_PREFIX + userSetup.getServerId() + "_" + deviceId + "_" + channelId, ssrcTransaction); 54 + redisUtil.set(VideoManagerConstants.MEDIA_TRANSACTION_USED_PREFIX + userSetup.getServerId()
  55 + + "_" + deviceId + "_" + channelId + "_" + callId + "_" + stream, ssrcTransaction);
  56 + redisUtil.set(VideoManagerConstants.MEDIA_TRANSACTION_USED_PREFIX + userSetup.getServerId()
  57 + + "_" + deviceId + "_" + channelId + "_" + callId + "_" + stream, ssrcTransaction);
43 } 58 }
44 59
45 - public void put(String deviceId, String channelId , Dialog dialog){  
46 - SsrcTransaction ssrcTransaction = getSsrcTransaction(deviceId, channelId); 60 + public void put(String deviceId, String channelId, String callId, Dialog dialog){
  61 + SsrcTransaction ssrcTransaction = getSsrcTransaction(deviceId, channelId, callId, null);
47 if (ssrcTransaction != null) { 62 if (ssrcTransaction != null) {
48 byte[] dialogByteArray = SerializeUtils.serialize(dialog); 63 byte[] dialogByteArray = SerializeUtils.serialize(dialog);
49 ssrcTransaction.setDialog(dialogByteArray); 64 ssrcTransaction.setDialog(dialogByteArray);
50 } 65 }
51 - redisUtil.set(VideoManagerConstants.MEDIA_TRANSACTION_USED_PREFIX + userSetup.getServerId() + "_" + deviceId + "_" + channelId, ssrcTransaction); 66 + redisUtil.set(VideoManagerConstants.MEDIA_TRANSACTION_USED_PREFIX + userSetup.getServerId()
  67 + + "_" + deviceId + "_" + channelId + "_" + ssrcTransaction.getCallId() + "_"
  68 + + ssrcTransaction.getStream(), ssrcTransaction);
52 } 69 }
53 70
54 71
55 - public ClientTransaction getTransaction(String deviceId, String channelId){  
56 - SsrcTransaction ssrcTransaction = getSsrcTransaction(deviceId, channelId); 72 + public ClientTransaction getTransactionByStream(String deviceId, String channelId, String stream){
  73 + SsrcTransaction ssrcTransaction = getSsrcTransaction(deviceId, channelId, null, stream);
57 if (ssrcTransaction == null) return null; 74 if (ssrcTransaction == null) return null;
58 byte[] transactionByteArray = ssrcTransaction.getTransaction(); 75 byte[] transactionByteArray = ssrcTransaction.getTransaction();
59 ClientTransaction clientTransaction = (ClientTransaction)SerializeUtils.deSerialize(transactionByteArray); 76 ClientTransaction clientTransaction = (ClientTransaction)SerializeUtils.deSerialize(transactionByteArray);
60 return clientTransaction; 77 return clientTransaction;
61 } 78 }
62 79
63 - public SIPDialog getDialog(String deviceId, String channelId){  
64 - SsrcTransaction ssrcTransaction = getSsrcTransaction(deviceId, channelId); 80 + public SIPDialog getDialogByStream(String deviceId, String channelId, String stream){
  81 + SsrcTransaction ssrcTransaction = getSsrcTransaction(deviceId, channelId, null, stream);
65 if (ssrcTransaction == null) return null; 82 if (ssrcTransaction == null) return null;
66 byte[] dialogByteArray = ssrcTransaction.getDialog(); 83 byte[] dialogByteArray = ssrcTransaction.getDialog();
67 if (dialogByteArray == null) return null; 84 if (dialogByteArray == null) return null;
@@ -69,36 +86,37 @@ public class VideoStreamSessionManager { @@ -69,36 +86,37 @@ public class VideoStreamSessionManager {
69 return dialog; 86 return dialog;
70 } 87 }
71 88
72 - public SsrcTransaction getSsrcTransaction(String deviceId, String channelId){  
73 - SsrcTransaction ssrcTransaction = (SsrcTransaction)redisUtil.get(VideoManagerConstants.MEDIA_TRANSACTION_USED_PREFIX + userSetup.getServerId() + "_" + deviceId + "_" + channelId);  
74 - return ssrcTransaction; 89 + public SsrcTransaction getSsrcTransaction(String deviceId, String channelId, String callId, String stream){
  90 + if (StringUtils.isEmpty(callId)) callId ="*";
  91 + if (StringUtils.isEmpty(stream)) stream ="*";
  92 + String key = VideoManagerConstants.MEDIA_TRANSACTION_USED_PREFIX + userSetup.getServerId() + "_" + deviceId + "_" + channelId + "_" + callId+ "_" + stream;
  93 + List<Object> scanResult = redisUtil.scan(key);
  94 + if (scanResult.size() == 0) return null;
  95 + return (SsrcTransaction)redisUtil.get((String) scanResult.get(0));
75 } 96 }
76 97
77 - public String getStreamId(String deviceId, String channelId){  
78 - SsrcTransaction ssrcTransaction = getSsrcTransaction(deviceId, channelId);  
79 - if (ssrcTransaction == null) return null;  
80 - return ssrcTransaction.getStreamId();  
81 - }  
82 - public String getMediaServerId(String deviceId, String channelId){  
83 - SsrcTransaction ssrcTransaction = getSsrcTransaction(deviceId, channelId); 98 + public String getMediaServerId(String deviceId, String channelId, String stream){
  99 + SsrcTransaction ssrcTransaction = getSsrcTransaction(deviceId, channelId, null, stream);
84 if (ssrcTransaction == null) return null; 100 if (ssrcTransaction == null) return null;
85 return ssrcTransaction.getMediaServerId(); 101 return ssrcTransaction.getMediaServerId();
86 } 102 }
87 103
88 - public String getSSRC(String deviceId, String channelId){  
89 - SsrcTransaction ssrcTransaction = getSsrcTransaction(deviceId, channelId); 104 + public String getSSRC(String deviceId, String channelId, String stream){
  105 + SsrcTransaction ssrcTransaction = getSsrcTransaction(deviceId, channelId, null, stream);
90 if (ssrcTransaction == null) return null; 106 if (ssrcTransaction == null) return null;
91 return ssrcTransaction.getSsrc(); 107 return ssrcTransaction.getSsrc();
92 } 108 }
93 109
94 - public void remove(String deviceId, String channelId) {  
95 - SsrcTransaction ssrcTransaction = getSsrcTransaction(deviceId, channelId); 110 + public void remove(String deviceId, String channelId, String stream) {
  111 + SsrcTransaction ssrcTransaction = getSsrcTransaction(deviceId, channelId, null, stream);
96 if (ssrcTransaction == null) return; 112 if (ssrcTransaction == null) return;
97 - redisUtil.del(VideoManagerConstants.MEDIA_TRANSACTION_USED_PREFIX + userSetup.getServerId() + "_" + deviceId + "_" + channelId); 113 + redisUtil.del(VideoManagerConstants.MEDIA_TRANSACTION_USED_PREFIX + userSetup.getServerId() + "_"
  114 + + deviceId + "_" + channelId + "_" + ssrcTransaction.getCallId() + "_" + ssrcTransaction.getStream());
98 } 115 }
99 116
  117 +
100 public List<SsrcTransaction> getAllSsrc() { 118 public List<SsrcTransaction> getAllSsrc() {
101 - List<Object> ssrcTransactionKeys = redisUtil.scan(String.format("%s_*_*", VideoManagerConstants.MEDIA_TRANSACTION_USED_PREFIX+ userSetup.getServerId() + "_" )); 119 + List<Object> ssrcTransactionKeys = redisUtil.scan(String.format("%s_*_*_*_*", VideoManagerConstants.MEDIA_TRANSACTION_USED_PREFIX+ userSetup.getServerId() + "_" ));
102 List<SsrcTransaction> result= new ArrayList<>(); 120 List<SsrcTransaction> result= new ArrayList<>();
103 for (int i = 0; i < ssrcTransactionKeys.size(); i++) { 121 for (int i = 0; i < ssrcTransactionKeys.size(); i++) {
104 String key = (String)ssrcTransactionKeys.get(i); 122 String key = (String)ssrcTransactionKeys.get(i);
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPProcessorObserver.java
@@ -73,6 +73,7 @@ public class SIPProcessorObserver implements ISIPProcessorObserver { @@ -73,6 +73,7 @@ public class SIPProcessorObserver implements ISIPProcessorObserver {
73 @Override 73 @Override
74 @Async 74 @Async
75 public void processRequest(RequestEvent requestEvent) { 75 public void processRequest(RequestEvent requestEvent) {
  76 + logger.debug("\n收到请求:\n{}", requestEvent.getRequest());
76 String method = requestEvent.getRequest().getMethod(); 77 String method = requestEvent.getRequest().getMethod();
77 ISIPRequestProcessor sipRequestProcessor = requestProcessorMap.get(method); 78 ISIPRequestProcessor sipRequestProcessor = requestProcessorMap.get(method);
78 if (sipRequestProcessor == null) { 79 if (sipRequestProcessor == null) {
@@ -90,9 +91,8 @@ public class SIPProcessorObserver implements ISIPProcessorObserver { @@ -90,9 +91,8 @@ public class SIPProcessorObserver implements ISIPProcessorObserver {
90 @Override 91 @Override
91 @Async 92 @Async
92 public void processResponse(ResponseEvent responseEvent) { 93 public void processResponse(ResponseEvent responseEvent) {
93 - logger.debug(responseEvent.getResponse().toString());  
94 Response response = responseEvent.getResponse(); 94 Response response = responseEvent.getResponse();
95 - logger.debug(responseEvent.getResponse().toString()); 95 + logger.debug("\n收到响应:\n{}", responseEvent.getResponse());
96 int status = response.getStatusCode(); 96 int status = response.getStatusCode();
97 if (((status >= 200) && (status < 300)) || status == 401) { // Success! 97 if (((status >= 200) && (status < 300)) || status == 401) { // Success!
98 CSeqHeader cseqHeader = (CSeqHeader) responseEvent.getResponse().getHeader(CSeqHeader.NAME); 98 CSeqHeader cseqHeader = (CSeqHeader) responseEvent.getResponse().getHeader(CSeqHeader.NAME);
@@ -107,8 +107,8 @@ public class SIPProcessorObserver implements ISIPProcessorObserver { @@ -107,8 +107,8 @@ public class SIPProcessorObserver implements ISIPProcessorObserver {
107 SipSubscribe.Event subscribe = sipSubscribe.getOkSubscribe(callIdHeader.getCallId()); 107 SipSubscribe.Event subscribe = sipSubscribe.getOkSubscribe(callIdHeader.getCallId());
108 if (subscribe != null) { 108 if (subscribe != null) {
109 SipSubscribe.EventResult eventResult = new SipSubscribe.EventResult(responseEvent); 109 SipSubscribe.EventResult eventResult = new SipSubscribe.EventResult(responseEvent);
110 - subscribe.response(eventResult);  
111 sipSubscribe.removeOkSubscribe(callIdHeader.getCallId()); 110 sipSubscribe.removeOkSubscribe(callIdHeader.getCallId());
  111 + subscribe.response(eventResult);
112 } 112 }
113 } 113 }
114 } 114 }
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/ISIPCommander.java
@@ -119,8 +119,8 @@ public interface ISIPCommander { @@ -119,8 +119,8 @@ public interface ISIPCommander {
119 /** 119 /**
120 * 视频流停止 120 * 视频流停止
121 */ 121 */
122 - void streamByeCmd(String deviceId, String channelId, SipSubscribe.Event okEvent);  
123 - void streamByeCmd(String deviceId, String channelId); 122 + void streamByeCmd(String deviceId, String channelId, String stream, SipSubscribe.Event okEvent);
  123 + void streamByeCmd(String deviceId, String channelId, String stream);
124 124
125 /** 125 /**
126 * 回放暂停 126 * 回放暂停
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/ISIPCommanderForPlatform.java
@@ -17,7 +17,7 @@ public interface ISIPCommanderForPlatform { @@ -17,7 +17,7 @@ public interface ISIPCommanderForPlatform {
17 * @return 17 * @return
18 */ 18 */
19 boolean register(ParentPlatform parentPlatform, SipSubscribe.Event errorEvent , SipSubscribe.Event okEvent); 19 boolean register(ParentPlatform parentPlatform, SipSubscribe.Event errorEvent , SipSubscribe.Event okEvent);
20 - boolean register(ParentPlatform parentPlatform, String callId, WWWAuthenticateHeader www, SipSubscribe.Event errorEvent , SipSubscribe.Event okEvent); 20 + boolean register(ParentPlatform parentPlatform, String callId, WWWAuthenticateHeader www, SipSubscribe.Event errorEvent , SipSubscribe.Event okEvent, boolean registerAgain);
21 21
22 /** 22 /**
23 * 向上级平台注销 23 * 向上级平台注销
@@ -78,13 +78,13 @@ public interface ISIPCommanderForPlatform { @@ -78,13 +78,13 @@ public interface ISIPCommanderForPlatform {
78 * @param parentPlatform 78 * @param parentPlatform
79 * @param deviceChannels 79 * @param deviceChannels
80 */ 80 */
81 - boolean sendNotifyForCatalogAddOrUpdate(String type, ParentPlatform parentPlatform, List<DeviceChannel> deviceChannels, SubscribeInfo subscribeInfo); 81 + boolean sendNotifyForCatalogAddOrUpdate(String type, ParentPlatform parentPlatform, List<DeviceChannel> deviceChannels, SubscribeInfo subscribeInfo, Integer index);
82 82
83 /** 83 /**
84 * 回复catalog事件-删除 84 * 回复catalog事件-删除
85 * @param parentPlatform 85 * @param parentPlatform
86 * @param deviceChannels 86 * @param deviceChannels
87 */ 87 */
88 - boolean sendNotifyForCatalogOther(String type, ParentPlatform parentPlatform, List<DeviceChannel> deviceChannels, SubscribeInfo subscribeInfo); 88 + boolean sendNotifyForCatalogOther(String type, ParentPlatform parentPlatform, List<DeviceChannel> deviceChannels, SubscribeInfo subscribeInfo, Integer index);
89 89
90 } 90 }
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/SIPRequestHeaderPlarformProvider.java
@@ -2,6 +2,7 @@ package com.genersoft.iot.vmp.gb28181.transmit.cmd; @@ -2,6 +2,7 @@ package com.genersoft.iot.vmp.gb28181.transmit.cmd;
2 2
3 import com.genersoft.iot.vmp.conf.SipConfig; 3 import com.genersoft.iot.vmp.conf.SipConfig;
4 import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform; 4 import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform;
  5 +import com.genersoft.iot.vmp.gb28181.bean.SubscribeInfo;
5 import com.genersoft.iot.vmp.storager.IRedisCatchStorage; 6 import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
6 import gov.nist.javax.sip.message.MessageFactoryImpl; 7 import gov.nist.javax.sip.message.MessageFactoryImpl;
7 import org.springframework.beans.factory.annotation.Autowired; 8 import org.springframework.beans.factory.annotation.Autowired;
@@ -127,7 +128,15 @@ public class SIPRequestHeaderPlarformProvider { @@ -127,7 +128,15 @@ public class SIPRequestHeaderPlarformProvider {
127 128
128 129
129 Request registerRequest = createRegisterRequest(parentPlatform, redisCatchStorage.getCSEQ(Request.REGISTER), fromTag, viaTag, callIdHeader); 130 Request registerRequest = createRegisterRequest(parentPlatform, redisCatchStorage.getCSEQ(Request.REGISTER), fromTag, viaTag, callIdHeader);
130 - 131 + SipURI requestURI = sipFactory.createAddressFactory().createSipURI(parentPlatform.getServerGBId(), parentPlatform.getServerIP() + ":" + parentPlatform.getServerPort());
  132 + if (www == null) {
  133 + AuthorizationHeader authorizationHeader = sipFactory.createHeaderFactory().createAuthorizationHeader("Digest");
  134 + authorizationHeader.setUsername(parentPlatform.getDeviceGBId());
  135 + authorizationHeader.setURI(requestURI);
  136 + authorizationHeader.setAlgorithm("MD5");
  137 + registerRequest.addHeader(authorizationHeader);
  138 + return registerRequest;
  139 + }
131 String realm = www.getRealm(); 140 String realm = www.getRealm();
132 String nonce = www.getNonce(); 141 String nonce = www.getNonce();
133 String scheme = www.getScheme(); 142 String scheme = www.getScheme();
@@ -138,7 +147,6 @@ public class SIPRequestHeaderPlarformProvider { @@ -138,7 +147,6 @@ public class SIPRequestHeaderPlarformProvider {
138 147
139 callIdHeader.setCallId(callId); 148 callIdHeader.setCallId(callId);
140 149
141 - SipURI requestURI = sipFactory.createAddressFactory().createSipURI(parentPlatform.getServerGBId(), parentPlatform.getServerIP() + ":" + parentPlatform.getServerPort());  
142 String cNonce = null; 150 String cNonce = null;
143 String nc = "00000001"; 151 String nc = "00000001";
144 if (qop != null) { 152 if (qop != null) {
@@ -223,30 +231,30 @@ public class SIPRequestHeaderPlarformProvider { @@ -223,30 +231,30 @@ public class SIPRequestHeaderPlarformProvider {
223 UserAgentHeader userAgentHeader = sipFactory.createHeaderFactory().createUserAgentHeader(agentParam); 231 UserAgentHeader userAgentHeader = sipFactory.createHeaderFactory().createUserAgentHeader(agentParam);
224 request.addHeader(userAgentHeader); 232 request.addHeader(userAgentHeader);
225 233
226 - ContentTypeHeader contentTypeHeader = sipFactory.createHeaderFactory().createContentTypeHeader("APPLICATION", "MANSCDP+xml"); 234 + ContentTypeHeader contentTypeHeader = sipFactory.createHeaderFactory().createContentTypeHeader("Application", "MANSCDP+xml");
227 request.setContent(content, contentTypeHeader); 235 request.setContent(content, contentTypeHeader);
228 return request; 236 return request;
229 } 237 }
230 238
231 - public Request createNotifyRequest(ParentPlatform parentPlatform, String content, String fromTag, String toTag, CallIdHeader callIdHeader) throws PeerUnavailableException, ParseException, InvalidArgumentException { 239 + public Request createNotifyRequest(ParentPlatform parentPlatform, String content, CallIdHeader callIdHeader, String viaTag, SubscribeInfo subscribeInfo) throws PeerUnavailableException, ParseException, InvalidArgumentException {
232 Request request = null; 240 Request request = null;
233 // sipuri 241 // sipuri
234 SipURI requestURI = sipFactory.createAddressFactory().createSipURI(parentPlatform.getServerGBId(), parentPlatform.getServerIP()+ ":" + parentPlatform.getServerPort()); 242 SipURI requestURI = sipFactory.createAddressFactory().createSipURI(parentPlatform.getServerGBId(), parentPlatform.getServerIP()+ ":" + parentPlatform.getServerPort());
235 // via 243 // via
236 ArrayList<ViaHeader> viaHeaders = new ArrayList<ViaHeader>(); 244 ArrayList<ViaHeader> viaHeaders = new ArrayList<ViaHeader>();
237 ViaHeader viaHeader = sipFactory.createHeaderFactory().createViaHeader(parentPlatform.getDeviceIp(), Integer.parseInt(parentPlatform.getDevicePort()), 245 ViaHeader viaHeader = sipFactory.createHeaderFactory().createViaHeader(parentPlatform.getDeviceIp(), Integer.parseInt(parentPlatform.getDevicePort()),
238 - parentPlatform.getTransport(), null); 246 + parentPlatform.getTransport(), subscribeInfo.getBranch());
239 viaHeader.setRPort(); 247 viaHeader.setRPort();
240 viaHeaders.add(viaHeader); 248 viaHeaders.add(viaHeader);
241 // from 249 // from
242 SipURI fromSipURI = sipFactory.createAddressFactory().createSipURI(parentPlatform.getDeviceGBId(), 250 SipURI fromSipURI = sipFactory.createAddressFactory().createSipURI(parentPlatform.getDeviceGBId(),
243 parentPlatform.getDeviceIp() + ":" + parentPlatform.getDevicePort()); 251 parentPlatform.getDeviceIp() + ":" + parentPlatform.getDevicePort());
244 Address fromAddress = sipFactory.createAddressFactory().createAddress(fromSipURI); 252 Address fromAddress = sipFactory.createAddressFactory().createAddress(fromSipURI);
245 - FromHeader fromHeader = sipFactory.createHeaderFactory().createFromHeader(fromAddress, fromTag); 253 + FromHeader fromHeader = sipFactory.createHeaderFactory().createFromHeader(fromAddress, subscribeInfo.getToTag());
246 // to 254 // to
247 SipURI toSipURI = sipFactory.createAddressFactory().createSipURI(parentPlatform.getServerGBId(), parentPlatform.getServerGBDomain()); 255 SipURI toSipURI = sipFactory.createAddressFactory().createSipURI(parentPlatform.getServerGBId(), parentPlatform.getServerGBDomain());
248 Address toAddress = sipFactory.createAddressFactory().createAddress(toSipURI); 256 Address toAddress = sipFactory.createAddressFactory().createAddress(toSipURI);
249 - ToHeader toHeader = sipFactory.createHeaderFactory().createToHeader(toAddress, toTag); 257 + ToHeader toHeader = sipFactory.createHeaderFactory().createToHeader(toAddress, subscribeInfo.getFromTag());
250 258
251 // Forwards 259 // Forwards
252 MaxForwardsHeader maxForwards = sipFactory.createHeaderFactory().createMaxForwardsHeader(70); 260 MaxForwardsHeader maxForwards = sipFactory.createHeaderFactory().createMaxForwardsHeader(70);
@@ -262,7 +270,22 @@ public class SIPRequestHeaderPlarformProvider { @@ -262,7 +270,22 @@ public class SIPRequestHeaderPlarformProvider {
262 UserAgentHeader userAgentHeader = sipFactory.createHeaderFactory().createUserAgentHeader(agentParam); 270 UserAgentHeader userAgentHeader = sipFactory.createHeaderFactory().createUserAgentHeader(agentParam);
263 request.addHeader(userAgentHeader); 271 request.addHeader(userAgentHeader);
264 272
265 - ContentTypeHeader contentTypeHeader = sipFactory.createHeaderFactory().createContentTypeHeader("APPLICATION", "MANSCDP+xml"); 273 + EventHeader event = sipFactory.createHeaderFactory().createEventHeader(subscribeInfo.getEventType());
  274 + if (subscribeInfo.getEventId() != null) {
  275 + event.setEventId(subscribeInfo.getEventId());
  276 + }
  277 +
  278 + request.addHeader(event);
  279 +
  280 + SubscriptionStateHeader active = sipFactory.createHeaderFactory().createSubscriptionStateHeader("active");
  281 + request.setHeader(active);
  282 +
  283 + String sipAddress = sipConfig.getIp() + ":" + sipConfig.getPort();
  284 + Address concatAddress = sipFactory.createAddressFactory().createAddress(sipFactory.createAddressFactory()
  285 + .createSipURI(parentPlatform.getDeviceGBId(), sipAddress));
  286 + request.addHeader(sipFactory.createHeaderFactory().createContactHeader(concatAddress));
  287 +
  288 + ContentTypeHeader contentTypeHeader = sipFactory.createHeaderFactory().createContentTypeHeader("Application", "MANSCDP+xml");
266 request.setContent(content, contentTypeHeader); 289 request.setContent(content, contentTypeHeader);
267 return request; 290 return request;
268 } 291 }
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/SIPRequestHeaderProvider.java
@@ -67,7 +67,7 @@ public class SIPRequestHeaderProvider { @@ -67,7 +67,7 @@ public class SIPRequestHeaderProvider {
67 67
68 request = sipFactory.createMessageFactory().createRequest(requestURI, Request.MESSAGE, callIdHeader, cSeqHeader, fromHeader, 68 request = sipFactory.createMessageFactory().createRequest(requestURI, Request.MESSAGE, callIdHeader, cSeqHeader, fromHeader,
69 toHeader, viaHeaders, maxForwards); 69 toHeader, viaHeaders, maxForwards);
70 - ContentTypeHeader contentTypeHeader = sipFactory.createHeaderFactory().createContentTypeHeader("APPLICATION", "MANSCDP+xml"); 70 + ContentTypeHeader contentTypeHeader = sipFactory.createHeaderFactory().createContentTypeHeader("Application", "MANSCDP+xml");
71 request.setContent(content, contentTypeHeader); 71 request.setContent(content, contentTypeHeader);
72 return request; 72 return request;
73 } 73 }
@@ -217,7 +217,7 @@ public class SIPRequestHeaderProvider { @@ -217,7 +217,7 @@ public class SIPRequestHeaderProvider {
217 EventHeader eventHeader = sipFactory.createHeaderFactory().createEventHeader(event); 217 EventHeader eventHeader = sipFactory.createHeaderFactory().createEventHeader(event);
218 request.addHeader(eventHeader); 218 request.addHeader(eventHeader);
219 219
220 - ContentTypeHeader contentTypeHeader = sipFactory.createHeaderFactory().createContentTypeHeader("APPLICATION", "MANSCDP+xml"); 220 + ContentTypeHeader contentTypeHeader = sipFactory.createHeaderFactory().createContentTypeHeader("Application", "MANSCDP+xml");
221 request.setContent(content, contentTypeHeader); 221 request.setContent(content, contentTypeHeader);
222 return request; 222 return request;
223 } 223 }
@@ -226,7 +226,7 @@ public class SIPRequestHeaderProvider { @@ -226,7 +226,7 @@ public class SIPRequestHeaderProvider {
226 throws PeerUnavailableException, ParseException, InvalidArgumentException { 226 throws PeerUnavailableException, ParseException, InvalidArgumentException {
227 Request request = null; 227 Request request = null;
228 if (streamInfo == null) return null; 228 if (streamInfo == null) return null;
229 - Dialog dialog = streamSession.getDialog(streamInfo.getDeviceID(), streamInfo.getChannelId()); 229 + Dialog dialog = streamSession.getDialogByStream(streamInfo.getDeviceID(), streamInfo.getChannelId(), streamInfo.getStream());
230 230
231 SipURI requestLine = sipFactory.createAddressFactory().createSipURI(device.getDeviceId(), 231 SipURI requestLine = sipFactory.createAddressFactory().createSipURI(device.getDeviceId(),
232 device.getHostAddress()); 232 device.getHostAddress());
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java
@@ -331,7 +331,7 @@ public class SIPCommander implements ISIPCommander { @@ -331,7 +331,7 @@ public class SIPCommander implements ISIPCommander {
331 */ 331 */
332 @Override 332 @Override
333 public void playStreamCmd(MediaServerItem mediaServerItem, SSRCInfo ssrcInfo, Device device, String channelId, ZLMHttpHookSubscribe.Event event, SipSubscribe.Event errorEvent) { 333 public void playStreamCmd(MediaServerItem mediaServerItem, SSRCInfo ssrcInfo, Device device, String channelId, ZLMHttpHookSubscribe.Event event, SipSubscribe.Event errorEvent) {
334 - String streamId = ssrcInfo.getStreamId(); 334 + String streamId = ssrcInfo.getStream();
335 try { 335 try {
336 if (device == null) return; 336 if (device == null) return;
337 String streamMode = device.getStreamMode().toUpperCase(); 337 String streamMode = device.getStreamMode().toUpperCase();
@@ -404,6 +404,8 @@ public class SIPCommander implements ISIPCommander { @@ -404,6 +404,8 @@ public class SIPCommander implements ISIPCommander {
404 } 404 }
405 405
406 content.append("y="+ssrcInfo.getSsrc()+"\r\n");//ssrc 406 content.append("y="+ssrcInfo.getSsrc()+"\r\n");//ssrc
  407 + // f字段:f= v/编码格式/分辨率/帧率/码率类型/码率大小a/编码格式/码率大小/采样率
  408 +// content.append("f=v/2/5/25/1/4000a/1/8/1" + "\r\n"); // 未发现支持此特性的设备
407 409
408 String tm = Long.toString(System.currentTimeMillis()); 410 String tm = Long.toString(System.currentTimeMillis());
409 411
@@ -412,14 +414,14 @@ public class SIPCommander implements ISIPCommander { @@ -412,14 +414,14 @@ public class SIPCommander implements ISIPCommander {
412 414
413 Request request = headerProvider.createInviteRequest(device, channelId, content.toString(), null, "FromInvt" + tm, null, ssrcInfo.getSsrc(), callIdHeader); 415 Request request = headerProvider.createInviteRequest(device, channelId, content.toString(), null, "FromInvt" + tm, null, ssrcInfo.getSsrc(), callIdHeader);
414 416
415 - String finalStreamId = streamId;  
416 transmitRequest(device, request, (e -> { 417 transmitRequest(device, request, (e -> {
417 - streamSession.remove(device.getDeviceId(), channelId); 418 + streamSession.remove(device.getDeviceId(), channelId, ssrcInfo.getStream());
418 mediaServerService.releaseSsrc(mediaServerItem, ssrcInfo.getSsrc()); 419 mediaServerService.releaseSsrc(mediaServerItem, ssrcInfo.getSsrc());
419 errorEvent.response(e); 420 errorEvent.response(e);
420 }), e ->{ 421 }), e ->{
421 - streamSession.put(device.getDeviceId(), channelId ,ssrcInfo.getSsrc(), finalStreamId, mediaServerItem.getId(), ((ResponseEvent)e.event).getClientTransaction());  
422 - streamSession.put(device.getDeviceId(), channelId , e.dialog); 422 + // 这里为例避免一个通道的点播只有一个callID这个参数使用一个固定值
  423 + streamSession.put(device.getDeviceId(), channelId ,"play", streamId, ssrcInfo.getSsrc(), mediaServerItem.getId(), ((ResponseEvent)e.event).getClientTransaction());
  424 + streamSession.put(device.getDeviceId(), channelId ,"play", e.dialog);
423 }); 425 });
424 426
425 427
@@ -441,12 +443,12 @@ public class SIPCommander implements ISIPCommander { @@ -441,12 +443,12 @@ public class SIPCommander implements ISIPCommander {
441 , SipSubscribe.Event errorEvent) { 443 , SipSubscribe.Event errorEvent) {
442 try { 444 try {
443 445
444 - logger.info("{} 分配的ZLM为: {} [{}:{}]", ssrcInfo.getStreamId(), mediaServerItem.getId(), mediaServerItem.getIp(), ssrcInfo.getPort()); 446 + logger.info("{} 分配的ZLM为: {} [{}:{}]", ssrcInfo.getStream(), mediaServerItem.getId(), mediaServerItem.getIp(), ssrcInfo.getPort());
445 447
446 // 添加订阅 448 // 添加订阅
447 JSONObject subscribeKey = new JSONObject(); 449 JSONObject subscribeKey = new JSONObject();
448 subscribeKey.put("app", "rtp"); 450 subscribeKey.put("app", "rtp");
449 - subscribeKey.put("stream", ssrcInfo.getStreamId()); 451 + subscribeKey.put("stream", ssrcInfo.getStream());
450 subscribeKey.put("regist", true); 452 subscribeKey.put("regist", true);
451 subscribeKey.put("mediaServerId", mediaServerItem.getId()); 453 subscribeKey.put("mediaServerId", mediaServerItem.getId());
452 logger.debug("录像回放添加订阅,订阅内容:" + subscribeKey.toString()); 454 logger.debug("录像回放添加订阅,订阅内容:" + subscribeKey.toString());
@@ -466,8 +468,6 @@ public class SIPCommander implements ISIPCommander { @@ -466,8 +468,6 @@ public class SIPCommander implements ISIPCommander {
466 content.append("t="+DateUtil.yyyy_MM_dd_HH_mm_ssToTimestamp(startTime)+" " 468 content.append("t="+DateUtil.yyyy_MM_dd_HH_mm_ssToTimestamp(startTime)+" "
467 +DateUtil.yyyy_MM_dd_HH_mm_ssToTimestamp(endTime) +"\r\n"); 469 +DateUtil.yyyy_MM_dd_HH_mm_ssToTimestamp(endTime) +"\r\n");
468 470
469 -  
470 -  
471 String streamMode = device.getStreamMode().toUpperCase(); 471 String streamMode = device.getStreamMode().toUpperCase();
472 472
473 if (userSetup.isSeniorSdp()) { 473 if (userSetup.isSeniorSdp()) {
@@ -527,8 +527,8 @@ public class SIPCommander implements ISIPCommander { @@ -527,8 +527,8 @@ public class SIPCommander implements ISIPCommander {
527 527
528 transmitRequest(device, request, errorEvent, okEvent -> { 528 transmitRequest(device, request, errorEvent, okEvent -> {
529 ResponseEvent responseEvent = (ResponseEvent) okEvent.event; 529 ResponseEvent responseEvent = (ResponseEvent) okEvent.event;
530 - streamSession.put(device.getDeviceId(), channelId, ssrcInfo.getSsrc(), ssrcInfo.getStreamId(), mediaServerItem.getId(), responseEvent.getClientTransaction());  
531 - streamSession.put(device.getDeviceId(), channelId, okEvent.dialog); 530 + streamSession.put(device.getDeviceId(), channelId, callIdHeader.getCallId(), ssrcInfo.getStream(), ssrcInfo.getSsrc(), mediaServerItem.getId(), responseEvent.getClientTransaction());
  531 + streamSession.put(device.getDeviceId(), channelId, callIdHeader.getCallId(), okEvent.dialog);
532 }); 532 });
533 } catch ( SipException | ParseException | InvalidArgumentException e) { 533 } catch ( SipException | ParseException | InvalidArgumentException e) {
534 e.printStackTrace(); 534 e.printStackTrace();
@@ -548,12 +548,12 @@ public class SIPCommander implements ISIPCommander { @@ -548,12 +548,12 @@ public class SIPCommander implements ISIPCommander {
548 public void downloadStreamCmd(MediaServerItem mediaServerItem, SSRCInfo ssrcInfo, Device device, String channelId, String startTime, String endTime, String downloadSpeed, ZLMHttpHookSubscribe.Event event 548 public void downloadStreamCmd(MediaServerItem mediaServerItem, SSRCInfo ssrcInfo, Device device, String channelId, String startTime, String endTime, String downloadSpeed, ZLMHttpHookSubscribe.Event event
549 , SipSubscribe.Event errorEvent) { 549 , SipSubscribe.Event errorEvent) {
550 try { 550 try {
551 - logger.info("{} 分配的ZLM为: {} [{}:{}]", ssrcInfo.getStreamId(), mediaServerItem.getId(), mediaServerItem.getIp(), ssrcInfo.getPort()); 551 + logger.info("{} 分配的ZLM为: {} [{}:{}]", ssrcInfo.getStream(), mediaServerItem.getId(), mediaServerItem.getIp(), ssrcInfo.getPort());
552 552
553 // 添加订阅 553 // 添加订阅
554 JSONObject subscribeKey = new JSONObject(); 554 JSONObject subscribeKey = new JSONObject();
555 subscribeKey.put("app", "rtp"); 555 subscribeKey.put("app", "rtp");
556 - subscribeKey.put("stream", ssrcInfo.getStreamId()); 556 + subscribeKey.put("stream", ssrcInfo.getStream());
557 subscribeKey.put("regist", true); 557 subscribeKey.put("regist", true);
558 subscribeKey.put("mediaServerId", mediaServerItem.getId()); 558 subscribeKey.put("mediaServerId", mediaServerItem.getId());
559 logger.debug("录像回放添加订阅,订阅内容:" + subscribeKey.toString()); 559 logger.debug("录像回放添加订阅,订阅内容:" + subscribeKey.toString());
@@ -634,7 +634,8 @@ public class SIPCommander implements ISIPCommander { @@ -634,7 +634,8 @@ public class SIPCommander implements ISIPCommander {
634 Request request = headerProvider.createPlaybackInviteRequest(device, channelId, content.toString(), null, "fromplybck" + tm, null, callIdHeader, ssrcInfo.getSsrc()); 634 Request request = headerProvider.createPlaybackInviteRequest(device, channelId, content.toString(), null, "fromplybck" + tm, null, callIdHeader, ssrcInfo.getSsrc());
635 635
636 ClientTransaction transaction = transmitRequest(device, request, errorEvent); 636 ClientTransaction transaction = transmitRequest(device, request, errorEvent);
637 - streamSession.put(device.getDeviceId(), channelId, ssrcInfo.getSsrc(), ssrcInfo.getStreamId(), mediaServerItem.getId(), transaction); 637 + streamSession.put(device.getDeviceId(), channelId, callIdHeader.getCallId(), ssrcInfo.getStream(), ssrcInfo.getSsrc(), mediaServerItem.getId(), transaction);
  638 + streamSession.put(device.getDeviceId(), channelId, callIdHeader.getCallId(), ssrcInfo.getStream(), ssrcInfo.getSsrc(), mediaServerItem.getId(), transaction);
638 639
639 } catch ( SipException | ParseException | InvalidArgumentException e) { 640 } catch ( SipException | ParseException | InvalidArgumentException e) {
640 e.printStackTrace(); 641 e.printStackTrace();
@@ -645,17 +646,17 @@ public class SIPCommander implements ISIPCommander { @@ -645,17 +646,17 @@ public class SIPCommander implements ISIPCommander {
645 * 视频流停止, 不使用回调 646 * 视频流停止, 不使用回调
646 */ 647 */
647 @Override 648 @Override
648 - public void streamByeCmd(String deviceId, String channelId) {  
649 - streamByeCmd(deviceId, channelId, null); 649 + public void streamByeCmd(String deviceId, String channelId, String stream) {
  650 + streamByeCmd(deviceId, channelId, stream, null);
650 } 651 }
651 652
652 /** 653 /**
653 * 视频流停止 654 * 视频流停止
654 */ 655 */
655 @Override 656 @Override
656 - public void streamByeCmd(String deviceId, String channelId, SipSubscribe.Event okEvent) { 657 + public void streamByeCmd(String deviceId, String channelId, String stream, SipSubscribe.Event okEvent) {
657 try { 658 try {
658 - ClientTransaction transaction = streamSession.getTransaction(deviceId, channelId); 659 + ClientTransaction transaction = streamSession.getTransactionByStream(deviceId, channelId, stream);
659 if (transaction == null) { 660 if (transaction == null) {
660 logger.warn("[ {} -> {}]停止视频流的时候发现事务已丢失", deviceId, channelId); 661 logger.warn("[ {} -> {}]停止视频流的时候发现事务已丢失", deviceId, channelId);
661 SipSubscribe.EventResult<Object> eventResult = new SipSubscribe.EventResult<>(); 662 SipSubscribe.EventResult<Object> eventResult = new SipSubscribe.EventResult<>();
@@ -664,7 +665,7 @@ public class SIPCommander implements ISIPCommander { @@ -664,7 +665,7 @@ public class SIPCommander implements ISIPCommander {
664 } 665 }
665 return; 666 return;
666 } 667 }
667 - SIPDialog dialog = streamSession.getDialog(deviceId, channelId); 668 + SIPDialog dialog = streamSession.getDialogByStream(deviceId, channelId, stream);
668 if (dialog == null) { 669 if (dialog == null) {
669 logger.warn("[ {} -> {}]停止视频流的时候发现对话已丢失", deviceId, channelId); 670 logger.warn("[ {} -> {}]停止视频流的时候发现对话已丢失", deviceId, channelId);
670 return; 671 return;
@@ -708,11 +709,11 @@ public class SIPCommander implements ISIPCommander { @@ -708,11 +709,11 @@ public class SIPCommander implements ISIPCommander {
708 709
709 dialog.sendRequest(clientTransaction); 710 dialog.sendRequest(clientTransaction);
710 711
711 - SsrcTransaction ssrcTransaction = streamSession.getSsrcTransaction(deviceId, channelId); 712 + SsrcTransaction ssrcTransaction = streamSession.getSsrcTransaction(deviceId, channelId, callIdHeader.getCallId(), null);
712 if (ssrcTransaction != null) { 713 if (ssrcTransaction != null) {
713 MediaServerItem mediaServerItem = mediaServerService.getOne(ssrcTransaction.getMediaServerId()); 714 MediaServerItem mediaServerItem = mediaServerService.getOne(ssrcTransaction.getMediaServerId());
714 mediaServerService.releaseSsrc(mediaServerItem, ssrcTransaction.getSsrc()); 715 mediaServerService.releaseSsrc(mediaServerItem, ssrcTransaction.getSsrc());
715 - streamSession.remove(deviceId, channelId); 716 + streamSession.remove(deviceId, channelId, ssrcTransaction.getStream());
716 } 717 }
717 } catch (SipException | ParseException e) { 718 } catch (SipException | ParseException e) {
718 e.printStackTrace(); 719 e.printStackTrace();
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommanderFroPlatform.java
@@ -32,21 +32,9 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform { @@ -32,21 +32,9 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform {
32 32
33 private final Logger logger = LoggerFactory.getLogger(SIPCommanderFroPlatform.class); 33 private final Logger logger = LoggerFactory.getLogger(SIPCommanderFroPlatform.class);
34 34
35 - // @Autowired  
36 - // private SipConfig sipConfig;  
37 -  
38 - // @Autowired  
39 - // private SIPRequestHeaderProvider headerProvider;  
40 -  
41 @Autowired 35 @Autowired
42 private SIPRequestHeaderPlarformProvider headerProviderPlarformProvider; 36 private SIPRequestHeaderPlarformProvider headerProviderPlarformProvider;
43 37
44 - // @Autowired  
45 - // private VideoStreamSessionManager streamSession;  
46 -  
47 - // @Autowired  
48 - // private IVideoManagerStorager storager;  
49 -  
50 @Autowired 38 @Autowired
51 private IRedisCatchStorage redisCatchStorage; 39 private IRedisCatchStorage redisCatchStorage;
52 40
@@ -65,7 +53,7 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform { @@ -65,7 +53,7 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform {
65 53
66 @Override 54 @Override
67 public boolean register(ParentPlatform parentPlatform, SipSubscribe.Event errorEvent , SipSubscribe.Event okEvent) { 55 public boolean register(ParentPlatform parentPlatform, SipSubscribe.Event errorEvent , SipSubscribe.Event okEvent) {
68 - return register(parentPlatform, null, null, errorEvent, okEvent); 56 + return register(parentPlatform, null, null, errorEvent, okEvent, false);
69 } 57 }
70 58
71 @Override 59 @Override
@@ -77,15 +65,16 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform { @@ -77,15 +65,16 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform {
77 redisCatchStorage.updatePlatformCatchInfo(parentPlatformCatch); 65 redisCatchStorage.updatePlatformCatchInfo(parentPlatformCatch);
78 } 66 }
79 67
80 - return register(parentPlatform, null, null, errorEvent, okEvent); 68 + return register(parentPlatform, null, null, errorEvent, okEvent, false);
81 } 69 }
82 70
83 @Override 71 @Override
84 - public boolean register(ParentPlatform parentPlatform, @Nullable String callId, @Nullable WWWAuthenticateHeader www, SipSubscribe.Event errorEvent , SipSubscribe.Event okEvent) { 72 + public boolean register(ParentPlatform parentPlatform, @Nullable String callId, @Nullable WWWAuthenticateHeader www,
  73 + SipSubscribe.Event errorEvent , SipSubscribe.Event okEvent, boolean registerAgain) {
85 try { 74 try {
86 Request request = null; 75 Request request = null;
87 String tm = Long.toString(System.currentTimeMillis()); 76 String tm = Long.toString(System.currentTimeMillis());
88 - if (www == null ) { 77 + if (!registerAgain ) {
89 // //callid 78 // //callid
90 CallIdHeader callIdHeader = null; 79 CallIdHeader callIdHeader = null;
91 if(parentPlatform.getTransport().equals("TCP")) { 80 if(parentPlatform.getTransport().equals("TCP")) {
@@ -173,6 +162,7 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform { @@ -173,6 +162,7 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform {
173 } 162 }
174 163
175 private void transmitRequest(ParentPlatform parentPlatform, Request request, SipSubscribe.Event errorEvent , SipSubscribe.Event okEvent) throws SipException { 164 private void transmitRequest(ParentPlatform parentPlatform, Request request, SipSubscribe.Event errorEvent , SipSubscribe.Event okEvent) throws SipException {
  165 + logger.debug("\n发送消息:\n{}", request);
176 if("TCP".equals(parentPlatform.getTransport())) { 166 if("TCP".equals(parentPlatform.getTransport())) {
177 tcpSipProvider.sendRequest(request); 167 tcpSipProvider.sendRequest(request);
178 168
@@ -223,7 +213,9 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform { @@ -223,7 +213,9 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform {
223 catalogXml.append("<CivilCode>" + channel.getCivilCode() + "</CivilCode>\r\n"); 213 catalogXml.append("<CivilCode>" + channel.getCivilCode() + "</CivilCode>\r\n");
224 catalogXml.append("<Address>" + channel.getAddress() + "</Address>\r\n"); 214 catalogXml.append("<Address>" + channel.getAddress() + "</Address>\r\n");
225 catalogXml.append("<Parental>" + channel.getParental() + "</Parental>\r\n"); 215 catalogXml.append("<Parental>" + channel.getParental() + "</Parental>\r\n");
226 - catalogXml.append("<ParentID>" + channel.getParentId() + "</ParentID>\r\n"); 216 + if (channel.getParentId() != null) {
  217 + catalogXml.append("<ParentID>" + channel.getParentId() + "</ParentID>\r\n");
  218 + }
227 catalogXml.append("<Secrecy>" + channel.getSecrecy() + "</Secrecy>\r\n"); 219 catalogXml.append("<Secrecy>" + channel.getSecrecy() + "</Secrecy>\r\n");
228 catalogXml.append("<RegisterWay>" + channel.getRegisterWay() + "</RegisterWay>\r\n"); 220 catalogXml.append("<RegisterWay>" + channel.getRegisterWay() + "</RegisterWay>\r\n");
229 catalogXml.append("<Status>" + (channel.getStatus() == 0?"OFF":"ON") + "</Status>\r\n"); 221 catalogXml.append("<Status>" + (channel.getStatus() == 0?"OFF":"ON") + "</Status>\r\n");
@@ -358,7 +350,9 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform { @@ -358,7 +350,9 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform {
358 350
359 String tm = Long.toString(System.currentTimeMillis()); 351 String tm = Long.toString(System.currentTimeMillis());
360 352
361 - Request request = headerProviderPlarformProvider.createNotifyRequest(parentPlatform, deviceStatusXml.toString(), subscribeInfo.getToTag(), subscribeInfo.getFromTag(), callIdHeader); 353 + Request request = headerProviderPlarformProvider.createNotifyRequest(parentPlatform,
  354 + deviceStatusXml.toString(),callIdHeader,
  355 + "z9hG4bK-" + UUID.randomUUID().toString().replace("-", ""), subscribeInfo);
362 transmitRequest(parentPlatform, request); 356 transmitRequest(parentPlatform, request);
363 357
364 } catch (SipException | ParseException | InvalidArgumentException e) { 358 } catch (SipException | ParseException | InvalidArgumentException e) {
@@ -369,65 +363,82 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform { @@ -369,65 +363,82 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform {
369 } 363 }
370 364
371 @Override 365 @Override
372 - public boolean sendNotifyForCatalogAddOrUpdate(String type, ParentPlatform parentPlatform, List<DeviceChannel> deviceChannels, SubscribeInfo subscribeInfo) { 366 + public boolean sendNotifyForCatalogAddOrUpdate(String type, ParentPlatform parentPlatform, List<DeviceChannel> deviceChannels, SubscribeInfo subscribeInfo, Integer index) {
373 if (parentPlatform == null || deviceChannels == null || deviceChannels.size() == 0 || subscribeInfo == null) { 367 if (parentPlatform == null || deviceChannels == null || deviceChannels.size() == 0 || subscribeInfo == null) {
374 return false; 368 return false;
375 } 369 }
376 - for (DeviceChannel channel : deviceChannels) {  
377 - try {  
378 - StringBuffer catalogXml = new StringBuffer(600);  
379 - catalogXml.append("<?xml version=\"1.0\" encoding=\"GB2312\"?>\r\n");  
380 - catalogXml.append("<Notify>\r\n");  
381 - catalogXml.append("<CmdType>Catalog</CmdType>\r\n");  
382 - catalogXml.append("<SN>" + (int) ((Math.random() * 9 + 1) * 100000) + "</SN>\r\n");  
383 - catalogXml.append("<SumNum>" + deviceChannels.size() + "</SumNum>\r\n");  
384 - catalogXml.append("<DeviceList Num=\"1\">\r\n");  
385 - catalogXml.append("<Item>\r\n");  
386 - catalogXml.append("<DeviceID>" + channel.getChannelId() + "</DeviceID>\r\n");  
387 - catalogXml.append("<Event>" + type + "</Event>\r\n");  
388 - catalogXml.append("<Name>" + channel.getName() + "</Name>\r\n");  
389 - catalogXml.append("<Manufacturer>" + channel.getManufacture() + "</Manufacturer>\r\n");  
390 - catalogXml.append("<Model>" + channel.getModel() + "</Model>\r\n");  
391 - catalogXml.append("<Owner>" + channel.getOwner() + "</Owner>\r\n");  
392 - catalogXml.append("<CivilCode>" + channel.getCivilCode() + "</CivilCode>\r\n");  
393 - catalogXml.append("<Address>" + channel.getAddress() + "</Address>\r\n");  
394 - catalogXml.append("<Parental>" + channel.getParental() + "</Parental>\r\n");  
395 - catalogXml.append("<ParentID>" + channel.getParentId() + "</ParentID>\r\n");  
396 - catalogXml.append("<Secrecy>" + channel.getSecrecy() + "</Secrecy>\r\n");  
397 - catalogXml.append("<RegisterWay>" + channel.getRegisterWay() + "</RegisterWay>\r\n");  
398 - catalogXml.append("<Status>" + (channel.getStatus() == 0 ? "OFF" : "ON") + "</Status>\r\n");  
399 - catalogXml.append("<Longitude>" + channel.getLongitude() + "</Longitude>\r\n");  
400 - catalogXml.append("<Latitude>" + channel.getLatitude() + "</Latitude>\r\n");  
401 - catalogXml.append("<IPAddress>" + channel.getIpAddress() + "</IPAddress>\r\n");  
402 - catalogXml.append("<Port>" + channel.getPort() + "</Port>\r\n");  
403 - catalogXml.append("<Info>\r\n");  
404 - catalogXml.append("<PTZType>" + channel.getPTZType() + "</PTZType>\r\n");  
405 - catalogXml.append("</Info>\r\n");  
406 - catalogXml.append("</Item>\r\n");  
407 - catalogXml.append("</DeviceList>\r\n");  
408 - catalogXml.append("</Notify>\r\n"); 370 + if (index == null) {
  371 + index = 0;
  372 + }
409 373
410 - CallIdHeader callIdHeader = parentPlatform.getTransport().equals("TCP") ? tcpSipProvider.getNewCallId()  
411 - : udpSipProvider.getNewCallId();  
412 - callIdHeader.setCallId(subscribeInfo.getCallId());  
413 -  
414 - String tm = Long.toString(System.currentTimeMillis());  
415 -  
416 - Request request = headerProviderPlarformProvider.createNotifyRequest(parentPlatform, catalogXml.toString(), subscribeInfo.getToTag(), subscribeInfo.getFromTag(), callIdHeader);  
417 - transmitRequest(parentPlatform, request);  
418 - Thread.sleep(10);  
419 - } catch (SipException | ParseException | InvalidArgumentException e) {  
420 - e.printStackTrace();  
421 - return false;  
422 - } catch (InterruptedException e) {  
423 - e.printStackTrace(); 374 + try {
  375 + if (index > deviceChannels.size() - 1) {
  376 + return true;
424 } 377 }
  378 + Request request = getCatalogNotifyRequestForCatalogAddOrUpdate(parentPlatform, deviceChannels.get(index), deviceChannels.size(), type, subscribeInfo);
  379 + index += 1;
  380 + Integer finalIndex = index;
  381 + transmitRequest(parentPlatform, request, null, (eventResult -> {
  382 + sendNotifyForCatalogAddOrUpdate(type, parentPlatform, deviceChannels, subscribeInfo, finalIndex);
  383 + }));
  384 + } catch (SipException | ParseException | InvalidArgumentException e) {
  385 + e.printStackTrace();
  386 + return false;
425 } 387 }
426 return true; 388 return true;
427 } 389 }
428 390
  391 + private Request getCatalogNotifyRequestForCatalogAddOrUpdate(ParentPlatform parentPlatform, DeviceChannel channel, int size, String type,
  392 + SubscribeInfo subscribeInfo) throws ParseException, InvalidArgumentException,
  393 + PeerUnavailableException {
  394 + String catalogXmlContent = getCatalogXmlContentForCatalogAddOrUpdate(parentPlatform, channel, size, type, subscribeInfo);
  395 +
  396 + CallIdHeader callIdHeader = parentPlatform.getTransport().equals("TCP") ? tcpSipProvider.getNewCallId()
  397 + : udpSipProvider.getNewCallId();
  398 + callIdHeader.setCallId(subscribeInfo.getCallId());
  399 + Request request = headerProviderPlarformProvider.createNotifyRequest(parentPlatform, catalogXmlContent,
  400 + callIdHeader, "z9hG4bK-" + UUID.randomUUID().toString().replace("-", ""), subscribeInfo);
  401 + return request;
  402 + }
  403 +
  404 + private String getCatalogXmlContentForCatalogAddOrUpdate(ParentPlatform parentPlatform, DeviceChannel channel, int sumNum, String type, SubscribeInfo subscribeInfo) {
  405 + StringBuffer catalogXml = new StringBuffer(600);
  406 + if (parentPlatform.getServerGBId().equals(channel.getParentId())) {
  407 + channel.setParentId(parentPlatform.getDeviceGBId());
  408 + }
  409 + catalogXml.append("<?xml version=\"1.0\" encoding=\"GB2312\"?>\r\n");
  410 + catalogXml.append("<Notify>\r\n");
  411 + catalogXml.append("<CmdType>Catalog</CmdType>\r\n");
  412 + catalogXml.append("<SN>" + (int) ((Math.random() * 9 + 1) * 100000) + "</SN>\r\n");
  413 + catalogXml.append("<DeviceID>" + parentPlatform.getDeviceGBId() + "</DeviceID>\r\n");
  414 + catalogXml.append("<SumNum>1</SumNum>\r\n");
  415 + catalogXml.append("<DeviceList Num=\"1\">\r\n");
  416 + catalogXml.append("<Item>\r\n");
  417 + catalogXml.append("<DeviceID>" + channel.getChannelId() + "</DeviceID>\r\n");
  418 + catalogXml.append("<Name>" + channel.getName() + "</Name>\r\n");
  419 + catalogXml.append("<Manufacturer>" + channel.getManufacture() + "</Manufacturer>\r\n");
  420 + catalogXml.append("<Model>" + channel.getModel() + "</Model>\r\n");
  421 + catalogXml.append("<Owner>0</Owner>\r\n");
  422 + catalogXml.append("<CivilCode>CivilCode</CivilCode>\r\n");
  423 + catalogXml.append("<Address>" + channel.getAddress() + "</Address>\r\n");
  424 + catalogXml.append("<Parental>" + channel.getParental() + "</Parental>\r\n");
  425 + if (channel.getParentId() != null) {
  426 + catalogXml.append("<ParentID>" + channel.getParentId() + "</ParentID>\r\n");
  427 + }
  428 + catalogXml.append("<Secrecy>" + channel.getSecrecy() + "</Secrecy>\r\n");
  429 + catalogXml.append("<RegisterWay>" + channel.getRegisterWay() + "</RegisterWay>\r\n");
  430 + catalogXml.append("<Status>" + (channel.getStatus() == 0 ? "OFF" : "ON") + "</Status>\r\n");
  431 + if (!"presence".equals(subscribeInfo.getEventType())) {
  432 + catalogXml.append("<Event>" + type + "</Event>\r\n");
  433 + }
  434 + catalogXml.append("</Item>\r\n");
  435 + catalogXml.append("</DeviceList>\r\n");
  436 + catalogXml.append("</Notify>\r\n");
  437 + return catalogXml.toString();
  438 + }
  439 +
429 @Override 440 @Override
430 - public boolean sendNotifyForCatalogOther(String type, ParentPlatform parentPlatform, List<DeviceChannel> deviceChannels, SubscribeInfo subscribeInfo) { 441 + public boolean sendNotifyForCatalogOther(String type, ParentPlatform parentPlatform, List<DeviceChannel> deviceChannels, SubscribeInfo subscribeInfo, Integer index) {
431 if (parentPlatform == null 442 if (parentPlatform == null
432 || deviceChannels == null 443 || deviceChannels == null
433 || deviceChannels.size() == 0 444 || deviceChannels.size() == 0
@@ -435,39 +446,55 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform { @@ -435,39 +446,55 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform {
435 return false; 446 return false;
436 } 447 }
437 448
438 - for (DeviceChannel channel : deviceChannels) {  
439 - try {  
440 - StringBuffer catalogXml = new StringBuffer(600);  
441 - catalogXml.append("<?xml version=\"1.0\" encoding=\"GB2312\"?>\r\n");  
442 - catalogXml.append("<Notify>\r\n");  
443 - catalogXml.append("<CmdType>Catalog</CmdType>\r\n");  
444 - catalogXml.append("<SN>" + (int) ((Math.random() * 9 + 1) * 100000) + "</SN>\r\n");  
445 - catalogXml.append("<SumNum>" + deviceChannels.size() + "</SumNum>\r\n");  
446 - catalogXml.append("<DeviceList Num=\"1\">\r\n");  
447 - catalogXml.append("<Item>\r\n");  
448 - catalogXml.append("<DeviceID>" + channel.getChannelId() + "</DeviceID>\r\n");  
449 - catalogXml.append("<Event>" + type + "</Event>\r\n");  
450 - catalogXml.append("</Item>\r\n");  
451 - catalogXml.append("</DeviceList>\r\n");  
452 - catalogXml.append("</Notify>\r\n"); 449 + if (index == null) {
  450 + index = 0;
  451 + }
453 452
454 - CallIdHeader callIdHeader = parentPlatform.getTransport().equals("TCP") ? tcpSipProvider.getNewCallId() 453 + if (index > deviceChannels.size() - 1) {
  454 + return true;
  455 + }
  456 + try {
  457 + String catalogXml = getCatalogXmlContentForCatalogOther(deviceChannels.get(index), type, parentPlatform);
  458 + CallIdHeader callIdHeader = parentPlatform.getTransport().equals("TCP") ? tcpSipProvider.getNewCallId()
455 : udpSipProvider.getNewCallId(); 459 : udpSipProvider.getNewCallId();
456 - callIdHeader.setCallId(subscribeInfo.getCallId());  
457 -  
458 - String tm = Long.toString(System.currentTimeMillis());  
459 -  
460 - Request request = headerProviderPlarformProvider.createNotifyRequest(parentPlatform, catalogXml.toString(), subscribeInfo.getToTag(), subscribeInfo.getFromTag(), callIdHeader);  
461 - transmitRequest(parentPlatform, request);  
462 - Thread.sleep(200);  
463 - } catch (SipException | ParseException | InvalidArgumentException e) {  
464 - e.printStackTrace();  
465 - return false;  
466 - } catch (InterruptedException e) {  
467 - e.printStackTrace();  
468 - } 460 + Request request = headerProviderPlarformProvider.createNotifyRequest(parentPlatform, catalogXml,
  461 + callIdHeader,
  462 + "z9hG4bK-" + UUID.randomUUID().toString().replace("-", ""), subscribeInfo);
  463 + index += 1;
  464 + Integer finalIndex = index;
  465 + transmitRequest(parentPlatform, request, null, eventResult -> {
  466 + sendNotifyForCatalogOther(type, parentPlatform, deviceChannels, subscribeInfo, finalIndex);
  467 + });
  468 + } catch (SipException e) {
  469 + e.printStackTrace();
  470 + } catch (InvalidArgumentException e) {
  471 + e.printStackTrace();
  472 + } catch (ParseException e) {
  473 + e.printStackTrace();
469 } 474 }
  475 +
470 return true; 476 return true;
471 } 477 }
472 478
  479 + private String getCatalogXmlContentForCatalogOther(DeviceChannel channel, String type, ParentPlatform parentPlatform) {
  480 + if (parentPlatform.getServerGBId().equals(channel.getParentId())) {
  481 + channel.setParentId(parentPlatform.getDeviceGBId());
  482 + }
  483 + StringBuffer catalogXml = new StringBuffer(600);
  484 + catalogXml.append("<?xml version=\"1.0\" encoding=\"GB2312\"?>\r\n");
  485 + catalogXml.append("<Notify>\r\n");
  486 + catalogXml.append("<CmdType>Catalog</CmdType>\r\n");
  487 + catalogXml.append("<SN>" + (int) ((Math.random() * 9 + 1) * 100000) + "</SN>\r\n");
  488 + catalogXml.append("<DeviceID>" + parentPlatform.getDeviceGBId() + "</DeviceID>\r\n");
  489 + catalogXml.append("<SumNum>1</SumNum>\r\n");
  490 + catalogXml.append("<DeviceList Num=\"1\">\r\n");
  491 + catalogXml.append("<Item>\r\n");
  492 + catalogXml.append("<DeviceID>" + channel.getChannelId() + "</DeviceID>\r\n");
  493 + catalogXml.append("<Event>" + type + "</Event>\r\n");
  494 + catalogXml.append("</Item>\r\n");
  495 + catalogXml.append("</DeviceList>\r\n");
  496 + catalogXml.append("</Notify>\r\n");
  497 + return catalogXml.toString();
  498 + }
  499 +
473 } 500 }
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/SIPRequestProcessorParent.java
1 package com.genersoft.iot.vmp.gb28181.transmit.event.request; 1 package com.genersoft.iot.vmp.gb28181.transmit.event.request;
2 2
  3 +import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform;
3 import gov.nist.javax.sip.SipProviderImpl; 4 import gov.nist.javax.sip.SipProviderImpl;
4 import gov.nist.javax.sip.SipStackImpl; 5 import gov.nist.javax.sip.SipStackImpl;
5 import gov.nist.javax.sip.message.SIPRequest; 6 import gov.nist.javax.sip.message.SIPRequest;
@@ -160,13 +161,18 @@ public abstract class SIPRequestProcessorParent { @@ -160,13 +161,18 @@ public abstract class SIPRequestProcessorParent {
160 * @throws InvalidArgumentException 161 * @throws InvalidArgumentException
161 * @throws ParseException 162 * @throws ParseException
162 */ 163 */
163 - public void responseSdpAck(RequestEvent evt, String sdp) throws SipException, InvalidArgumentException, ParseException { 164 + public void responseSdpAck(RequestEvent evt, String sdp, ParentPlatform platform) throws SipException, InvalidArgumentException, ParseException {
164 Response response = getMessageFactory().createResponse(Response.OK, evt.getRequest()); 165 Response response = getMessageFactory().createResponse(Response.OK, evt.getRequest());
165 SipFactory sipFactory = SipFactory.getInstance(); 166 SipFactory sipFactory = SipFactory.getInstance();
166 ContentTypeHeader contentTypeHeader = sipFactory.createHeaderFactory().createContentTypeHeader("APPLICATION", "SDP"); 167 ContentTypeHeader contentTypeHeader = sipFactory.createHeaderFactory().createContentTypeHeader("APPLICATION", "SDP");
167 response.setContent(sdp, contentTypeHeader); 168 response.setContent(sdp, contentTypeHeader);
168 169
  170 + // 兼容国标中的使用编码@域名作为RequestURI的情况
169 SipURI sipURI = (SipURI)evt.getRequest().getRequestURI(); 171 SipURI sipURI = (SipURI)evt.getRequest().getRequestURI();
  172 + if (sipURI.getPort() == -1) {
  173 + sipURI = sipFactory.createAddressFactory().createSipURI(platform.getServerGBId(), platform.getServerIP()+":"+platform.getServerPort());
  174 + }
  175 + logger.debug("responseSdpAck SipURI: {}:{}", sipURI.getHost(), sipURI.getPort());
170 176
171 Address concatAddress = sipFactory.createAddressFactory().createAddress( 177 Address concatAddress = sipFactory.createAddressFactory().createAddress(
172 sipFactory.createAddressFactory().createSipURI(sipURI.getUser(), sipURI.getHost()+":"+sipURI.getPort() 178 sipFactory.createAddressFactory().createSipURI(sipURI.getUser(), sipURI.getHost()+":"+sipURI.getPort()
@@ -183,13 +189,18 @@ public abstract class SIPRequestProcessorParent { @@ -183,13 +189,18 @@ public abstract class SIPRequestProcessorParent {
183 * @throws InvalidArgumentException 189 * @throws InvalidArgumentException
184 * @throws ParseException 190 * @throws ParseException
185 */ 191 */
186 - public Response responseXmlAck(RequestEvent evt, String xml) throws SipException, InvalidArgumentException, ParseException { 192 + public Response responseXmlAck(RequestEvent evt, String xml, ParentPlatform platform) throws SipException, InvalidArgumentException, ParseException {
187 Response response = getMessageFactory().createResponse(Response.OK, evt.getRequest()); 193 Response response = getMessageFactory().createResponse(Response.OK, evt.getRequest());
188 SipFactory sipFactory = SipFactory.getInstance(); 194 SipFactory sipFactory = SipFactory.getInstance();
189 - ContentTypeHeader contentTypeHeader = sipFactory.createHeaderFactory().createContentTypeHeader("APPLICATION", "MANSCDP+xml"); 195 + ContentTypeHeader contentTypeHeader = sipFactory.createHeaderFactory().createContentTypeHeader("Application", "MANSCDP+xml");
190 response.setContent(xml, contentTypeHeader); 196 response.setContent(xml, contentTypeHeader);
191 197
  198 + // 兼容国标中的使用编码@域名作为RequestURI的情况
192 SipURI sipURI = (SipURI)evt.getRequest().getRequestURI(); 199 SipURI sipURI = (SipURI)evt.getRequest().getRequestURI();
  200 + if (sipURI.getPort() == -1) {
  201 + sipURI = sipFactory.createAddressFactory().createSipURI(platform.getServerGBId(), platform.getServerIP()+":"+platform.getServerPort());
  202 + }
  203 + logger.debug("responseXmlAck SipURI: {}:{}", sipURI.getHost(), sipURI.getPort());
193 204
194 Address concatAddress = sipFactory.createAddressFactory().createAddress( 205 Address concatAddress = sipFactory.createAddressFactory().createAddress(
195 sipFactory.createAddressFactory().createSipURI(sipURI.getUser(), sipURI.getHost()+":"+sipURI.getPort() 206 sipFactory.createAddressFactory().createSipURI(sipURI.getUser(), sipURI.getHost()+":"+sipURI.getPort()
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/AckRequestProcessor.java
@@ -72,10 +72,10 @@ public class AckRequestProcessor extends SIPRequestProcessorParent implements In @@ -72,10 +72,10 @@ public class AckRequestProcessor extends SIPRequestProcessorParent implements In
72 if (deviceId == null) { 72 if (deviceId == null) {
73 streamInfo = new StreamInfo(); 73 streamInfo = new StreamInfo();
74 streamInfo.setApp(sendRtpItem.getApp()); 74 streamInfo.setApp(sendRtpItem.getApp());
75 - streamInfo.setStreamId(sendRtpItem.getStreamId()); 75 + streamInfo.setStream(sendRtpItem.getStreamId());
76 }else { 76 }else {
77 streamInfo = redisCatchStorage.queryPlayByDevice(deviceId, channelId); 77 streamInfo = redisCatchStorage.queryPlayByDevice(deviceId, channelId);
78 - sendRtpItem.setStreamId(streamInfo.getStreamId()); 78 + sendRtpItem.setStreamId(streamInfo.getStream());
79 streamInfo.setApp("rtp"); 79 streamInfo.setApp("rtp");
80 } 80 }
81 81
@@ -85,7 +85,7 @@ public class AckRequestProcessor extends SIPRequestProcessorParent implements In @@ -85,7 +85,7 @@ public class AckRequestProcessor extends SIPRequestProcessorParent implements In
85 Map<String, Object> param = new HashMap<>(); 85 Map<String, Object> param = new HashMap<>();
86 param.put("vhost","__defaultVhost__"); 86 param.put("vhost","__defaultVhost__");
87 param.put("app",streamInfo.getApp()); 87 param.put("app",streamInfo.getApp());
88 - param.put("stream",streamInfo.getStreamId()); 88 + param.put("stream",streamInfo.getStream());
89 param.put("ssrc", sendRtpItem.getSsrc()); 89 param.put("ssrc", sendRtpItem.getSsrc());
90 param.put("dst_url",sendRtpItem.getIp()); 90 param.put("dst_url",sendRtpItem.getIp());
91 param.put("dst_port", sendRtpItem.getPort()); 91 param.put("dst_port", sendRtpItem.getPort());
@@ -98,21 +98,21 @@ public class AckRequestProcessor extends SIPRequestProcessorParent implements In @@ -98,21 +98,21 @@ public class AckRequestProcessor extends SIPRequestProcessorParent implements In
98 try { 98 try {
99 if (System.currentTimeMillis() - startTime < 30 * 1000) { 99 if (System.currentTimeMillis() - startTime < 30 * 1000) {
100 MediaServerItem mediaInfo = mediaServerService.getOne(sendRtpItem.getMediaServerId()); 100 MediaServerItem mediaInfo = mediaServerService.getOne(sendRtpItem.getMediaServerId());
101 - if (zlmrtpServerFactory.isStreamReady(mediaInfo, streamInfo.getApp(), streamInfo.getStreamId())) { 101 + if (zlmrtpServerFactory.isStreamReady(mediaInfo, streamInfo.getApp(), streamInfo.getStream())) {
102 rtpPushed = true; 102 rtpPushed = true;
103 logger.info("已获取设备推流[{}/{}],开始向上级推流[{}:{}]", 103 logger.info("已获取设备推流[{}/{}],开始向上级推流[{}:{}]",
104 - streamInfo.getApp() ,streamInfo.getStreamId(), sendRtpItem.getIp(), sendRtpItem.getPort()); 104 + streamInfo.getApp() ,streamInfo.getStream(), sendRtpItem.getIp(), sendRtpItem.getPort());
105 zlmrtpServerFactory.startSendRtpStream(mediaInfo, param); 105 zlmrtpServerFactory.startSendRtpStream(mediaInfo, param);
106 } else { 106 } else {
107 logger.info("等待设备推流[{}/{}].......", 107 logger.info("等待设备推流[{}/{}].......",
108 - streamInfo.getApp() ,streamInfo.getStreamId()); 108 + streamInfo.getApp() ,streamInfo.getStream());
109 Thread.sleep(1000); 109 Thread.sleep(1000);
110 continue; 110 continue;
111 } 111 }
112 } else { 112 } else {
113 rtpPushed = true; 113 rtpPushed = true;
114 logger.info("设备推流[{}/{}]超时,终止向上级推流", 114 logger.info("设备推流[{}/{}]超时,终止向上级推流",
115 - streamInfo.getApp() ,streamInfo.getStreamId()); 115 + streamInfo.getApp() ,streamInfo.getStream());
116 } 116 }
117 } catch (InterruptedException e) { 117 } catch (InterruptedException e) {
118 e.printStackTrace(); 118 e.printStackTrace();
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/ByeRequestProcessor.java
@@ -89,18 +89,19 @@ public class ByeRequestProcessor extends SIPRequestProcessorParent implements In @@ -89,18 +89,19 @@ public class ByeRequestProcessor extends SIPRequestProcessorParent implements In
89 redisCatchStorage.deleteSendRTPServer(platformGbId, channelId); 89 redisCatchStorage.deleteSendRTPServer(platformGbId, channelId);
90 if (zlmrtpServerFactory.totalReaderCount(mediaInfo, sendRtpItem.getApp(), streamId) == 0) { 90 if (zlmrtpServerFactory.totalReaderCount(mediaInfo, sendRtpItem.getApp(), streamId) == 0) {
91 logger.info(streamId + "无其它观看者,通知设备停止推流"); 91 logger.info(streamId + "无其它观看者,通知设备停止推流");
92 - cmder.streamByeCmd(sendRtpItem.getDeviceId(), channelId); 92 + cmder.streamByeCmd(sendRtpItem.getDeviceId(), channelId, streamId);
93 } 93 }
94 } 94 }
95 // 可能是设备主动停止 95 // 可能是设备主动停止
96 Device device = storager.queryVideoDeviceByChannelId(platformGbId); 96 Device device = storager.queryVideoDeviceByChannelId(platformGbId);
97 if (device != null) { 97 if (device != null) {
98 StreamInfo streamInfo = redisCatchStorage.queryPlayByDevice(device.getDeviceId(), channelId); 98 StreamInfo streamInfo = redisCatchStorage.queryPlayByDevice(device.getDeviceId(), channelId);
  99 +
99 if (streamInfo != null) { 100 if (streamInfo != null) {
100 redisCatchStorage.stopPlay(streamInfo); 101 redisCatchStorage.stopPlay(streamInfo);
101 } 102 }
102 storager.stopPlay(device.getDeviceId(), channelId); 103 storager.stopPlay(device.getDeviceId(), channelId);
103 - mediaServerService.closeRTPServer(device, channelId); 104 + mediaServerService.closeRTPServer(device, channelId, streamInfo.getStream());
104 } 105 }
105 } 106 }
106 } catch (SipException e) { 107 } catch (SipException e) {
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/InviteRequestProcessor.java
@@ -252,7 +252,7 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements @@ -252,7 +252,7 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements
252 content.append("f=\r\n"); 252 content.append("f=\r\n");
253 253
254 try { 254 try {
255 - responseSdpAck(evt, content.toString()); 255 + responseSdpAck(evt, content.toString(), platform);
256 } catch (SipException e) { 256 } catch (SipException e) {
257 e.printStackTrace(); 257 e.printStackTrace();
258 } catch (InvalidArgumentException e) { 258 } catch (InvalidArgumentException e) {
@@ -309,7 +309,7 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements @@ -309,7 +309,7 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements
309 content.append("f=\r\n"); 309 content.append("f=\r\n");
310 310
311 try { 311 try {
312 - responseSdpAck(evt, content.toString()); 312 + responseSdpAck(evt, content.toString(), platform);
313 } catch (SipException e) { 313 } catch (SipException e) {
314 e.printStackTrace(); 314 e.printStackTrace();
315 } catch (InvalidArgumentException e) { 315 } catch (InvalidArgumentException e) {
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/SubscribeRequestProcessor.java
@@ -4,6 +4,7 @@ import com.genersoft.iot.vmp.common.VideoManagerConstants; @@ -4,6 +4,7 @@ import com.genersoft.iot.vmp.common.VideoManagerConstants;
4 import com.genersoft.iot.vmp.conf.DynamicTask; 4 import com.genersoft.iot.vmp.conf.DynamicTask;
5 import com.genersoft.iot.vmp.conf.UserSetup; 5 import com.genersoft.iot.vmp.conf.UserSetup;
6 import com.genersoft.iot.vmp.gb28181.bean.CmdType; 6 import com.genersoft.iot.vmp.gb28181.bean.CmdType;
  7 +import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform;
7 import com.genersoft.iot.vmp.gb28181.bean.SubscribeInfo; 8 import com.genersoft.iot.vmp.gb28181.bean.SubscribeInfo;
8 import com.genersoft.iot.vmp.gb28181.task.GPSSubscribeTask; 9 import com.genersoft.iot.vmp.gb28181.task.GPSSubscribeTask;
9 import com.genersoft.iot.vmp.gb28181.transmit.SIPProcessorObserver; 10 import com.genersoft.iot.vmp.gb28181.transmit.SIPProcessorObserver;
@@ -105,9 +106,6 @@ public class SubscribeRequestProcessor extends SIPRequestProcessorParent impleme @@ -105,9 +106,6 @@ public class SubscribeRequestProcessor extends SIPRequestProcessorParent impleme
105 logger.info("processRequest serverTransactionId is null."); 106 logger.info("processRequest serverTransactionId is null.");
106 } 107 }
107 } 108 }
108 -  
109 -  
110 -  
111 } catch (ParseException e) { 109 } catch (ParseException e) {
112 e.printStackTrace(); 110 e.printStackTrace();
113 } catch (SipException e) { 111 } catch (SipException e) {
@@ -155,7 +153,8 @@ public class SubscribeRequestProcessor extends SIPRequestProcessorParent impleme @@ -155,7 +153,8 @@ public class SubscribeRequestProcessor extends SIPRequestProcessorParent impleme
155 153
156 154
157 try { 155 try {
158 - Response response = responseXmlAck(evt, resultXml.toString()); 156 + ParentPlatform parentPlatform = storager.queryParentPlatByServerGBId(platformId);
  157 + Response response = responseXmlAck(evt, resultXml.toString(), parentPlatform);
159 ToHeader toHeader = (ToHeader)response.getHeader(ToHeader.NAME); 158 ToHeader toHeader = (ToHeader)response.getHeader(ToHeader.NAME);
160 subscribeInfo.setToTag(toHeader.getTag()); 159 subscribeInfo.setToTag(toHeader.getTag());
161 redisCatchStorage.updateSubscribe(key, subscribeInfo); 160 redisCatchStorage.updateSubscribe(key, subscribeInfo);
@@ -196,7 +195,8 @@ public class SubscribeRequestProcessor extends SIPRequestProcessorParent impleme @@ -196,7 +195,8 @@ public class SubscribeRequestProcessor extends SIPRequestProcessorParent impleme
196 } 195 }
197 196
198 try { 197 try {
199 - Response response = responseXmlAck(evt, resultXml.toString()); 198 + ParentPlatform parentPlatform = storager.queryParentPlatByServerGBId(platformId);
  199 + Response response = responseXmlAck(evt, resultXml.toString(), parentPlatform);
200 ToHeader toHeader = (ToHeader)response.getHeader(ToHeader.NAME); 200 ToHeader toHeader = (ToHeader)response.getHeader(ToHeader.NAME);
201 subscribeInfo.setToTag(toHeader.getTag()); 201 subscribeInfo.setToTag(toHeader.getTag());
202 redisCatchStorage.updateSubscribe(key, subscribeInfo); 202 redisCatchStorage.updateSubscribe(key, subscribeInfo);
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/AlarmNotifyMessageHandler.java
@@ -22,7 +22,7 @@ import org.springframework.util.StringUtils; @@ -22,7 +22,7 @@ import org.springframework.util.StringUtils;
22 22
23 import javax.sip.RequestEvent; 23 import javax.sip.RequestEvent;
24 24
25 -import static com.genersoft.iot.vmp.gb28181.utils.XmlUtil.getText; 25 +import static com.genersoft.iot.vmp.gb28181.utils.XmlUtil.*;
26 26
27 @Component 27 @Component
28 public class AlarmNotifyMessageHandler extends SIPRequestProcessorParent implements InitializingBean, IMessageHandler { 28 public class AlarmNotifyMessageHandler extends SIPRequestProcessorParent implements InitializingBean, IMessageHandler {
@@ -105,6 +105,11 @@ public class AlarmNotifyMessageHandler extends SIPRequestProcessorParent impleme @@ -105,6 +105,11 @@ public class AlarmNotifyMessageHandler extends SIPRequestProcessorParent impleme
105 storager.insertMobilePosition(mobilePosition); 105 storager.insertMobilePosition(mobilePosition);
106 } 106 }
107 } 107 }
  108 + if (!StringUtils.isEmpty(deviceAlarm.getDeviceId())) {
  109 + if (deviceAlarm.getAlarmMethod().equals("5")) {
  110 + deviceAlarm.setAlarmType(getText(rootElement.element("Info"), "AlarmType"));
  111 + }
  112 + }
108 logger.debug("存储报警信息、报警分类"); 113 logger.debug("存储报警信息、报警分类");
109 // 存储报警信息、报警分类 114 // 存储报警信息、报警分类
110 deviceAlarmService.add(deviceAlarm); 115 deviceAlarmService.add(deviceAlarm);
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/CatalogNotifyMessageHandler.java
@@ -72,6 +72,9 @@ public class CatalogNotifyMessageHandler extends SIPRequestProcessorParent imple @@ -72,6 +72,9 @@ public class CatalogNotifyMessageHandler extends SIPRequestProcessorParent imple
72 List<PlatformCatalog> catalogs = storager.queryCatalogInPlatform(parentPlatform.getServerGBId()); 72 List<PlatformCatalog> catalogs = storager.queryCatalogInPlatform(parentPlatform.getServerGBId());
73 if (catalogs.size() > 0) { 73 if (catalogs.size() > 0) {
74 for (PlatformCatalog catalog : catalogs) { 74 for (PlatformCatalog catalog : catalogs) {
  75 + if (catalog.getParentId().equals(catalog.getPlatformId())) {
  76 + catalog.setParentId(parentPlatform.getDeviceGBId());
  77 + }
75 DeviceChannel deviceChannel = new DeviceChannel(); 78 DeviceChannel deviceChannel = new DeviceChannel();
76 deviceChannel.setChannelId(catalog.getId()); 79 deviceChannel.setChannelId(catalog.getId());
77 deviceChannel.setName(catalog.getName()); 80 deviceChannel.setName(catalog.getName());
@@ -83,30 +86,35 @@ public class CatalogNotifyMessageHandler extends SIPRequestProcessorParent imple @@ -83,30 +86,35 @@ public class CatalogNotifyMessageHandler extends SIPRequestProcessorParent imple
83 deviceChannel.setParental(1); 86 deviceChannel.setParental(1);
84 deviceChannel.setParentId(catalog.getParentId()); 87 deviceChannel.setParentId(catalog.getParentId());
85 deviceChannel.setRegisterWay(1); 88 deviceChannel.setRegisterWay(1);
86 - deviceChannel.setCivilCode(config.getDomain()); 89 + deviceChannel.setCivilCode(config.getDomain().substring(0, config.getDomain().length() - 2));
87 deviceChannel.setModel("live"); 90 deviceChannel.setModel("live");
88 deviceChannel.setOwner("wvp-pro"); 91 deviceChannel.setOwner("wvp-pro");
89 deviceChannel.setSecrecy("0"); 92 deviceChannel.setSecrecy("0");
90 cmderFroPlatform.catalogQuery(deviceChannel, parentPlatform, sn, fromHeader.getTag(), size); 93 cmderFroPlatform.catalogQuery(deviceChannel, parentPlatform, sn, fromHeader.getTag(), size);
91 // 防止发送过快 94 // 防止发送过快
92 - Thread.sleep(50); 95 + Thread.sleep(100);
93 } 96 }
94 } 97 }
95 // 回复级联的通道 98 // 回复级联的通道
96 if (channelReduces.size() > 0) { 99 if (channelReduces.size() > 0) {
97 for (ChannelReduce channelReduce : channelReduces) { 100 for (ChannelReduce channelReduce : channelReduces) {
  101 + if (channelReduce.getCatalogId().equals(parentPlatform.getServerGBId())) {
  102 + channelReduce.setCatalogId(parentPlatform.getDeviceGBId());
  103 + }
98 DeviceChannel deviceChannel = storager.queryChannel(channelReduce.getDeviceId(), channelReduce.getChannelId()); 104 DeviceChannel deviceChannel = storager.queryChannel(channelReduce.getDeviceId(), channelReduce.getChannelId());
99 deviceChannel.setParental(0); 105 deviceChannel.setParental(0);
100 deviceChannel.setParentId(channelReduce.getCatalogId()); 106 deviceChannel.setParentId(channelReduce.getCatalogId());
101 -  
102 cmderFroPlatform.catalogQuery(deviceChannel, parentPlatform, sn, fromHeader.getTag(), size); 107 cmderFroPlatform.catalogQuery(deviceChannel, parentPlatform, sn, fromHeader.getTag(), size);
103 // 防止发送过快 108 // 防止发送过快
104 - Thread.sleep(50); 109 + Thread.sleep(100);
105 } 110 }
106 } 111 }
107 // 回复直播的通道 112 // 回复直播的通道
108 if (gbStreams.size() > 0) { 113 if (gbStreams.size() > 0) {
109 for (GbStream gbStream : gbStreams) { 114 for (GbStream gbStream : gbStreams) {
  115 + if (gbStream.getCatalogId().equals(parentPlatform.getServerGBId())) {
  116 + gbStream.setCatalogId(null);
  117 + }
110 DeviceChannel deviceChannel = new DeviceChannel(); 118 DeviceChannel deviceChannel = new DeviceChannel();
111 deviceChannel.setChannelId(gbStream.getGbId()); 119 deviceChannel.setChannelId(gbStream.getGbId());
112 deviceChannel.setName(gbStream.getName()); 120 deviceChannel.setName(gbStream.getName());
@@ -117,14 +125,14 @@ public class CatalogNotifyMessageHandler extends SIPRequestProcessorParent imple @@ -117,14 +125,14 @@ public class CatalogNotifyMessageHandler extends SIPRequestProcessorParent imple
117 deviceChannel.setStatus(gbStream.isStatus()?1:0); 125 deviceChannel.setStatus(gbStream.isStatus()?1:0);
118 deviceChannel.setParentId(gbStream.getCatalogId()); 126 deviceChannel.setParentId(gbStream.getCatalogId());
119 deviceChannel.setRegisterWay(1); 127 deviceChannel.setRegisterWay(1);
120 - deviceChannel.setCivilCode(config.getDomain()); 128 + deviceChannel.setCivilCode(config.getDomain().substring(0, config.getDomain().length() - 2));
121 deviceChannel.setModel("live"); 129 deviceChannel.setModel("live");
122 deviceChannel.setOwner("wvp-pro"); 130 deviceChannel.setOwner("wvp-pro");
123 deviceChannel.setParental(0); 131 deviceChannel.setParental(0);
124 deviceChannel.setSecrecy("0"); 132 deviceChannel.setSecrecy("0");
125 cmderFroPlatform.catalogQuery(deviceChannel, parentPlatform, sn, fromHeader.getTag(), size); 133 cmderFroPlatform.catalogQuery(deviceChannel, parentPlatform, sn, fromHeader.getTag(), size);
126 // 防止发送过快 134 // 防止发送过快
127 - Thread.sleep(50); 135 + Thread.sleep(100);
128 } 136 }
129 } 137 }
130 if (size == 0) { 138 if (size == 0) {
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/KeepaliveNotifyMessageHandler.java
@@ -68,6 +68,7 @@ public class KeepaliveNotifyMessageHandler extends SIPRequestProcessorParent imp @@ -68,6 +68,7 @@ public class KeepaliveNotifyMessageHandler extends SIPRequestProcessorParent imp
68 } 68 }
69 if (device.getPort() != rPort) { 69 if (device.getPort() != rPort) {
70 device.setPort(rPort); 70 device.setPort(rPort);
  71 + device.setHostAddress(received.concat(":").concat(String.valueOf(rPort)));
71 videoManagerStorager.updateDevice(device); 72 videoManagerStorager.updateDevice(device);
72 redisCatchStorage.updateDevice(device); 73 redisCatchStorage.updateDevice(device);
73 } 74 }
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/MediaStatusNotifyMessageHandler.java
@@ -62,7 +62,7 @@ public class MediaStatusNotifyMessageHandler extends SIPRequestProcessorParent i @@ -62,7 +62,7 @@ public class MediaStatusNotifyMessageHandler extends SIPRequestProcessorParent i
62 StreamInfo streamInfo = redisCatchStorage.queryPlaybackByDevice(device.getDeviceId(), "*"); 62 StreamInfo streamInfo = redisCatchStorage.queryPlaybackByDevice(device.getDeviceId(), "*");
63 if (streamInfo != null) { 63 if (streamInfo != null) {
64 redisCatchStorage.stopPlayback(streamInfo); 64 redisCatchStorage.stopPlayback(streamInfo);
65 - cmder.streamByeCmd(streamInfo.getDeviceID(), streamInfo.getChannelId()); 65 + cmder.streamByeCmd(streamInfo.getDeviceID(), streamInfo.getChannelId(), streamInfo.getStream());
66 } 66 }
67 } 67 }
68 } 68 }
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/query/cmd/CatalogQueryMessageHandler.java
@@ -75,6 +75,9 @@ public class CatalogQueryMessageHandler extends SIPRequestProcessorParent implem @@ -75,6 +75,9 @@ public class CatalogQueryMessageHandler extends SIPRequestProcessorParent implem
75 int size = catalogs.size() + channelReduces.size() + gbStreams.size(); 75 int size = catalogs.size() + channelReduces.size() + gbStreams.size();
76 if (catalogs.size() > 0) { 76 if (catalogs.size() > 0) {
77 for (PlatformCatalog catalog : catalogs) { 77 for (PlatformCatalog catalog : catalogs) {
  78 + if (catalog.getParentId().equals(parentPlatform.getServerGBId())) {
  79 + catalog.setParentId(parentPlatform.getDeviceGBId());
  80 + }
78 DeviceChannel deviceChannel = new DeviceChannel(); 81 DeviceChannel deviceChannel = new DeviceChannel();
79 deviceChannel.setChannelId(catalog.getId()); 82 deviceChannel.setChannelId(catalog.getId());
80 deviceChannel.setName(catalog.getName()); 83 deviceChannel.setName(catalog.getName());
@@ -86,30 +89,35 @@ public class CatalogQueryMessageHandler extends SIPRequestProcessorParent implem @@ -86,30 +89,35 @@ public class CatalogQueryMessageHandler extends SIPRequestProcessorParent implem
86 deviceChannel.setParental(1); 89 deviceChannel.setParental(1);
87 deviceChannel.setParentId(catalog.getParentId()); 90 deviceChannel.setParentId(catalog.getParentId());
88 deviceChannel.setRegisterWay(1); 91 deviceChannel.setRegisterWay(1);
89 - deviceChannel.setCivilCode(config.getDomain()); 92 + deviceChannel.setCivilCode(config.getDomain().substring(0, config.getDomain().length() - 2));
90 deviceChannel.setModel("live"); 93 deviceChannel.setModel("live");
91 deviceChannel.setOwner("wvp-pro"); 94 deviceChannel.setOwner("wvp-pro");
92 deviceChannel.setSecrecy("0"); 95 deviceChannel.setSecrecy("0");
93 cmderFroPlatform.catalogQuery(deviceChannel, parentPlatform, sn, fromHeader.getTag(), size); 96 cmderFroPlatform.catalogQuery(deviceChannel, parentPlatform, sn, fromHeader.getTag(), size);
94 // 防止发送过快 97 // 防止发送过快
95 - Thread.sleep(50); 98 + Thread.sleep(100);
96 } 99 }
97 } 100 }
98 // 回复级联的通道 101 // 回复级联的通道
99 if (channelReduces.size() > 0) { 102 if (channelReduces.size() > 0) {
100 for (ChannelReduce channelReduce : channelReduces) { 103 for (ChannelReduce channelReduce : channelReduces) {
  104 + if (channelReduce.getCatalogId().equals(parentPlatform.getServerGBId())) {
  105 + channelReduce.setCatalogId(parentPlatform.getDeviceGBId());
  106 + }
101 DeviceChannel deviceChannel = storager.queryChannel(channelReduce.getDeviceId(), channelReduce.getChannelId()); 107 DeviceChannel deviceChannel = storager.queryChannel(channelReduce.getDeviceId(), channelReduce.getChannelId());
102 - // TODO 目前暂时认为这里只用通道没有目录  
103 deviceChannel.setParental(0); 108 deviceChannel.setParental(0);
104 deviceChannel.setParentId(channelReduce.getCatalogId()); 109 deviceChannel.setParentId(channelReduce.getCatalogId());
105 cmderFroPlatform.catalogQuery(deviceChannel, parentPlatform, sn, fromHeader.getTag(), size); 110 cmderFroPlatform.catalogQuery(deviceChannel, parentPlatform, sn, fromHeader.getTag(), size);
106 // 防止发送过快 111 // 防止发送过快
107 - Thread.sleep(50); 112 + Thread.sleep(100);
108 } 113 }
109 } 114 }
110 // 回复直播的通道 115 // 回复直播的通道
111 if (gbStreams.size() > 0) { 116 if (gbStreams.size() > 0) {
112 for (GbStream gbStream : gbStreams) { 117 for (GbStream gbStream : gbStreams) {
  118 + if (gbStream.getCatalogId().equals(parentPlatform.getServerGBId())) {
  119 + gbStream.setCatalogId(parentPlatform.getDeviceGBId());
  120 + }
113 DeviceChannel deviceChannel = new DeviceChannel(); 121 DeviceChannel deviceChannel = new DeviceChannel();
114 deviceChannel.setChannelId(gbStream.getGbId()); 122 deviceChannel.setChannelId(gbStream.getGbId());
115 deviceChannel.setName(gbStream.getName()); 123 deviceChannel.setName(gbStream.getName());
@@ -120,7 +128,7 @@ public class CatalogQueryMessageHandler extends SIPRequestProcessorParent implem @@ -120,7 +128,7 @@ public class CatalogQueryMessageHandler extends SIPRequestProcessorParent implem
120 deviceChannel.setStatus(gbStream.isStatus()?1:0); 128 deviceChannel.setStatus(gbStream.isStatus()?1:0);
121 deviceChannel.setParentId(gbStream.getCatalogId()); 129 deviceChannel.setParentId(gbStream.getCatalogId());
122 deviceChannel.setRegisterWay(1); 130 deviceChannel.setRegisterWay(1);
123 - deviceChannel.setCivilCode(config.getDomain()); 131 + deviceChannel.setCivilCode(config.getDomain().substring(0, config.getDomain().length() - 2));
124 deviceChannel.setModel("live"); 132 deviceChannel.setModel("live");
125 deviceChannel.setOwner("wvp-pro"); 133 deviceChannel.setOwner("wvp-pro");
126 deviceChannel.setParental(0); 134 deviceChannel.setParental(0);
@@ -128,7 +136,7 @@ public class CatalogQueryMessageHandler extends SIPRequestProcessorParent implem @@ -128,7 +136,7 @@ public class CatalogQueryMessageHandler extends SIPRequestProcessorParent implem
128 136
129 cmderFroPlatform.catalogQuery(deviceChannel, parentPlatform, sn, fromHeader.getTag(), size); 137 cmderFroPlatform.catalogQuery(deviceChannel, parentPlatform, sn, fromHeader.getTag(), size);
130 // 防止发送过快 138 // 防止发送过快
131 - Thread.sleep(50); 139 + Thread.sleep(100);
132 } 140 }
133 } 141 }
134 if (size == 0) { 142 if (size == 0) {
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/response/impl/RegisterResponseProcessor.java
@@ -78,7 +78,7 @@ public class RegisterResponseProcessor extends SIPResponseProcessorAbstract { @@ -78,7 +78,7 @@ public class RegisterResponseProcessor extends SIPResponseProcessorAbstract {
78 78
79 if (response.getStatusCode() == 401) { 79 if (response.getStatusCode() == 401) {
80 WWWAuthenticateHeader www = (WWWAuthenticateHeader)response.getHeader(WWWAuthenticateHeader.NAME); 80 WWWAuthenticateHeader www = (WWWAuthenticateHeader)response.getHeader(WWWAuthenticateHeader.NAME);
81 - sipCommanderForPlatform.register(parentPlatform, callId, www, null, null); 81 + sipCommanderForPlatform.register(parentPlatform, callId, www, null, null, true);
82 }else if (response.getStatusCode() == 200){ 82 }else if (response.getStatusCode() == 200){
83 // 注册/注销成功 83 // 注册/注销成功
84 logger.info(String.format("%s %s成功", platformGBId, action)); 84 logger.info(String.format("%s %s成功", platformGBId, action));
src/main/java/com/genersoft/iot/vmp/gb28181/utils/XmlUtil.java
@@ -191,7 +191,7 @@ public class XmlUtil { @@ -191,7 +191,7 @@ public class XmlUtil {
191 String channelId = channdelIdElement != null ? channdelIdElement.getTextTrim().toString() : ""; 191 String channelId = channdelIdElement != null ? channdelIdElement.getTextTrim().toString() : "";
192 deviceChannel.setChannelId(channelId); 192 deviceChannel.setChannelId(channelId);
193 // ONLINE OFFLINE HIKVISION DS-7716N-E4 NVR的兼容性处理 193 // ONLINE OFFLINE HIKVISION DS-7716N-E4 NVR的兼容性处理
194 - if (status.equals("ON") || status.equals("On") || status.equals("ONLINE")) { 194 + if (status.equals("ON") || status.equals("On") || status.equals("ONLINE") || status.equals("OK")) {
195 deviceChannel.setStatus(1); 195 deviceChannel.setStatus(1);
196 } 196 }
197 if (status.equals("OFF") || status.equals("Off") || status.equals("OFFLINE")) { 197 if (status.equals("OFF") || status.equals("Off") || status.equals("OFFLINE")) {
@@ -255,9 +255,14 @@ public class XmlUtil { @@ -255,9 +255,14 @@ public class XmlUtil {
255 } else { 255 } else {
256 deviceChannel.setLatitude(0.00); 256 deviceChannel.setLatitude(0.00);
257 } 257 }
258 - if (XmlUtil.getText(itemDevice, "PTZType") == null  
259 - || XmlUtil.getText(itemDevice, "PTZType") == "") {  
260 - deviceChannel.setPTZType(0); 258 + if (XmlUtil.getText(itemDevice, "PTZType") == null || "".equals(XmlUtil.getText(itemDevice, "PTZType"))) {
  259 + //兼容INFO中的信息
  260 + Element info = itemDevice.element("Info");
  261 + if(XmlUtil.getText(info, "PTZType") == null || "".equals(XmlUtil.getText(info, "PTZType"))){
  262 + deviceChannel.setPTZType(0);
  263 + }else{
  264 + deviceChannel.setPTZType(Integer.parseInt(XmlUtil.getText(info, "PTZType")));
  265 + }
261 } else { 266 } else {
262 deviceChannel.setPTZType(Integer.parseInt(XmlUtil.getText(itemDevice, "PTZType"))); 267 deviceChannel.setPTZType(Integer.parseInt(XmlUtil.getText(itemDevice, "PTZType")));
263 } 268 }
src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java
@@ -361,6 +361,9 @@ public class ZLMHttpHookListener { @@ -361,6 +361,9 @@ public class ZLMHttpHookListener {
361 if (mediaServerItem != null){ 361 if (mediaServerItem != null){
362 if (regist) { 362 if (regist) {
363 StreamPushItem streamPushItem = null; 363 StreamPushItem streamPushItem = null;
  364 + StreamInfo streamInfoByAppAndStream = mediaService.getStreamInfoByAppAndStream(mediaServerItem, app, streamId, tracks);
  365 + item.setStreamInfo(streamInfoByAppAndStream);
  366 +
364 redisCatchStorage.addStream(mediaServerItem, type, app, streamId, item); 367 redisCatchStorage.addStream(mediaServerItem, type, app, streamId, item);
365 if (item.getOriginType() == OriginType.RTSP_PUSH.ordinal() 368 if (item.getOriginType() == OriginType.RTSP_PUSH.ordinal()
366 || item.getOriginType() == OriginType.RTMP_PUSH.ordinal() 369 || item.getOriginType() == OriginType.RTMP_PUSH.ordinal()
@@ -378,7 +381,7 @@ public class ZLMHttpHookListener { @@ -378,7 +381,7 @@ public class ZLMHttpHookListener {
378 } 381 }
379 } 382 }
380 if (gbStreams.size() > 0) { 383 if (gbStreams.size() > 0) {
381 - eventPublisher.catalogEventPublishForStream(null, gbStreams.toArray(new GbStream[0]), CatalogEvent.ON); 384 + eventPublisher.catalogEventPublishForStream(null, gbStreams, CatalogEvent.ON);
382 } 385 }
383 386
384 }else { 387 }else {
@@ -439,14 +442,16 @@ public class ZLMHttpHookListener { @@ -439,14 +442,16 @@ public class ZLMHttpHookListener {
439 if (redisCatchStorage.isChannelSendingRTP(streamInfoForPlayCatch.getChannelId())) { 442 if (redisCatchStorage.isChannelSendingRTP(streamInfoForPlayCatch.getChannelId())) {
440 ret.put("close", false); 443 ret.put("close", false);
441 } else { 444 } else {
442 - cmder.streamByeCmd(streamInfoForPlayCatch.getDeviceID(), streamInfoForPlayCatch.getChannelId()); 445 + cmder.streamByeCmd(streamInfoForPlayCatch.getDeviceID(), streamInfoForPlayCatch.getChannelId(),
  446 + streamInfoForPlayCatch.getStream());
443 redisCatchStorage.stopPlay(streamInfoForPlayCatch); 447 redisCatchStorage.stopPlay(streamInfoForPlayCatch);
444 storager.stopPlay(streamInfoForPlayCatch.getDeviceID(), streamInfoForPlayCatch.getChannelId()); 448 storager.stopPlay(streamInfoForPlayCatch.getDeviceID(), streamInfoForPlayCatch.getChannelId());
445 } 449 }
446 }else{ 450 }else{
447 StreamInfo streamInfoForPlayBackCatch = redisCatchStorage.queryPlaybackByStreamId(streamId); 451 StreamInfo streamInfoForPlayBackCatch = redisCatchStorage.queryPlaybackByStreamId(streamId);
448 if (streamInfoForPlayBackCatch != null) { 452 if (streamInfoForPlayBackCatch != null) {
449 - cmder.streamByeCmd(streamInfoForPlayBackCatch.getDeviceID(), streamInfoForPlayBackCatch.getChannelId()); 453 + cmder.streamByeCmd(streamInfoForPlayBackCatch.getDeviceID(),
  454 + streamInfoForPlayBackCatch.getChannelId(), streamInfoForPlayBackCatch.getStream());
450 redisCatchStorage.stopPlayback(streamInfoForPlayBackCatch); 455 redisCatchStorage.stopPlayback(streamInfoForPlayBackCatch);
451 }else { 456 }else {
452 StreamInfo streamInfoForDownload = redisCatchStorage.queryDownloadByStreamId(streamId); 457 StreamInfo streamInfoForDownload = redisCatchStorage.queryDownloadByStreamId(streamId);
src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookSubscribe.java
@@ -91,6 +91,7 @@ public class ZLMHttpHookSubscribe { @@ -91,6 +91,7 @@ public class ZLMHttpHookSubscribe {
91 } 91 }
92 } 92 }
93 if (null != result && result){ 93 if (null != result && result){
  94 + // TODO 报错未处理
94 iterator.remove(); 95 iterator.remove();
95 } 96 }
96 } 97 }
src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaListManager.java
@@ -122,7 +122,6 @@ public class ZLMMediaListManager { @@ -122,7 +122,6 @@ public class ZLMMediaListManager {
122 transform.setName(thirdPartyGB.getName()); 122 transform.setName(thirdPartyGB.getName());
123 } 123 }
124 } 124 }
125 - storager.updateMedia(transform);  
126 if (!StringUtils.isEmpty(transform.getGbId())) { 125 if (!StringUtils.isEmpty(transform.getGbId())) {
127 // 如果这个国标ID已经给了其他推流且流已离线,则移除其他推流 126 // 如果这个国标ID已经给了其他推流且流已离线,则移除其他推流
128 List<GbStream> gbStreams = gbStreamMapper.selectByGBId(transform.getGbId()); 127 List<GbStream> gbStreams = gbStreamMapper.selectByGBId(transform.getGbId());
@@ -135,13 +134,16 @@ public class ZLMMediaListManager { @@ -135,13 +134,16 @@ public class ZLMMediaListManager {
135 } 134 }
136 } 135 }
137 } 136 }
138 - if (gbStreamMapper.selectOne(transform.getApp(), transform.getStream()) != null) { 137 + StreamProxyItem streamProxyItem = gbStreamMapper.selectOne(transform.getApp(), transform.getStream());
  138 + if (streamProxyItem != null) {
  139 + transform.setGbStreamId(streamProxyItem.getGbStreamId());
139 gbStreamMapper.update(transform); 140 gbStreamMapper.update(transform);
140 }else { 141 }else {
141 transform.setCreateStamp(System.currentTimeMillis()); 142 transform.setCreateStamp(System.currentTimeMillis());
142 gbStreamMapper.add(transform); 143 gbStreamMapper.add(transform);
143 } 144 }
144 } 145 }
  146 + storager.updateMedia(transform);
145 return transform; 147 return transform;
146 } 148 }
147 149
src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRESTfulUtils.java
@@ -4,6 +4,7 @@ import com.alibaba.fastjson.JSON; @@ -4,6 +4,7 @@ import com.alibaba.fastjson.JSON;
4 import com.alibaba.fastjson.JSONObject; 4 import com.alibaba.fastjson.JSONObject;
5 import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; 5 import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
6 import okhttp3.*; 6 import okhttp3.*;
  7 +import okhttp3.logging.HttpLoggingInterceptor;
7 import org.jetbrains.annotations.NotNull; 8 import org.jetbrains.annotations.NotNull;
8 import org.slf4j.Logger; 9 import org.slf4j.Logger;
9 import org.slf4j.LoggerFactory; 10 import org.slf4j.LoggerFactory;
@@ -25,8 +26,23 @@ public class ZLMRESTfulUtils { @@ -25,8 +26,23 @@ public class ZLMRESTfulUtils {
25 void run(JSONObject response); 26 void run(JSONObject response);
26 } 27 }
27 28
  29 + private OkHttpClient getClient(){
  30 + OkHttpClient.Builder httpClientBuilder = new OkHttpClient.Builder();
  31 + if (logger.isDebugEnabled()) {
  32 + HttpLoggingInterceptor logging = new HttpLoggingInterceptor(message -> {
  33 + logger.debug("http请求参数:" + message);
  34 + });
  35 + logging.setLevel(HttpLoggingInterceptor.Level.BASIC);
  36 + // OkHttp進行添加攔截器loggingInterceptor
  37 + httpClientBuilder.addInterceptor(logging);
  38 + }
  39 + return httpClientBuilder.build();
  40 + }
  41 +
  42 +
28 public JSONObject sendPost(MediaServerItem mediaServerItem, String api, Map<String, Object> param, RequestCallback callback) { 43 public JSONObject sendPost(MediaServerItem mediaServerItem, String api, Map<String, Object> param, RequestCallback callback) {
29 - OkHttpClient client = new OkHttpClient(); 44 + OkHttpClient client = getClient();
  45 +
30 if (mediaServerItem == null) { 46 if (mediaServerItem == null) {
31 return null; 47 return null;
32 } 48 }
src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRunner.java
@@ -92,6 +92,7 @@ public class ZLMRunner implements CommandLineRunner { @@ -92,6 +92,7 @@ public class ZLMRunner implements CommandLineRunner {
92 92
93 // 获取所有的zlm, 并开启主动连接 93 // 获取所有的zlm, 并开启主动连接
94 List<MediaServerItem> all = mediaServerService.getAllFromDatabase(); 94 List<MediaServerItem> all = mediaServerService.getAllFromDatabase();
  95 + mediaServerService.updateVmServer(all);
95 if (all.size() == 0) { 96 if (all.size() == 0) {
96 all.add(mediaConfig.getMediaSerItem()); 97 all.add(mediaConfig.getMediaSerItem());
97 } 98 }
src/main/java/com/genersoft/iot/vmp/media/zlm/dto/MediaItem.java
1 package com.genersoft.iot.vmp.media.zlm.dto; 1 package com.genersoft.iot.vmp.media.zlm.dto;
2 2
  3 +import com.genersoft.iot.vmp.common.StreamInfo;
  4 +
3 import java.util.List; 5 import java.util.List;
4 6
5 public class MediaItem { 7 public class MediaItem {
@@ -281,6 +283,8 @@ public class MediaItem { @@ -281,6 +283,8 @@ public class MediaItem {
281 } 283 }
282 } 284 }
283 285
  286 + private StreamInfo streamInfo;
  287 +
284 public String getApp() { 288 public String getApp() {
285 return app; 289 return app;
286 } 290 }
@@ -402,4 +406,12 @@ public class MediaItem { @@ -402,4 +406,12 @@ public class MediaItem {
402 public void setMediaServerId(String mediaServerId) { 406 public void setMediaServerId(String mediaServerId) {
403 this.mediaServerId = mediaServerId; 407 this.mediaServerId = mediaServerId;
404 } 408 }
  409 +
  410 + public StreamInfo getStreamInfo() {
  411 + return streamInfo;
  412 + }
  413 +
  414 + public void setStreamInfo(StreamInfo streamInfo) {
  415 + this.streamInfo = streamInfo;
  416 + }
405 } 417 }
src/main/java/com/genersoft/iot/vmp/service/IMediaServerService.java
@@ -42,11 +42,13 @@ public interface IMediaServerService { @@ -42,11 +42,13 @@ public interface IMediaServerService {
42 42
43 void setZLMConfig(MediaServerItem mediaServerItem, boolean restart); 43 void setZLMConfig(MediaServerItem mediaServerItem, boolean restart);
44 44
  45 + void updateVmServer(List<MediaServerItem> mediaServerItemList);
  46 +
45 SSRCInfo openRTPServer(MediaServerItem mediaServerItem, String streamId); 47 SSRCInfo openRTPServer(MediaServerItem mediaServerItem, String streamId);
46 48
47 SSRCInfo openRTPServer(MediaServerItem mediaServerItem, String streamId, boolean isPlayback); 49 SSRCInfo openRTPServer(MediaServerItem mediaServerItem, String streamId, boolean isPlayback);
48 50
49 - void closeRTPServer(Device device, String channelId); 51 + void closeRTPServer(Device device, String channelId, String ssrc);
50 52
51 void clearRTPServer(MediaServerItem mediaServerItem); 53 void clearRTPServer(MediaServerItem mediaServerItem);
52 54
@@ -74,6 +76,8 @@ public interface IMediaServerService { @@ -74,6 +76,8 @@ public interface IMediaServerService {
74 76
75 void delete(String id); 77 void delete(String id);
76 78
  79 + void deleteDb(String id);
  80 +
77 MediaServerItem getDefaultMediaServer(); 81 MediaServerItem getDefaultMediaServer();
78 82
79 void updateMediaServerKeepalive(String mediaServerId, JSONObject data); 83 void updateMediaServerKeepalive(String mediaServerId, JSONObject data);
src/main/java/com/genersoft/iot/vmp/service/IPlayService.java
@@ -5,14 +5,16 @@ import com.genersoft.iot.vmp.gb28181.bean.Device; @@ -5,14 +5,16 @@ import com.genersoft.iot.vmp.gb28181.bean.Device;
5 import com.genersoft.iot.vmp.gb28181.event.SipSubscribe; 5 import com.genersoft.iot.vmp.gb28181.event.SipSubscribe;
6 import com.genersoft.iot.vmp.media.zlm.ZLMHttpHookSubscribe; 6 import com.genersoft.iot.vmp.media.zlm.ZLMHttpHookSubscribe;
7 import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; 7 import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
  8 +import com.genersoft.iot.vmp.service.bean.PlayBackCallback;
8 import com.genersoft.iot.vmp.vmanager.gb28181.play.bean.PlayResult; 9 import com.genersoft.iot.vmp.vmanager.gb28181.play.bean.PlayResult;
  10 +import org.springframework.http.ResponseEntity;
  11 +import org.springframework.web.context.request.async.DeferredResult;
9 12
10 /** 13 /**
11 * 点播处理 14 * 点播处理
12 */ 15 */
13 public interface IPlayService { 16 public interface IPlayService {
14 17
15 - void onPublishHandlerForPlayBack(MediaServerItem mediaServerItem, JSONObject resonse, String deviceId, String channelId, String uuid);  
16 void onPublishHandlerForPlay(MediaServerItem mediaServerItem, JSONObject resonse, String deviceId, String channelId, String uuid); 18 void onPublishHandlerForPlay(MediaServerItem mediaServerItem, JSONObject resonse, String deviceId, String channelId, String uuid);
17 19
18 PlayResult play(MediaServerItem mediaServerItem, String deviceId, String channelId, ZLMHttpHookSubscribe.Event event, SipSubscribe.Event errorEvent); 20 PlayResult play(MediaServerItem mediaServerItem, String deviceId, String channelId, ZLMHttpHookSubscribe.Event event, SipSubscribe.Event errorEvent);
@@ -20,4 +22,6 @@ public interface IPlayService { @@ -20,4 +22,6 @@ public interface IPlayService {
20 MediaServerItem getNewMediaServerItem(Device device); 22 MediaServerItem getNewMediaServerItem(Device device);
21 23
22 void onPublishHandlerForDownload(MediaServerItem mediaServerItem, JSONObject response, String deviceId, String channelId, String toString); 24 void onPublishHandlerForDownload(MediaServerItem mediaServerItem, JSONObject response, String deviceId, String channelId, String toString);
  25 +
  26 + DeferredResult<ResponseEntity<String>> playBack(String deviceId, String channelId, String startTime, String endTime, PlayBackCallback errorCallBack);
23 } 27 }
src/main/java/com/genersoft/iot/vmp/service/bean/PlayBackCallback.java 0 → 100644
  1 +package com.genersoft.iot.vmp.service.bean;
  2 +
  3 +import com.genersoft.iot.vmp.gb28181.transmit.callback.RequestMessage;
  4 +
  5 +public interface PlayBackCallback {
  6 +
  7 + void call(RequestMessage msg);
  8 +
  9 +}
src/main/java/com/genersoft/iot/vmp/service/bean/SSRCInfo.java
@@ -4,12 +4,12 @@ public class SSRCInfo { @@ -4,12 +4,12 @@ public class SSRCInfo {
4 4
5 private int port; 5 private int port;
6 private String ssrc; 6 private String ssrc;
7 - private String StreamId; 7 + private String Stream;
8 8
9 - public SSRCInfo(int port, String ssrc, String streamId) { 9 + public SSRCInfo(int port, String ssrc, String stream) {
10 this.port = port; 10 this.port = port;
11 this.ssrc = ssrc; 11 this.ssrc = ssrc;
12 - StreamId = streamId; 12 + Stream = stream;
13 } 13 }
14 14
15 public int getPort() { 15 public int getPort() {
@@ -28,11 +28,11 @@ public class SSRCInfo { @@ -28,11 +28,11 @@ public class SSRCInfo {
28 this.ssrc = ssrc; 28 this.ssrc = ssrc;
29 } 29 }
30 30
31 - public String getStreamId() {  
32 - return StreamId; 31 + public String getStream() {
  32 + return Stream;
33 } 33 }
34 34
35 - public void setStreamId(String streamId) {  
36 - StreamId = streamId; 35 + public void setStream(String stream) {
  36 + Stream = stream;
37 } 37 }
38 } 38 }
src/main/java/com/genersoft/iot/vmp/service/impl/GbStreamServiceImpl.java
@@ -103,7 +103,7 @@ public class GbStreamServiceImpl implements IGbStreamService { @@ -103,7 +103,7 @@ public class GbStreamServiceImpl implements IGbStreamService {
103 deviceChannel.setStatus(gbStream.isStatus()?1:0); 103 deviceChannel.setStatus(gbStream.isStatus()?1:0);
104 deviceChannel.setParentId(catalogId ==null?gbStream.getCatalogId():catalogId); 104 deviceChannel.setParentId(catalogId ==null?gbStream.getCatalogId():catalogId);
105 deviceChannel.setRegisterWay(1); 105 deviceChannel.setRegisterWay(1);
106 - deviceChannel.setCivilCode(sipConfig.getDomain()); 106 + deviceChannel.setCivilCode(sipConfig.getDomain().substring(0, sipConfig.getDomain().length() - 2));
107 deviceChannel.setModel("live"); 107 deviceChannel.setModel("live");
108 deviceChannel.setOwner("wvp-pro"); 108 deviceChannel.setOwner("wvp-pro");
109 deviceChannel.setParental(0); 109 deviceChannel.setParental(0);
src/main/java/com/genersoft/iot/vmp/service/impl/MediaServerServiceImpl.java
@@ -4,6 +4,7 @@ import com.alibaba.fastjson.JSON; @@ -4,6 +4,7 @@ import com.alibaba.fastjson.JSON;
4 import com.alibaba.fastjson.JSONArray; 4 import com.alibaba.fastjson.JSONArray;
5 import com.alibaba.fastjson.JSONObject; 5 import com.alibaba.fastjson.JSONObject;
6 import com.genersoft.iot.vmp.common.VideoManagerConstants; 6 import com.genersoft.iot.vmp.common.VideoManagerConstants;
  7 +import com.genersoft.iot.vmp.conf.MediaConfig;
7 import com.genersoft.iot.vmp.conf.SipConfig; 8 import com.genersoft.iot.vmp.conf.SipConfig;
8 import com.genersoft.iot.vmp.conf.UserSetup; 9 import com.genersoft.iot.vmp.conf.UserSetup;
9 import com.genersoft.iot.vmp.gb28181.bean.Device; 10 import com.genersoft.iot.vmp.gb28181.bean.Device;
@@ -45,8 +46,7 @@ import java.util.*; @@ -45,8 +46,7 @@ import java.util.*;
45 * 媒体服务器节点管理 46 * 媒体服务器节点管理
46 */ 47 */
47 @Service 48 @Service
48 -@Order(value=2)  
49 -public class MediaServerServiceImpl implements IMediaServerService, CommandLineRunner { 49 +public class MediaServerServiceImpl implements IMediaServerService {
50 50
51 private final static Logger logger = LoggerFactory.getLogger(MediaServerServiceImpl.class); 51 private final static Logger logger = LoggerFactory.getLogger(MediaServerServiceImpl.class);
52 52
@@ -101,9 +101,8 @@ public class MediaServerServiceImpl implements IMediaServerService, CommandLineR @@ -101,9 +101,8 @@ public class MediaServerServiceImpl implements IMediaServerService, CommandLineR
101 * 初始化 101 * 初始化
102 */ 102 */
103 @Override 103 @Override
104 - public void run(String... args) throws Exception { 104 + public void updateVmServer(List<MediaServerItem> mediaServerItemList) {
105 logger.info("[缓存初始化] Media Server "); 105 logger.info("[缓存初始化] Media Server ");
106 - List<MediaServerItem> mediaServerItemList = mediaServerMapper.queryAll();  
107 for (MediaServerItem mediaServerItem : mediaServerItemList) { 106 for (MediaServerItem mediaServerItem : mediaServerItemList) {
108 if (StringUtils.isEmpty(mediaServerItem.getId())) { 107 if (StringUtils.isEmpty(mediaServerItem.getId())) {
109 continue; 108 continue;
@@ -161,15 +160,16 @@ public class MediaServerServiceImpl implements IMediaServerService, CommandLineR @@ -161,15 +160,16 @@ public class MediaServerServiceImpl implements IMediaServerService, CommandLineR
161 } 160 }
162 161
163 @Override 162 @Override
164 - public void closeRTPServer(Device device, String channelId) {  
165 - String mediaServerId = streamSession.getMediaServerId(device.getDeviceId(), channelId); 163 + public void closeRTPServer(Device device, String channelId, String stream) {
  164 + String mediaServerId = streamSession.getMediaServerId(device.getDeviceId(), channelId, stream);
  165 + String ssrc = streamSession.getSSRC(device.getDeviceId(), channelId, stream);
166 MediaServerItem mediaServerItem = this.getOne(mediaServerId); 166 MediaServerItem mediaServerItem = this.getOne(mediaServerId);
167 if (mediaServerItem != null) { 167 if (mediaServerItem != null) {
168 String streamId = String.format("%s_%s", device.getDeviceId(), channelId); 168 String streamId = String.format("%s_%s", device.getDeviceId(), channelId);
169 zlmrtpServerFactory.closeRTPServer(mediaServerItem, streamId); 169 zlmrtpServerFactory.closeRTPServer(mediaServerItem, streamId);
170 - releaseSsrc(mediaServerItem, streamSession.getSSRC(device.getDeviceId(), channelId)); 170 + releaseSsrc(mediaServerItem, ssrc);
171 } 171 }
172 - streamSession.remove(device.getDeviceId(), channelId); 172 + streamSession.remove(device.getDeviceId(), channelId, stream);
173 } 173 }
174 174
175 @Override 175 @Override
@@ -223,7 +223,8 @@ public class MediaServerServiceImpl implements IMediaServerService, CommandLineR @@ -223,7 +223,8 @@ public class MediaServerServiceImpl implements IMediaServerService, CommandLineR
223 String key = (String) mediaServerKey; 223 String key = (String) mediaServerKey;
224 MediaServerItem mediaServerItem = (MediaServerItem) redisUtil.get(key); 224 MediaServerItem mediaServerItem = (MediaServerItem) redisUtil.get(key);
225 // 检查状态 225 // 检查状态
226 - if (redisUtil.zScore(onlineKey, mediaServerItem.getId()) != null) { 226 + Double aDouble = redisUtil.zScore(onlineKey, mediaServerItem.getId());
  227 + if (aDouble != null) {
227 mediaServerItem.setStatus(true); 228 mediaServerItem.setStatus(true);
228 } 229 }
229 result.add(mediaServerItem); 230 result.add(mediaServerItem);
@@ -278,6 +279,7 @@ public class MediaServerServiceImpl implements IMediaServerService, CommandLineR @@ -278,6 +279,7 @@ public class MediaServerServiceImpl implements IMediaServerService, CommandLineR
278 279
279 @Override 280 @Override
280 public MediaServerItem getDefaultMediaServer() { 281 public MediaServerItem getDefaultMediaServer() {
  282 +
281 return mediaServerMapper.queryDefault(); 283 return mediaServerMapper.queryDefault();
282 } 284 }
283 285
@@ -607,6 +609,11 @@ public class MediaServerServiceImpl implements IMediaServerService, CommandLineR @@ -607,6 +609,11 @@ public class MediaServerServiceImpl implements IMediaServerService, CommandLineR
607 String key = VideoManagerConstants.MEDIA_SERVER_PREFIX + userSetup.getServerId() + "_" + id; 609 String key = VideoManagerConstants.MEDIA_SERVER_PREFIX + userSetup.getServerId() + "_" + id;
608 redisUtil.del(key); 610 redisUtil.del(key);
609 } 611 }
  612 + @Override
  613 + public void deleteDb(String id){
  614 + //同步删除数据库中的数据
  615 + mediaServerMapper.delOne(id);
  616 + }
610 617
611 @Override 618 @Override
612 public void updateMediaServerKeepalive(String mediaServerId, JSONObject data) { 619 public void updateMediaServerKeepalive(String mediaServerId, JSONObject data) {
src/main/java/com/genersoft/iot/vmp/service/impl/MediaServiceImpl.java
@@ -4,6 +4,7 @@ import com.alibaba.fastjson.JSON; @@ -4,6 +4,7 @@ import com.alibaba.fastjson.JSON;
4 import com.alibaba.fastjson.JSONArray; 4 import com.alibaba.fastjson.JSONArray;
5 import com.alibaba.fastjson.JSONObject; 5 import com.alibaba.fastjson.JSONObject;
6 import com.genersoft.iot.vmp.common.StreamInfo; 6 import com.genersoft.iot.vmp.common.StreamInfo;
  7 +import com.genersoft.iot.vmp.conf.MediaConfig;
7 import com.genersoft.iot.vmp.media.zlm.ZLMRESTfulUtils; 8 import com.genersoft.iot.vmp.media.zlm.ZLMRESTfulUtils;
8 import com.genersoft.iot.vmp.media.zlm.dto.MediaItem; 9 import com.genersoft.iot.vmp.media.zlm.dto.MediaItem;
9 import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; 10 import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
@@ -26,6 +27,10 @@ public class MediaServiceImpl implements IMediaService { @@ -26,6 +27,10 @@ public class MediaServiceImpl implements IMediaService {
26 @Autowired 27 @Autowired
27 private IMediaServerService mediaServerService; 28 private IMediaServerService mediaServerService;
28 29
  30 +
  31 + @Autowired
  32 + private MediaConfig mediaConfig;
  33 +
29 @Autowired 34 @Autowired
30 private ZLMRESTfulUtils zlmresTfulUtils; 35 private ZLMRESTfulUtils zlmresTfulUtils;
31 36
@@ -39,15 +44,12 @@ public class MediaServiceImpl implements IMediaService { @@ -39,15 +44,12 @@ public class MediaServiceImpl implements IMediaService {
39 @Override 44 @Override
40 public StreamInfo getStreamInfoByAppAndStreamWithCheck(String app, String stream, String mediaServerId, String addr) { 45 public StreamInfo getStreamInfoByAppAndStreamWithCheck(String app, String stream, String mediaServerId, String addr) {
41 StreamInfo streamInfo = null; 46 StreamInfo streamInfo = null;
42 -  
43 - MediaServerItem mediaInfo;  
44 if (mediaServerId == null) { 47 if (mediaServerId == null) {
45 - mediaInfo = mediaServerService.getDefaultMediaServer();  
46 - }else {  
47 - mediaInfo = mediaServerService.getOne(mediaServerId); 48 + mediaServerId = mediaConfig.getId();
48 } 49 }
  50 + MediaServerItem mediaInfo = mediaServerService.getOne(mediaServerId);;
49 if (mediaInfo == null) { 51 if (mediaInfo == null) {
50 - return streamInfo; 52 + return null;
51 } 53 }
52 JSONObject mediaList = zlmresTfulUtils.getMediaList(mediaInfo, app, stream); 54 JSONObject mediaList = zlmresTfulUtils.getMediaList(mediaInfo, app, stream);
53 if (mediaList != null) { 55 if (mediaList != null) {
@@ -72,7 +74,7 @@ public class MediaServiceImpl implements IMediaService { @@ -72,7 +74,7 @@ public class MediaServiceImpl implements IMediaService {
72 @Override 74 @Override
73 public StreamInfo getStreamInfoByAppAndStream(MediaServerItem mediaInfo, String app, String stream, Object tracks, String addr) { 75 public StreamInfo getStreamInfoByAppAndStream(MediaServerItem mediaInfo, String app, String stream, Object tracks, String addr) {
74 StreamInfo streamInfoResult = new StreamInfo(); 76 StreamInfo streamInfoResult = new StreamInfo();
75 - streamInfoResult.setStreamId(stream); 77 + streamInfoResult.setStream(stream);
76 streamInfoResult.setApp(app); 78 streamInfoResult.setApp(app);
77 if (addr == null) { 79 if (addr == null) {
78 addr = mediaInfo.getStreamIp(); 80 addr = mediaInfo.getStreamIp();
src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java
@@ -16,10 +16,10 @@ import com.genersoft.iot.vmp.media.zlm.ZLMHttpHookSubscribe; @@ -16,10 +16,10 @@ import com.genersoft.iot.vmp.media.zlm.ZLMHttpHookSubscribe;
16 import com.genersoft.iot.vmp.media.zlm.ZLMRESTfulUtils; 16 import com.genersoft.iot.vmp.media.zlm.ZLMRESTfulUtils;
17 import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; 17 import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
18 import com.genersoft.iot.vmp.service.IMediaServerService; 18 import com.genersoft.iot.vmp.service.IMediaServerService;
  19 +import com.genersoft.iot.vmp.service.bean.PlayBackCallback;
19 import com.genersoft.iot.vmp.service.bean.SSRCInfo; 20 import com.genersoft.iot.vmp.service.bean.SSRCInfo;
20 import com.genersoft.iot.vmp.storager.IRedisCatchStorage; 21 import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
21 import com.genersoft.iot.vmp.storager.IVideoManagerStorager; 22 import com.genersoft.iot.vmp.storager.IVideoManagerStorager;
22 -import com.genersoft.iot.vmp.utils.redis.RedisUtil;  
23 import com.genersoft.iot.vmp.vmanager.bean.WVPResult; 23 import com.genersoft.iot.vmp.vmanager.bean.WVPResult;
24 import com.genersoft.iot.vmp.vmanager.gb28181.play.bean.PlayResult; 24 import com.genersoft.iot.vmp.vmanager.gb28181.play.bean.PlayResult;
25 import com.genersoft.iot.vmp.service.IMediaService; 25 import com.genersoft.iot.vmp.service.IMediaService;
@@ -54,9 +54,6 @@ public class PlayServiceImpl implements IPlayService { @@ -54,9 +54,6 @@ public class PlayServiceImpl implements IPlayService {
54 private IRedisCatchStorage redisCatchStorage; 54 private IRedisCatchStorage redisCatchStorage;
55 55
56 @Autowired 56 @Autowired
57 - private RedisUtil redis;  
58 -  
59 - @Autowired  
60 private DeferredResultHolder resultHolder; 57 private DeferredResultHolder resultHolder;
61 58
62 @Autowired 59 @Autowired
@@ -104,19 +101,21 @@ public class PlayServiceImpl implements IPlayService { @@ -104,19 +101,21 @@ public class PlayServiceImpl implements IPlayService {
104 logger.warn(String.format("设备点播超时,deviceId:%s ,channelId:%s", deviceId, channelId)); 101 logger.warn(String.format("设备点播超时,deviceId:%s ,channelId:%s", deviceId, channelId));
105 WVPResult wvpResult = new WVPResult(); 102 WVPResult wvpResult = new WVPResult();
106 wvpResult.setCode(-1); 103 wvpResult.setCode(-1);
107 - SIPDialog dialog = streamSession.getDialog(deviceId, channelId); 104 + SIPDialog dialog = streamSession.getDialogByStream(deviceId, channelId, streamInfo.getStream());
108 if (dialog != null) { 105 if (dialog != null) {
109 wvpResult.setMsg("收流超时,请稍候重试"); 106 wvpResult.setMsg("收流超时,请稍候重试");
110 }else { 107 }else {
111 wvpResult.setMsg("点播超时,请稍候重试"); 108 wvpResult.setMsg("点播超时,请稍候重试");
112 } 109 }
  110 +
113 msg.setData(wvpResult); 111 msg.setData(wvpResult);
114 // 点播超时回复BYE 112 // 点播超时回复BYE
115 - cmder.streamByeCmd(device.getDeviceId(), channelId); 113 + cmder.streamByeCmd(device.getDeviceId(), channelId, streamInfo.getStream());
116 // 释放rtpserver 114 // 释放rtpserver
117 - mediaServerService.closeRTPServer(playResult.getDevice(), channelId); 115 + mediaServerService.closeRTPServer(playResult.getDevice(), channelId, streamInfo.getStream());
118 // 回复之前所有的点播请求 116 // 回复之前所有的点播请求
119 resultHolder.invokeAllResult(msg); 117 resultHolder.invokeAllResult(msg);
  118 + // TODO 释放ssrc
120 }); 119 });
121 result.onCompletion(()->{ 120 result.onCompletion(()->{
122 // 点播结束时调用截图接口 121 // 点播结束时调用截图接口
@@ -154,14 +153,12 @@ public class PlayServiceImpl implements IPlayService { @@ -154,14 +153,12 @@ public class PlayServiceImpl implements IPlayService {
154 } 153 }
155 }); 154 });
156 if (streamInfo == null) { 155 if (streamInfo == null) {
157 - SSRCInfo ssrcInfo;  
158 String streamId = null; 156 String streamId = null;
159 if (mediaServerItem.isRtpEnable()) { 157 if (mediaServerItem.isRtpEnable()) {
160 streamId = String.format("%s_%s", device.getDeviceId(), channelId); 158 streamId = String.format("%s_%s", device.getDeviceId(), channelId);
161 } 159 }
162 160
163 - ssrcInfo = mediaServerService.openRTPServer(mediaServerItem, streamId);  
164 - 161 + SSRCInfo ssrcInfo = mediaServerService.openRTPServer(mediaServerItem, streamId);
165 // 发送点播消息 162 // 发送点播消息
166 cmder.playStreamCmd(mediaServerItem, ssrcInfo, device, channelId, (MediaServerItem mediaServerItemInUse, JSONObject response) -> { 163 cmder.playStreamCmd(mediaServerItem, ssrcInfo, device, channelId, (MediaServerItem mediaServerItemInUse, JSONObject response) -> {
167 logger.info("收到订阅消息: " + response.toJSONString()); 164 logger.info("收到订阅消息: " + response.toJSONString());
@@ -173,7 +170,7 @@ public class PlayServiceImpl implements IPlayService { @@ -173,7 +170,7 @@ public class PlayServiceImpl implements IPlayService {
173 WVPResult wvpResult = new WVPResult(); 170 WVPResult wvpResult = new WVPResult();
174 wvpResult.setCode(-1); 171 wvpResult.setCode(-1);
175 // 点播返回sip错误 172 // 点播返回sip错误
176 - mediaServerService.closeRTPServer(playResult.getDevice(), channelId); 173 + mediaServerService.closeRTPServer(playResult.getDevice(), channelId, ssrcInfo.getStream());
177 wvpResult.setMsg(String.format("点播失败, 错误码: %s, %s", event.statusCode, event.msg)); 174 wvpResult.setMsg(String.format("点播失败, 错误码: %s, %s", event.statusCode, event.msg));
178 msg.setData(wvpResult); 175 msg.setData(wvpResult);
179 resultHolder.invokeAllResult(msg); 176 resultHolder.invokeAllResult(msg);
@@ -184,7 +181,7 @@ public class PlayServiceImpl implements IPlayService { @@ -184,7 +181,7 @@ public class PlayServiceImpl implements IPlayService {
184 181
185 }); 182 });
186 } else { 183 } else {
187 - String streamId = streamInfo.getStreamId(); 184 + String streamId = streamInfo.getStream();
188 if (streamId == null) { 185 if (streamId == null) {
189 WVPResult wvpResult = new WVPResult(); 186 WVPResult wvpResult = new WVPResult();
190 wvpResult.setCode(-1); 187 wvpResult.setCode(-1);
@@ -213,18 +210,16 @@ public class PlayServiceImpl implements IPlayService { @@ -213,18 +210,16 @@ public class PlayServiceImpl implements IPlayService {
213 // TODO 点播前是否重置状态 210 // TODO 点播前是否重置状态
214 redisCatchStorage.stopPlay(streamInfo); 211 redisCatchStorage.stopPlay(streamInfo);
215 storager.stopPlay(streamInfo.getDeviceID(), streamInfo.getChannelId()); 212 storager.stopPlay(streamInfo.getDeviceID(), streamInfo.getChannelId());
216 - SSRCInfo ssrcInfo;  
217 String streamId2 = null; 213 String streamId2 = null;
218 if (mediaServerItem.isRtpEnable()) { 214 if (mediaServerItem.isRtpEnable()) {
219 streamId2 = String.format("%s_%s", device.getDeviceId(), channelId); 215 streamId2 = String.format("%s_%s", device.getDeviceId(), channelId);
220 } 216 }
221 - ssrcInfo = mediaServerService.openRTPServer(mediaServerItem, streamId2);  
222 - 217 + SSRCInfo ssrcInfo = mediaServerService.openRTPServer(mediaServerItem, streamId2);
223 cmder.playStreamCmd(mediaServerItem, ssrcInfo, device, channelId, (MediaServerItem mediaServerItemInuse, JSONObject response) -> { 218 cmder.playStreamCmd(mediaServerItem, ssrcInfo, device, channelId, (MediaServerItem mediaServerItemInuse, JSONObject response) -> {
224 logger.info("收到订阅消息: " + response.toJSONString()); 219 logger.info("收到订阅消息: " + response.toJSONString());
225 onPublishHandlerForPlay(mediaServerItemInuse, response, deviceId, channelId, uuid); 220 onPublishHandlerForPlay(mediaServerItemInuse, response, deviceId, channelId, uuid);
226 }, (event) -> { 221 }, (event) -> {
227 - mediaServerService.closeRTPServer(playResult.getDevice(), channelId); 222 + mediaServerService.closeRTPServer(playResult.getDevice(), channelId, ssrcInfo.getStream());
228 WVPResult wvpResult = new WVPResult(); 223 WVPResult wvpResult = new WVPResult();
229 wvpResult.setCode(-1); 224 wvpResult.setCode(-1);
230 wvpResult.setMsg(String.format("点播失败, 错误码: %s, %s", event.statusCode, event.msg)); 225 wvpResult.setMsg(String.format("点播失败, 错误码: %s, %s", event.statusCode, event.msg));
@@ -242,12 +237,12 @@ public class PlayServiceImpl implements IPlayService { @@ -242,12 +237,12 @@ public class PlayServiceImpl implements IPlayService {
242 RequestMessage msg = new RequestMessage(); 237 RequestMessage msg = new RequestMessage();
243 msg.setId(uuid); 238 msg.setId(uuid);
244 msg.setKey(DeferredResultHolder.CALLBACK_CMD_PLAY + deviceId + channelId); 239 msg.setKey(DeferredResultHolder.CALLBACK_CMD_PLAY + deviceId + channelId);
245 - StreamInfo streamInfo = onPublishHandler(mediaServerItem, resonse, deviceId, channelId, uuid); 240 + StreamInfo streamInfo = onPublishHandler(mediaServerItem, resonse, deviceId, channelId);
246 if (streamInfo != null) { 241 if (streamInfo != null) {
247 DeviceChannel deviceChannel = storager.queryChannel(deviceId, channelId); 242 DeviceChannel deviceChannel = storager.queryChannel(deviceId, channelId);
248 if (deviceChannel != null) { 243 if (deviceChannel != null) {
249 - deviceChannel.setStreamId(streamInfo.getStreamId());  
250 - storager.startPlay(deviceId, channelId, streamInfo.getStreamId()); 244 + deviceChannel.setStreamId(streamInfo.getStream());
  245 + storager.startPlay(deviceId, channelId, streamInfo.getStream());
251 } 246 }
252 redisCatchStorage.startPlay(streamInfo); 247 redisCatchStorage.startPlay(streamInfo);
253 msg.setData(JSON.toJSONString(streamInfo)); 248 msg.setData(JSON.toJSONString(streamInfo));
@@ -284,29 +279,53 @@ public class PlayServiceImpl implements IPlayService { @@ -284,29 +279,53 @@ public class PlayServiceImpl implements IPlayService {
284 279
285 280
286 @Override 281 @Override
287 - public void onPublishHandlerForPlayBack(MediaServerItem mediaServerItem, JSONObject resonse, String deviceId, String channelId, String uuid) { 282 + public DeferredResult<ResponseEntity<String>> playBack(String deviceId, String channelId, String startTime, String endTime, PlayBackCallback callback) {
  283 + String uuid = UUID.randomUUID().toString();
  284 + String key = DeferredResultHolder.CALLBACK_CMD_PLAYBACK + deviceId + channelId;
  285 + DeferredResult<ResponseEntity<String>> result = new DeferredResult<>(30000L);
  286 + Device device = storager.queryVideoDevice(deviceId);
  287 + if (device == null) {
  288 + result.setResult(new ResponseEntity<>(HttpStatus.BAD_REQUEST));
  289 + return result;
  290 + }
  291 +
  292 + MediaServerItem newMediaServerItem = getNewMediaServerItem(device);
  293 + SSRCInfo ssrcInfo = mediaServerService.openRTPServer(newMediaServerItem, null, true);
  294 + resultHolder.put(DeferredResultHolder.CALLBACK_CMD_PLAY + deviceId + channelId, uuid, result);
288 RequestMessage msg = new RequestMessage(); 295 RequestMessage msg = new RequestMessage();
289 - msg.setKey(DeferredResultHolder.CALLBACK_CMD_PLAYBACK + deviceId + channelId);  
290 msg.setId(uuid); 296 msg.setId(uuid);
291 - StreamInfo streamInfo = onPublishHandler(mediaServerItem, resonse, deviceId, channelId, uuid);  
292 - if (streamInfo != null) { 297 + msg.setKey(key);
  298 + result.onTimeout(()->{
  299 + msg.setData("回放超时");
  300 + callback.call(msg);
  301 + });
  302 + cmder.playbackStreamCmd(newMediaServerItem, ssrcInfo, device, channelId, startTime, endTime, (MediaServerItem mediaServerItem, JSONObject response) -> {
  303 + logger.info("收到订阅消息: " + response.toJSONString());
  304 + StreamInfo streamInfo = onPublishHandler(mediaServerItem, response, deviceId, channelId);
  305 + if (streamInfo == null) {
  306 + logger.warn("设备回放API调用失败!");
  307 + msg.setData("设备回放API调用失败!");
  308 + callback.call(msg);
  309 + return;
  310 + }
293 redisCatchStorage.startPlayback(streamInfo); 311 redisCatchStorage.startPlayback(streamInfo);
294 msg.setData(JSON.toJSONString(streamInfo)); 312 msg.setData(JSON.toJSONString(streamInfo));
295 - resultHolder.invokeResult(msg);  
296 - } else {  
297 - logger.warn("设备回放API调用失败!");  
298 - msg.setData("设备回放API调用失败!");  
299 - resultHolder.invokeResult(msg);  
300 - } 313 + callback.call(msg);
  314 + }, event -> {
  315 + msg.setData(String.format("回放失败, 错误码: %s, %s", event.statusCode, event.msg));
  316 + callback.call(msg);
  317 + });
  318 + return result;
301 } 319 }
302 320
303 321
  322 +
304 @Override 323 @Override
305 public void onPublishHandlerForDownload(MediaServerItem mediaServerItem, JSONObject response, String deviceId, String channelId, String uuid) { 324 public void onPublishHandlerForDownload(MediaServerItem mediaServerItem, JSONObject response, String deviceId, String channelId, String uuid) {
306 RequestMessage msg = new RequestMessage(); 325 RequestMessage msg = new RequestMessage();
307 msg.setKey(DeferredResultHolder.CALLBACK_CMD_DOWNLOAD + deviceId + channelId); 326 msg.setKey(DeferredResultHolder.CALLBACK_CMD_DOWNLOAD + deviceId + channelId);
308 msg.setId(uuid); 327 msg.setId(uuid);
309 - StreamInfo streamInfo = onPublishHandler(mediaServerItem, response, deviceId, channelId, uuid); 328 + StreamInfo streamInfo = onPublishHandler(mediaServerItem, response, deviceId, channelId);
310 if (streamInfo != null) { 329 if (streamInfo != null) {
311 redisCatchStorage.startDownload(streamInfo); 330 redisCatchStorage.startDownload(streamInfo);
312 msg.setData(JSON.toJSONString(streamInfo)); 331 msg.setData(JSON.toJSONString(streamInfo));
@@ -319,7 +338,7 @@ public class PlayServiceImpl implements IPlayService { @@ -319,7 +338,7 @@ public class PlayServiceImpl implements IPlayService {
319 } 338 }
320 339
321 340
322 - public StreamInfo onPublishHandler(MediaServerItem mediaServerItem, JSONObject resonse, String deviceId, String channelId, String uuid) { 341 + public StreamInfo onPublishHandler(MediaServerItem mediaServerItem, JSONObject resonse, String deviceId, String channelId) {
323 String streamId = resonse.getString("stream"); 342 String streamId = resonse.getString("stream");
324 JSONArray tracks = resonse.getJSONArray("tracks"); 343 JSONArray tracks = resonse.getJSONArray("tracks");
325 StreamInfo streamInfo = mediaService.getStreamInfoByAppAndStream(mediaServerItem,"rtp", streamId, tracks); 344 StreamInfo streamInfo = mediaService.getStreamInfoByAppAndStream(mediaServerItem,"rtp", streamId, tracks);
src/main/java/com/genersoft/iot/vmp/service/impl/RedisGPSMsgListener.java
@@ -3,6 +3,8 @@ package com.genersoft.iot.vmp.service.impl; @@ -3,6 +3,8 @@ package com.genersoft.iot.vmp.service.impl;
3 import com.alibaba.fastjson.JSON; 3 import com.alibaba.fastjson.JSON;
4 import com.genersoft.iot.vmp.service.bean.GPSMsgInfo; 4 import com.genersoft.iot.vmp.service.bean.GPSMsgInfo;
5 import com.genersoft.iot.vmp.storager.IRedisCatchStorage; 5 import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
  6 +import org.slf4j.Logger;
  7 +import org.slf4j.LoggerFactory;
6 import org.springframework.beans.factory.annotation.Autowired; 8 import org.springframework.beans.factory.annotation.Autowired;
7 import org.springframework.data.redis.connection.Message; 9 import org.springframework.data.redis.connection.Message;
8 import org.springframework.data.redis.connection.MessageListener; 10 import org.springframework.data.redis.connection.MessageListener;
@@ -11,11 +13,14 @@ import org.springframework.stereotype.Component; @@ -11,11 +13,14 @@ import org.springframework.stereotype.Component;
11 @Component 13 @Component
12 public class RedisGPSMsgListener implements MessageListener { 14 public class RedisGPSMsgListener implements MessageListener {
13 15
  16 + private final static Logger logger = LoggerFactory.getLogger(RedisGPSMsgListener.class);
  17 +
14 @Autowired 18 @Autowired
15 private IRedisCatchStorage redisCatchStorage; 19 private IRedisCatchStorage redisCatchStorage;
16 20
17 @Override 21 @Override
18 public void onMessage(Message message, byte[] bytes) { 22 public void onMessage(Message message, byte[] bytes) {
  23 + logger.debug("收到来自REDIS的GPS通知: {}", new String(message.getBody()));
19 GPSMsgInfo gpsMsgInfo = JSON.parseObject(message.getBody(), GPSMsgInfo.class); 24 GPSMsgInfo gpsMsgInfo = JSON.parseObject(message.getBody(), GPSMsgInfo.class);
20 redisCatchStorage.updateGpsMsgInfo(gpsMsgInfo); 25 redisCatchStorage.updateGpsMsgInfo(gpsMsgInfo);
21 } 26 }
src/main/java/com/genersoft/iot/vmp/service/impl/StreamProxyServiceImpl.java
@@ -132,7 +132,7 @@ public class StreamProxyServiceImpl implements IStreamProxyService { @@ -132,7 +132,7 @@ public class StreamProxyServiceImpl implements IStreamProxyService {
132 }else { 132 }else {
133 streamLive = true; 133 streamLive = true;
134 StreamInfo streamInfo = mediaService.getStreamInfoByAppAndStream( 134 StreamInfo streamInfo = mediaService.getStreamInfoByAppAndStream(
135 - mediaInfo, param.getApp(), param.getStream(), null); 135 + mediaInfo, param.getApp(), param.getStream(), null, null);
136 wvpResult.setData(streamInfo); 136 wvpResult.setData(streamInfo);
137 137
138 } 138 }
src/main/java/com/genersoft/iot/vmp/service/impl/StreamPushServiceImpl.java
@@ -377,7 +377,7 @@ public class StreamPushServiceImpl implements IStreamPushService { @@ -377,7 +377,7 @@ public class StreamPushServiceImpl implements IStreamPushService {
377 377
378 if (streamPushItemsForPlatform.size() > 0) { 378 if (streamPushItemsForPlatform.size() > 0) {
379 List<StreamPushItem> streamPushItemListFroPlatform = new ArrayList<>(); 379 List<StreamPushItem> streamPushItemListFroPlatform = new ArrayList<>();
380 - Map<String, List<StreamPushItem>> platformForEvent = new HashMap<>(); 380 + Map<String, List<GbStream>> platformForEvent = new HashMap<>();
381 // 遍历存储结果,查找app+Stream->platformId+catalogId的对应关系,然后执行批量写入 381 // 遍历存储结果,查找app+Stream->platformId+catalogId的对应关系,然后执行批量写入
382 for (StreamPushItem streamPushItem : streamPushItemsForPlatform) { 382 for (StreamPushItem streamPushItem : streamPushItemsForPlatform) {
383 List<String[]> platFormInfoList = streamPushItemsForAll.get(streamPushItem.getApp() + streamPushItem.getStream()); 383 List<String[]> platFormInfoList = streamPushItemsForAll.get(streamPushItem.getApp() + streamPushItem.getStream());
@@ -390,16 +390,17 @@ public class StreamPushServiceImpl implements IStreamPushService { @@ -390,16 +390,17 @@ public class StreamPushServiceImpl implements IStreamPushService {
390 // 数组 platFormInfoArray 0 为平台ID。 1为目录ID 390 // 数组 platFormInfoArray 0 为平台ID。 1为目录ID
391 streamPushItemForPlatform.setPlatformId(platFormInfoArray[0]); 391 streamPushItemForPlatform.setPlatformId(platFormInfoArray[0]);
392 392
393 - List<StreamPushItem> streamPushItemsInPlatform = platformForEvent.get(streamPushItem.getPlatformId());  
394 - if (streamPushItemsInPlatform == null) {  
395 - streamPushItemsInPlatform = new ArrayList<>();  
396 - platformForEvent.put(platFormInfoArray[0], streamPushItemsInPlatform); 393 + List<GbStream> gbStreamList = platformForEvent.get(streamPushItem.getPlatformId());
  394 + if (gbStreamList == null) {
  395 + gbStreamList = new ArrayList<>();
  396 + platformForEvent.put(platFormInfoArray[0], gbStreamList);
397 } 397 }
398 // 为发送通知整理数据 398 // 为发送通知整理数据
  399 + streamPushItemForPlatform.setName(streamPushItem.getName());
399 streamPushItemForPlatform.setApp(streamPushItem.getApp()); 400 streamPushItemForPlatform.setApp(streamPushItem.getApp());
400 streamPushItemForPlatform.setStream(streamPushItem.getStream()); 401 streamPushItemForPlatform.setStream(streamPushItem.getStream());
401 streamPushItemForPlatform.setGbId(streamPushItem.getGbId()); 402 streamPushItemForPlatform.setGbId(streamPushItem.getGbId());
402 - streamPushItemsInPlatform.add(streamPushItemForPlatform); 403 + gbStreamList.add(streamPushItemForPlatform);
403 } 404 }
404 if (platFormInfoArray.length > 1) { 405 if (platFormInfoArray.length > 1) {
405 streamPushItemForPlatform.setCatalogId(platFormInfoArray[1]); 406 streamPushItemForPlatform.setCatalogId(platFormInfoArray[1]);
@@ -416,7 +417,7 @@ public class StreamPushServiceImpl implements IStreamPushService { @@ -416,7 +417,7 @@ public class StreamPushServiceImpl implements IStreamPushService {
416 // 发送通知 417 // 发送通知
417 for (String platformId : platformForEvent.keySet()) { 418 for (String platformId : platformForEvent.keySet()) {
418 eventPublisher.catalogEventPublishForStream( 419 eventPublisher.catalogEventPublishForStream(
419 - platformId, platformForEvent.get(platformId).toArray(new GbStream[0]), CatalogEvent.ADD); 420 + platformId, platformForEvent.get(platformId), CatalogEvent.ADD);
420 } 421 }
421 } 422 }
422 } 423 }
src/main/java/com/genersoft/iot/vmp/storager/IRedisCatchStorage.java
@@ -7,6 +7,7 @@ import com.genersoft.iot.vmp.media.zlm.dto.MediaItem; @@ -7,6 +7,7 @@ import com.genersoft.iot.vmp.media.zlm.dto.MediaItem;
7 import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; 7 import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
8 import com.genersoft.iot.vmp.media.zlm.dto.StreamPushItem; 8 import com.genersoft.iot.vmp.media.zlm.dto.StreamPushItem;
9 import com.genersoft.iot.vmp.service.bean.GPSMsgInfo; 9 import com.genersoft.iot.vmp.service.bean.GPSMsgInfo;
  10 +import com.genersoft.iot.vmp.service.bean.SSRCInfo;
10 import com.genersoft.iot.vmp.service.bean.ThirdPartyGB; 11 import com.genersoft.iot.vmp.service.bean.ThirdPartyGB;
11 12
12 import java.util.List; 13 import java.util.List;
@@ -220,4 +221,5 @@ public interface IRedisCatchStorage { @@ -220,4 +221,5 @@ public interface IRedisCatchStorage {
220 void addMemInfo(double memInfo); 221 void addMemInfo(double memInfo);
221 222
222 void addNetInfo(Map<String, String> networkInterfaces); 223 void addNetInfo(Map<String, String> networkInterfaces);
  224 +
223 } 225 }
src/main/java/com/genersoft/iot/vmp/storager/dao/DeviceChannelMapper.java
@@ -87,26 +87,27 @@ public interface DeviceChannelMapper { @@ -87,26 +87,27 @@ public interface DeviceChannelMapper {
87 void startPlay(String deviceId, String channelId, String streamId); 87 void startPlay(String deviceId, String channelId, String streamId);
88 88
89 @Select(value = {" <script>" + 89 @Select(value = {" <script>" +
90 - "SELECT dc.channelId, "+  
91 - "dc.deviceId, " +  
92 - "dc.name, " +  
93 - "de.manufacturer, " +  
94 - "de.hostAddress, " +  
95 - "dc.subCount, " +  
96 - "pgc.platformId as platformId, " +  
97 - "pgc.catalogId as catalogId " +  
98 - "FROM device_channel dc " +  
99 - "LEFT JOIN device de ON dc.deviceId = de.deviceId " +  
100 - "LEFT JOIN platform_gb_channel pgc on de.deviceId = pgc.deviceId and pgc.channelId = dc.channelId " +  
101 - "LEFT JOIN device_channel dc2 ON dc2.deviceId = de.deviceId AND dc2.parentId = dc.channelId " + 90 + "SELECT " +
  91 + " dc.id,\n" +
  92 + " dc.channelId,\n" +
  93 + " dc.deviceId,\n" +
  94 + " dc.name,\n" +
  95 + " de.manufacturer,\n" +
  96 + " de.hostAddress,\n" +
  97 + " dc.subCount,\n" +
  98 + " pgc.platformId as platformId,\n" +
  99 + " pgc.catalogId as catalogId " +
  100 + " FROM device_channel dc " +
  101 + " LEFT JOIN device de ON dc.deviceId = de.deviceId " +
  102 + " LEFT JOIN platform_gb_channel pgc on pgc.deviceChannelId = dc.id " +
102 " WHERE 1=1 " + 103 " WHERE 1=1 " +
103 " <if test='query != null'> AND (dc.channelId LIKE '%${query}%' OR dc.name LIKE '%${query}%' OR dc.name LIKE '%${query}%')</if> " + 104 " <if test='query != null'> AND (dc.channelId LIKE '%${query}%' OR dc.name LIKE '%${query}%' OR dc.name LIKE '%${query}%')</if> " +
104 " <if test='online == true' > AND dc.status=1</if> " + 105 " <if test='online == true' > AND dc.status=1</if> " +
105 " <if test='online == false' > AND dc.status=0</if> " + 106 " <if test='online == false' > AND dc.status=0</if> " +
106 - " <if test='hasSubChannel!= null and hasSubChannel == true' > AND dc2.channelId is not null</if> " +  
107 - " <if test='hasSubChannel!= null and hasSubChannel == false' > AND dc2.channelId is null</if> " +  
108 - " <if test='catalogId == null ' > AND ((pgc.platformId IS NULL AND pgc.catalogId IS NULL) or (pgc.platformId != #{platformId}))</if> " +  
109 - " <if test='catalogId != null ' > AND pgc.platformId =#{platformId} AND pgc.catalogId = #{catalogId}</if> " + 107 + " <if test='hasSubChannel!= null and hasSubChannel == true' > AND dc.subCount > 0</if> " +
  108 + " <if test='hasSubChannel!= null and hasSubChannel == false' > AND dc.subCount == 0</if> " +
  109 + " <if test='catalogId == null ' > AND dc.id not in (select deviceChannelId from platform_gb_channel where platformId=#{platformId} ) </if> " +
  110 + " <if test='catalogId != null ' > AND pgc.platformId = #{platformId} and pgc.catalogId=#{catalogId} </if> " +
110 " ORDER BY dc.deviceId, dc.channelId ASC" + 111 " ORDER BY dc.deviceId, dc.channelId ASC" +
111 " </script>"}) 112 " </script>"})
112 List<ChannelReduce> queryChannelListInAll(String query, Boolean online, Boolean hasSubChannel, String platformId, String catalogId); 113 List<ChannelReduce> queryChannelListInAll(String query, Boolean online, Boolean hasSubChannel, String platformId, String catalogId);
@@ -196,8 +197,8 @@ public interface DeviceChannelMapper { @@ -196,8 +197,8 @@ public interface DeviceChannelMapper {
196 List<DeviceChannel> queryOnlineChannelsByDeviceId(String deviceId); 197 List<DeviceChannel> queryOnlineChannelsByDeviceId(String deviceId);
197 198
198 @Select(" SELECT\n" + 199 @Select(" SELECT\n" +
  200 + " id,\n" +
199 " channelId,\n" + 201 " channelId,\n" +
200 - " channelId as id,\n" +  
201 " deviceId,\n" + 202 " deviceId,\n" +
202 " parentId,\n" + 203 " parentId,\n" +
203 " status,\n" + 204 " status,\n" +
src/main/java/com/genersoft/iot/vmp/storager/dao/DeviceMapper.java
@@ -74,7 +74,7 @@ public interface DeviceMapper { @@ -74,7 +74,7 @@ public interface DeviceMapper {
74 "<if test=\"keepaliveTime != null\">, keepaliveTime='${keepaliveTime}'</if>" + 74 "<if test=\"keepaliveTime != null\">, keepaliveTime='${keepaliveTime}'</if>" +
75 "<if test=\"expires != null\">, expires=${expires}</if>" + 75 "<if test=\"expires != null\">, expires=${expires}</if>" +
76 "<if test=\"charset != null\">, charset='${charset}'</if>" + 76 "<if test=\"charset != null\">, charset='${charset}'</if>" +
77 - "<if test=\"subscribeCycleForCatalog != null\">, subscribeCycleForCatalog=#{subscribeCycleForCatalog}</if>" + 77 + "<if test=\"subscribeCycleForCatalog != null\">, subscribeCycleForCatalog=${subscribeCycleForCatalog}</if>" +
78 "WHERE deviceId='${deviceId}'"+ 78 "WHERE deviceId='${deviceId}'"+
79 " </script>"}) 79 " </script>"})
80 int update(Device device); 80 int update(Device device);
src/main/java/com/genersoft/iot/vmp/storager/dao/GbStreamMapper.java
@@ -19,6 +19,7 @@ public interface GbStreamMapper { @@ -19,6 +19,7 @@ public interface GbStreamMapper {
19 "('${app}', '${stream}', '${gbId}', '${name}', " + 19 "('${app}', '${stream}', '${gbId}', '${name}', " +
20 "'${longitude}', '${latitude}', '${streamType}', " + 20 "'${longitude}', '${latitude}', '${streamType}', " +
21 "'${mediaServerId}', ${status}, ${createStamp})") 21 "'${mediaServerId}', ${status}, ${createStamp})")
  22 + @Options(useGeneratedKeys = true, keyProperty = "gbStreamId", keyColumn = "gbStreamId")
22 int add(GbStream gbStream); 23 int add(GbStream gbStream);
23 24
24 @Update("UPDATE gb_stream " + 25 @Update("UPDATE gb_stream " +
src/main/java/com/genersoft/iot/vmp/storager/dao/PlatformChannelMapper.java
@@ -21,27 +21,31 @@ public interface PlatformChannelMapper { @@ -21,27 +21,31 @@ public interface PlatformChannelMapper {
21 * 查询列表里已经关联的 21 * 查询列表里已经关联的
22 */ 22 */
23 @Select("<script> "+ 23 @Select("<script> "+
24 - "SELECT deviceAndChannelId FROM platform_gb_channel WHERE platformId='${platformId}' AND deviceAndChannelId in" +  
25 - "<foreach collection='deviceAndChannelIds' open='(' item='id_' separator=',' close=')'> '${id_}'</foreach> ORDER BY deviceAndChannelId ASC" + 24 + "SELECT deviceChannelId FROM platform_gb_channel WHERE platformId='${platformId}' AND deviceChannelId in" +
  25 + "<foreach collection='channelReduces' open='(' item='item' separator=',' close=')'> '${item.id}'</foreach>" +
26 "</script>") 26 "</script>")
27 - List<String> findChannelRelatedPlatform(String platformId, List<String> deviceAndChannelIds); 27 + List<Integer> findChannelRelatedPlatform(String platformId, List<ChannelReduce> channelReduces);
28 28
29 @Insert("<script> "+ 29 @Insert("<script> "+
30 - "INSERT INTO platform_gb_channel (channelId, deviceId, platformId, deviceAndChannelId, catalogId) VALUES" + 30 + "INSERT INTO platform_gb_channel (platformId, deviceChannelId, catalogId) VALUES" +
31 "<foreach collection='channelReducesToAdd' item='item' separator=','>" + 31 "<foreach collection='channelReducesToAdd' item='item' separator=','>" +
32 - " ('${item.channelId}','${item.deviceId}', '${platformId}', '${item.deviceId}_${item.channelId}' , '${item.catalogId}' )" + 32 + " ('${platformId}', '${item.id}' , '${item.catalogId}' )" +
33 "</foreach>" + 33 "</foreach>" +
34 "</script>") 34 "</script>")
35 int addChannels(String platformId, List<ChannelReduce> channelReducesToAdd); 35 int addChannels(String platformId, List<ChannelReduce> channelReducesToAdd);
36 36
37 @Delete("<script> "+ 37 @Delete("<script> "+
38 - "DELETE FROM platform_gb_channel WHERE platformId='${platformId}' AND deviceAndChannelId in" +  
39 - "<foreach collection='channelReducesToDel' item='item' open='(' separator=',' close=')' > '${item.deviceId}_${item.channelId}'</foreach>" + 38 + "DELETE FROM platform_gb_channel WHERE platformId='${platformId}' AND deviceChannelId in" +
  39 + "<foreach collection='channelReducesToDel' item='item' open='(' separator=',' close=')' > '${item.id}'</foreach>" +
40 "</script>") 40 "</script>")
41 int delChannelForGB(String platformId, List<ChannelReduce> channelReducesToDel); 41 int delChannelForGB(String platformId, List<ChannelReduce> channelReducesToDel);
42 42
43 @Delete("<script> "+ 43 @Delete("<script> "+
44 - "DELETE FROM platform_gb_channel WHERE deviceId='${deviceId}' " + 44 + "DELETE FROM platform_gb_channel WHERE deviceChannelId in " +
  45 + "( select temp.deviceChannelId from " +
  46 + "(select pgc.deviceChannelId from platform_gb_channel pgc " +
  47 + "left join device_channel dc on dc.id = pgc.deviceChannelId where dc.deviceId =#{deviceId} " +
  48 + ") temp)" +
45 "</script>") 49 "</script>")
46 int delChannelForDeviceId(String deviceId); 50 int delChannelForDeviceId(String deviceId);
47 51
@@ -50,16 +54,19 @@ public interface PlatformChannelMapper { @@ -50,16 +54,19 @@ public interface PlatformChannelMapper {
50 "</script>") 54 "</script>")
51 int cleanChannelForGB(String platformId); 55 int cleanChannelForGB(String platformId);
52 56
53 - @Select("SELECT * FROM device_channel WHERE deviceId = (SELECT deviceId FROM platform_gb_channel WHERE " +  
54 - "platformId='${platformId}' AND channelId='${channelId}' ) AND channelId='${channelId}'") 57 + @Select("SELECT dc.* FROM platform_gb_channel pgc left join device_channel dc on dc.id = pgc.deviceChannelId WHERE dc.channelId='${channelId}' and pgc.platformId='${platformId}'")
55 DeviceChannel queryChannelInParentPlatform(String platformId, String channelId); 58 DeviceChannel queryChannelInParentPlatform(String platformId, String channelId);
56 59
57 - @Select("select dc.channelId as id, dc.name as name, pgc.platformId as platformId, pgc.catalogId as parentId, 0 as childrenCount, 1 as type " +  
58 - "from device_channel dc left join platform_gb_channel pgc on dc.deviceId = pgc.deviceId and dc.channelId = pgc.channelId " +  
59 - "where pgc.platformId=#{platformId} and pgc.catalogId=#{catalogId}") 60 + @Select(" select dc.channelId as id, dc.name as name, pgc.platformId as platformId, pgc.catalogId as parentId, 0 as childrenCount, 1 as type " +
  61 + " from device_channel dc left join platform_gb_channel pgc on dc.id = pgc.deviceChannelId " +
  62 + " where pgc.platformId=#{platformId} and pgc.catalogId=#{catalogId}")
60 List<PlatformCatalog> queryChannelInParentPlatformAndCatalog(String platformId, String catalogId); 63 List<PlatformCatalog> queryChannelInParentPlatformAndCatalog(String platformId, String catalogId);
61 64
62 - @Select("SELECT * FROM device WHERE deviceId = (SELECT deviceId FROM platform_gb_channel WHERE platformId='${platformId}' AND channelId='${channelId}')") 65 + @Select("select d.*\n" +
  66 + "from platform_gb_channel pgc\n" +
  67 + " left join device_channel dc on dc.id = pgc.deviceChannelId\n" +
  68 + " left join device d on dc.deviceId = d.deviceId\n" +
  69 + "where dc.channelId = #{channelId} and pgc.platformId=#{platformId}")
63 Device queryVideoDeviceByPlatformIdAndChannelId(String platformId, String channelId); 70 Device queryVideoDeviceByPlatformIdAndChannelId(String platformId, String channelId);
64 71
65 @Delete("<script> "+ 72 @Delete("<script> "+
@@ -79,8 +86,10 @@ public interface PlatformChannelMapper { @@ -79,8 +86,10 @@ public interface PlatformChannelMapper {
79 "parent_platform pp " + 86 "parent_platform pp " +
80 "left join platform_gb_channel pgc on " + 87 "left join platform_gb_channel pgc on " +
81 "pp.serverGBId = pgc.platformId " + 88 "pp.serverGBId = pgc.platformId " +
  89 + "left join device_channel dc on " +
  90 + "dc.id = pgc.deviceChannelId " +
82 "WHERE " + 91 "WHERE " +
83 - "pgc.channelId = #{channelId} and pp.status = true " + 92 + "dc.channelId = #{channelId} and pp.status = true " +
84 "AND pp.serverGBId IN" + 93 "AND pp.serverGBId IN" +
85 "<foreach collection='platforms' item='item' open='(' separator=',' close=')' > #{item}</foreach>" + 94 "<foreach collection='platforms' item='item' open='(' separator=',' close=')' > #{item}</foreach>" +
86 "</script> ") 95 "</script> ")
src/main/java/com/genersoft/iot/vmp/storager/dao/StreamProxyMapper.java
@@ -19,6 +19,7 @@ public interface StreamProxyMapper { @@ -19,6 +19,7 @@ public interface StreamProxyMapper {
19 19
20 @Update("UPDATE stream_proxy " + 20 @Update("UPDATE stream_proxy " +
21 "SET type=#{type}, " + 21 "SET type=#{type}, " +
  22 + "name=#{name}," +
22 "app=#{app}," + 23 "app=#{app}," +
23 "name=#{name}," + 24 "name=#{name}," +
24 "stream=#{stream}," + 25 "stream=#{stream}," +
src/main/java/com/genersoft/iot/vmp/storager/dao/StreamPushMapper.java
@@ -3,7 +3,7 @@ package com.genersoft.iot.vmp.storager.dao; @@ -3,7 +3,7 @@ package com.genersoft.iot.vmp.storager.dao;
3 import com.genersoft.iot.vmp.gb28181.bean.GbStream; 3 import com.genersoft.iot.vmp.gb28181.bean.GbStream;
4 import com.genersoft.iot.vmp.media.zlm.dto.StreamPushItem; 4 import com.genersoft.iot.vmp.media.zlm.dto.StreamPushItem;
5 import org.apache.ibatis.annotations.*; 5 import org.apache.ibatis.annotations.*;
6 -import org.omg.PortableInterceptor.INACTIVE; 6 +// import org.omg.PortableInterceptor.INACTIVE;
7 import org.springframework.stereotype.Repository; 7 import org.springframework.stereotype.Repository;
8 8
9 import java.util.Collection; 9 import java.util.Collection;
src/main/java/com/genersoft/iot/vmp/storager/impl/RedisCatchStorageImpl.java
@@ -10,6 +10,7 @@ import com.genersoft.iot.vmp.media.zlm.dto.MediaItem; @@ -10,6 +10,7 @@ import com.genersoft.iot.vmp.media.zlm.dto.MediaItem;
10 import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; 10 import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
11 import com.genersoft.iot.vmp.media.zlm.dto.StreamPushItem; 11 import com.genersoft.iot.vmp.media.zlm.dto.StreamPushItem;
12 import com.genersoft.iot.vmp.service.bean.GPSMsgInfo; 12 import com.genersoft.iot.vmp.service.bean.GPSMsgInfo;
  13 +import com.genersoft.iot.vmp.service.bean.SSRCInfo;
13 import com.genersoft.iot.vmp.service.bean.ThirdPartyGB; 14 import com.genersoft.iot.vmp.service.bean.ThirdPartyGB;
14 import com.genersoft.iot.vmp.storager.IRedisCatchStorage; 15 import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
15 import com.genersoft.iot.vmp.storager.dao.DeviceChannelMapper; 16 import com.genersoft.iot.vmp.storager.dao.DeviceChannelMapper;
@@ -91,7 +92,8 @@ public class RedisCatchStorageImpl implements IRedisCatchStorage { @@ -91,7 +92,8 @@ public class RedisCatchStorageImpl implements IRedisCatchStorage {
91 */ 92 */
92 @Override 93 @Override
93 public boolean startPlay(StreamInfo stream) { 94 public boolean startPlay(StreamInfo stream) {
94 - return redis.set(String.format("%S_%S_%s_%s_%s", VideoManagerConstants.PLAYER_PREFIX, userSetup.getServerId(), stream.getStreamId(),stream.getDeviceID(), stream.getChannelId()), 95 + return redis.set(String.format("%S_%S_%s_%s_%s", VideoManagerConstants.PLAYER_PREFIX, userSetup.getServerId(),
  96 + stream.getStream(), stream.getDeviceID(), stream.getChannelId()),
95 stream); 97 stream);
96 } 98 }
97 99
@@ -105,7 +107,7 @@ public class RedisCatchStorageImpl implements IRedisCatchStorage { @@ -105,7 +107,7 @@ public class RedisCatchStorageImpl implements IRedisCatchStorage {
105 if (streamInfo == null) return false; 107 if (streamInfo == null) return false;
106 return redis.del(String.format("%S_%s_%s_%s_%s", VideoManagerConstants.PLAYER_PREFIX, 108 return redis.del(String.format("%S_%s_%s_%s_%s", VideoManagerConstants.PLAYER_PREFIX,
107 userSetup.getServerId(), 109 userSetup.getServerId(),
108 - streamInfo.getStreamId(), 110 + streamInfo.getStream(),
109 streamInfo.getDeviceID(), 111 streamInfo.getDeviceID(),
110 streamInfo.getChannelId())); 112 streamInfo.getChannelId()));
111 } 113 }
@@ -119,7 +121,7 @@ public class RedisCatchStorageImpl implements IRedisCatchStorage { @@ -119,7 +121,7 @@ public class RedisCatchStorageImpl implements IRedisCatchStorage {
119 return (StreamInfo)redis.get(String.format("%S_%s_%s_%s_%s", 121 return (StreamInfo)redis.get(String.format("%S_%s_%s_%s_%s",
120 VideoManagerConstants.PLAYER_PREFIX, 122 VideoManagerConstants.PLAYER_PREFIX,
121 userSetup.getServerId(), 123 userSetup.getServerId(),
122 - streamInfo.getStreamId(), 124 + streamInfo.getStream(),
123 streamInfo.getDeviceID(), 125 streamInfo.getDeviceID(),
124 streamInfo.getChannelId())); 126 streamInfo.getChannelId()));
125 } 127 }
@@ -165,14 +167,14 @@ public class RedisCatchStorageImpl implements IRedisCatchStorage { @@ -165,14 +167,14 @@ public class RedisCatchStorageImpl implements IRedisCatchStorage {
165 167
166 @Override 168 @Override
167 public boolean startPlayback(StreamInfo stream) { 169 public boolean startPlayback(StreamInfo stream) {
168 - return redis.set(String.format("%S_%s_%s_%s_%s", VideoManagerConstants.PLAY_BLACK_PREFIX, userSetup.getServerId(),stream.getStreamId(),  
169 - stream.getDeviceID(), stream.getChannelId()), stream); 170 + return redis.set(String.format("%S_%s_%s_%s_%s", VideoManagerConstants.PLAY_BLACK_PREFIX,
  171 + userSetup.getServerId(), stream.getStream(), stream.getDeviceID(), stream.getChannelId()), stream);
170 } 172 }
171 173
172 @Override 174 @Override
173 public boolean startDownload(StreamInfo streamInfo) { 175 public boolean startDownload(StreamInfo streamInfo) {
174 - return redis.set(String.format("%S_%s_%s_%s_%s", VideoManagerConstants.DOWNLOAD_PREFIX, userSetup.getServerId(),streamInfo.getStreamId(),  
175 - streamInfo.getDeviceID(), streamInfo.getChannelId()), streamInfo); 176 + return redis.set(String.format("%S_%s_%s_%s_%s", VideoManagerConstants.DOWNLOAD_PREFIX, userSetup.getServerId(),
  177 + streamInfo.getStream(), streamInfo.getDeviceID(), streamInfo.getChannelId()), streamInfo);
176 } 178 }
177 179
178 @Override 180 @Override
@@ -186,7 +188,7 @@ public class RedisCatchStorageImpl implements IRedisCatchStorage { @@ -186,7 +188,7 @@ public class RedisCatchStorageImpl implements IRedisCatchStorage {
186 } 188 }
187 return redis.del(String.format("%S_%s_%s_%s_%s", VideoManagerConstants.PLAY_BLACK_PREFIX, 189 return redis.del(String.format("%S_%s_%s_%s_%s", VideoManagerConstants.PLAY_BLACK_PREFIX,
188 userSetup.getServerId(), 190 userSetup.getServerId(),
189 - streamInfo.getStreamId(), 191 + streamInfo.getStream(),
190 streamInfo.getDeviceID(), 192 streamInfo.getDeviceID(),
191 streamInfo.getChannelId())); 193 streamInfo.getChannelId()));
192 } 194 }
src/main/java/com/genersoft/iot/vmp/storager/impl/VideoManagerStoragerImpl.java
1 package com.genersoft.iot.vmp.storager.impl; 1 package com.genersoft.iot.vmp.storager.impl;
2 2
  3 +import com.genersoft.iot.vmp.common.StreamInfo;
3 import com.genersoft.iot.vmp.conf.SipConfig; 4 import com.genersoft.iot.vmp.conf.SipConfig;
4 import com.genersoft.iot.vmp.gb28181.bean.*; 5 import com.genersoft.iot.vmp.gb28181.bean.*;
5 import com.genersoft.iot.vmp.gb28181.event.EventPublisher; 6 import com.genersoft.iot.vmp.gb28181.event.EventPublisher;
@@ -156,7 +157,10 @@ public class VideoManagerStoragerImpl implements IVideoManagerStorager { @@ -156,7 +157,10 @@ public class VideoManagerStoragerImpl implements IVideoManagerStorager {
156 public synchronized void updateChannel(String deviceId, DeviceChannel channel) { 157 public synchronized void updateChannel(String deviceId, DeviceChannel channel) {
157 String channelId = channel.getChannelId(); 158 String channelId = channel.getChannelId();
158 channel.setDeviceId(deviceId); 159 channel.setDeviceId(deviceId);
159 - channel.setStreamId(streamSession.getStreamId(deviceId, channel.getChannelId())); 160 + StreamInfo streamInfo = redisCatchStorage.queryPlayByDevice(deviceId, channelId);
  161 + if (streamInfo != null) {
  162 + channel.setStreamId(streamInfo.getStream());
  163 + }
160 String now = this.format.format(System.currentTimeMillis()); 164 String now = this.format.format(System.currentTimeMillis());
161 channel.setUpdateTime(now); 165 channel.setUpdateTime(now);
162 DeviceChannel deviceChannel = deviceChannelMapper.queryChannel(deviceId, channelId); 166 DeviceChannel deviceChannel = deviceChannelMapper.queryChannel(deviceId, channelId);
@@ -178,7 +182,10 @@ public class VideoManagerStoragerImpl implements IVideoManagerStorager { @@ -178,7 +182,10 @@ public class VideoManagerStoragerImpl implements IVideoManagerStorager {
178 if (channelList.size() == 0) { 182 if (channelList.size() == 0) {
179 for (DeviceChannel channel : channels) { 183 for (DeviceChannel channel : channels) {
180 channel.setDeviceId(deviceId); 184 channel.setDeviceId(deviceId);
181 - channel.setStreamId(streamSession.getStreamId(deviceId, channel.getChannelId())); 185 + StreamInfo streamInfo = redisCatchStorage.queryPlayByDevice(deviceId, channel.getChannelId());
  186 + if (streamInfo != null) {
  187 + channel.setStreamId(streamInfo.getStream());
  188 + }
182 String now = this.format.format(System.currentTimeMillis()); 189 String now = this.format.format(System.currentTimeMillis());
183 channel.setUpdateTime(now); 190 channel.setUpdateTime(now);
184 channel.setCreateTime(now); 191 channel.setCreateTime(now);
@@ -189,9 +196,11 @@ public class VideoManagerStoragerImpl implements IVideoManagerStorager { @@ -189,9 +196,11 @@ public class VideoManagerStoragerImpl implements IVideoManagerStorager {
189 channelsInStore.put(deviceChannel.getChannelId(), deviceChannel); 196 channelsInStore.put(deviceChannel.getChannelId(), deviceChannel);
190 } 197 }
191 for (DeviceChannel channel : channels) { 198 for (DeviceChannel channel : channels) {
192 - String channelId = channel.getChannelId();  
193 channel.setDeviceId(deviceId); 199 channel.setDeviceId(deviceId);
194 - channel.setStreamId(streamSession.getStreamId(deviceId, channel.getChannelId())); 200 + StreamInfo streamInfo = redisCatchStorage.queryPlayByDevice(deviceId, channel.getChannelId());
  201 + if (streamInfo != null) {
  202 + channel.setStreamId(streamInfo.getStream());
  203 + }
195 String now = this.format.format(System.currentTimeMillis()); 204 String now = this.format.format(System.currentTimeMillis());
196 channel.setUpdateTime(now); 205 channel.setUpdateTime(now);
197 if (channelsInStore.get(channel.getChannelId()) != null) { 206 if (channelsInStore.get(channel.getChannelId()) != null) {
@@ -607,19 +616,19 @@ public class VideoManagerStoragerImpl implements IVideoManagerStorager { @@ -607,19 +616,19 @@ public class VideoManagerStoragerImpl implements IVideoManagerStorager {
607 @Override 616 @Override
608 public int updateChannelForGB(String platformId, List<ChannelReduce> channelReduces, String catalogId) { 617 public int updateChannelForGB(String platformId, List<ChannelReduce> channelReduces, String catalogId) {
609 618
610 - Map<String, ChannelReduce> deviceAndChannels = new HashMap<>(); 619 + Map<Integer, ChannelReduce> deviceAndChannels = new HashMap<>();
611 for (ChannelReduce channelReduce : channelReduces) { 620 for (ChannelReduce channelReduce : channelReduces) {
612 channelReduce.setCatalogId(catalogId); 621 channelReduce.setCatalogId(catalogId);
613 - deviceAndChannels.put(channelReduce.getDeviceId() + "_" + channelReduce.getChannelId(), channelReduce); 622 + deviceAndChannels.put(channelReduce.getId(), channelReduce);
614 } 623 }
615 - List<String> deviceAndChannelList = new ArrayList<>(deviceAndChannels.keySet()); 624 + List<Integer> deviceAndChannelList = new ArrayList<>(deviceAndChannels.keySet());
616 // 查询当前已经存在的 625 // 查询当前已经存在的
617 - List<String> relatedPlatformchannels = platformChannelMapper.findChannelRelatedPlatform(platformId, deviceAndChannelList);  
618 - if (relatedPlatformchannels != null) {  
619 - deviceAndChannelList.removeAll(relatedPlatformchannels); 626 + List<Integer> channelIds = platformChannelMapper.findChannelRelatedPlatform(platformId, channelReduces);
  627 + if (deviceAndChannelList != null) {
  628 + deviceAndChannelList.removeAll(channelIds);
620 } 629 }
621 - for (String relatedPlatformchannel : relatedPlatformchannels) {  
622 - deviceAndChannels.remove(relatedPlatformchannel); 630 + for (Integer channelId : channelIds) {
  631 + deviceAndChannels.remove(channelId);
623 } 632 }
624 List<ChannelReduce> channelReducesToAdd = new ArrayList<>(deviceAndChannels.values()); 633 List<ChannelReduce> channelReducesToAdd = new ArrayList<>(deviceAndChannels.values());
625 // 对剩下的数据进行存储 634 // 对剩下的数据进行存储
src/main/java/com/genersoft/iot/vmp/utils/node/BaseNode.java
@@ -18,7 +18,7 @@ public class BaseNode&lt;T&gt; implements INode&lt;T&gt; { @@ -18,7 +18,7 @@ public class BaseNode&lt;T&gt; implements INode&lt;T&gt; {
18 /** 18 /**
19 * 主键ID 19 * 主键ID
20 */ 20 */
21 - protected String id; 21 + protected int id;
22 22
23 /** 23 /**
24 * 父节点ID 24 * 父节点ID
src/main/java/com/genersoft/iot/vmp/utils/node/ForestNode.java
@@ -19,7 +19,7 @@ public class ForestNode extends BaseNode&lt;ForestNode&gt; { @@ -19,7 +19,7 @@ public class ForestNode extends BaseNode&lt;ForestNode&gt; {
19 */ 19 */
20 private Object content; 20 private Object content;
21 21
22 - public ForestNode(String id, String parentId, Object content) { 22 + public ForestNode(int id, String parentId, Object content) {
23 this.id = id; 23 this.id = id;
24 this.parentId = parentId; 24 this.parentId = parentId;
25 this.content = content; 25 this.content = content;
src/main/java/com/genersoft/iot/vmp/utils/node/ForestNodeManager.java
@@ -17,12 +17,12 @@ public class ForestNodeManager&lt;T extends INode&lt;T&gt;&gt; { @@ -17,12 +17,12 @@ public class ForestNodeManager&lt;T extends INode&lt;T&gt;&gt; {
17 /** 17 /**
18 * 森林的所有节点 18 * 森林的所有节点
19 */ 19 */
20 - private final ImmutableMap<String, T> nodeMap; 20 + private final ImmutableMap<Integer, T> nodeMap;
21 21
22 /** 22 /**
23 * 森林的父节点ID 23 * 森林的父节点ID
24 */ 24 */
25 - private final Map<String, Object> parentIdMap = Maps.newHashMap(); 25 + private final Map<Integer, Object> parentIdMap = Maps.newHashMap();
26 26
27 public ForestNodeManager(List<T> nodes) { 27 public ForestNodeManager(List<T> nodes) {
28 nodeMap = Maps.uniqueIndex(nodes, INode::getId); 28 nodeMap = Maps.uniqueIndex(nodes, INode::getId);
@@ -46,7 +46,7 @@ public class ForestNodeManager&lt;T extends INode&lt;T&gt;&gt; { @@ -46,7 +46,7 @@ public class ForestNodeManager&lt;T extends INode&lt;T&gt;&gt; {
46 * 46 *
47 * @param parentId 父节点ID 47 * @param parentId 父节点ID
48 */ 48 */
49 - public void addParentId(String parentId) { 49 + public void addParentId(int parentId) {
50 parentIdMap.put(parentId, ""); 50 parentIdMap.put(parentId, "");
51 } 51 }
52 52
src/main/java/com/genersoft/iot/vmp/utils/node/INode.java
@@ -14,7 +14,7 @@ public interface INode&lt;T&gt; extends Serializable { @@ -14,7 +14,7 @@ public interface INode&lt;T&gt; extends Serializable {
14 * 14 *
15 * @return String 15 * @return String
16 */ 16 */
17 - String getId(); 17 + int getId();
18 18
19 /** 19 /**
20 * 父主键 20 * 父主键
src/main/java/com/genersoft/iot/vmp/vmanager/bean/DeviceChannelTree.java
@@ -19,7 +19,7 @@ public class DeviceChannelTree extends DeviceChannel implements INode&lt;DeviceChan @@ -19,7 +19,7 @@ public class DeviceChannelTree extends DeviceChannel implements INode&lt;DeviceChan
19 /** 19 /**
20 * 主键ID 20 * 主键ID
21 */ 21 */
22 - private String id; 22 + private int id;
23 23
24 /** 24 /**
25 * 父节点ID 25 * 父节点ID
src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/device/DeviceQuery.java
@@ -204,10 +204,7 @@ public class DeviceQuery { @@ -204,10 +204,7 @@ public class DeviceQuery {
204 if (logger.isDebugEnabled()) { 204 if (logger.isDebugEnabled()) {
205 logger.debug("设备信息删除API调用,deviceId:" + deviceId); 205 logger.debug("设备信息删除API调用,deviceId:" + deviceId);
206 } 206 }
207 -  
208 - if (offLineDetector.isOnline(deviceId)) {  
209 - return new ResponseEntity<String>("不允许删除在线设备!", HttpStatus.NOT_ACCEPTABLE);  
210 - } 207 +
211 // 清除redis记录 208 // 清除redis记录
212 boolean isSuccess = storager.delete(deviceId); 209 boolean isSuccess = storager.delete(deviceId);
213 if (isSuccess) { 210 if (isSuccess) {
@@ -319,20 +316,20 @@ public class DeviceQuery { @@ -319,20 +316,20 @@ public class DeviceQuery {
319 if (!StringUtils.isEmpty(device.getCharset())) deviceInStore.setCharset(device.getCharset()); 316 if (!StringUtils.isEmpty(device.getCharset())) deviceInStore.setCharset(device.getCharset());
320 if (!StringUtils.isEmpty(device.getMediaServerId())) deviceInStore.setMediaServerId(device.getMediaServerId()); 317 if (!StringUtils.isEmpty(device.getMediaServerId())) deviceInStore.setMediaServerId(device.getMediaServerId());
321 318
322 - if ((deviceInStore.getSubscribeCycleForCatalog() <=0 && device.getSubscribeCycleForCatalog() > 0)  
323 - || deviceInStore.getSubscribeCycleForCatalog() != device.getSubscribeCycleForCatalog()) {  
324 - deviceInStore.setSubscribeCycleForCatalog(device.getSubscribeCycleForCatalog());  
325 - // 开启订阅  
326 - deviceService.addCatalogSubscribe(deviceInStore);  
327 - }  
328 - if (deviceInStore.getSubscribeCycleForCatalog() > 0 && device.getSubscribeCycleForCatalog() <= 0) {  
329 - deviceInStore.setSubscribeCycleForCatalog(device.getSubscribeCycleForCatalog());  
330 - // 取消订阅  
331 - deviceService.removeCatalogSubscribe(deviceInStore); 319 + if (device.getSubscribeCycleForCatalog() > 0) {
  320 + if (deviceInStore.getSubscribeCycleForCatalog() == 0 || deviceInStore.getSubscribeCycleForCatalog() != device.getSubscribeCycleForCatalog()) {
  321 + // 开启订阅
  322 + deviceService.addCatalogSubscribe(deviceInStore);
  323 + }
  324 + }else if (device.getSubscribeCycleForCatalog() == 0) {
  325 + if (deviceInStore.getSubscribeCycleForCatalog() != 0) {
  326 + // 取消订阅
  327 + deviceService.removeCatalogSubscribe(deviceInStore);
  328 + }
332 } 329 }
333 330
334 - storager.updateDevice(deviceInStore);  
335 - cmder.deviceInfoQuery(deviceInStore); 331 + storager.updateDevice(device);
  332 + cmder.deviceInfoQuery(device);
336 } 333 }
337 WVPResult<String> result = new WVPResult<>(); 334 WVPResult<String> result = new WVPResult<>();
338 result.setCode(0); 335 result.setCode(0);
src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/media/MediaController.java
1 package com.genersoft.iot.vmp.vmanager.gb28181.media; 1 package com.genersoft.iot.vmp.vmanager.gb28181.media;
2 2
3 import com.genersoft.iot.vmp.common.StreamInfo; 3 import com.genersoft.iot.vmp.common.StreamInfo;
  4 +import com.genersoft.iot.vmp.service.IMediaServerService;
4 import com.genersoft.iot.vmp.service.IStreamPushService; 5 import com.genersoft.iot.vmp.service.IStreamPushService;
5 import com.genersoft.iot.vmp.service.IMediaService; 6 import com.genersoft.iot.vmp.service.IMediaService;
6 import com.genersoft.iot.vmp.storager.IVideoManagerStorager; 7 import com.genersoft.iot.vmp.storager.IVideoManagerStorager;
@@ -9,6 +10,7 @@ import io.swagger.annotations.Api; @@ -9,6 +10,7 @@ import io.swagger.annotations.Api;
9 import io.swagger.annotations.ApiImplicitParam; 10 import io.swagger.annotations.ApiImplicitParam;
10 import io.swagger.annotations.ApiImplicitParams; 11 import io.swagger.annotations.ApiImplicitParams;
11 import io.swagger.annotations.ApiOperation; 12 import io.swagger.annotations.ApiOperation;
  13 +import org.apache.commons.lang3.StringUtils;
12 import org.slf4j.Logger; 14 import org.slf4j.Logger;
13 import org.slf4j.LoggerFactory; 15 import org.slf4j.LoggerFactory;
14 import org.springframework.beans.factory.annotation.Autowired; 16 import org.springframework.beans.factory.annotation.Autowired;
@@ -33,6 +35,9 @@ public class MediaController { @@ -33,6 +35,9 @@ public class MediaController {
33 @Autowired 35 @Autowired
34 private IMediaService mediaService; 36 private IMediaService mediaService;
35 37
  38 + @Autowired
  39 + private IMediaServerService mediaServerService;
  40 +
36 41
37 /** 42 /**
38 * 根据应用名和流id获取播放地址 43 * 根据应用名和流id获取播放地址
src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/platform/PlatformController.java
@@ -149,8 +149,16 @@ public class PlatformController { @@ -149,8 +149,16 @@ public class PlatformController {
149 if (updateResult) { 149 if (updateResult) {
150 // 保存时启用就发送注册 150 // 保存时启用就发送注册
151 if (parentPlatform.isEnable()) { 151 if (parentPlatform.isEnable()) {
152 - // 只要保存就发送注册  
153 - commanderForPlatform.register(parentPlatform, null, null); 152 + if (parentPlatformOld.isStatus()) {
  153 + commanderForPlatform.unregister(parentPlatformOld, null, eventResult -> {
  154 + // 只要保存就发送注册
  155 + commanderForPlatform.register(parentPlatform, null, null);
  156 + });
  157 + }else {
  158 + // 只要保存就发送注册
  159 + commanderForPlatform.register(parentPlatform, null, null);
  160 + }
  161 +
154 } else if (parentPlatformOld != null && parentPlatformOld.isEnable() && !parentPlatform.isEnable()){ // 关闭启用时注销 162 } else if (parentPlatformOld != null && parentPlatformOld.isEnable() && !parentPlatform.isEnable()){ // 关闭启用时注销
155 commanderForPlatform.unregister(parentPlatform, null, null); 163 commanderForPlatform.unregister(parentPlatform, null, null);
156 } 164 }
@@ -203,10 +211,21 @@ public class PlatformController { @@ -203,10 +211,21 @@ public class PlatformController {
203 if (updateResult) { 211 if (updateResult) {
204 // 保存时启用就发送注册 212 // 保存时启用就发送注册
205 if (parentPlatform.isEnable()) { 213 if (parentPlatform.isEnable()) {
206 - // 只要保存就发送注册  
207 - commanderForPlatform.register(parentPlatform, null, null); 214 + if (parentPlatformOld.isStatus()) {
  215 + commanderForPlatform.unregister(parentPlatformOld, null, null);
  216 + try {
  217 + Thread.sleep(500);
  218 + } catch (InterruptedException e) {
  219 + e.printStackTrace();
  220 + }
  221 + // 只要保存就发送注册
  222 + commanderForPlatform.register(parentPlatform, null, null);
  223 + }else {
  224 + // 只要保存就发送注册
  225 + commanderForPlatform.register(parentPlatform, null, null);
  226 + }
208 } else if (parentPlatformOld != null && parentPlatformOld.isEnable() && !parentPlatform.isEnable()){ // 关闭启用时注销 227 } else if (parentPlatformOld != null && parentPlatformOld.isEnable() && !parentPlatform.isEnable()){ // 关闭启用时注销
209 - commanderForPlatform.unregister(parentPlatform, null, null); 228 + commanderForPlatform.unregister(parentPlatformOld, null, null);
210 } 229 }
211 wvpResult.setCode(0); 230 wvpResult.setCode(0);
212 wvpResult.setMsg("success"); 231 wvpResult.setMsg("success");
src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/platform/bean/ChannelReduce.java
1 package com.genersoft.iot.vmp.vmanager.gb28181.platform.bean; 1 package com.genersoft.iot.vmp.vmanager.gb28181.platform.bean;
2 2
  3 +import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel;
  4 +
3 /** 5 /**
4 * 精简的channel信息展示,主要是选择通道的时候展示列表使用 6 * 精简的channel信息展示,主要是选择通道的时候展示列表使用
5 */ 7 */
6 public class ChannelReduce { 8 public class ChannelReduce {
7 9
8 /** 10 /**
  11 + * deviceChannel的数据库自增ID
  12 + */
  13 + private int id;
  14 +
  15 + /**
9 * 通道id 16 * 通道id
10 */ 17 */
11 private String channelId; 18 private String channelId;
@@ -45,6 +52,13 @@ public class ChannelReduce { @@ -45,6 +52,13 @@ public class ChannelReduce {
45 */ 52 */
46 private String catalogId; 53 private String catalogId;
47 54
  55 + public int getId() {
  56 + return id;
  57 + }
  58 +
  59 + public void setId(int id) {
  60 + this.id = id;
  61 + }
48 62
49 public String getChannelId() { 63 public String getChannelId() {
50 return channelId; 64 return channelId;
src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/play/PlayController.java
@@ -110,26 +110,26 @@ public class PlayController { @@ -110,26 +110,26 @@ public class PlayController {
110 String key = DeferredResultHolder.CALLBACK_CMD_STOP + deviceId + channelId; 110 String key = DeferredResultHolder.CALLBACK_CMD_STOP + deviceId + channelId;
111 resultHolder.put(key, uuid, result); 111 resultHolder.put(key, uuid, result);
112 Device device = storager.queryVideoDevice(deviceId); 112 Device device = storager.queryVideoDevice(deviceId);
113 - cmder.streamByeCmd(deviceId, channelId, (event) -> {  
114 - StreamInfo streamInfo = redisCatchStorage.queryPlayByDevice(deviceId, channelId);  
115 - if (streamInfo == null) {  
116 - RequestMessage msg = new RequestMessage();  
117 - msg.setId(uuid);  
118 - msg.setKey(key);  
119 - msg.setData("点播未找到");  
120 - resultHolder.invokeAllResult(msg);  
121 - storager.stopPlay(deviceId, channelId);  
122 - }else {  
123 - redisCatchStorage.stopPlay(streamInfo);  
124 - storager.stopPlay(streamInfo.getDeviceID(), streamInfo.getChannelId());  
125 - RequestMessage msg = new RequestMessage();  
126 - msg.setId(uuid);  
127 - msg.setKey(key);  
128 - //Response response = event.getResponse();  
129 - msg.setData(String.format("success"));  
130 - resultHolder.invokeAllResult(msg);  
131 - }  
132 - mediaServerService.closeRTPServer(device, channelId); 113 + StreamInfo streamInfo = redisCatchStorage.queryPlayByDevice(deviceId, channelId);
  114 + if (streamInfo == null) {
  115 + RequestMessage msg = new RequestMessage();
  116 + msg.setId(uuid);
  117 + msg.setKey(key);
  118 + msg.setData("点播未找到");
  119 + resultHolder.invokeAllResult(msg);
  120 + storager.stopPlay(deviceId, channelId);
  121 + return result;
  122 + }
  123 + cmder.streamByeCmd(deviceId, channelId, streamInfo.getStream(), (event) -> {
  124 + redisCatchStorage.stopPlay(streamInfo);
  125 + storager.stopPlay(streamInfo.getDeviceID(), streamInfo.getChannelId());
  126 + RequestMessage msg = new RequestMessage();
  127 + msg.setId(uuid);
  128 + msg.setKey(key);
  129 + //Response response = event.getResponse();
  130 + msg.setData(String.format("success"));
  131 + resultHolder.invokeAllResult(msg);
  132 + mediaServerService.closeRTPServer(device, channelId, streamInfo.getStream());
133 }); 133 });
134 134
135 if (deviceId != null || channelId != null) { 135 if (deviceId != null || channelId != null) {
@@ -329,7 +329,7 @@ public class PlayController { @@ -329,7 +329,7 @@ public class PlayController {
329 jsonObject.put("deviceId", transaction.getDeviceId()); 329 jsonObject.put("deviceId", transaction.getDeviceId());
330 jsonObject.put("channelId", transaction.getChannelId()); 330 jsonObject.put("channelId", transaction.getChannelId());
331 jsonObject.put("ssrc", transaction.getSsrc()); 331 jsonObject.put("ssrc", transaction.getSsrc());
332 - jsonObject.put("streamId", transaction.getStreamId()); 332 + jsonObject.put("streamId", transaction.getStream());
333 objects.add(jsonObject); 333 objects.add(jsonObject);
334 } 334 }
335 335
src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/playback/DownloadController.java
@@ -96,7 +96,7 @@ public class DownloadController { @@ -96,7 +96,7 @@ public class DownloadController {
96 StreamInfo streamInfo = redisCatchStorage.queryPlaybackByDevice(deviceId, channelId); 96 StreamInfo streamInfo = redisCatchStorage.queryPlaybackByDevice(deviceId, channelId);
97 if (streamInfo != null) { 97 if (streamInfo != null) {
98 // 停止之前的下载 98 // 停止之前的下载
99 - cmder.streamByeCmd(deviceId, channelId); 99 + cmder.streamByeCmd(deviceId, channelId, streamInfo.getStream());
100 } 100 }
101 101
102 MediaServerItem newMediaServerItem = playService.getNewMediaServerItem(device); 102 MediaServerItem newMediaServerItem = playService.getNewMediaServerItem(device);
@@ -114,7 +114,7 @@ public class DownloadController { @@ -114,7 +114,7 @@ public class DownloadController {
114 114
115 cmder.downloadStreamCmd(newMediaServerItem, ssrcInfo, device, channelId, startTime, endTime, downloadSpeed, (MediaServerItem mediaServerItem, JSONObject response) -> { 115 cmder.downloadStreamCmd(newMediaServerItem, ssrcInfo, device, channelId, startTime, endTime, downloadSpeed, (MediaServerItem mediaServerItem, JSONObject response) -> {
116 logger.info("收到订阅消息: " + response.toJSONString()); 116 logger.info("收到订阅消息: " + response.toJSONString());
117 - playService.onPublishHandlerForDownload(mediaServerItem, response, deviceId, channelId, uuid.toString()); 117 + playService.onPublishHandlerForDownload(mediaServerItem, response, deviceId, channelId, uuid);
118 }, event -> { 118 }, event -> {
119 RequestMessage msg = new RequestMessage(); 119 RequestMessage msg = new RequestMessage();
120 msg.setId(uuid); 120 msg.setId(uuid);
@@ -130,11 +130,12 @@ public class DownloadController { @@ -130,11 +130,12 @@ public class DownloadController {
130 @ApiImplicitParams({ 130 @ApiImplicitParams({
131 @ApiImplicitParam(name = "deviceId", value = "设备ID", dataTypeClass = String.class), 131 @ApiImplicitParam(name = "deviceId", value = "设备ID", dataTypeClass = String.class),
132 @ApiImplicitParam(name = "channelId", value = "通道ID", dataTypeClass = String.class), 132 @ApiImplicitParam(name = "channelId", value = "通道ID", dataTypeClass = String.class),
  133 + @ApiImplicitParam(name = "stream", value = "流ID", dataTypeClass = String.class),
133 }) 134 })
134 - @GetMapping("/stop/{deviceId}/{channelId}")  
135 - public ResponseEntity<String> playStop(@PathVariable String deviceId, @PathVariable String channelId) { 135 + @GetMapping("/stop/{deviceId}/{channelId}/{stream}")
  136 + public ResponseEntity<String> playStop(@PathVariable String deviceId, @PathVariable String channelId, @PathVariable String stream) {
136 137
137 - cmder.streamByeCmd(deviceId, channelId); 138 + cmder.streamByeCmd(deviceId, channelId, stream);
138 139
139 if (logger.isDebugEnabled()) { 140 if (logger.isDebugEnabled()) {
140 logger.debug(String.format("设备历史媒体下载停止 API调用,deviceId/channelId:%s_%s", deviceId, channelId)); 141 logger.debug(String.format("设备历史媒体下载停止 API调用,deviceId/channelId:%s_%s", deviceId, channelId));
src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/playback/PlaybackController.java
@@ -18,6 +18,7 @@ import org.slf4j.LoggerFactory; @@ -18,6 +18,7 @@ import org.slf4j.LoggerFactory;
18 import org.springframework.beans.factory.annotation.Autowired; 18 import org.springframework.beans.factory.annotation.Autowired;
19 import org.springframework.http.HttpStatus; 19 import org.springframework.http.HttpStatus;
20 import org.springframework.http.ResponseEntity; 20 import org.springframework.http.ResponseEntity;
  21 +import org.springframework.util.StringUtils;
21 import org.springframework.web.bind.annotation.CrossOrigin; 22 import org.springframework.web.bind.annotation.CrossOrigin;
22 import org.springframework.web.bind.annotation.GetMapping; 23 import org.springframework.web.bind.annotation.GetMapping;
23 import org.springframework.web.bind.annotation.PathVariable; 24 import org.springframework.web.bind.annotation.PathVariable;
@@ -75,52 +76,8 @@ public class PlaybackController { @@ -75,52 +76,8 @@ public class PlaybackController {
75 if (logger.isDebugEnabled()) { 76 if (logger.isDebugEnabled()) {
76 logger.debug(String.format("设备回放 API调用,deviceId:%s ,channelId:%s", deviceId, channelId)); 77 logger.debug(String.format("设备回放 API调用,deviceId:%s ,channelId:%s", deviceId, channelId));
77 } 78 }
78 - String uuid = UUID.randomUUID().toString();  
79 - String key = DeferredResultHolder.CALLBACK_CMD_PLAYBACK + deviceId + channelId;  
80 - DeferredResult<ResponseEntity<String>> result = new DeferredResult<ResponseEntity<String>>(30000L);  
81 - Device device = storager.queryVideoDevice(deviceId);  
82 - if (device == null) {  
83 - result.setResult(new ResponseEntity<>(HttpStatus.BAD_REQUEST));  
84 - return result;  
85 - }  
86 - MediaServerItem newMediaServerItem = playService.getNewMediaServerItem(device);  
87 - SSRCInfo ssrcInfo = mediaServerService.openRTPServer(newMediaServerItem, null, true);  
88 -  
89 - // 超时处理  
90 - result.onTimeout(()->{  
91 - logger.warn(String.format("设备回放超时,deviceId:%s ,channelId:%s", deviceId, channelId));  
92 - RequestMessage msg = new RequestMessage();  
93 - msg.setId(uuid);  
94 - msg.setKey(key);  
95 - msg.setData("Timeout");  
96 - resultHolder.invokeResult(msg);  
97 - });  
98 -  
99 - StreamInfo streamInfo = redisCatchStorage.queryPlaybackByDevice(deviceId, channelId);  
100 - if (streamInfo != null) {  
101 - // 停止之前的回放  
102 - cmder.streamByeCmd(deviceId, channelId);  
103 - }  
104 - resultHolder.put(DeferredResultHolder.CALLBACK_CMD_PLAY + deviceId + channelId, uuid, result);  
105 -  
106 - if (newMediaServerItem == null) {  
107 - logger.warn(String.format("设备回放超时,deviceId:%s ,channelId:%s", deviceId, channelId));  
108 - RequestMessage msg = new RequestMessage();  
109 - msg.setId(uuid);  
110 - msg.setKey(key);  
111 - msg.setData("Timeout");  
112 - resultHolder.invokeResult(msg);  
113 - return result;  
114 - }  
115 79
116 - cmder.playbackStreamCmd(newMediaServerItem, ssrcInfo, device, channelId, startTime, endTime, (MediaServerItem mediaServerItem, JSONObject response) -> {  
117 - logger.info("收到订阅消息: " + response.toJSONString());  
118 - playService.onPublishHandlerForPlayBack(mediaServerItem, response, deviceId, channelId, uuid.toString());  
119 - }, event -> {  
120 - RequestMessage msg = new RequestMessage();  
121 - msg.setId(uuid);  
122 - msg.setKey(key);  
123 - msg.setData(String.format("回放失败, 错误码: %s, %s", event.statusCode, event.msg)); 80 + DeferredResult<ResponseEntity<String>> result = playService.playBack(deviceId, channelId, startTime, endTime, msg->{
124 resultHolder.invokeResult(msg); 81 resultHolder.invokeResult(msg);
125 }); 82 });
126 83
@@ -131,24 +88,31 @@ public class PlaybackController { @@ -131,24 +88,31 @@ public class PlaybackController {
131 @ApiImplicitParams({ 88 @ApiImplicitParams({
132 @ApiImplicitParam(name = "deviceId", value = "设备ID", dataTypeClass = String.class), 89 @ApiImplicitParam(name = "deviceId", value = "设备ID", dataTypeClass = String.class),
133 @ApiImplicitParam(name = "channelId", value = "通道ID", dataTypeClass = String.class), 90 @ApiImplicitParam(name = "channelId", value = "通道ID", dataTypeClass = String.class),
  91 + @ApiImplicitParam(name = "stream", value = "流ID", dataTypeClass = String.class),
134 }) 92 })
135 - @GetMapping("/stop/{deviceId}/{channelId}")  
136 - public ResponseEntity<String> playStop(@PathVariable String deviceId, @PathVariable String channelId) { 93 + @GetMapping("/stop/{deviceId}/{channelId}/{stream}")
  94 + public ResponseEntity<String> playStop(
  95 + @PathVariable String deviceId,
  96 + @PathVariable String channelId,
  97 + @PathVariable String stream) {
137 98
138 - cmder.streamByeCmd(deviceId, channelId); 99 + cmder.streamByeCmd(deviceId, channelId, stream);
139 100
140 if (logger.isDebugEnabled()) { 101 if (logger.isDebugEnabled()) {
141 logger.debug(String.format("设备录像回放停止 API调用,deviceId/channelId:%s/%s", deviceId, channelId)); 102 logger.debug(String.format("设备录像回放停止 API调用,deviceId/channelId:%s/%s", deviceId, channelId));
142 } 103 }
  104 + if (StringUtils.isEmpty(deviceId) || StringUtils.isEmpty(channelId) || StringUtils.isEmpty(stream)) {
  105 + return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
  106 + }
143 107
144 if (deviceId != null && channelId != null) { 108 if (deviceId != null && channelId != null) {
145 JSONObject json = new JSONObject(); 109 JSONObject json = new JSONObject();
146 json.put("deviceId", deviceId); 110 json.put("deviceId", deviceId);
147 json.put("channelId", channelId); 111 json.put("channelId", channelId);
148 - return new ResponseEntity<String>(json.toString(), HttpStatus.OK); 112 + return new ResponseEntity<>(json.toString(), HttpStatus.OK);
149 } else { 113 } else {
150 logger.warn("设备录像回放停止API调用失败!"); 114 logger.warn("设备录像回放停止API调用失败!");
151 - return new ResponseEntity<String>(HttpStatus.INTERNAL_SERVER_ERROR); 115 + return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
152 } 116 }
153 } 117 }
154 118
src/main/java/com/genersoft/iot/vmp/vmanager/server/ServerController.java
@@ -158,6 +158,7 @@ public class ServerController { @@ -158,6 +158,7 @@ public class ServerController {
158 public WVPResult<String> deleteMediaServer(@RequestParam String id){ 158 public WVPResult<String> deleteMediaServer(@RequestParam String id){
159 if (mediaServerService.getOne(id) != null) { 159 if (mediaServerService.getOne(id) != null) {
160 mediaServerService.delete(id); 160 mediaServerService.delete(id);
  161 + mediaServerService.deleteDb(id);
161 }else { 162 }else {
162 WVPResult<String> result = new WVPResult<>(); 163 WVPResult<String> result = new WVPResult<>();
163 result.setCode(-1); 164 result.setCode(-1);
src/main/java/com/genersoft/iot/vmp/web/gb28181/ApiStreamController.java
@@ -103,7 +103,7 @@ public class ApiStreamController { @@ -103,7 +103,7 @@ public class ApiStreamController {
103 PlayResult play = playService.play(newMediaServerItem, serial, code, (mediaServerItem, response)->{ 103 PlayResult play = playService.play(newMediaServerItem, serial, code, (mediaServerItem, response)->{
104 StreamInfo streamInfo = redisCatchStorage.queryPlayByDevice(serial, code); 104 StreamInfo streamInfo = redisCatchStorage.queryPlayByDevice(serial, code);
105 JSONObject result = new JSONObject(); 105 JSONObject result = new JSONObject();
106 - result.put("StreamID", streamInfo.getStreamId()); 106 + result.put("StreamID", streamInfo.getStream());
107 result.put("DeviceID", device.getDeviceId()); 107 result.put("DeviceID", device.getDeviceId());
108 result.put("ChannelID", code); 108 result.put("ChannelID", code);
109 result.put("ChannelName", deviceChannel.getName()); 109 result.put("ChannelName", deviceChannel.getName());
@@ -177,7 +177,7 @@ public class ApiStreamController { @@ -177,7 +177,7 @@ public class ApiStreamController {
177 result.put("error","未找到流信息"); 177 result.put("error","未找到流信息");
178 return result; 178 return result;
179 } 179 }
180 - cmder.streamByeCmd(serial, code); 180 + cmder.streamByeCmd(serial, code, streamInfo.getStream());
181 redisCatchStorage.stopPlay(streamInfo); 181 redisCatchStorage.stopPlay(streamInfo);
182 storager.stopPlay(streamInfo.getDeviceID(), streamInfo.getChannelId()); 182 storager.stopPlay(streamInfo.getDeviceID(), streamInfo.getChannelId());
183 return null; 183 return null;
src/main/resources/all-application.yml
@@ -30,24 +30,44 @@ spring: @@ -30,24 +30,44 @@ spring:
30 poolMaxWait: 5 30 poolMaxWait: 5
31 # [可选] jdbc数据库配置, 项目使用sqlite作为数据库,一般不需要配置 31 # [可选] jdbc数据库配置, 项目使用sqlite作为数据库,一般不需要配置
32 datasource: 32 datasource:
33 - # 使用mysql 打开23-28行注释, 删除29-36行  
34 - # name: wvp  
35 - # url: jdbc:mysql://127.0.0.1:3306/wvp?useUnicode=true&characterEncoding=UTF8&rewriteBatchedStatements=true&allowMultiQueries=true  
36 - # username:  
37 - # password:  
38 - # type: com.alibaba.druid.pool.DruidDataSource  
39 - # driver-class-name: com.mysql.cj.jdbc.Driver  
40 - name: eiot  
41 - url: jdbc:sqlite::resource:wvp.sqlite  
42 - username:  
43 - password:  
44 type: com.alibaba.druid.pool.DruidDataSource 33 type: com.alibaba.druid.pool.DruidDataSource
45 - driver-class-name: org.sqlite.JDBC  
46 - journal_mode: WAL  
47 - synchronous: NORMAL  
48 - transaction_mode: IMMEDIATE  
49 - max-active: 1  
50 - min-idle: 1 34 + driver-class-name: com.mysql.cj.jdbc.Driver
  35 + url: jdbc:mysql://127.0.0.1:3306/wvp?useUnicode=true&characterEncoding=UTF8&rewriteBatchedStatements=true&serverTimezone=PRC&useSSL=false
  36 + username: root
  37 + password: root123
  38 + druid:
  39 + initialSize: 10 # 连接池初始化连接数
  40 + maxActive: 200 # 连接池最大连接数
  41 + minIdle: 5 # 连接池最小空闲连接数
  42 + maxWait: 60000 # 获取连接时最大等待时间,单位毫秒。配置了maxWait之后,缺省启用公平锁,并发效率会有所下降,如果需要可以通过配置useUnfairLock属性为true使用非公平锁。
  43 + keepAlive: true # 连接池中的minIdle数量以内的连接,空闲时间超过minEvictableIdleTimeMillis,则会执行keepAlive操作。
  44 + validationQuery: select 1 # 检测连接是否有效sql,要求是查询语句,常用select 'x'。如果validationQuery为null,testOnBorrow、testOnReturn、testWhileIdle都不会起作用。
  45 + testWhileIdle: true # 建议配置为true,不影响性能,并且保证安全性。申请连接的时候检测,如果空闲时间大于timeBetweenEvictionRunsMillis,执行validationQuery检测连接是否有效。
  46 + testOnBorrow: false # 申请连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能。
  47 + testOnReturn: false # 归还连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能。
  48 + poolPreparedStatements: false # 是否開啟PSCache,並且指定每個連線上PSCache的大小
  49 + timeBetweenEvictionRunsMillis: 60000 # 配置間隔多久才進行一次檢測,檢測需要關閉的空閒連線,單位是毫秒
  50 + minEvictableIdleTimeMillis: 300000 # 配置一個連線在池中最小生存的時間,單位是毫秒
  51 + filters: stat,wall,slf4j # 配置监控统计拦截的filters,监控统计用的filter:sta, 日志用的filter:log4j, 防御sql注入的filter:wall
  52 + useGlobalDataSourceStat: true # 合并多个DruidDataSource的监控数据
  53 + # 通过connectProperties属性来打开mergeSql功能;慢SQL记录
  54 + connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=1000
  55 + #stat-view-servlet.url-pattern: /admin/druid/*
  56 +
  57 +# druid管理监控页面的一些配置
  58 +rj-druid-manage:
  59 + allow: # 访问druid监控页面的IP白名单
  60 + deny: 192.168.1.100 # 访问druid监控页面IP黑名单
  61 + loginUsername: rjAdmin # 访问druid监控页面账号
  62 + loginPassword: rj@2022 # 访问druid监控页面密码
  63 +
  64 +#mybatis:
  65 +# configuration:
  66 +# # 这个配置会将执行的sql打印出来,在开发或测试的时候可以用
  67 +# log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
  68 +# # 返回类型为Map,显示null对应的字段
  69 +# call-setters-on-nulls: true
  70 +## [可选] WVP监听的HTTP端口, 网页和接口调用都是这个端口
51 71
52 # [可选] WVP监听的HTTP端口, 网页和接口调用都是这个端口 72 # [可选] WVP监听的HTTP端口, 网页和接口调用都是这个端口
53 server: 73 server:
@@ -136,15 +156,8 @@ media: @@ -136,15 +156,8 @@ media:
136 156
137 # [可选] 日志配置, 一般不需要改 157 # [可选] 日志配置, 一般不需要改
138 logging: 158 logging:
139 - file:  
140 - name: logs/wvp.log  
141 - max-history: 30  
142 - max-size: 10MB  
143 - total-size-cap: 300MB  
144 - level:  
145 - com.genersoft.iot: debug  
146 - com.genersoft.iot.vmp.storager.dao: info  
147 - com.genersoft.iot.vmp.gb28181: debug 159 + config: classpath:logback-spring-local.xml
  160 +
148 # [根据业务需求配置] 161 # [根据业务需求配置]
149 user-settings: 162 user-settings:
150 # [可选] 服务ID,不写则为000000 163 # [可选] 服务ID,不写则为000000
@@ -173,7 +186,7 @@ user-settings: @@ -173,7 +186,7 @@ user-settings:
173 # 是否将日志存储进数据库 186 # 是否将日志存储进数据库
174 logInDatebase: true 187 logInDatebase: true
175 # 第三方匹配,用于从stream钟获取有效信息 188 # 第三方匹配,用于从stream钟获取有效信息
176 - thirdPartyGBIdReg: [\s\S]* 189 + thirdPartyGBIdReg: "[\\s\\S]*"
177 190
178 # 在线文档: swagger-ui(生产环境建议关闭) 191 # 在线文档: swagger-ui(生产环境建议关闭)
179 swagger-ui: 192 swagger-ui:
src/main/resources/application-dev.yml
@@ -16,24 +16,41 @@ spring: @@ -16,24 +16,41 @@ spring:
16 password: 16 password:
17 # [可选] 超时时间 17 # [可选] 超时时间
18 timeout: 10000 18 timeout: 10000
19 - # [可选] jdbc数据库配置, 项目使用sqlite作为数据库,一般不需要配置 19 + # [可选] jdbc数据库配置, 项目使用sqlite作为数据库,一般不需要配置
  20 + # mysql数据源
20 datasource: 21 datasource:
21 - # 使用mysql 打开23-28行注释, 删除29-36行  
22 - name: wvp  
23 - url: jdbc:mysql://127.0.0.1:3306/wvp?useUnicode=true&characterEncoding=UTF8&rewriteBatchedStatements=true&allowMultiQueries=true&useSSL=false  
24 - username:  
25 - password:  
26 type: com.alibaba.druid.pool.DruidDataSource 22 type: com.alibaba.druid.pool.DruidDataSource
27 driver-class-name: com.mysql.cj.jdbc.Driver 23 driver-class-name: com.mysql.cj.jdbc.Driver
  24 + url: jdbc:mysql://127.0.0.1:3306/wvp?useUnicode=true&characterEncoding=UTF8&rewriteBatchedStatements=true&serverTimezone=PRC&useSSL=false
  25 + username: root
  26 + password: root123
  27 + druid:
  28 + initialSize: 10 # 连接池初始化连接数
  29 + maxActive: 200 # 连接池最大连接数
  30 + minIdle: 5 # 连接池最小空闲连接数
  31 + maxWait: 60000 # 获取连接时最大等待时间,单位毫秒。配置了maxWait之后,缺省启用公平锁,并发效率会有所下降,如果需要可以通过配置useUnfairLock属性为true使用非公平锁。
  32 + keepAlive: true # 连接池中的minIdle数量以内的连接,空闲时间超过minEvictableIdleTimeMillis,则会执行keepAlive操作。
  33 + validationQuery: select 1 # 检测连接是否有效sql,要求是查询语句,常用select 'x'。如果validationQuery为null,testOnBorrow、testOnReturn、testWhileIdle都不会起作用。
  34 + testWhileIdle: true # 建议配置为true,不影响性能,并且保证安全性。申请连接的时候检测,如果空闲时间大于timeBetweenEvictionRunsMillis,执行validationQuery检测连接是否有效。
  35 + testOnBorrow: false # 申请连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能。
  36 + testOnReturn: false # 归还连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能。
  37 + poolPreparedStatements: false # 是否開啟PSCache,並且指定每個連線上PSCache的大小
  38 + timeBetweenEvictionRunsMillis: 60000 # 配置間隔多久才進行一次檢測,檢測需要關閉的空閒連線,單位是毫秒
  39 + minEvictableIdleTimeMillis: 300000 # 配置一個連線在池中最小生存的時間,單位是毫秒
  40 + filters: stat,wall,slf4j # 配置监控统计拦截的filters,监控统计用的filter:sta, 日志用的filter:log4j, 防御sql注入的filter:wall
  41 + useGlobalDataSourceStat: true # 合并多个DruidDataSource的监控数据
  42 + # 通过connectProperties属性来打开mergeSql功能;慢SQL记录
  43 + connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=1000
  44 + #stat-view-servlet.url-pattern: /admin/druid/*
28 45
29 -# [可选] WVP监听的HTTP端口, 网页和接口调用都是这个端口 46 +#[可选] WVP监听的HTTP端口, 网页和接口调用都是这个端口
30 server: 47 server:
31 port: 18080 48 port: 18080
32 49
33 # 作为28181服务器的配置 50 # 作为28181服务器的配置
34 sip: 51 sip:
35 # [必须修改] 本机的IP 52 # [必须修改] 本机的IP
36 - ip: 53 + ip: 192.168.118.70
37 # [可选] 28181服务监听的端口 54 # [可选] 28181服务监听的端口
38 port: 5060 55 port: 5060
39 # 根据国标6.1.2中规定,domain宜采用ID统一编码的前十位编码。国标附录D中定义前8位为中心编码(由省级、市级、区级、基层编号组成,参照GB/T 2260-2007) 56 # 根据国标6.1.2中规定,domain宜采用ID统一编码的前十位编码。国标附录D中定义前8位为中心编码(由省级、市级、区级、基层编号组成,参照GB/T 2260-2007)
@@ -48,10 +65,9 @@ sip: @@ -48,10 +65,9 @@ sip:
48 65
49 #zlm 默认服务器配置 66 #zlm 默认服务器配置
50 media: 67 media:
51 - # [必须修改] zlm服务器唯一id,用于触发hook时区别是哪台服务器,general.mediaServerId  
52 - id: 68 + id: FQ3TF8yT83wh5Wvz
53 # [必须修改] zlm服务器的内网IP 69 # [必须修改] zlm服务器的内网IP
54 - ip: 70 + ip: 192.168.118.70
55 # [必须修改] zlm服务器的http.port 71 # [必须修改] zlm服务器的http.port
56 http-port: 80 72 http-port: 80
57 # [可选] zlm服务器的hook.admin_params=secret 73 # [可选] zlm服务器的hook.admin_params=secret
@@ -68,25 +84,7 @@ media: @@ -68,25 +84,7 @@ media:
68 record-assist-port: 18081 84 record-assist-port: 18081
69 # [可选] 日志配置, 一般不需要改 85 # [可选] 日志配置, 一般不需要改
70 logging: 86 logging:
71 - file:  
72 - name: logs/wvp.log  
73 - max-history: 30  
74 - max-size: 10MB  
75 - total-size-cap: 300MB  
76 - level:  
77 - com.genersoft.iot: debug  
78 - com.genersoft.iot.vmp.storager.dao: info  
79 - com.genersoft.iot.vmp.gb28181: info  
80 -  
81 -# [根据业务需求配置]  
82 -user-settings:  
83 - # 推流直播是否录制  
84 - record-push-live: true  
85 - auto-apply-play: false  
86 -  
87 -# 在线文档: swagger-ui(生产环境建议关闭)  
88 -swagger-ui:  
89 - enabled: true 87 + config: classpath:logback-spring-local.xml
90 88
91 # 版本信息, 不需修改 89 # 版本信息, 不需修改
92 version: 90 version:
src/main/resources/application-docker.yml
@@ -69,16 +69,9 @@ media: @@ -69,16 +69,9 @@ media:
69 sdp-ip: ${sip.ip} 69 sdp-ip: ${sip.ip}
70 stream-ip: ${sip.ip} 70 stream-ip: ${sip.ip}
71 # [可选] 日志配置, 一般不需要改 71 # [可选] 日志配置, 一般不需要改
  72 +# [可选] 日志配置, 一般不需要改
72 logging: 73 logging:
73 - file:  
74 - name: logs/wvp.log  
75 - max-history: 30  
76 - max-size: 10MB  
77 - total-size-cap: 300MB  
78 - level:  
79 - com.genersoft.iot: debug  
80 - com.genersoft.iot.vmp.storager.dao: info  
81 - com.genersoft.iot.vmp.gb28181: info 74 + config: classpath:logback-spring-local.xml
82 75
83 # [根据业务需求配置] 76 # [根据业务需求配置]
84 user-settings: 77 user-settings:
src/main/resources/application.yml
1 spring: 1 spring:
2 profiles: 2 profiles:
3 - active: local 3 + active: dev
src/main/resources/logback-spring-local.xml 0 → 100644
  1 +<?xml version="1.0" encoding="UTF-8"?>
  2 +<configuration debug="false">
  3 + <!--定义日志文件的存储地址 -->
  4 + <springProperty scop="context" name="spring.application.name" source="spring.application.name" defaultValue=""/>
  5 + <property name="LOG_HOME" value="logs/${spring.application.name}" />
  6 +
  7 + <!--<property name="COLOR_PATTERN" value="%black(%contextName-) %red(%d{yyyy-MM-dd HH:mm:ss}) %green([%thread]) %highlight(%-5level) %boldMagenta( %replace(%caller{1}){'\t|Caller.{1}0|\r\n', ''})- %gray(%msg%xEx%n)" />-->
  8 + <!-- 控制台输出 -->
  9 + <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
  10 + <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
  11 + <!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符 -->
  12 + <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50}:%L - %msg%n</pattern>
  13 + </encoder>
  14 + </appender>
  15 +
  16 + <!-- 按照每天生成日志文件 DEBUG以上级别的日志,仅用于测试环境,正式环境为info级别以上的日志-->
  17 + <appender name="RollingFile" class="ch.qos.logback.core.rolling.RollingFileAppender">
  18 +
  19 + <!-- 文件路径 -->
  20 + <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
  21 + <!--历史日志文件输出的文件名 -->
  22 + <FileNamePattern>${LOG_HOME}/wvp-%d{yyyy-MM-dd}.%i.log</FileNamePattern>
  23 + <!--日志文件保留天数 -->
  24 + <MaxHistory>30</MaxHistory>
  25 + <maxFileSize>20MB</maxFileSize>
  26 + </rollingPolicy>
  27 + <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
  28 + <!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符 -->
  29 + <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50}:%L - %msg%n</pattern>
  30 + </encoder>
  31 + <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
  32 + <!--与ThresholdFilter的区别,允许onmatch-->
  33 + <!--设置日志级别 接收info级别的日志-->
  34 + <level>DEBUG</level>
  35 + </filter>
  36 + </appender>
  37 +
  38 + <!-- 生成 error格式日志开始 -->
  39 + <appender name="RollingFileError" class="ch.qos.logback.core.rolling.RollingFileAppender">
  40 +
  41 + <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
  42 + <!--历史日志文件输出的文件名 -->
  43 + <FileNamePattern>${LOG_HOME}/error-%d{yyyy-MM-dd}.%i.log</FileNamePattern>
  44 + <!--日志文件保留天数 -->
  45 + <MaxHistory>30</MaxHistory>
  46 + <maxFileSize>20MB</maxFileSize>
  47 + </rollingPolicy>
  48 + <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
  49 + <!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符 -->
  50 + <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50}:%L - %msg%n</pattern>
  51 + </encoder>
  52 + <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
  53 + <!--设置日志级别,过滤掉info日志,只输入error日志-->
  54 + <level>WARN</level>
  55 + <!-- <onMatch>ACCEPT</onMatch> &lt;!&ndash; 用过滤器,只接受ERROR级别的日志信息,其余全部过滤掉 &ndash;&gt;-->
  56 + <!-- <onMismatch>DENY</onMismatch>-->
  57 + </filter>
  58 + </appender>
  59 +
  60 + <!-- 生成 druid日志追加 -->
  61 + <appender name="druidSqlRollingFile" class="ch.qos.logback.core.rolling.RollingFileAppender">
  62 + <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
  63 + <!--历史日志文件输出的文件名 -->
  64 + <FileNamePattern>${LOG_HOME}/druid-%d{yyyy-MM-dd}.%i.log</FileNamePattern>
  65 + <!--日志文件保留天数 -->
  66 + <MaxHistory>30</MaxHistory>
  67 + <maxFileSize>50MB</maxFileSize>
  68 + </rollingPolicy>
  69 + <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
  70 + <!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符 -->
  71 + <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50}:%L - %msg%n</pattern>
  72 + </encoder>
  73 + </appender>
  74 +
  75 +
  76 + <!-- 日志输出级别 -->
  77 + <root level="INFO">
  78 + <appender-ref ref="STDOUT" />
  79 + <appender-ref ref="RollingFile" />
  80 + <appender-ref ref="RollingFileError" />
  81 + </root>
  82 +
  83 + <logger name="com.genersoft.iot.vmp.storager.dao" level="INFO">
  84 + <appender-ref ref="STDOUT"/>
  85 + </logger>
  86 + <logger name="com.genersoft.iot.vmp.gb28181" level="INFO">
  87 + <appender-ref ref="STDOUT"/>
  88 + </logger>
  89 +
  90 + <!--记录druid-sql的记录-->
  91 + <logger name="druid.sql.Statement" level="debug" additivity="true">
  92 + <!--AppenderRef ref="Console"/-->
  93 + <!-- <appender-ref ref="RollingFile"/>-->
  94 + <appender-ref ref="RollingFileError"/>
  95 + <appender-ref ref="druidSqlRollingFile"/>
  96 + </logger>
  97 +</configuration>
0 \ No newline at end of file 98 \ No newline at end of file
web_src/src/components/DeviceList.vue
@@ -55,14 +55,14 @@ @@ -55,14 +55,14 @@
55 <el-table-column prop="createTime" label="创建时间" align="center" width="140"> 55 <el-table-column prop="createTime" label="创建时间" align="center" width="140">
56 </el-table-column> 56 </el-table-column>
57 57
58 - <el-table-column label="操作" width="360" align="center" fixed="right"> 58 + <el-table-column label="操作" width="450" align="center" fixed="right">
59 <template slot-scope="scope"> 59 <template slot-scope="scope">
60 <el-button size="mini" :ref="scope.row.deviceId + 'refbtn' " v-if="scope.row.online!=0" icon="el-icon-refresh" @click="refDevice(scope.row)">刷新</el-button> 60 <el-button size="mini" :ref="scope.row.deviceId + 'refbtn' " v-if="scope.row.online!=0" icon="el-icon-refresh" @click="refDevice(scope.row)">刷新</el-button>
61 <el-button-group> 61 <el-button-group>
62 <el-button size="mini" icon="el-icon-video-camera-solid" v-bind:disabled="scope.row.online==0" type="primary" @click="showChannelList(scope.row)">通道</el-button> 62 <el-button size="mini" icon="el-icon-video-camera-solid" v-bind:disabled="scope.row.online==0" type="primary" @click="showChannelList(scope.row)">通道</el-button>
63 <el-button size="mini" icon="el-icon-location" v-bind:disabled="scope.row.online==0" type="primary" @click="showDevicePosition(scope.row)">定位</el-button> 63 <el-button size="mini" icon="el-icon-location" v-bind:disabled="scope.row.online==0" type="primary" @click="showDevicePosition(scope.row)">定位</el-button>
64 <el-button size="mini" icon="el-icon-edit" type="primary" @click="edit(scope.row)">编辑</el-button> 64 <el-button size="mini" icon="el-icon-edit" type="primary" @click="edit(scope.row)">编辑</el-button>
65 - <el-button size="mini" icon="el-icon-delete" type="danger" v-if="scope.row.online==0" @click="deleteDevice(scope.row)">删除</el-button> 65 + <el-button size="mini" icon="el-icon-delete" type="danger" @click="deleteDevice(scope.row)">删除</el-button>
66 </el-button-group> 66 </el-button-group>
67 </template> 67 </template>
68 </el-table-column> 68 </el-table-column>
@@ -165,15 +165,29 @@ @@ -165,15 +165,29 @@
165 165
166 }, 166 },
167 deleteDevice: function(row) { 167 deleteDevice: function(row) {
168 - let that = this;  
169 - this.$axios({  
170 - method: 'delete',  
171 - url:`/api/device/query/devices/${row.deviceId}/delete`  
172 - }).then((res)=>{  
173 - this.getDeviceList();  
174 - }).catch((error) =>{  
175 - console.log(error);  
176 - }); 168 + let msg = "确定删除此设备?"
  169 + if (row.online !== 0) {
  170 + msg = "在线设备删除后仍可通过注册再次上线。<br/>如需彻底删除请先将设备离线。<br/><strong>确定删除此设备?</strong>"
  171 + }
  172 + this.$confirm(msg, '提示', {
  173 + dangerouslyUseHTMLString : true,
  174 + confirmButtonText: '确定',
  175 + cancelButtonText: '取消',
  176 + center: true,
  177 + type: 'warning'
  178 + }).then(() => {
  179 + this.$axios({
  180 + method: 'delete',
  181 + url:`/api/device/query/devices/${row.deviceId}/delete`
  182 + }).then((res)=>{
  183 + this.getDeviceList();
  184 + }).catch((error) =>{
  185 + console.log(error);
  186 + });
  187 + }).catch(() => {
  188 +
  189 + });
  190 +
177 191
178 }, 192 },
179 showChannelList: function(row) { 193 showChannelList: function(row) {
web_src/src/components/channelList.vue
@@ -28,9 +28,7 @@ @@ -28,9 +28,7 @@
28 <devicePlayer ref="devicePlayer" v-loading="isLoging"></devicePlayer> 28 <devicePlayer ref="devicePlayer" v-loading="isLoging"></devicePlayer>
29 <!--设备列表--> 29 <!--设备列表-->
30 <el-table ref="channelListTable" :data="deviceChannelList" :height="winHeight" border style="width: 100%"> 30 <el-table ref="channelListTable" :data="deviceChannelList" :height="winHeight" border style="width: 100%">
31 - <el-table-column prop="channelId" label="通道编号" width="210">  
32 - </el-table-column>  
33 - <el-table-column prop="deviceId" label="设备编号" width="210"> 31 + <el-table-column prop="channelId" label="通道编号" width="200">
34 </el-table-column> 32 </el-table-column>
35 <el-table-column prop="name" label="通道名称"> 33 <el-table-column prop="name" label="通道名称">
36 </el-table-column> 34 </el-table-column>
web_src/src/components/dialog/changePassword.vue
@@ -75,7 +75,10 @@ export default { @@ -75,7 +75,10 @@ export default {
75 isLoging: false, 75 isLoging: false,
76 rules: { 76 rules: {
77 oldPassword: [{ required: true, validator: validatePass0, trigger: "blur" }], 77 oldPassword: [{ required: true, validator: validatePass0, trigger: "blur" }],
78 - newPassword: [{ required: true, validator: validatePass1, trigger: "blur" }], 78 + newPassword: [{ required: true, validator: validatePass1, trigger: "blur" }, {
  79 + pattern: /^(?=.*[a-zA-Z])(?=.*\d)(?=.*[~!@#$%^&*()_+`\-={}:";'<>?,.\/]).{8,20}$/,
  80 + message: "密码长度在8-20位之间,由字母+数字+特殊字符组成",
  81 + },],
79 confirmPassword: [{ required: true, validator: validatePass2, trigger: "blur" }], 82 confirmPassword: [{ required: true, validator: validatePass2, trigger: "blur" }],
80 }, 83 },
81 }; 84 };
web_src/src/components/dialog/devicePlayer.vue
@@ -307,7 +307,7 @@ export default { @@ -307,7 +307,7 @@ export default {
307 this.isLoging = false; 307 this.isLoging = false;
308 // this.videoUrl = streamInfo.rtc; 308 // this.videoUrl = streamInfo.rtc;
309 this.videoUrl = this.getUrlByStreamInfo(streamInfo); 309 this.videoUrl = this.getUrlByStreamInfo(streamInfo);
310 - this.streamId = streamInfo.streamId; 310 + this.streamId = streamInfo.stream;
311 this.app = streamInfo.app; 311 this.app = streamInfo.app;
312 this.mediaServerId = streamInfo.mediaServerId; 312 this.mediaServerId = streamInfo.mediaServerId;
313 this.playFromStreamInfo(false, streamInfo) 313 this.playFromStreamInfo(false, streamInfo)
@@ -485,8 +485,9 @@ export default { @@ -485,8 +485,9 @@ export default {
485 }).then(function (res) { 485 }).then(function (res) {
486 var streamInfo = res.data; 486 var streamInfo = res.data;
487 that.app = streamInfo.app; 487 that.app = streamInfo.app;
488 - that.streamId = streamInfo.streamId; 488 + that.streamId = streamInfo.stream;
489 that.mediaServerId = streamInfo.mediaServerId; 489 that.mediaServerId = streamInfo.mediaServerId;
  490 + that.ssrc = streamInfo.ssrc;
490 that.videoUrl = that.getUrlByStreamInfo(streamInfo); 491 that.videoUrl = that.getUrlByStreamInfo(streamInfo);
491 that.recordPlay = true; 492 that.recordPlay = true;
492 }); 493 });
@@ -497,7 +498,7 @@ export default { @@ -497,7 +498,7 @@ export default {
497 this.videoUrl = ''; 498 this.videoUrl = '';
498 this.$axios({ 499 this.$axios({
499 method: 'get', 500 method: 'get',
500 - url: '/api/playback/stop/' + this.deviceId + "/" + this.channelId 501 + url: '/api/playback/stop/' + this.deviceId + "/" + this.channelId + "/" + this.streamId
501 }).then(function (res) { 502 }).then(function (res) {
502 if (callback) callback() 503 if (callback) callback()
503 }); 504 });
@@ -517,7 +518,7 @@ export default { @@ -517,7 +518,7 @@ export default {
517 }).then(function (res) { 518 }).then(function (res) {
518 var streamInfo = res.data; 519 var streamInfo = res.data;
519 that.app = streamInfo.app; 520 that.app = streamInfo.app;
520 - that.streamId = streamInfo.streamId; 521 + that.streamId = streamInfo.stream;
521 that.mediaServerId = streamInfo.mediaServerId; 522 that.mediaServerId = streamInfo.mediaServerId;
522 that.videoUrl = that.getUrlByStreamInfo(streamInfo); 523 that.videoUrl = that.getUrlByStreamInfo(streamInfo);
523 that.recordPlay = true; 524 that.recordPlay = true;
@@ -529,7 +530,7 @@ export default { @@ -529,7 +530,7 @@ export default {
529 this.videoUrl = ''; 530 this.videoUrl = '';
530 this.$axios({ 531 this.$axios({
531 method: 'get', 532 method: 'get',
532 - url: '/api/download/stop/' + this.deviceId + "/" + this.channelId 533 + url: '/api/download/stop/' + this.deviceId + "/" + this.channelId+ "/" + this.streamId
533 }).then(function (res) { 534 }).then(function (res) {
534 if (callback) callback() 535 if (callback) callback()
535 }); 536 });
@@ -539,8 +540,6 @@ export default { @@ -539,8 +540,6 @@ export default {
539 let that = this; 540 let that = this;
540 this.$axios({ 541 this.$axios({
541 method: 'post', 542 method: 'post',
542 - // url: '/api/ptz/' + this.deviceId + '/' + this.channelId + '?leftRight=' + leftRight + '&upDown=' + upDown +  
543 - // '&inOut=' + zoom + '&moveSpeed=50&zoomSpeed=50'  
544 url: '/api/ptz/control/' + this.deviceId + '/' + this.channelId + '?command=' + command + '&horizonSpeed=' + this.controSpeed + '&verticalSpeed=' + this.controSpeed + '&zoomSpeed=' + this.controSpeed 543 url: '/api/ptz/control/' + this.deviceId + '/' + this.channelId + '?command=' + command + '&horizonSpeed=' + this.controSpeed + '&verticalSpeed=' + this.controSpeed + '&zoomSpeed=' + this.controSpeed
545 }).then(function (res) {}); 544 }).then(function (res) {});
546 }, 545 },