Commit bfcb4d23351c5eb8db753ed8670a0d16601c1992

Authored by 648540858
2 parents f99c9cac 098dd8a0

合并主分支

Showing 58 changed files with 2131 additions and 166 deletions

Too many changes to show.

To preserve performance only 58 of 70 files are displayed.

README.md
... ... @@ -95,15 +95,13 @@ https://gitee.com/pan648540858/wvp-GB28181-pro.git
95 95 - [X] 平台状态查询
96 96 - [X] 平台信息查询
97 97 - [X] 平台远程启动
  98 + - [X] 每个级联平台可自定义的虚拟目录
98 99 - [X] 添加RTSP视频
99 100 - [X] 添加接口鉴权
100   -- [ ] 添加ONVIF探测局域网内的设备
101 101 - [X] 添加RTMP视频
102 102 - [X] 云端录像(需要部署单独服务配合使用)
103 103 - [X] 多流媒体节点,自动选择负载最低的节点使用。
104 104 - [X] 支持使用mysql作为数据库,默认sqlite3,开箱即用。
105   -- [ ] 添加系统配置
106   -- [ ] 添加用户管理
107 105 - [X] WEB端支持播放H264与H265,音频支持G.711A/G.711U/AAC,覆盖国标常用编码格式。
108 106  
109 107 # docker快速体验
... ...
sql/dump-wvp-202201051515.sql 0 → 100644
  1 +-- MySQL dump 10.13 Distrib 8.0.27, for Linux (x86_64)
  2 +--
  3 +-- Host: localhost Database: wvp
  4 +-- ------------------------------------------------------
  5 +-- Server version 8.0.27-0ubuntu0.20.04.1
  6 +
  7 +/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
  8 +/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
  9 +/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
  10 +/*!50503 SET NAMES utf8mb4 */;
  11 +/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
  12 +/*!40103 SET TIME_ZONE='+00:00' */;
  13 +/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
  14 +/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
  15 +/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
  16 +/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
  17 +
  18 +--
  19 +-- Table structure for table `device`
  20 +--
  21 +
  22 +DROP TABLE IF EXISTS `device`;
  23 +/*!40101 SET @saved_cs_client = @@character_set_client */;
  24 +/*!50503 SET character_set_client = utf8mb4 */;
  25 +CREATE TABLE `device` (
  26 + `deviceId` varchar(50) NOT NULL,
  27 + `name` varchar(255) DEFAULT NULL,
  28 + `manufacturer` varchar(255) DEFAULT NULL,
  29 + `model` varchar(255) DEFAULT NULL,
  30 + `firmware` varchar(255) DEFAULT NULL,
  31 + `transport` varchar(50) DEFAULT NULL,
  32 + `streamMode` varchar(50) DEFAULT NULL,
  33 + `online` varchar(50) DEFAULT NULL,
  34 + `registerTime` varchar(50) DEFAULT NULL,
  35 + `keepaliveTime` varchar(50) DEFAULT NULL,
  36 + `ip` varchar(50) NOT NULL,
  37 + `createTime` varchar(50) NOT NULL,
  38 + `updateTime` varchar(50) NOT NULL,
  39 + `port` int NOT NULL,
  40 + `expires` int NOT NULL,
  41 + `subscribeCycleForCatalog` int NOT NULL,
  42 + `hostAddress` varchar(50) NOT NULL,
  43 + `charset` varchar(50) NOT NULL,
  44 + PRIMARY KEY (`deviceId`)
  45 +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
  46 +/*!40101 SET character_set_client = @saved_cs_client */;
  47 +
  48 +--
  49 +-- Dumping data for table `device`
  50 +--
  51 +
  52 +LOCK TABLES `device` WRITE;
  53 +/*!40000 ALTER TABLE `device` DISABLE KEYS */;
  54 +INSERT INTO `device` VALUES ('34020000001320000005','IPC-HFW4433M-I2','Dahua','IPC-HFW4433M-I2','2.622.0000000.31.R,2017-12-14','UDP','UDP','1','2022-01-05 15:08:26','2022-01-05 15:15:26','192.168.1.100','2022-01-05 15:08:26','2022-01-05 15:15:26',5060,3600,0,'192.168.1.100:5060','gb2312'),('34020000002000000005','DH-NVR5864-I','Dahua','DH-NVR5864-I','4.001.0000000.3,2020-10-22','UDP','UDP','1','2022-01-05 14:07:36','2022-01-05 15:15:25','192.168.1.19','2022-01-05 15:08:25','2022-01-05 15:15:25',5060,3600,0,'192.168.1.19:5060','gb2312'),('44010000001110008008',NULL,'Mercury','MIPC368(P)W-4','1.0.1 Build 210304 Rel.60784n','UDP','UDP','1','2022-01-05 15:08:35','2022-01-05 15:14:35','192.168.1.17','2022-01-05 15:08:35','2022-01-05 15:14:35',5060,36000,0,'192.168.1.17:5060','gb2312');
  55 +/*!40000 ALTER TABLE `device` ENABLE KEYS */;
  56 +UNLOCK TABLES;
  57 +
  58 +--
  59 +-- Table structure for table `device_alarm`
  60 +--
  61 +
  62 +DROP TABLE IF EXISTS `device_alarm`;
  63 +/*!40101 SET @saved_cs_client = @@character_set_client */;
  64 +/*!50503 SET character_set_client = utf8mb4 */;
  65 +CREATE TABLE `device_alarm` (
  66 + `id` int NOT NULL AUTO_INCREMENT,
  67 + `deviceId` varchar(50) NOT NULL,
  68 + `channelId` varchar(50) NOT NULL,
  69 + `alarmPriority` varchar(50) NOT NULL,
  70 + `alarmMethod` varchar(50) DEFAULT NULL,
  71 + `alarmTime` varchar(50) NOT NULL,
  72 + `alarmDescription` varchar(255) DEFAULT NULL,
  73 + `longitude` double DEFAULT NULL,
  74 + `latitude` double DEFAULT NULL,
  75 + `alarmType` varchar(50) DEFAULT NULL,
  76 + PRIMARY KEY (`id`)
  77 +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
  78 +/*!40101 SET character_set_client = @saved_cs_client */;
  79 +
  80 +--
  81 +-- Dumping data for table `device_alarm`
  82 +--
  83 +
  84 +LOCK TABLES `device_alarm` WRITE;
  85 +/*!40000 ALTER TABLE `device_alarm` DISABLE KEYS */;
  86 +/*!40000 ALTER TABLE `device_alarm` ENABLE KEYS */;
  87 +UNLOCK TABLES;
  88 +
  89 +--
  90 +-- Table structure for table `device_channel`
  91 +--
  92 +
  93 +DROP TABLE IF EXISTS `device_channel`;
  94 +/*!40101 SET @saved_cs_client = @@character_set_client */;
  95 +/*!50503 SET character_set_client = utf8mb4 */;
  96 +CREATE TABLE `device_channel` (
  97 + `channelId` varchar(50) NOT NULL,
  98 + `name` varchar(255) DEFAULT NULL,
  99 + `manufacture` varchar(50) DEFAULT NULL,
  100 + `model` varchar(50) DEFAULT NULL,
  101 + `owner` varchar(50) DEFAULT NULL,
  102 + `civilCode` varchar(50) DEFAULT NULL,
  103 + `block` varchar(50) DEFAULT NULL,
  104 + `address` varchar(50) DEFAULT NULL,
  105 + `parentId` varchar(50) DEFAULT NULL,
  106 + `safetyWay` int DEFAULT NULL,
  107 + `registerWay` int DEFAULT NULL,
  108 + `certNum` varchar(50) DEFAULT NULL,
  109 + `certifiable` int DEFAULT NULL,
  110 + `errCode` int DEFAULT NULL,
  111 + `endTime` varchar(50) DEFAULT NULL,
  112 + `secrecy` varchar(50) DEFAULT NULL,
  113 + `ipAddress` varchar(50) DEFAULT NULL,
  114 + `port` int DEFAULT NULL,
  115 + `password` varchar(255) DEFAULT NULL,
  116 + `PTZType` int DEFAULT NULL,
  117 + `status` int DEFAULT NULL,
  118 + `longitude` double DEFAULT NULL,
  119 + `latitude` double DEFAULT NULL,
  120 + `streamId` varchar(50) DEFAULT NULL,
  121 + `deviceId` varchar(50) NOT NULL,
  122 + `parental` varchar(50) DEFAULT NULL,
  123 + `hasAudio` bit(1) DEFAULT NULL,
  124 + `createTime` varchar(50) NOT NULL,
  125 + `updateTime` varchar(50) NOT NULL,
  126 + PRIMARY KEY (`channelId`,`deviceId`)
  127 +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
  128 +/*!40101 SET character_set_client = @saved_cs_client */;
  129 +
  130 +--
  131 +-- Dumping data for table `device_channel`
  132 +--
  133 +
  134 +LOCK TABLES `device_channel` WRITE;
  135 +/*!40000 ALTER TABLE `device_channel` DISABLE KEYS */;
  136 +INSERT INTO `device_channel` VALUES ('34020000001310000001','IPC','Dahua','IPC-HFW4433M-I2','0','340200','','axy','34020000001320000005',0,1,'',0,0,NULL,'0','',0,'',0,1,0,0,'','34020000001320000005','0',NULL,'2022-01-05 15:11:21','2022-01-05 15:11:21'),('34020000001310000001','通道1','Dahua','DH-NVR5864-I','0','340200','','axy','34020000002000000005',0,1,'',0,0,NULL,'0','192.168.1.17',37777,'',0,1,0,0,'','34020000002000000005','0',NULL,'2022-01-05 15:11:25','2022-01-05 15:11:25'),('34020000001310000065','GB_Chn_065','Dahua','DH-NVR5864-I','0','340200','','axy','34020000002000000005',0,1,'',0,0,NULL,'0','',0,'',0,1,0,0,'','34020000002000000005','0',NULL,'2022-01-05 15:11:25','2022-01-05 15:11:25'),('34020000001320000001','IPCamera 01','Mercury','MIPC368(P)W-4','Owner','CivilCode','','Address','',0,1,'',0,0,NULL,'0','',0,'',0,1,0,0,'','44010000001110008008','0',NULL,'2022-01-05 15:11:26','2022-01-05 15:11:26');
  137 +/*!40000 ALTER TABLE `device_channel` ENABLE KEYS */;
  138 +UNLOCK TABLES;
  139 +
  140 +--
  141 +-- Table structure for table `device_mobile_position`
  142 +--
  143 +
  144 +DROP TABLE IF EXISTS `device_mobile_position`;
  145 +/*!40101 SET @saved_cs_client = @@character_set_client */;
  146 +/*!50503 SET character_set_client = utf8mb4 */;
  147 +CREATE TABLE `device_mobile_position` (
  148 + `deviceId` varchar(50) NOT NULL,
  149 + `channelId` varchar(50) NOT NULL,
  150 + `deviceName` varchar(255) DEFAULT NULL,
  151 + `time` varchar(50) NOT NULL,
  152 + `longitude` double NOT NULL,
  153 + `latitude` double NOT NULL,
  154 + `altitude` double DEFAULT NULL,
  155 + `speed` double DEFAULT NULL,
  156 + `direction` double DEFAULT NULL,
  157 + `reportSource` varchar(50) DEFAULT NULL,
  158 + `geodeticSystem` varchar(50) DEFAULT NULL,
  159 + `cnLng` varchar(50) DEFAULT NULL,
  160 + `cnLat` varchar(50) DEFAULT NULL,
  161 + PRIMARY KEY (`deviceId`,`time`)
  162 +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
  163 +/*!40101 SET character_set_client = @saved_cs_client */;
  164 +
  165 +--
  166 +-- Dumping data for table `device_mobile_position`
  167 +--
  168 +
  169 +LOCK TABLES `device_mobile_position` WRITE;
  170 +/*!40000 ALTER TABLE `device_mobile_position` DISABLE KEYS */;
  171 +/*!40000 ALTER TABLE `device_mobile_position` ENABLE KEYS */;
  172 +UNLOCK TABLES;
  173 +
  174 +--
  175 +-- Table structure for table `gb_stream`
  176 +--
  177 +
  178 +DROP TABLE IF EXISTS `gb_stream`;
  179 +/*!40101 SET @saved_cs_client = @@character_set_client */;
  180 +/*!50503 SET character_set_client = utf8mb4 */;
  181 +CREATE TABLE `gb_stream` (
  182 + `app` varchar(255) NOT NULL,
  183 + `stream` varchar(255) NOT NULL,
  184 + `gbId` varchar(50) NOT NULL,
  185 + `name` varchar(255) DEFAULT NULL,
  186 + `longitude` double DEFAULT NULL,
  187 + `latitude` double DEFAULT NULL,
  188 + `streamType` varchar(50) DEFAULT NULL,
  189 + `mediaServerId` varchar(50) DEFAULT NULL,
  190 + `status` int DEFAULT NULL,
  191 + PRIMARY KEY (`app`,`stream`,`gbId`)
  192 +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
  193 +/*!40101 SET character_set_client = @saved_cs_client */;
  194 +
  195 +--
  196 +-- Dumping data for table `gb_stream`
  197 +--
  198 +
  199 +LOCK TABLES `gb_stream` WRITE;
  200 +/*!40000 ALTER TABLE `gb_stream` DISABLE KEYS */;
  201 +INSERT INTO `gb_stream` VALUES ('1000','10000001_52869999','77777777777777777777','shoulei1111',0,0,'push','XR1LEpKlfQtSg9Z1',1);
  202 +/*!40000 ALTER TABLE `gb_stream` ENABLE KEYS */;
  203 +UNLOCK TABLES;
  204 +
  205 +--
  206 +-- Table structure for table `log`
  207 +--
  208 +
  209 +DROP TABLE IF EXISTS `log`;
  210 +/*!40101 SET @saved_cs_client = @@character_set_client */;
  211 +/*!50503 SET character_set_client = utf8mb4 */;
  212 +CREATE TABLE `log` (
  213 + `id` int NOT NULL AUTO_INCREMENT,
  214 + `name` varchar(50) NOT NULL,
  215 + `type` varchar(50) NOT NULL,
  216 + `uri` varchar(200) NOT NULL,
  217 + `address` varchar(50) NOT NULL,
  218 + `result` varchar(50) NOT NULL,
  219 + `timing` bigint NOT NULL,
  220 + `username` varchar(50) NOT NULL,
  221 + `createTime` varchar(50) NOT NULL,
  222 + PRIMARY KEY (`id`)
  223 +) ENGINE=InnoDB AUTO_INCREMENT=21 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
  224 +/*!40101 SET character_set_client = @saved_cs_client */;
  225 +
  226 +--
  227 +-- Dumping data for table `log`
  228 +--
  229 +
  230 +LOCK TABLES `log` WRITE;
  231 +/*!40000 ALTER TABLE `log` DISABLE KEYS */;
  232 +INSERT INTO `log` VALUES (1,'登录','GET','/api/user/login','127.0.0.1','200 OK',245,'admin','2022-01-05 15:09:06'),(2,'添加上级平台','POST','/api/platform/save','127.0.0.1','200 OK',88,'admin','2022-01-05 15:09:24'),(3,'[设备查询] 同步设备通道','POST','/api/device/query/devices/34020000001320000005/sync','127.0.0.1','200 OK',17,'admin','2022-01-05 15:11:21'),(4,'[设备查询] 同步设备通道','POST','/api/device/query/devices/34020000002000000005/sync','127.0.0.1','200 OK',4,'admin','2022-01-05 15:11:25'),(5,'[设备查询] 同步设备通道','POST','/api/device/query/devices/44010000001110008008/sync','127.0.0.1','200 OK',4,'admin','2022-01-05 15:11:26'),(6,'向上级平台添加国标通道','POST','/api/platform/update_channel_for_gb','127.0.0.1','200 OK',52,'admin','2022-01-05 15:11:32'),(7,'从上级平台移除国标通道','DELETE','/api/platform/del_channel_for_gb','127.0.0.1','200 OK',35,'admin','2022-01-05 15:11:34'),(8,'向上级平台添加国标通道','POST','/api/platform/update_channel_for_gb','127.0.0.1','200 OK',39,'admin','2022-01-05 15:11:35'),(9,'从上级平台移除国标通道','DELETE','/api/platform/del_channel_for_gb','127.0.0.1','200 OK',46,'admin','2022-01-05 15:14:00'),(10,'向上级平台添加国标通道','POST','/api/platform/update_channel_for_gb','127.0.0.1','200 OK',59,'admin','2022-01-05 15:14:01'),(11,'添加通道与国标的关联','POST','/api/gbStream/add','127.0.0.1','200 OK',12,'admin','2022-01-05 15:14:16'),(12,'添加通道与国标的关联','POST','/api/gbStream/add','127.0.0.1','200 OK',8,'admin','2022-01-05 15:14:17'),(13,'添加通道与国标的关联','POST','/api/gbStream/add','127.0.0.1','200 OK',6,'admin','2022-01-05 15:14:19'),(14,'添加通道与国标的关联','POST','/api/gbStream/add','127.0.0.1','200 OK',8,'admin','2022-01-05 15:14:19'),(15,'移除通道与国标的关联','DELETE','/api/gbStream/del','127.0.0.1','200 OK',11,'admin','2022-01-05 15:14:21'),(16,'添加通道与国标的关联','POST','/api/gbStream/add','127.0.0.1','200 OK',42,'admin','2022-01-05 15:14:24'),(17,'移除通道与国标的关联','DELETE','/api/gbStream/del','127.0.0.1','200 OK',43,'admin','2022-01-05 15:14:25'),(18,'添加通道与国标的关联','POST','/api/gbStream/add','127.0.0.1','200 OK',9,'admin','2022-01-05 15:14:27'),(19,'添加通道与国标的关联','POST','/api/gbStream/add','127.0.0.1','200 OK',9,'admin','2022-01-05 15:14:37'),(20,'添加通道与国标的关联','POST','/api/gbStream/add','127.0.0.1','200 OK',10,'admin','2022-01-05 15:14:38');
  233 +/*!40000 ALTER TABLE `log` ENABLE KEYS */;
  234 +UNLOCK TABLES;
  235 +
  236 +--
  237 +-- Table structure for table `media_server`
  238 +--
  239 +
  240 +DROP TABLE IF EXISTS `media_server`;
  241 +/*!40101 SET @saved_cs_client = @@character_set_client */;
  242 +/*!50503 SET character_set_client = utf8mb4 */;
  243 +CREATE TABLE `media_server` (
  244 + `id` varchar(255) NOT NULL,
  245 + `ip` varchar(50) NOT NULL,
  246 + `hookIp` varchar(50) NOT NULL,
  247 + `sdpIp` varchar(50) NOT NULL,
  248 + `streamIp` varchar(50) NOT NULL,
  249 + `httpPort` int NOT NULL,
  250 + `httpSSlPort` int NOT NULL,
  251 + `rtmpPort` int NOT NULL,
  252 + `rtmpSSlPort` int NOT NULL,
  253 + `rtpProxyPort` int NOT NULL,
  254 + `rtspPort` int NOT NULL,
  255 + `rtspSSLPort` int NOT NULL,
  256 + `autoConfig` int NOT NULL,
  257 + `secret` varchar(50) NOT NULL,
  258 + `streamNoneReaderDelayMS` int NOT NULL,
  259 + `rtpEnable` int NOT NULL,
  260 + `rtpPortRange` varchar(50) NOT NULL,
  261 + `sendRtpPortRange` varchar(50) NOT NULL,
  262 + `recordAssistPort` int NOT NULL,
  263 + `defaultServer` int NOT NULL,
  264 + `createTime` varchar(50) NOT NULL,
  265 + `updateTime` varchar(50) NOT NULL,
  266 + `hookAliveInterval` int NOT NULL,
  267 + PRIMARY KEY (`id`),
  268 + UNIQUE KEY `media_server_i` (`ip`,`httpPort`)
  269 +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
  270 +/*!40101 SET character_set_client = @saved_cs_client */;
  271 +
  272 +--
  273 +-- Dumping data for table `media_server`
  274 +--
  275 +
  276 +LOCK TABLES `media_server` WRITE;
  277 +/*!40000 ALTER TABLE `media_server` DISABLE KEYS */;
  278 +INSERT INTO `media_server` VALUES ('XR1LEpKlfQtSg9Z1','192.168.1.3','127.0.0.1','192.168.1.3','192.168.1.3',6080,0,10935,0,10000,10554,0,1,'035c73f7-bb6b-4889-a715-d9eb2d1925cc',100000,1,'30000,30500','30000,30500',18081,1,'2022-01-05 15:08:27','2022-01-05 15:08:27',10);
  279 +/*!40000 ALTER TABLE `media_server` ENABLE KEYS */;
  280 +UNLOCK TABLES;
  281 +
  282 +--
  283 +-- Table structure for table `parent_platform`
  284 +--
  285 +
  286 +DROP TABLE IF EXISTS `parent_platform`;
  287 +/*!40101 SET @saved_cs_client = @@character_set_client */;
  288 +/*!50503 SET character_set_client = utf8mb4 */;
  289 +CREATE TABLE `parent_platform` (
  290 + `id` int NOT NULL AUTO_INCREMENT,
  291 + `enable` int DEFAULT NULL,
  292 + `name` varchar(255) DEFAULT NULL,
  293 + `serverGBId` varchar(50) NOT NULL,
  294 + `serverGBDomain` varchar(50) DEFAULT NULL,
  295 + `serverIP` varchar(50) DEFAULT NULL,
  296 + `serverPort` int DEFAULT NULL,
  297 + `deviceGBId` varchar(50) NOT NULL,
  298 + `deviceIp` varchar(50) DEFAULT NULL,
  299 + `devicePort` varchar(50) DEFAULT NULL,
  300 + `username` varchar(255) DEFAULT NULL,
  301 + `password` varchar(50) DEFAULT NULL,
  302 + `expires` varchar(50) DEFAULT NULL,
  303 + `keepTimeout` varchar(50) DEFAULT NULL,
  304 + `transport` varchar(50) DEFAULT NULL,
  305 + `characterSet` varchar(50) DEFAULT NULL,
  306 + `catalogId` varchar(50) NOT NULL,
  307 + `ptz` int DEFAULT NULL,
  308 + `rtcp` int DEFAULT NULL,
  309 + `status` bit(1) DEFAULT NULL,
  310 + `shareAllLiveStream` int DEFAULT NULL,
  311 + PRIMARY KEY (`id`,`serverGBId`)
  312 +) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
  313 +/*!40101 SET character_set_client = @saved_cs_client */;
  314 +
  315 +--
  316 +-- Dumping data for table `parent_platform`
  317 +--
  318 +
  319 +LOCK TABLES `parent_platform` WRITE;
  320 +/*!40000 ALTER TABLE `parent_platform` DISABLE KEYS */;
  321 +INSERT INTO `parent_platform` VALUES (1,1,'1112','1111111111111','1111111111','11.11.11.11',111111,'34020000002110000015','192.168.1.3','5060','34020000002110000015','12345678','300','60','UDP','GB2312','1111111111111',1,0,_binary '\0',1);
  322 +/*!40000 ALTER TABLE `parent_platform` ENABLE KEYS */;
  323 +UNLOCK TABLES;
  324 +
  325 +--
  326 +-- Table structure for table `platform_catalog`
  327 +--
  328 +
  329 +DROP TABLE IF EXISTS `platform_catalog`;
  330 +/*!40101 SET @saved_cs_client = @@character_set_client */;
  331 +/*!50503 SET character_set_client = utf8mb4 */;
  332 +CREATE TABLE `platform_catalog` (
  333 + `id` varchar(50) NOT NULL,
  334 + `platformId` varchar(50) NOT NULL,
  335 + `name` varchar(255) NOT NULL,
  336 + `parentId` varchar(50) DEFAULT NULL,
  337 + PRIMARY KEY (`id`)
  338 +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
  339 +/*!40101 SET character_set_client = @saved_cs_client */;
  340 +
  341 +--
  342 +-- Dumping data for table `platform_catalog`
  343 +--
  344 +
  345 +LOCK TABLES `platform_catalog` WRITE;
  346 +/*!40000 ALTER TABLE `platform_catalog` DISABLE KEYS */;
  347 +INSERT INTO `platform_catalog` VALUES ('1111111111','1111111111111','11122','1111111111111');
  348 +/*!40000 ALTER TABLE `platform_catalog` ENABLE KEYS */;
  349 +UNLOCK TABLES;
  350 +
  351 +--
  352 +-- Table structure for table `platform_gb_channel`
  353 +--
  354 +
  355 +DROP TABLE IF EXISTS `platform_gb_channel`;
  356 +/*!40101 SET @saved_cs_client = @@character_set_client */;
  357 +/*!50503 SET character_set_client = utf8mb4 */;
  358 +CREATE TABLE `platform_gb_channel` (
  359 + `channelId` varchar(50) NOT NULL,
  360 + `deviceId` varchar(50) NOT NULL,
  361 + `platformId` varchar(50) NOT NULL,
  362 + `deviceAndChannelId` varchar(50) NOT NULL,
  363 + `catalogId` varchar(50) NOT NULL,
  364 + PRIMARY KEY (`deviceAndChannelId`,`platformId`)
  365 +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
  366 +/*!40101 SET character_set_client = @saved_cs_client */;
  367 +
  368 +--
  369 +-- Dumping data for table `platform_gb_channel`
  370 +--
  371 +
  372 +LOCK TABLES `platform_gb_channel` WRITE;
  373 +/*!40000 ALTER TABLE `platform_gb_channel` DISABLE KEYS */;
  374 +INSERT INTO `platform_gb_channel` VALUES ('34020000001310000001','34020000001320000005','1111111111111','34020000001320000005_34020000001310000001','1111111111'),('34020000001310000001','34020000002000000005','1111111111111','34020000002000000005_34020000001310000001','1111111111'),('34020000001310000065','34020000002000000005','1111111111111','34020000002000000005_34020000001310000065','1111111111'),('34020000001320000001','44010000001110008008','1111111111111','44010000001110008008_34020000001320000001','1111111111');
  375 +/*!40000 ALTER TABLE `platform_gb_channel` ENABLE KEYS */;
  376 +UNLOCK TABLES;
  377 +
  378 +--
  379 +-- Table structure for table `platform_gb_stream`
  380 +--
  381 +
  382 +DROP TABLE IF EXISTS `platform_gb_stream`;
  383 +/*!40101 SET @saved_cs_client = @@character_set_client */;
  384 +/*!50503 SET character_set_client = utf8mb4 */;
  385 +CREATE TABLE `platform_gb_stream` (
  386 + `platformId` varchar(50) NOT NULL,
  387 + `app` varchar(255) NOT NULL,
  388 + `stream` varchar(255) NOT NULL,
  389 + `catalogId` varchar(50) NOT NULL,
  390 + PRIMARY KEY (`platformId`,`app`,`stream`)
  391 +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
  392 +/*!40101 SET character_set_client = @saved_cs_client */;
  393 +
  394 +--
  395 +-- Dumping data for table `platform_gb_stream`
  396 +--
  397 +
  398 +LOCK TABLES `platform_gb_stream` WRITE;
  399 +/*!40000 ALTER TABLE `platform_gb_stream` DISABLE KEYS */;
  400 +INSERT INTO `platform_gb_stream` VALUES ('1111111111111','1000','10000001_52869999','1111111111');
  401 +/*!40000 ALTER TABLE `platform_gb_stream` ENABLE KEYS */;
  402 +UNLOCK TABLES;
  403 +
  404 +--
  405 +-- Table structure for table `role`
  406 +--
  407 +
  408 +DROP TABLE IF EXISTS `role`;
  409 +/*!40101 SET @saved_cs_client = @@character_set_client */;
  410 +/*!50503 SET character_set_client = utf8mb4 */;
  411 +CREATE TABLE `role` (
  412 + `id` int NOT NULL AUTO_INCREMENT,
  413 + `name` text NOT NULL,
  414 + `authority` text NOT NULL,
  415 + `createTime` varchar(50) NOT NULL,
  416 + `updateTime` varchar(50) NOT NULL,
  417 + PRIMARY KEY (`id`)
  418 +) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
  419 +/*!40101 SET character_set_client = @saved_cs_client */;
  420 +
  421 +--
  422 +-- Dumping data for table `role`
  423 +--
  424 +
  425 +LOCK TABLES `role` WRITE;
  426 +/*!40000 ALTER TABLE `role` DISABLE KEYS */;
  427 +INSERT INTO `role` VALUES (1,'admin','0','2021-04-13 14:14:57','2021-04-13 14:14:57');
  428 +/*!40000 ALTER TABLE `role` ENABLE KEYS */;
  429 +UNLOCK TABLES;
  430 +
  431 +--
  432 +-- Table structure for table `stream_proxy`
  433 +--
  434 +
  435 +DROP TABLE IF EXISTS `stream_proxy`;
  436 +/*!40101 SET @saved_cs_client = @@character_set_client */;
  437 +/*!50503 SET character_set_client = utf8mb4 */;
  438 +CREATE TABLE `stream_proxy` (
  439 + `type` varchar(50) NOT NULL,
  440 + `app` varchar(255) NOT NULL,
  441 + `stream` varchar(255) NOT NULL,
  442 + `url` varchar(255) DEFAULT NULL,
  443 + `src_url` varchar(255) DEFAULT NULL,
  444 + `dst_url` varchar(255) DEFAULT NULL,
  445 + `timeout_ms` int DEFAULT NULL,
  446 + `ffmpeg_cmd_key` varchar(255) DEFAULT NULL,
  447 + `rtp_type` varchar(50) DEFAULT NULL,
  448 + `mediaServerId` varchar(50) DEFAULT NULL,
  449 + `enable_hls` bit(1) DEFAULT NULL,
  450 + `enable_mp4` bit(1) DEFAULT NULL,
  451 + `enable` bit(1) NOT NULL,
  452 + `enable_remove_none_reader` bit(1) NOT NULL,
  453 + `createTime` varchar(50) NOT NULL,
  454 + PRIMARY KEY (`app`,`stream`)
  455 +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
  456 +/*!40101 SET character_set_client = @saved_cs_client */;
  457 +
  458 +--
  459 +-- Dumping data for table `stream_proxy`
  460 +--
  461 +
  462 +LOCK TABLES `stream_proxy` WRITE;
  463 +/*!40000 ALTER TABLE `stream_proxy` DISABLE KEYS */;
  464 +/*!40000 ALTER TABLE `stream_proxy` ENABLE KEYS */;
  465 +UNLOCK TABLES;
  466 +
  467 +--
  468 +-- Table structure for table `stream_push`
  469 +--
  470 +
  471 +DROP TABLE IF EXISTS `stream_push`;
  472 +/*!40101 SET @saved_cs_client = @@character_set_client */;
  473 +/*!50503 SET character_set_client = utf8mb4 */;
  474 +CREATE TABLE `stream_push` (
  475 + `app` varchar(255) NOT NULL,
  476 + `stream` varchar(255) NOT NULL,
  477 + `totalReaderCount` varchar(50) DEFAULT NULL,
  478 + `originType` int DEFAULT NULL,
  479 + `originTypeStr` varchar(50) DEFAULT NULL,
  480 + `createStamp` int DEFAULT NULL,
  481 + `aliveSecond` int DEFAULT NULL,
  482 + `mediaServerId` varchar(50) DEFAULT NULL,
  483 + PRIMARY KEY (`app`,`stream`)
  484 +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
  485 +/*!40101 SET character_set_client = @saved_cs_client */;
  486 +
  487 +--
  488 +-- Dumping data for table `stream_push`
  489 +--
  490 +
  491 +LOCK TABLES `stream_push` WRITE;
  492 +/*!40000 ALTER TABLE `stream_push` DISABLE KEYS */;
  493 +INSERT INTO `stream_push` VALUES ('1000','10000001_52869999','0',2,'rtsp_push',1641366850,0,'XR1LEpKlfQtSg9Z1');
  494 +/*!40000 ALTER TABLE `stream_push` ENABLE KEYS */;
  495 +UNLOCK TABLES;
  496 +
  497 +--
  498 +-- Table structure for table `user`
  499 +--
  500 +
  501 +DROP TABLE IF EXISTS `user`;
  502 +/*!40101 SET @saved_cs_client = @@character_set_client */;
  503 +/*!50503 SET character_set_client = utf8mb4 */;
  504 +CREATE TABLE `user` (
  505 + `id` int NOT NULL AUTO_INCREMENT,
  506 + `username` varchar(255) NOT NULL,
  507 + `password` varchar(255) NOT NULL,
  508 + `roleId` int NOT NULL,
  509 + `createTime` varchar(50) NOT NULL,
  510 + `updateTime` varchar(50) NOT NULL,
  511 + PRIMARY KEY (`id`),
  512 + UNIQUE KEY `user_username_uindex` (`username`)
  513 +) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
  514 +/*!40101 SET character_set_client = @saved_cs_client */;
  515 +
  516 +--
  517 +-- Dumping data for table `user`
  518 +--
  519 +
  520 +LOCK TABLES `user` WRITE;
  521 +/*!40000 ALTER TABLE `user` DISABLE KEYS */;
  522 +INSERT INTO `user` VALUES (1,'admin','21232f297a57a5a743894a0e4a801fc3',1,'2021-04-13 14:14:57','2021-04-13 14:14:57');
  523 +/*!40000 ALTER TABLE `user` ENABLE KEYS */;
  524 +UNLOCK TABLES;
  525 +
  526 +--
  527 +-- Dumping routines for database 'wvp'
  528 +--
  529 +/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
  530 +
  531 +/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
  532 +/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
  533 +/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
  534 +/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
  535 +/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
  536 +/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
  537 +/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
  538 +
  539 +-- Dump completed on 2022-01-05 15:15:35
... ...
sql/mysql.sql
... ... @@ -171,6 +171,7 @@ create table parent_platform
171 171 keepTimeout varchar(50) null,
172 172 transport varchar(50) null,
173 173 characterSet varchar(50) null,
  174 + catalogId varchar(50) not null,
174 175 ptz int null,
175 176 rtcp int null,
176 177 status bit null,
... ... @@ -178,12 +179,22 @@ create table parent_platform
178 179 primary key (id, serverGBId)
179 180 );
180 181  
  182 +
  183 +create table platform_catalog
  184 +(
  185 + id varchar(50) primary key,
  186 + platformId varchar(50) not null,
  187 + name varchar(255) not null,
  188 + parentId varchar(50)
  189 +);
  190 +
181 191 create table platform_gb_channel
182 192 (
183 193 channelId varchar(50) not null,
184 194 deviceId varchar(50) not null,
185 195 platformId varchar(50) not null,
186 196 deviceAndChannelId varchar(50) not null,
  197 + catalogId varchar(50) not null,
187 198 primary key (deviceAndChannelId, platformId)
188 199 );
189 200  
... ... @@ -192,6 +203,7 @@ create table platform_gb_stream
192 203 platformId varchar(50) not null,
193 204 app varchar(255) not null,
194 205 stream varchar(255) not null,
  206 + catalogId varchar(50) not null,
195 207 primary key (platformId, app, stream)
196 208 );
197 209  
... ...
src/main/java/com/genersoft/iot/vmp/common/VideoManagerConstants.java
... ... @@ -58,9 +58,15 @@ public class VideoManagerConstants {
58 58  
59 59 public static final String SIP_CSEQ_PREFIX = "VMP_SIP_CSEQ_";
60 60  
  61 + public static final String SIP_SN_PREFIX = "VMP_SIP_SN_";
  62 +
  63 + public static final String SIP_SUBSCRIBE_PREFIX = "SIP_SUBSCRIBE_";
  64 +
61 65 //************************** redis 消息*********************************
62 66 public static final String WVP_MSG_STREAM_CHANGE_PREFIX = "WVP_MSG_STREAM_CHANGE_";
  67 + public static final String WVP_MSG_GPS_PREFIX = "WVP_MSG_GPS_";
63 68  
64 69 //************************** 第三方 ****************************************
65 70 public static final String WVP_STREAM_GB_ID_PREFIX = "memberNo_";
  71 + public static final String WVP_STREAM_GPS_MSG_PREFIX = "WVP_STREAM_GPS_MSG_";
66 72 }
... ...
src/main/java/com/genersoft/iot/vmp/conf/RedisConfig.java
1 1 package com.genersoft.iot.vmp.conf;
2 2  
  3 +import com.genersoft.iot.vmp.common.VideoManagerConstants;
  4 +import com.genersoft.iot.vmp.service.impl.RedisGPSMsgListener;
3 5 import org.apache.commons.lang3.StringUtils;
  6 +import org.springframework.beans.factory.annotation.Autowired;
4 7 import org.springframework.beans.factory.annotation.Value;
5 8 import org.springframework.cache.annotation.CachingConfigurerSupport;
6 9 import org.springframework.context.annotation.Bean;
7 10 import org.springframework.context.annotation.Configuration;
8 11 import org.springframework.data.redis.connection.RedisConnectionFactory;
9 12 import org.springframework.data.redis.core.RedisTemplate;
  13 +import org.springframework.data.redis.listener.PatternTopic;
10 14 import org.springframework.data.redis.listener.RedisMessageListenerContainer;
11 15 import org.springframework.data.redis.serializer.StringRedisSerializer;
12 16  
... ... @@ -41,6 +45,9 @@ public class RedisConfig extends CachingConfigurerSupport {
41 45 @Value("${spring.redis.poolMaxWait:5}")
42 46 private int poolMaxWait;
43 47  
  48 + @Autowired
  49 + private RedisGPSMsgListener redisGPSMsgListener;
  50 +
44 51 @Bean
45 52 public JedisPool jedisPool() {
46 53 if (StringUtils.isBlank(password)) {
... ... @@ -85,6 +92,7 @@ public class RedisConfig extends CachingConfigurerSupport {
85 92  
86 93 RedisMessageListenerContainer container = new RedisMessageListenerContainer();
87 94 container.setConnectionFactory(connectionFactory);
  95 + container.addMessageListener(redisGPSMsgListener, new PatternTopic(VideoManagerConstants.WVP_MSG_GPS_PREFIX));
88 96 return container;
89 97 }
90 98  
... ...
src/main/java/com/genersoft/iot/vmp/conf/RedisKeyExpirationEventMessageListener.java 0 → 100644
  1 +package com.genersoft.iot.vmp.conf;
  2 +
  3 +import org.springframework.data.redis.connection.RedisConnection;
  4 +import org.springframework.data.redis.listener.KeyExpirationEventMessageListener;
  5 +import org.springframework.data.redis.listener.RedisMessageListenerContainer;
  6 +import org.springframework.util.StringUtils;
  7 +
  8 +import java.util.Properties;
  9 +
  10 +public class RedisKeyExpirationEventMessageListener extends KeyExpirationEventMessageListener {
  11 +
  12 + private UserSetup userSetup;
  13 + private RedisMessageListenerContainer listenerContainer;
  14 + private String keyspaceNotificationsConfigParameter = "EA";
  15 +
  16 + public RedisKeyExpirationEventMessageListener(RedisMessageListenerContainer listenerContainer, UserSetup userSetup) {
  17 + super(listenerContainer);
  18 + this.listenerContainer = listenerContainer;
  19 + this.userSetup = userSetup;
  20 + }
  21 +
  22 + @Override
  23 + public void init() {
  24 + if (!userSetup.getRedisConfig()) {
  25 + // 配置springboot默认Config为空,即不让应用去修改redis的默认配置,因为Redis服务出于安全会禁用CONFIG命令给远程用户使用
  26 + setKeyspaceNotificationsConfigParameter("");
  27 + }else {
  28 +
  29 + RedisConnection connection = this.listenerContainer.getConnectionFactory().getConnection();
  30 + Properties config = connection.getConfig("notify-keyspace-events");
  31 + try {
  32 + if (!config.getProperty("notify-keyspace-events").equals(keyspaceNotificationsConfigParameter)) {
  33 + connection.setConfig("notify-keyspace-events", keyspaceNotificationsConfigParameter);
  34 + }
  35 + } finally {
  36 + connection.close();
  37 + }
  38 + }
  39 + super.init();
  40 + }
  41 +}
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/bean/CmdType.java 0 → 100644
  1 +package com.genersoft.iot.vmp.gb28181.bean;
  2 +
  3 +public class CmdType {
  4 +
  5 + public static final String CATALOG = "Catalog";
  6 + public static final String ALARM = "Alarm";
  7 + public static final String MOBILE_POSITION = "MobilePosition";
  8 +}
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/bean/DeviceNotFoundEvent.java 0 → 100644
  1 +package com.genersoft.iot.vmp.gb28181.bean;
  2 +
  3 +import javax.sip.Dialog;
  4 +import java.util.EventObject;
  5 +
  6 +public class DeviceNotFoundEvent extends EventObject {
  7 + /**
  8 + * Constructs a prototypical Event.
  9 + *
  10 + * @param dialog
  11 + * @throws IllegalArgumentException if source is null.
  12 + */
  13 + public DeviceNotFoundEvent(Dialog dialog) {
  14 + super(dialog);
  15 + }
  16 +
  17 +
  18 + public Dialog getDialog() {
  19 + return (Dialog)super.getSource();
  20 + }
  21 +}
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/bean/ParentPlatform.java
... ... @@ -109,6 +109,11 @@ public class ParentPlatform {
109 109 */
110 110 private boolean shareAllLiveStream;
111 111  
  112 + /**
  113 + * 默认目录Id,自动添加的通道多放在这个目录下
  114 + */
  115 + private String catalogId;
  116 +
112 117 public Integer getId() {
113 118 return id;
114 119 }
... ... @@ -277,4 +282,12 @@ public class ParentPlatform {
277 282 public void setShareAllLiveStream(boolean shareAllLiveStream) {
278 283 this.shareAllLiveStream = shareAllLiveStream;
279 284 }
  285 +
  286 + public String getCatalogId() {
  287 + return catalogId;
  288 + }
  289 +
  290 + public void setCatalogId(String catalogId) {
  291 + this.catalogId = catalogId;
  292 + }
280 293 }
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/bean/PlatformCatalog.java 0 → 100644
  1 +package com.genersoft.iot.vmp.gb28181.bean;
  2 +
  3 +public class PlatformCatalog {
  4 + private String id;
  5 + private String name;
  6 + private String platformId;
  7 + private String parentId;
  8 + private int childrenCount; // 子节点数
  9 + private int type; // 0 目录, 1 国标通道, 2 直播流
  10 +
  11 + public String getId() {
  12 + return id;
  13 + }
  14 +
  15 + public void setId(String id) {
  16 + this.id = id;
  17 + }
  18 +
  19 + public String getName() {
  20 + return name;
  21 + }
  22 +
  23 + public void setName(String name) {
  24 + this.name = name;
  25 + }
  26 +
  27 + public String getPlatformId() {
  28 + return platformId;
  29 + }
  30 +
  31 + public void setPlatformId(String platformId) {
  32 + this.platformId = platformId;
  33 + }
  34 +
  35 + public String getParentId() {
  36 + return parentId;
  37 + }
  38 +
  39 + public void setParentId(String parentId) {
  40 + this.parentId = parentId;
  41 + }
  42 +
  43 + public int getChildrenCount() {
  44 + return childrenCount;
  45 + }
  46 +
  47 + public void setChildrenCount(int childrenCount) {
  48 + this.childrenCount = childrenCount;
  49 + }
  50 +
  51 + public int getType() {
  52 + return type;
  53 + }
  54 +
  55 + public void setType(int type) {
  56 + this.type = type;
  57 + }
  58 +
  59 + public void setTypeForCatalog() {
  60 + this.type = 0;
  61 + }
  62 +
  63 + public void setTypeForGb() {
  64 + this.type = 1;
  65 + }
  66 +
  67 + public void setTypeForStream() {
  68 + this.type = 2;
  69 + }
  70 +
  71 +}
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/bean/PlatformGbStream.java
... ... @@ -4,6 +4,7 @@ public class PlatformGbStream {
4 4 private String app;
5 5 private String stream;
6 6 private String platformId;
  7 + private String catalogId;
7 8  
8 9 public String getApp() {
9 10 return app;
... ... @@ -29,4 +30,11 @@ public class PlatformGbStream {
29 30 this.platformId = platformId;
30 31 }
31 32  
  33 + public String getCatalogId() {
  34 + return catalogId;
  35 + }
  36 +
  37 + public void setCatalogId(String catalogId) {
  38 + this.catalogId = catalogId;
  39 + }
32 40 }
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/bean/SubscribeInfo.java 0 → 100644
  1 +package com.genersoft.iot.vmp.gb28181.bean;
  2 +
  3 +import javax.sip.RequestEvent;
  4 +import javax.sip.header.*;
  5 +import javax.sip.message.Request;
  6 +
  7 +public class SubscribeInfo {
  8 +
  9 + public SubscribeInfo() {
  10 + }
  11 +
  12 + public SubscribeInfo(RequestEvent evt, String id) {
  13 + this.id = id;
  14 + Request request = evt.getRequest();
  15 + CallIdHeader callIdHeader = (CallIdHeader)request.getHeader(CallIdHeader.NAME);
  16 + this.callId = callIdHeader.getCallId();
  17 + FromHeader fromHeader = (FromHeader)request.getHeader(FromHeader.NAME);
  18 + this.fromTag = fromHeader.getTag();
  19 + ExpiresHeader expiresHeader = (ExpiresHeader)request.getHeader(ExpiresHeader.NAME);
  20 + this.expires = expiresHeader.getExpires();
  21 + this.event = (EventHeader)request.getHeader(EventHeader.NAME);
  22 + }
  23 +
  24 + private String id;
  25 + private int expires;
  26 + private String callId;
  27 + private EventHeader event;
  28 + private String fromTag;
  29 + private String toTag;
  30 +
  31 + public String getId() {
  32 + return id;
  33 + }
  34 +
  35 + public int getExpires() {
  36 + return expires;
  37 + }
  38 +
  39 + public String getCallId() {
  40 + return callId;
  41 + }
  42 +
  43 + public EventHeader getEvent() {
  44 + return event;
  45 + }
  46 +
  47 + public String getFromTag() {
  48 + return fromTag;
  49 + }
  50 +
  51 + public void setToTag(String toTag) {
  52 + this.toTag = toTag;
  53 + }
  54 +
  55 + public String getToTag() {
  56 + return toTag;
  57 + }
  58 +
  59 + public void setId(String id) {
  60 + this.id = id;
  61 + }
  62 +
  63 + public void setExpires(int expires) {
  64 + this.expires = expires;
  65 + }
  66 +
  67 + public void setCallId(String callId) {
  68 + this.callId = callId;
  69 + }
  70 +
  71 + public void setEvent(EventHeader event) {
  72 + this.event = event;
  73 + }
  74 +
  75 + public void setFromTag(String fromTag) {
  76 + this.fromTag = fromTag;
  77 + }
  78 +}
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/event/SipSubscribe.java
1 1 package com.genersoft.iot.vmp.gb28181.event;
2 2  
  3 +import com.genersoft.iot.vmp.gb28181.bean.DeviceNotFoundEvent;
3 4 import org.slf4j.Logger;
4 5 import org.slf4j.LoggerFactory;
5 6 import org.springframework.scheduling.annotation.Scheduled;
... ... @@ -91,6 +92,13 @@ public class SipSubscribe {
91 92 this.statusCode = -1024;
92 93 this.callId = dialogTerminatedEvent.getDialog().getCallId().getCallId();
93 94 this.dialog = dialogTerminatedEvent.getDialog();
  95 + }else if (event instanceof DeviceNotFoundEvent) {
  96 + DeviceNotFoundEvent deviceNotFoundEvent = (DeviceNotFoundEvent)event;
  97 + this.type = "deviceNotFoundEvent";
  98 + this.msg = "设备未找到";
  99 + this.statusCode = -1024;
  100 + this.callId = deviceNotFoundEvent.getDialog().getCallId().getCallId();
  101 + this.dialog = deviceNotFoundEvent.getDialog();
94 102 }
95 103 }
96 104 }
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/event/offline/KeepaliveTimeoutListenerForPlatform.java
1 1 package com.genersoft.iot.vmp.gb28181.event.offline;
2 2  
  3 +import com.genersoft.iot.vmp.conf.RedisKeyExpirationEventMessageListener;
3 4 import com.genersoft.iot.vmp.conf.UserSetup;
4 5 import org.slf4j.Logger;
5 6 import org.slf4j.LoggerFactory;
... ... @@ -7,12 +8,16 @@ import org.springframework.beans.factory.InitializingBean;
7 8 import org.springframework.beans.factory.annotation.Autowired;
8 9 import org.springframework.context.annotation.DependsOn;
9 10 import org.springframework.data.redis.connection.Message;
  11 +import org.springframework.data.redis.connection.RedisConnection;
10 12 import org.springframework.data.redis.listener.KeyExpirationEventMessageListener;
11 13 import org.springframework.data.redis.listener.RedisMessageListenerContainer;
12 14 import org.springframework.stereotype.Component;
13 15  
14 16 import com.genersoft.iot.vmp.common.VideoManagerConstants;
15 17 import com.genersoft.iot.vmp.gb28181.event.EventPublisher;
  18 +import org.springframework.util.StringUtils;
  19 +
  20 +import java.util.Properties;
16 21  
17 22 /**
18 23 * @description:设备心跳超时监听,借助redis过期特性,进行监听,监听到说明设备心跳超时,发送离线事件
... ... @@ -20,7 +25,7 @@ import com.genersoft.iot.vmp.gb28181.event.EventPublisher;
20 25 * @date: 2020年5月6日 上午11:35:46
21 26 */
22 27 @Component
23   -public class KeepaliveTimeoutListenerForPlatform extends KeyExpirationEventMessageListener {
  28 +public class KeepaliveTimeoutListenerForPlatform extends RedisKeyExpirationEventMessageListener {
24 29  
25 30 private Logger logger = LoggerFactory.getLogger(KeepaliveTimeoutListenerForPlatform.class);
26 31  
... ... @@ -30,17 +35,8 @@ public class KeepaliveTimeoutListenerForPlatform extends KeyExpirationEventMessa
30 35 @Autowired
31 36 private UserSetup userSetup;
32 37  
33   - @Override
34   - public void init() {
35   - if (!userSetup.getRedisConfig()) {
36   - // 配置springboot默认Config为空,即不让应用去修改redis的默认配置,因为Redis服务出于安全会禁用CONFIG命令给远程用户使用
37   - setKeyspaceNotificationsConfigParameter("");
38   - }
39   - super.init();
40   - }
41   -
42   - public KeepaliveTimeoutListenerForPlatform(RedisMessageListenerContainer listenerContainer) {
43   - super(listenerContainer);
  38 + public KeepaliveTimeoutListenerForPlatform(RedisMessageListenerContainer listenerContainer, UserSetup userSetup) {
  39 + super(listenerContainer, userSetup);
44 40 }
45 41  
46 42  
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/event/offline/KeepliveTimeoutListener.java
1 1 package com.genersoft.iot.vmp.gb28181.event.offline;
2 2  
  3 +import com.genersoft.iot.vmp.conf.RedisKeyExpirationEventMessageListener;
3 4 import com.genersoft.iot.vmp.conf.UserSetup;
4 5 import org.slf4j.Logger;
5 6 import org.slf4j.LoggerFactory;
... ... @@ -20,7 +21,7 @@ import com.genersoft.iot.vmp.gb28181.event.EventPublisher;
20 21 * @date: 2020年5月6日 上午11:35:46
21 22 */
22 23 @Component
23   -public class KeepliveTimeoutListener extends KeyExpirationEventMessageListener {
  24 +public class KeepliveTimeoutListener extends RedisKeyExpirationEventMessageListener {
24 25  
25 26 private Logger logger = LoggerFactory.getLogger(KeepliveTimeoutListener.class);
26 27  
... ... @@ -30,6 +31,10 @@ public class KeepliveTimeoutListener extends KeyExpirationEventMessageListener {
30 31 @Autowired
31 32 private UserSetup userSetup;
32 33  
  34 + public KeepliveTimeoutListener(RedisMessageListenerContainer listenerContainer, UserSetup userSetup) {
  35 + super(listenerContainer, userSetup);
  36 + }
  37 +
33 38 @Override
34 39 public void init() {
35 40 if (!userSetup.getRedisConfig()) {
... ... @@ -39,9 +44,6 @@ public class KeepliveTimeoutListener extends KeyExpirationEventMessageListener {
39 44 super.init();
40 45 }
41 46  
42   - public KeepliveTimeoutListener(RedisMessageListenerContainer listenerContainer) {
43   - super(listenerContainer);
44   - }
45 47  
46 48 /**
47 49 * 监听失效的key,key格式为keeplive_deviceId
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/event/subscribe/SubscribeListenerForPlatform.java 0 → 100644
  1 +package com.genersoft.iot.vmp.gb28181.event.subscribe;
  2 +
  3 +import com.genersoft.iot.vmp.common.VideoManagerConstants;
  4 +import com.genersoft.iot.vmp.conf.DynamicTask;
  5 +import com.genersoft.iot.vmp.conf.RedisKeyExpirationEventMessageListener;
  6 +import com.genersoft.iot.vmp.conf.UserSetup;
  7 +import com.genersoft.iot.vmp.gb28181.event.EventPublisher;
  8 +import org.checkerframework.checker.units.qual.A;
  9 +import org.slf4j.Logger;
  10 +import org.slf4j.LoggerFactory;
  11 +import org.springframework.beans.factory.annotation.Autowired;
  12 +import org.springframework.data.redis.connection.Message;
  13 +import org.springframework.data.redis.listener.RedisMessageListenerContainer;
  14 +import org.springframework.stereotype.Component;
  15 +
  16 +/**
  17 + * 平台订阅到期事件
  18 + */
  19 +@Component
  20 +public class SubscribeListenerForPlatform extends RedisKeyExpirationEventMessageListener {
  21 +
  22 + private Logger logger = LoggerFactory.getLogger(SubscribeListenerForPlatform.class);
  23 +
  24 + @Autowired
  25 + private UserSetup userSetup;
  26 +
  27 + @Autowired
  28 + private DynamicTask dynamicTask;
  29 +
  30 + public SubscribeListenerForPlatform(RedisMessageListenerContainer listenerContainer, UserSetup userSetup) {
  31 + super(listenerContainer, userSetup);
  32 + }
  33 +
  34 +
  35 + /**
  36 + * 监听失效的key
  37 + * @param message
  38 + * @param pattern
  39 + */
  40 + @Override
  41 + public void onMessage(Message message, byte[] pattern) {
  42 + // 获取失效的key
  43 + String expiredKey = message.toString();
  44 + logger.debug(expiredKey);
  45 + // 订阅到期
  46 + String PLATFORM_KEEPLIVEKEY_PREFIX = VideoManagerConstants.SIP_SUBSCRIBE_PREFIX + userSetup.getServerId() + "_";
  47 + if (expiredKey.startsWith(PLATFORM_KEEPLIVEKEY_PREFIX)) {
  48 + // 取消定时任务
  49 + dynamicTask.stopCron(expiredKey);
  50 + }
  51 + }
  52 +}
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/task/GPSSubscribeTask.java 0 → 100644
  1 +package com.genersoft.iot.vmp.gb28181.task;
  2 +
  3 +import com.genersoft.iot.vmp.gb28181.bean.GbStream;
  4 +import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform;
  5 +import com.genersoft.iot.vmp.gb28181.bean.SubscribeInfo;
  6 +import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform;
  7 +import com.genersoft.iot.vmp.service.bean.GPSMsgInfo;
  8 +import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
  9 +import com.genersoft.iot.vmp.storager.IVideoManagerStorager;
  10 +
  11 +import java.text.SimpleDateFormat;
  12 +import java.util.List;
  13 +
  14 +public class GPSSubscribeTask implements Runnable{
  15 +
  16 + private IRedisCatchStorage redisCatchStorage;
  17 + private IVideoManagerStorager storager;
  18 + private ISIPCommanderForPlatform sipCommanderForPlatform;
  19 + private String platformId;
  20 + private String sn;
  21 + private String key;
  22 +
  23 + private final SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
  24 +
  25 + public GPSSubscribeTask(IRedisCatchStorage redisCatchStorage, ISIPCommanderForPlatform sipCommanderForPlatform, IVideoManagerStorager storager, String platformId, String sn, String key) {
  26 + this.redisCatchStorage = redisCatchStorage;
  27 + this.storager = storager;
  28 + this.platformId = platformId;
  29 + this.sn = sn;
  30 + this.key = key;
  31 + this.sipCommanderForPlatform = sipCommanderForPlatform;
  32 + }
  33 +
  34 + @Override
  35 + public void run() {
  36 +
  37 + SubscribeInfo subscribe = redisCatchStorage.getSubscribe(key);
  38 + if (subscribe != null) {
  39 + System.out.println("发送GPS消息");
  40 + ParentPlatform parentPlatform = storager.queryParentPlatByServerGBId(platformId);
  41 + if (parentPlatform == null || parentPlatform.isStatus()) {
  42 + // TODO 暂时只处理视频流的回复,后续增加对国标设备的支持
  43 + List<GbStream> gbStreams = storager.queryGbStreamListInPlatform(platformId);
  44 + if (gbStreams.size() > 0) {
  45 + for (GbStream gbStream : gbStreams) {
  46 + String gbId = gbStream.getGbId();
  47 + GPSMsgInfo gpsMsgInfo = redisCatchStorage.getGpsMsgInfo(gbId);
  48 + if (gbStream.isStatus()) {
  49 + if (gpsMsgInfo != null) {
  50 + // 发送GPS消息
  51 + sipCommanderForPlatform.sendMobilePosition(parentPlatform, gpsMsgInfo, subscribe);
  52 + }else {
  53 + // 没有在redis找到新的消息就使用数据库的消息
  54 + gpsMsgInfo = new GPSMsgInfo();
  55 + gpsMsgInfo.setId(gbId);
  56 + gpsMsgInfo.setLat(gbStream.getLongitude());
  57 + gpsMsgInfo.setLng(gbStream.getLongitude());
  58 + // 发送GPS消息
  59 + sipCommanderForPlatform.sendMobilePosition(parentPlatform, gpsMsgInfo, subscribe);
  60 + }
  61 + }
  62 +
  63 + }
  64 + }
  65 + }
  66 + }
  67 +
  68 +
  69 + }
  70 +}
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPProcessorObserver.java
... ... @@ -94,7 +94,6 @@ public class SIPProcessorObserver implements ISIPProcessorObserver {
94 94 logger.debug(responseEvent.getResponse().toString());
95 95 int status = response.getStatusCode();
96 96 if (((status >= 200) && (status < 300)) || status == 401) { // Success!
97   -// ISIPResponseProcessor processor = processorFactory.createResponseProcessor(evt);
98 97 CSeqHeader cseqHeader = (CSeqHeader) responseEvent.getResponse().getHeader(CSeqHeader.NAME);
99 98 String method = cseqHeader.getMethod();
100 99 ISIPResponseProcessor sipRequestProcessor = responseProcessorMap.get(method);
... ... @@ -108,6 +107,7 @@ public class SIPProcessorObserver implements ISIPProcessorObserver {
108 107 if (subscribe != null) {
109 108 SipSubscribe.EventResult eventResult = new SipSubscribe.EventResult(responseEvent);
110 109 subscribe.response(eventResult);
  110 + sipSubscribe.removeOkSubscribe(callIdHeader.getCallId());
111 111 }
112 112 }
113 113 }
... ... @@ -122,6 +122,7 @@ public class SIPProcessorObserver implements ISIPProcessorObserver {
122 122 if (subscribe != null) {
123 123 SipSubscribe.EventResult eventResult = new SipSubscribe.EventResult(responseEvent);
124 124 subscribe.response(eventResult);
  125 + sipSubscribe.removeErrorSubscribe(callIdHeader.getCallId());
125 126 }
126 127 }
127 128 }
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/ISIPCommanderForPlatform.java
... ... @@ -2,7 +2,9 @@ package com.genersoft.iot.vmp.gb28181.transmit.cmd;
2 2  
3 3 import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel;
4 4 import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform;
  5 +import com.genersoft.iot.vmp.gb28181.bean.SubscribeInfo;
5 6 import com.genersoft.iot.vmp.gb28181.event.SipSubscribe;
  7 +import com.genersoft.iot.vmp.service.bean.GPSMsgInfo;
6 8  
7 9 import javax.sip.header.WWWAuthenticateHeader;
8 10  
... ... @@ -61,4 +63,12 @@ public interface ISIPCommanderForPlatform {
61 63 */
62 64 boolean deviceStatusResponse(ParentPlatform parentPlatform, String sn, String fromTag);
63 65  
  66 + /**
  67 + * 向上级回复移动位置订阅消息
  68 + * @param parentPlatform 平台信息
  69 + * @param gpsMsgInfo GPS信息
  70 + * @param subscribeInfo 订阅相关的信息
  71 + * @return
  72 + */
  73 + boolean sendMobilePosition(ParentPlatform parentPlatform, GPSMsgInfo gpsMsgInfo, SubscribeInfo subscribeInfo);
64 74 }
... ...
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 2  
3 3 import com.genersoft.iot.vmp.conf.SipConfig;
4 4 import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform;
  5 +import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
5 6 import gov.nist.javax.sip.message.MessageFactoryImpl;
6 7 import org.springframework.beans.factory.annotation.Autowired;
7 8 import org.springframework.stereotype.Component;
... ... @@ -32,6 +33,9 @@ public class SIPRequestHeaderPlarformProvider {
32 33 @Autowired
33 34 private SipFactory sipFactory;
34 35  
  36 + @Autowired
  37 + private IRedisCatchStorage redisCatchStorage;
  38 +
35 39  
36 40 public Request createKeetpaliveMessageRequest(ParentPlatform parentPlatform, String content, String viaTag, String fromTag, String toTag, CallIdHeader callIdHeader) throws ParseException, InvalidArgumentException, PeerUnavailableException {
37 41 Request request = null;
... ... @@ -57,7 +61,7 @@ public class SIPRequestHeaderPlarformProvider {
57 61 // Forwards
58 62 MaxForwardsHeader maxForwards = sipFactory.createHeaderFactory().createMaxForwardsHeader(70);
59 63 // ceq
60   - CSeqHeader cSeqHeader = sipFactory.createHeaderFactory().createCSeqHeader(1L, Request.MESSAGE);
  64 + CSeqHeader cSeqHeader = sipFactory.createHeaderFactory().createCSeqHeader(redisCatchStorage.getCSEQ(Request.MESSAGE), Request.MESSAGE);
61 65  
62 66 request = sipFactory.createMessageFactory().createRequest(requestURI, Request.MESSAGE, callIdHeader, cSeqHeader, fromHeader,
63 67 toHeader, viaHeaders, maxForwards);
... ... @@ -122,7 +126,7 @@ public class SIPRequestHeaderPlarformProvider {
122 126 String callId, WWWAuthenticateHeader www , CallIdHeader callIdHeader) throws ParseException, PeerUnavailableException, InvalidArgumentException {
123 127  
124 128  
125   - Request registerRequest = createRegisterRequest(parentPlatform, 2L, fromTag, viaTag, callIdHeader);
  129 + Request registerRequest = createRegisterRequest(parentPlatform, redisCatchStorage.getCSEQ(Request.REGISTER), fromTag, viaTag, callIdHeader);
126 130  
127 131 String realm = www.getRealm();
128 132 String nonce = www.getNonce();
... ... @@ -208,7 +212,7 @@ public class SIPRequestHeaderPlarformProvider {
208 212 // Forwards
209 213 MaxForwardsHeader maxForwards = sipFactory.createHeaderFactory().createMaxForwardsHeader(70);
210 214 // ceq
211   - CSeqHeader cSeqHeader = sipFactory.createHeaderFactory().createCSeqHeader(1L, Request.MESSAGE);
  215 + CSeqHeader cSeqHeader = sipFactory.createHeaderFactory().createCSeqHeader(redisCatchStorage.getCSEQ(Request.MESSAGE), Request.MESSAGE);
212 216 MessageFactoryImpl messageFactory = (MessageFactoryImpl) sipFactory.createMessageFactory();
213 217 // 设置编码, 防止中文乱码
214 218 messageFactory.setDefaultContentEncodingCharset("gb2312");
... ... @@ -223,4 +227,43 @@ public class SIPRequestHeaderPlarformProvider {
223 227 request.setContent(content, contentTypeHeader);
224 228 return request;
225 229 }
  230 +
  231 + public Request createNotifyRequest(ParentPlatform parentPlatform, String content, String fromTag, String toTag, CallIdHeader callIdHeader) throws PeerUnavailableException, ParseException, InvalidArgumentException {
  232 + Request request = null;
  233 + // sipuri
  234 + SipURI requestURI = sipFactory.createAddressFactory().createSipURI(parentPlatform.getServerGBId(), parentPlatform.getServerIP()+ ":" + parentPlatform.getServerPort());
  235 + // via
  236 + ArrayList<ViaHeader> viaHeaders = new ArrayList<ViaHeader>();
  237 + ViaHeader viaHeader = sipFactory.createHeaderFactory().createViaHeader(parentPlatform.getDeviceIp(), Integer.parseInt(parentPlatform.getDevicePort()),
  238 + parentPlatform.getTransport(), null);
  239 + viaHeader.setRPort();
  240 + viaHeaders.add(viaHeader);
  241 + // from
  242 + SipURI fromSipURI = sipFactory.createAddressFactory().createSipURI(parentPlatform.getDeviceGBId(),
  243 + parentPlatform.getDeviceIp() + ":" + parentPlatform.getDevicePort());
  244 + Address fromAddress = sipFactory.createAddressFactory().createAddress(fromSipURI);
  245 + FromHeader fromHeader = sipFactory.createHeaderFactory().createFromHeader(fromAddress, fromTag);
  246 + // to
  247 + SipURI toSipURI = sipFactory.createAddressFactory().createSipURI(parentPlatform.getServerGBId(), parentPlatform.getServerGBDomain());
  248 + Address toAddress = sipFactory.createAddressFactory().createAddress(toSipURI);
  249 + ToHeader toHeader = sipFactory.createHeaderFactory().createToHeader(toAddress, toTag);
  250 +
  251 + // Forwards
  252 + MaxForwardsHeader maxForwards = sipFactory.createHeaderFactory().createMaxForwardsHeader(70);
  253 + // ceq
  254 + CSeqHeader cSeqHeader = sipFactory.createHeaderFactory().createCSeqHeader(redisCatchStorage.getCSEQ(Request.NOTIFY), Request.NOTIFY);
  255 + MessageFactoryImpl messageFactory = (MessageFactoryImpl) sipFactory.createMessageFactory();
  256 + // 设置编码, 防止中文乱码
  257 + messageFactory.setDefaultContentEncodingCharset("gb2312");
  258 + request = messageFactory.createRequest(requestURI, Request.NOTIFY, callIdHeader, cSeqHeader, fromHeader,
  259 + toHeader, viaHeaders, maxForwards);
  260 + List<String> agentParam = new ArrayList<>();
  261 + agentParam.add("wvp-pro");
  262 + UserAgentHeader userAgentHeader = sipFactory.createHeaderFactory().createUserAgentHeader(agentParam);
  263 + request.addHeader(userAgentHeader);
  264 +
  265 + ContentTypeHeader contentTypeHeader = sipFactory.createHeaderFactory().createContentTypeHeader("APPLICATION", "MANSCDP+xml");
  266 + request.setContent(content, contentTypeHeader);
  267 + return request;
  268 + }
226 269 }
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommanderFroPlatform.java
... ... @@ -3,9 +3,11 @@ package com.genersoft.iot.vmp.gb28181.transmit.cmd.impl;
3 3 import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel;
4 4 import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform;
5 5 import com.genersoft.iot.vmp.gb28181.bean.ParentPlatformCatch;
  6 +import com.genersoft.iot.vmp.gb28181.bean.SubscribeInfo;
6 7 import com.genersoft.iot.vmp.gb28181.event.SipSubscribe;
7 8 import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform;
8 9 import com.genersoft.iot.vmp.gb28181.transmit.cmd.SIPRequestHeaderPlarformProvider;
  10 +import com.genersoft.iot.vmp.service.bean.GPSMsgInfo;
9 11 import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
10 12 import org.slf4j.Logger;
11 13 import org.slf4j.LoggerFactory;
... ... @@ -92,7 +94,7 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform {
92 94 callIdHeader = udpSipProvider.getNewCallId();
93 95 }
94 96  
95   - request = headerProviderPlarformProvider.createRegisterRequest(parentPlatform, 1L, "FromRegister" + tm, null, callIdHeader);
  97 + request = headerProviderPlarformProvider.createRegisterRequest(parentPlatform, redisCatchStorage.getCSEQ(Request.REGISTER), "FromRegister" + tm, null, callIdHeader);
96 98 // 将 callid 写入缓存, 等注册成功可以更新状态
97 99 redisCatchStorage.updatePlatformRegisterInfo(callIdHeader.getCallId(), parentPlatform.getServerGBId());
98 100  
... ... @@ -222,7 +224,13 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform {
222 224 catalogXml.append("<Secrecy>" + channel.getSecrecy() + "</Secrecy>\r\n");
223 225 catalogXml.append("<RegisterWay>" + channel.getRegisterWay() + "</RegisterWay>\r\n");
224 226 catalogXml.append("<Status>" + (channel.getStatus() == 0?"OFF":"ON") + "</Status>\r\n");
225   - catalogXml.append("<Info></Info>\r\n");
  227 + catalogXml.append("<Longitude>" + channel.getLongitude() + "</Longitude>\r\n");
  228 + catalogXml.append("<Latitude>" + channel.getLatitude() + "</Latitude>\r\n");
  229 + catalogXml.append("<IPAddress>" + channel.getIpAddress() + "</IPAddress>\r\n");
  230 + catalogXml.append("<Port>" + channel.getPort() + "</Port>\r\n");
  231 + catalogXml.append("<Info>\r\n");
  232 + catalogXml.append("<PTZType>" + channel.getPTZType() + "</PTZType>\r\n");
  233 + catalogXml.append("</Info>\r\n");
226 234 }
227 235  
228 236  
... ... @@ -319,4 +327,41 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform {
319 327 }
320 328 return true;
321 329 }
  330 +
  331 + @Override
  332 + public boolean sendMobilePosition(ParentPlatform parentPlatform, GPSMsgInfo gpsMsgInfo, SubscribeInfo subscribeInfo) {
  333 + if (parentPlatform == null) {
  334 + return false;
  335 + }
  336 +
  337 + try {
  338 + StringBuffer deviceStatusXml = new StringBuffer(600);
  339 + deviceStatusXml.append("<?xml version=\"1.0\" encoding=\"GB2312\"?>\r\n");
  340 + deviceStatusXml.append("<Notify>\r\n");
  341 + deviceStatusXml.append("<CmdType>MobilePosition</CmdType>\r\n");
  342 + deviceStatusXml.append("<SN>" + (int)((Math.random()*9+1)*100000) + "</SN>\r\n");
  343 + deviceStatusXml.append("<DeviceID>" + gpsMsgInfo.getId() + "</DeviceID>\r\n");
  344 + deviceStatusXml.append("<Time>" + gpsMsgInfo.getTime() + "</Time>\r\n");
  345 + deviceStatusXml.append("<Longitude>" + gpsMsgInfo.getLng() + "</Longitude>\r\n");
  346 + deviceStatusXml.append("<Latitude>" + gpsMsgInfo.getLat() + "</Latitude>\r\n");
  347 + deviceStatusXml.append("<Speed>" + gpsMsgInfo.getSpeed() + "</Speed>\r\n");
  348 + deviceStatusXml.append("<Direction>" + gpsMsgInfo.getDirection() + "</Direction>\r\n");
  349 + deviceStatusXml.append("<Altitude>" + gpsMsgInfo.getAltitude() + "</Altitude>\r\n");
  350 + deviceStatusXml.append("</Notify>\r\n");
  351 +
  352 + CallIdHeader callIdHeader = parentPlatform.getTransport().equals("TCP") ? tcpSipProvider.getNewCallId()
  353 + : udpSipProvider.getNewCallId();
  354 + callIdHeader.setCallId(subscribeInfo.getCallId());
  355 +
  356 + String tm = Long.toString(System.currentTimeMillis());
  357 +
  358 + Request request = headerProviderPlarformProvider.createNotifyRequest(parentPlatform, deviceStatusXml.toString(), subscribeInfo.getToTag(), subscribeInfo.getFromTag(), callIdHeader);
  359 + transmitRequest(parentPlatform, request);
  360 +
  361 + } catch (SipException | ParseException | InvalidArgumentException e) {
  362 + e.printStackTrace();
  363 + return false;
  364 + }
  365 + return true;
  366 + }
322 367 }
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/SIPRequestProcessorParent.java
... ... @@ -18,6 +18,7 @@ import javax.sip.address.Address;
18 18 import javax.sip.address.AddressFactory;
19 19 import javax.sip.address.SipURI;
20 20 import javax.sip.header.ContentTypeHeader;
  21 +import javax.sip.header.ExpiresHeader;
21 22 import javax.sip.header.HeaderFactory;
22 23 import javax.sip.header.ViaHeader;
23 24 import javax.sip.message.MessageFactory;
... ... @@ -153,7 +154,7 @@ public abstract class SIPRequestProcessorParent {
153 154 * @throws InvalidArgumentException
154 155 * @throws ParseException
155 156 */
156   - public void responseAck(RequestEvent evt, String sdp) throws SipException, InvalidArgumentException, ParseException {
  157 + public void responseSdpAck(RequestEvent evt, String sdp) throws SipException, InvalidArgumentException, ParseException {
157 158 Response response = getMessageFactory().createResponse(Response.OK, evt.getRequest());
158 159 SipFactory sipFactory = SipFactory.getInstance();
159 160 ContentTypeHeader contentTypeHeader = sipFactory.createHeaderFactory().createContentTypeHeader("APPLICATION", "SDP");
... ... @@ -168,6 +169,31 @@ public abstract class SIPRequestProcessorParent {
168 169 getServerTransaction(evt).sendResponse(response);
169 170 }
170 171  
  172 + /**
  173 + * 回复带xml的200
  174 + * @param evt
  175 + * @param xml
  176 + * @throws SipException
  177 + * @throws InvalidArgumentException
  178 + * @throws ParseException
  179 + */
  180 + public Response responseXmlAck(RequestEvent evt, String xml) throws SipException, InvalidArgumentException, ParseException {
  181 + Response response = getMessageFactory().createResponse(Response.OK, evt.getRequest());
  182 + SipFactory sipFactory = SipFactory.getInstance();
  183 + ContentTypeHeader contentTypeHeader = sipFactory.createHeaderFactory().createContentTypeHeader("APPLICATION", "MANSCDP+xml");
  184 + response.setContent(xml, contentTypeHeader);
  185 +
  186 + SipURI sipURI = (SipURI)evt.getRequest().getRequestURI();
  187 +
  188 + Address concatAddress = sipFactory.createAddressFactory().createAddress(
  189 + sipFactory.createAddressFactory().createSipURI(sipURI.getUser(), sipURI.getHost()+":"+sipURI.getPort()
  190 + ));
  191 + response.addHeader(sipFactory.createHeaderFactory().createContactHeader(concatAddress));
  192 + response.addHeader(evt.getRequest().getHeader(ExpiresHeader.NAME));
  193 + getServerTransaction(evt).sendResponse(response);
  194 + return response;
  195 + }
  196 +
171 197 public Element getRootElement(RequestEvent evt) throws DocumentException {
172 198 return getRootElement(evt, "gb2312");
173 199 }
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/InviteRequestProcessor.java
... ... @@ -107,6 +107,7 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements
107 107 // 查询平台下是否有该通道
108 108 DeviceChannel channel = storager.queryChannelInParentPlatform(requesterId, channelId);
109 109 List<GbStream> gbStreams = storager.queryStreamInParentPlatform(requesterId, channelId);
  110 + PlatformCatalog catalog = storager.getCatalog(channelId);
110 111 GbStream gbStream = gbStreams.size() > 0? gbStreams.get(0):null;
111 112 MediaServerItem mediaServerItem = null;
112 113 // 不是通道可能是直播流
... ... @@ -132,7 +133,10 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements
132 133 return;
133 134 }
134 135 responseAck(evt, Response.CALL_IS_BEING_FORWARDED); // 通道存在,发181,呼叫转接中
135   - }else {
  136 + }else if (catalog != null) {
  137 + responseAck(evt, Response.BAD_REQUEST, "catalog channel can not play"); // 目录不支持点播
  138 + return;
  139 + } else {
136 140 logger.info("通道不存在,返回404");
137 141 responseAck(evt, Response.NOT_FOUND); // 通道不存在,发404,资源不存在
138 142 return;
... ... @@ -249,7 +253,7 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements
249 253 content.append("f=\r\n");
250 254  
251 255 try {
252   - responseAck(evt, content.toString());
  256 + responseSdpAck(evt, content.toString());
253 257 } catch (SipException e) {
254 258 e.printStackTrace();
255 259 } catch (InvalidArgumentException e) {
... ... @@ -306,7 +310,7 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements
306 310 content.append("f=\r\n");
307 311  
308 312 try {
309   - responseAck(evt, content.toString());
  313 + responseSdpAck(evt, content.toString());
310 314 } catch (SipException e) {
311 315 e.printStackTrace();
312 316 } catch (InvalidArgumentException e) {
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/NotifyRequestProcessor.java
... ... @@ -62,9 +62,7 @@ public class NotifyRequestProcessor extends SIPRequestProcessorParent implements
62 62 @Autowired
63 63 private DeviceOffLineDetector offLineDetector;
64 64  
65   - private static final String NOTIFY_CATALOG = "Catalog";
66   - private static final String NOTIFY_ALARM = "Alarm";
67   - private static final String NOTIFY_MOBILE_POSITION = "MobilePosition";
  65 +
68 66 private String method = "NOTIFY";
69 67  
70 68 @Autowired
... ... @@ -82,13 +80,13 @@ public class NotifyRequestProcessor extends SIPRequestProcessorParent implements
82 80 Element rootElement = getRootElement(evt);
83 81 String cmd = XmlUtil.getText(rootElement, "CmdType");
84 82  
85   - if (NOTIFY_CATALOG.equals(cmd)) {
  83 + if (CmdType.CATALOG.equals(cmd)) {
86 84 logger.info("接收到Catalog通知");
87 85 processNotifyCatalogList(evt);
88   - } else if (NOTIFY_ALARM.equals(cmd)) {
  86 + } else if (CmdType.ALARM.equals(cmd)) {
89 87 logger.info("接收到Alarm通知");
90 88 processNotifyAlarm(evt);
91   - } else if (NOTIFY_MOBILE_POSITION.equals(cmd)) {
  89 + } else if (CmdType.MOBILE_POSITION.equals(cmd)) {
92 90 logger.info("接收到MobilePosition通知");
93 91 processNotifyMobilePosition(evt);
94 92 } else {
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/SubscribeRequestProcessor.java
1 1 package com.genersoft.iot.vmp.gb28181.transmit.event.request.impl;
2 2  
  3 +import com.genersoft.iot.vmp.common.VideoManagerConstants;
  4 +import com.genersoft.iot.vmp.conf.DynamicTask;
  5 +import com.genersoft.iot.vmp.conf.UserSetup;
  6 +import com.genersoft.iot.vmp.gb28181.bean.CmdType;
  7 +import com.genersoft.iot.vmp.gb28181.bean.SubscribeInfo;
  8 +import com.genersoft.iot.vmp.gb28181.task.GPSSubscribeTask;
3 9 import com.genersoft.iot.vmp.gb28181.transmit.SIPProcessorObserver;
  10 +import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform;
4 11 import com.genersoft.iot.vmp.gb28181.transmit.event.request.ISIPRequestProcessor;
5 12 import com.genersoft.iot.vmp.gb28181.transmit.event.request.SIPRequestProcessorParent;
  13 +import com.genersoft.iot.vmp.gb28181.utils.SipUtils;
  14 +import com.genersoft.iot.vmp.gb28181.utils.XmlUtil;
  15 +import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
  16 +import com.genersoft.iot.vmp.storager.IVideoManagerStorager;
  17 +import org.dom4j.DocumentException;
  18 +import org.dom4j.Element;
6 19 import org.slf4j.Logger;
7 20 import org.slf4j.LoggerFactory;
8 21 import org.springframework.beans.factory.InitializingBean;
... ... @@ -13,7 +26,10 @@ import javax.sip.InvalidArgumentException;
13 26 import javax.sip.RequestEvent;
14 27 import javax.sip.ServerTransaction;
15 28 import javax.sip.SipException;
  29 +import javax.sip.header.CallIdHeader;
16 30 import javax.sip.header.ExpiresHeader;
  31 +import javax.sip.header.Header;
  32 +import javax.sip.header.ToHeader;
17 33 import javax.sip.message.Request;
18 34 import javax.sip.message.Response;
19 35 import java.text.ParseException;
... ... @@ -30,6 +46,21 @@ public class SubscribeRequestProcessor extends SIPRequestProcessorParent impleme
30 46 @Autowired
31 47 private SIPProcessorObserver sipProcessorObserver;
32 48  
  49 + @Autowired
  50 + private IRedisCatchStorage redisCatchStorage;
  51 +
  52 + @Autowired
  53 + private ISIPCommanderForPlatform sipCommanderForPlatform;
  54 +
  55 + @Autowired
  56 + private IVideoManagerStorager storager;
  57 +
  58 + @Autowired
  59 + private DynamicTask dynamicTask;
  60 +
  61 + @Autowired
  62 + private UserSetup userSetup;
  63 +
33 64 @Override
34 65 public void afterPropertiesSet() throws Exception {
35 66 // 添加消息处理的订阅
... ... @@ -46,30 +77,107 @@ public class SubscribeRequestProcessor extends SIPRequestProcessorParent impleme
46 77 Request request = evt.getRequest();
47 78  
48 79 try {
49   - Response response = null;
50   - response = getMessageFactory().createResponse(200, request);
51   - if (response != null) {
52   - ExpiresHeader expireHeader = getHeaderFactory().createExpiresHeader(30);
53   - response.setExpires(expireHeader);
54   - }
55   - logger.info("response : " + response.toString());
56   - ServerTransaction transaction = getServerTransaction(evt);
57   - if (transaction != null) {
58   - transaction.sendResponse(response);
59   - transaction.getDialog().delete();
60   - transaction.terminate();
  80 + Element rootElement = getRootElement(evt);
  81 + String cmd = XmlUtil.getText(rootElement, "CmdType");
  82 + if (CmdType.MOBILE_POSITION.equals(cmd)) {
  83 + logger.info("接收到MobilePosition订阅");
  84 + processNotifyMobilePosition(evt, rootElement);
  85 +// } else if (CmdType.ALARM.equals(cmd)) {
  86 +// logger.info("接收到Alarm订阅");
  87 +// processNotifyAlarm(evt, rootElement);
  88 +// } else if (CmdType.CATALOG.equals(cmd)) {
  89 +// logger.info("接收到Catalog订阅");
  90 +// processNotifyCatalogList(evt, rootElement);
61 91 } else {
62   - logger.info("processRequest serverTransactionId is null.");
  92 + logger.info("接收到消息:" + cmd);
  93 +// responseAck(evt, Response.OK);
  94 +
  95 + Response response = null;
  96 + response = getMessageFactory().createResponse(200, request);
  97 + if (response != null) {
  98 + ExpiresHeader expireHeader = getHeaderFactory().createExpiresHeader(30);
  99 + response.setExpires(expireHeader);
  100 + }
  101 + logger.info("response : " + response.toString());
  102 + ServerTransaction transaction = getServerTransaction(evt);
  103 + if (transaction != null) {
  104 + transaction.sendResponse(response);
  105 + transaction.getDialog().delete();
  106 + transaction.terminate();
  107 + } else {
  108 + logger.info("processRequest serverTransactionId is null.");
  109 + }
63 110 }
64 111  
  112 +
  113 +
65 114 } catch (ParseException e) {
66 115 e.printStackTrace();
67 116 } catch (SipException e) {
68 117 e.printStackTrace();
69 118 } catch (InvalidArgumentException e) {
70 119 e.printStackTrace();
  120 + } catch (DocumentException e) {
  121 + e.printStackTrace();
  122 + }
  123 +
  124 + }
  125 +
  126 + /**
  127 + * 处理移动位置订阅消息
  128 + */
  129 + private void processNotifyMobilePosition(RequestEvent evt, Element rootElement) {
  130 + String platformId = SipUtils.getUserIdFromFromHeader(evt.getRequest());
  131 + String deviceID = XmlUtil.getText(rootElement, "DeviceID");
  132 + SubscribeInfo subscribeInfo = new SubscribeInfo(evt, platformId);
  133 + String sn = XmlUtil.getText(rootElement, "SN");
  134 + String key = VideoManagerConstants.SIP_SUBSCRIBE_PREFIX + userSetup.getServerId() + "_MobilePosition_" + platformId;
  135 +
  136 + StringBuilder resultXml = new StringBuilder(200);
  137 + resultXml.append("<?xml version=\"1.0\" ?>\r\n")
  138 + .append("<Response>\r\n")
  139 + .append("<CmdType>MobilePosition</CmdType>\r\n")
  140 + .append("<SN>" + sn + "</SN>\r\n")
  141 + .append("<DeviceID>" + deviceID + "</DeviceID>\r\n")
  142 + .append("<Result>OK</Result>\r\n")
  143 + .append("</Response>\r\n");
  144 +
  145 + if (subscribeInfo.getExpires() > 0) {
  146 + if (redisCatchStorage.getSubscribe(key) != null) {
  147 + dynamicTask.stopCron(key);
  148 + }
  149 + String interval = XmlUtil.getText(rootElement, "Interval"); // GPS上报时间间隔
  150 + dynamicTask.startCron(key, new GPSSubscribeTask(redisCatchStorage, sipCommanderForPlatform, storager, platformId, sn, key), Integer.parseInt(interval));
  151 +
  152 + redisCatchStorage.updateSubscribe(key, subscribeInfo);
  153 + }else if (subscribeInfo.getExpires() == 0) {
  154 + dynamicTask.stopCron(key);
  155 + redisCatchStorage.delSubscribe(key);
  156 + }
  157 +
  158 +
  159 +
  160 + try {
  161 + Response response = responseXmlAck(evt, resultXml.toString());
  162 + ToHeader toHeader = (ToHeader)response.getHeader(ToHeader.NAME);
  163 + subscribeInfo.setToTag(toHeader.getTag());
  164 + redisCatchStorage.updateSubscribe(key, subscribeInfo);
  165 +
  166 + } catch (SipException e) {
  167 + e.printStackTrace();
  168 + } catch (InvalidArgumentException e) {
  169 + e.printStackTrace();
  170 + } catch (ParseException e) {
  171 + e.printStackTrace();
71 172 }
72   -
  173 + }
  174 +
  175 + private void processNotifyAlarm(RequestEvent evt, Element rootElement) {
  176 +
  177 + }
  178 +
  179 + private void processNotifyCatalogList(RequestEvent evt, Element rootElement) {
  180 +
73 181 }
74 182  
75 183 }
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/MessageRequestProcessor.java
1 1 package com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message;
2 2  
3 3 import com.genersoft.iot.vmp.gb28181.bean.Device;
  4 +import com.genersoft.iot.vmp.gb28181.bean.DeviceNotFoundEvent;
4 5 import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform;
  6 +import com.genersoft.iot.vmp.gb28181.event.SipSubscribe;
5 7 import com.genersoft.iot.vmp.gb28181.transmit.SIPProcessorObserver;
6 8 import com.genersoft.iot.vmp.gb28181.transmit.event.request.ISIPRequestProcessor;
7 9 import com.genersoft.iot.vmp.gb28181.transmit.event.request.SIPRequestProcessorParent;
... ... @@ -19,6 +21,7 @@ import org.springframework.stereotype.Component;
19 21 import javax.sip.InvalidArgumentException;
20 22 import javax.sip.RequestEvent;
21 23 import javax.sip.SipException;
  24 +import javax.sip.header.CallIdHeader;
22 25 import javax.sip.message.Response;
23 26 import java.text.ParseException;
24 27 import java.util.Map;
... ... @@ -40,6 +43,9 @@ public class MessageRequestProcessor extends SIPRequestProcessorParent implement
40 43 private IVideoManagerStorager storage;
41 44  
42 45 @Autowired
  46 + private SipSubscribe sipSubscribe;
  47 +
  48 + @Autowired
43 49 private IRedisCatchStorage redisCatchStorage;
44 50  
45 51 @Override
... ... @@ -56,6 +62,7 @@ public class MessageRequestProcessor extends SIPRequestProcessorParent implement
56 62 public void process(RequestEvent evt) {
57 63 logger.debug("接收到消息:" + evt.getRequest());
58 64 String deviceId = SipUtils.getUserIdFromFromHeader(evt.getRequest());
  65 + CallIdHeader callIdHeader = (CallIdHeader)evt.getRequest().getHeader(CallIdHeader.NAME);
59 66 // 查询设备是否存在
60 67 Device device = redisCatchStorage.getDevice(deviceId);
61 68 // 查询上级平台是否存在
... ... @@ -63,7 +70,12 @@ public class MessageRequestProcessor extends SIPRequestProcessorParent implement
63 70 try {
64 71 if (device == null && parentPlatform == null) {
65 72 // 不存在则回复404
66   - responseAck(evt, Response.NOT_FOUND, "device id not found");
  73 + responseAck(evt, Response.NOT_FOUND, "device "+ deviceId +" not found");
  74 + logger.warn("[设备未找到 ]: {}", deviceId);
  75 + if (sipSubscribe.getErrorSubscribe(callIdHeader.getCallId()) != null){
  76 + SipSubscribe.EventResult eventResult = new SipSubscribe.EventResult(new DeviceNotFoundEvent(evt.getDialog()));
  77 + sipSubscribe.getErrorSubscribe(callIdHeader.getCallId()).response(eventResult);
  78 + };
67 79 }else {
68 80 Element rootElement = getRootElement(evt);
69 81 String name = rootElement.getName();
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/CatalogNotifyMessageHandler.java
1 1 package com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.notify.cmd;
2 2  
3 3 import com.genersoft.iot.vmp.conf.SipConfig;
4   -import com.genersoft.iot.vmp.gb28181.bean.Device;
5   -import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel;
6   -import com.genersoft.iot.vmp.gb28181.bean.GbStream;
7   -import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform;
  4 +import com.genersoft.iot.vmp.gb28181.bean.*;
8 5 import com.genersoft.iot.vmp.gb28181.event.EventPublisher;
9 6 import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder;
10 7 import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommanderFroPlatform;
... ... @@ -71,11 +68,41 @@ public class CatalogNotifyMessageHandler extends SIPRequestProcessorParent imple
71 68 // 查询关联的直播通道
72 69 List<GbStream> gbStreams = storager.queryGbStreamListInPlatform(parentPlatform.getServerGBId());
73 70 int size = channelReduces.size() + gbStreams.size();
  71 + // 回复目录信息
  72 + List<PlatformCatalog> catalogs = storager.queryCatalogInPlatform(parentPlatform.getServerGBId());
  73 + if (catalogs.size() > 0) {
  74 + for (PlatformCatalog catalog : catalogs) {
  75 + DeviceChannel deviceChannel = new DeviceChannel();
  76 + deviceChannel.setChannelId(catalog.getId());
  77 + deviceChannel.setName(catalog.getName());
  78 + deviceChannel.setLongitude(0.0);
  79 + deviceChannel.setLatitude(0.0);
  80 + deviceChannel.setDeviceId(parentPlatform.getDeviceGBId());
  81 + deviceChannel.setManufacture("wvp-pro");
  82 + deviceChannel.setStatus(1);
  83 + deviceChannel.setParental(1);
  84 + deviceChannel.setParentId(catalog.getParentId());
  85 + deviceChannel.setRegisterWay(1);
  86 + deviceChannel.setCivilCode(config.getDomain());
  87 + deviceChannel.setModel("live");
  88 + deviceChannel.setOwner("wvp-pro");
  89 + deviceChannel.setSecrecy("0");
  90 + cmderFroPlatform.catalogQuery(deviceChannel, parentPlatform, sn, fromHeader.getTag(), size);
  91 + // 防止发送过快
  92 + Thread.sleep(10);
  93 + }
  94 + }
74 95 // 回复级联的通道
75 96 if (channelReduces.size() > 0) {
76 97 for (ChannelReduce channelReduce : channelReduces) {
77 98 DeviceChannel deviceChannel = storager.queryChannel(channelReduce.getDeviceId(), channelReduce.getChannelId());
  99 + // TODO 目前暂时认为这里只用通道没有目录
  100 + deviceChannel.setParental(0);
  101 + deviceChannel.setParentId(channelReduce.getCatalogId());
  102 +
78 103 cmderFroPlatform.catalogQuery(deviceChannel, parentPlatform, sn, fromHeader.getTag(), size);
  104 + // 防止发送过快
  105 + Thread.sleep(10);
79 106 }
80 107 }
81 108 // 回复直播的通道
... ... @@ -89,16 +116,16 @@ public class CatalogNotifyMessageHandler extends SIPRequestProcessorParent imple
89 116 deviceChannel.setDeviceId(parentPlatform.getDeviceGBId());
90 117 deviceChannel.setManufacture("wvp-pro");
91 118 deviceChannel.setStatus(gbStream.isStatus()?1:0);
92   - // deviceChannel.setParentId(parentPlatform.getDeviceGBId());
  119 + deviceChannel.setParentId(gbStream.getCatalogId());
93 120 deviceChannel.setRegisterWay(1);
94 121 deviceChannel.setCivilCode(config.getDomain());
95 122 deviceChannel.setModel("live");
96 123 deviceChannel.setOwner("wvp-pro");
97 124 deviceChannel.setParental(0);
98 125 deviceChannel.setSecrecy("0");
99   - deviceChannel.setSecrecy("0");
100   -
101 126 cmderFroPlatform.catalogQuery(deviceChannel, parentPlatform, sn, fromHeader.getTag(), size);
  127 + // 防止发送过快
  128 + Thread.sleep(10);
102 129 }
103 130 }
104 131 if (size == 0) {
... ... @@ -111,6 +138,8 @@ public class CatalogNotifyMessageHandler extends SIPRequestProcessorParent imple
111 138 e.printStackTrace();
112 139 } catch (ParseException e) {
113 140 e.printStackTrace();
  141 + } catch (InterruptedException e) {
  142 + e.printStackTrace();
114 143 }
115 144  
116 145 }
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/query/cmd/CatalogQueryMessageHandler.java
1 1 package com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.query.cmd;
2 2  
3 3 import com.genersoft.iot.vmp.conf.SipConfig;
4   -import com.genersoft.iot.vmp.gb28181.bean.Device;
5   -import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel;
6   -import com.genersoft.iot.vmp.gb28181.bean.GbStream;
7   -import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform;
  4 +import com.genersoft.iot.vmp.gb28181.bean.*;
8 5 import com.genersoft.iot.vmp.gb28181.event.EventPublisher;
9 6 import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder;
10 7 import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommanderFroPlatform;
... ... @@ -73,12 +70,41 @@ public class CatalogQueryMessageHandler extends SIPRequestProcessorParent implem
73 70 List<ChannelReduce> channelReduces = storager.queryChannelListInParentPlatform(parentPlatform.getServerGBId());
74 71 // 查询关联的直播通道
75 72 List<GbStream> gbStreams = storager.queryGbStreamListInPlatform(parentPlatform.getServerGBId());
76   - int size = channelReduces.size() + gbStreams.size();
  73 + // 回复目录信息
  74 + List<PlatformCatalog> catalogs = storager.queryCatalogInPlatform(parentPlatform.getServerGBId());
  75 + int size = catalogs.size() + channelReduces.size() + gbStreams.size();
  76 + if (catalogs.size() > 0) {
  77 + for (PlatformCatalog catalog : catalogs) {
  78 + DeviceChannel deviceChannel = new DeviceChannel();
  79 + deviceChannel.setChannelId(catalog.getId());
  80 + deviceChannel.setName(catalog.getName());
  81 + deviceChannel.setLongitude(0.0);
  82 + deviceChannel.setLatitude(0.0);
  83 + deviceChannel.setDeviceId(parentPlatform.getDeviceGBId());
  84 + deviceChannel.setManufacture("wvp-pro");
  85 + deviceChannel.setStatus(1);
  86 + deviceChannel.setParental(1);
  87 + deviceChannel.setParentId(catalog.getParentId());
  88 + deviceChannel.setRegisterWay(1);
  89 + deviceChannel.setCivilCode(config.getDomain());
  90 + deviceChannel.setModel("live");
  91 + deviceChannel.setOwner("wvp-pro");
  92 + deviceChannel.setSecrecy("0");
  93 + cmderFroPlatform.catalogQuery(deviceChannel, parentPlatform, sn, fromHeader.getTag(), size);
  94 + // 防止发送过快
  95 + Thread.sleep(10);
  96 + }
  97 + }
77 98 // 回复级联的通道
78 99 if (channelReduces.size() > 0) {
79 100 for (ChannelReduce channelReduce : channelReduces) {
80 101 DeviceChannel deviceChannel = storager.queryChannel(channelReduce.getDeviceId(), channelReduce.getChannelId());
  102 + // TODO 目前暂时认为这里只用通道没有目录
  103 + deviceChannel.setParental(0);
  104 + deviceChannel.setParentId(channelReduce.getCatalogId());
81 105 cmderFroPlatform.catalogQuery(deviceChannel, parentPlatform, sn, fromHeader.getTag(), size);
  106 + // 防止发送过快
  107 + Thread.sleep(10);
82 108 }
83 109 }
84 110 // 回复直播的通道
... ... @@ -92,14 +118,13 @@ public class CatalogQueryMessageHandler extends SIPRequestProcessorParent implem
92 118 deviceChannel.setDeviceId(parentPlatform.getDeviceGBId());
93 119 deviceChannel.setManufacture("wvp-pro");
94 120 deviceChannel.setStatus(gbStream.isStatus()?1:0);
95   - // deviceChannel.setParentId(parentPlatform.getDeviceGBId());
  121 + deviceChannel.setParentId(gbStream.getCatalogId());
96 122 deviceChannel.setRegisterWay(1);
97 123 deviceChannel.setCivilCode(config.getDomain());
98 124 deviceChannel.setModel("live");
99 125 deviceChannel.setOwner("wvp-pro");
100 126 deviceChannel.setParental(0);
101 127 deviceChannel.setSecrecy("0");
102   - deviceChannel.setSecrecy("0");
103 128  
104 129 cmderFroPlatform.catalogQuery(deviceChannel, parentPlatform, sn, fromHeader.getTag(), size);
105 130 }
... ... @@ -114,6 +139,8 @@ public class CatalogQueryMessageHandler extends SIPRequestProcessorParent implem
114 139 e.printStackTrace();
115 140 } catch (ParseException e) {
116 141 e.printStackTrace();
  142 + } catch (InterruptedException e) {
  143 + e.printStackTrace();
117 144 }
118 145  
119 146 }
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/response/cmd/CatalogResponseMessageHandler.java
... ... @@ -91,7 +91,6 @@ public class CatalogResponseMessageHandler extends SIPRequestProcessorParent imp
91 91 // 遍历DeviceList
92 92 while (deviceListIterator.hasNext()) {
93 93 Element itemDevice = deviceListIterator.next();
94   -
95 94 Element channelDeviceElement = itemDevice.element("DeviceID");
96 95 if (channelDeviceElement == null) {
97 96 continue;
... ...
src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java
... ... @@ -4,7 +4,6 @@ import java.util.List;
4 4 import java.util.UUID;
5 5  
6 6 import com.alibaba.fastjson.JSON;
7   -import com.alibaba.fastjson.JSONArray;
8 7 import com.genersoft.iot.vmp.common.StreamInfo;
9 8 import com.genersoft.iot.vmp.conf.MediaConfig;
10 9 import com.genersoft.iot.vmp.conf.UserSetup;
... ... @@ -302,7 +301,7 @@ public class ZLMHttpHookListener {
302 301 @ResponseBody
303 302 @PostMapping(value = "/on_stream_changed", produces = "application/json;charset=UTF-8")
304 303 public ResponseEntity<String> onStreamChanged(@RequestBody MediaItem item){
305   -
  304 +
306 305 if (logger.isDebugEnabled()) {
307 306 logger.debug("[ ZLM HOOK ]on_stream_changed API调用,参数:" + JSONObject.toJSONString(item));
308 307 }
... ... @@ -322,10 +321,8 @@ public class ZLMHttpHookListener {
322 321 String schema = item.getSchema();
323 322 List<MediaItem.MediaTrack> tracks = item.getTracks();
324 323 boolean regist = item.isRegist();
325   - if (tracks != null) {
326   - logger.info("[stream: " + streamId + "] on_stream_changed->>" + schema);
327   - }
328 324 if ("rtmp".equals(schema)){
  325 + logger.info("on_stream_changed:注册->{}, app->{}, stream->{}", regist, app, streamId);
329 326 if (regist) {
330 327 mediaServerService.addCount(mediaServerId);
331 328 }else {
... ... @@ -346,24 +343,16 @@ public class ZLMHttpHookListener {
346 343 MediaServerItem mediaServerItem = mediaServerService.getOne(mediaServerId);
347 344 if (mediaServerItem != null){
348 345 if (regist) {
349   - StreamInfo streamInfo = mediaService.getStreamInfoByAppAndStream(mediaServerItem, app, streamId, tracks);
350   - redisCatchStorage.addStream(mediaServerItem, type, app, streamId, streamInfo);
  346 + redisCatchStorage.addStream(mediaServerItem, type, app, streamId, item);
351 347 if (item.getOriginType() == OriginType.RTSP_PUSH.ordinal()
352 348 || item.getOriginType() == OriginType.RTMP_PUSH.ordinal()
353 349 || item.getOriginType() == OriginType.RTC_PUSH.ordinal() ) {
354 350 zlmMediaListManager.addPush(item);
355 351 }
356 352 }else {
357   - // 兼容流注销时类型错误的问题,等zlm更新后删除
358   - StreamPushItem streamPushItem = streamPushService.getPush(app, streamId);
359   - if (streamPushItem != null) {
360   - type = "PUSH";
361   - }else {
362   - StreamProxyItem streamProxyByAppAndStream = streamProxyService.getStreamProxyByAppAndStream(app, streamId);
363   - if (streamProxyByAppAndStream != null) {
364   - type = "PULL";
365   - }
366   - }
  353 + // 兼容流注销时类型从redis记录获取
  354 + MediaItem mediaItem = redisCatchStorage.getStreamInfo(app, streamId, mediaServerId);
  355 + type = OriginType.values()[mediaItem.getOriginType()].getType();
367 356 zlmMediaListManager.removeMedia(app, streamId);
368 357 redisCatchStorage.removeStream(mediaServerItem.getId(), type, app, streamId);
369 358 }
... ...
src/main/java/com/genersoft/iot/vmp/media/zlm/event/ZLMKeepliveTimeoutListener.java
... ... @@ -2,6 +2,7 @@ package com.genersoft.iot.vmp.media.zlm.event;
2 2  
3 3 import com.alibaba.fastjson.JSONObject;
4 4 import com.genersoft.iot.vmp.common.VideoManagerConstants;
  5 +import com.genersoft.iot.vmp.conf.RedisKeyExpirationEventMessageListener;
5 6 import com.genersoft.iot.vmp.conf.UserSetup;
6 7 import com.genersoft.iot.vmp.gb28181.event.EventPublisher;
7 8 import com.genersoft.iot.vmp.media.zlm.ZLMRESTfulUtils;
... ... @@ -21,7 +22,7 @@ import org.springframework.stereotype.Component;
21 22 * @date: 2020年5月6日 上午11:35:46
22 23 */
23 24 @Component
24   -public class ZLMKeepliveTimeoutListener extends KeyExpirationEventMessageListener {
  25 +public class ZLMKeepliveTimeoutListener extends RedisKeyExpirationEventMessageListener {
25 26  
26 27 private Logger logger = LoggerFactory.getLogger(ZLMKeepliveTimeoutListener.class);
27 28  
... ... @@ -37,20 +38,12 @@ public class ZLMKeepliveTimeoutListener extends KeyExpirationEventMessageListene
37 38 @Autowired
38 39 private IMediaServerService mediaServerService;
39 40  
40   - @Override
41   - public void init() {
42   - if (!userSetup.getRedisConfig()) {
43   - // 配置springboot默认Config为空,即不让应用去修改redis的默认配置,因为Redis服务出于安全会禁用CONFIG命令给远程用户使用
44   - setKeyspaceNotificationsConfigParameter("");
45   - }
46   - super.init();
  41 + public ZLMKeepliveTimeoutListener(RedisMessageListenerContainer listenerContainer, UserSetup userSetup) {
  42 + super(listenerContainer, userSetup);
47 43 }
48 44  
49   - public ZLMKeepliveTimeoutListener(RedisMessageListenerContainer listenerContainer) {
50   - super(listenerContainer);
51   - }
52 45  
53   - /**
  46 + /**
54 47 * 监听失效的key,key格式为keeplive_deviceId
55 48 * @param message
56 49 * @param pattern
... ...
src/main/java/com/genersoft/iot/vmp/service/IGbStreamService.java
... ... @@ -30,7 +30,7 @@ public interface IGbStreamService {
30 30 * 保存国标关联
31 31 * @param gbStreams
32 32 */
33   - boolean addPlatformInfo(List<GbStream> gbStreams, String platformId);
  33 + boolean addPlatformInfo(List<GbStream> gbStreams, String platformId, String catalogId);
34 34  
35 35 /**
36 36 * 移除国标关联
... ...
src/main/java/com/genersoft/iot/vmp/service/StreamGPSSubscribeTask.java 0 → 100644
  1 +package com.genersoft.iot.vmp.service;
  2 +
  3 +import com.genersoft.iot.vmp.service.bean.GPSMsgInfo;
  4 +import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
  5 +import com.genersoft.iot.vmp.storager.IVideoManagerStorager;
  6 +import org.springframework.beans.factory.annotation.Autowired;
  7 +import org.springframework.scheduling.annotation.Scheduled;
  8 +import org.springframework.stereotype.Component;
  9 +
  10 +import java.util.List;
  11 +
  12 +
  13 +/**
  14 + * 定时查找redis中的GPS推送消息,并保存到对应的流中
  15 + */
  16 +@Component
  17 +public class StreamGPSSubscribeTask {
  18 +
  19 + @Autowired
  20 + private IRedisCatchStorage redisCatchStorage;
  21 +
  22 + @Autowired
  23 + private IVideoManagerStorager storager;
  24 +
  25 +
  26 +
  27 + @Scheduled(fixedRate = 30 * 1000) //每30秒执行一次
  28 + public void execute(){
  29 + List<GPSMsgInfo> gpsMsgInfo = redisCatchStorage.getAllGpsMsgInfo();
  30 + if (gpsMsgInfo.size() > 0) {
  31 + storager.updateStreamGPS(gpsMsgInfo);
  32 + for (GPSMsgInfo msgInfo : gpsMsgInfo) {
  33 + msgInfo.setStored(true);
  34 + redisCatchStorage.updateGpsMsgInfo(msgInfo);
  35 + }
  36 + }
  37 +
  38 + }
  39 +}
... ...
src/main/java/com/genersoft/iot/vmp/service/bean/GPSMsgInfo.java 0 → 100644
  1 +package com.genersoft.iot.vmp.service.bean;
  2 +
  3 +public class GPSMsgInfo {
  4 +
  5 + /**
  6 + *
  7 + */
  8 + private String id;
  9 +
  10 + /**
  11 + * 经度 (必选)
  12 + */
  13 + private double lng;
  14 +
  15 + /**
  16 + * 纬度 (必选)
  17 + */
  18 + private double lat;
  19 +
  20 + /**
  21 + * 速度,单位:km/h (可选)
  22 + */
  23 + private double speed;
  24 +
  25 + /**
  26 + * 产生通知时间, 时间格式: 2020-01-14T14:32:12
  27 + */
  28 + private String time;
  29 +
  30 + /**
  31 + * 方向,取值为当前摄像头方向与正北方的顺时针夹角,取值范围0°~360°,单位:(°)(可选)
  32 + */
  33 + private String direction;
  34 +
  35 + /**
  36 + * 海拔高度,单位:m(可选)
  37 + */
  38 + private String altitude;
  39 +
  40 + private boolean stored;
  41 +
  42 +
  43 + public String getId() {
  44 + return id;
  45 + }
  46 +
  47 + public void setId(String id) {
  48 + this.id = id;
  49 + }
  50 +
  51 + public double getLng() {
  52 + return lng;
  53 + }
  54 +
  55 + public void setLng(double lng) {
  56 + this.lng = lng;
  57 + }
  58 +
  59 + public double getLat() {
  60 + return lat;
  61 + }
  62 +
  63 + public void setLat(double lat) {
  64 + this.lat = lat;
  65 + }
  66 +
  67 + public double getSpeed() {
  68 + return speed;
  69 + }
  70 +
  71 + public void setSpeed(double speed) {
  72 + this.speed = speed;
  73 + }
  74 +
  75 + public String getTime() {
  76 + return time;
  77 + }
  78 +
  79 + public void setTime(String time) {
  80 + this.time = time;
  81 + }
  82 +
  83 + public String getDirection() {
  84 + return direction;
  85 + }
  86 +
  87 + public void setDirection(String direction) {
  88 + this.direction = direction;
  89 + }
  90 +
  91 + public String getAltitude() {
  92 + return altitude;
  93 + }
  94 +
  95 + public void setAltitude(String altitude) {
  96 + this.altitude = altitude;
  97 + }
  98 +
  99 + public boolean isStored() {
  100 + return stored;
  101 + }
  102 +
  103 + public void setStored(boolean stored) {
  104 + this.stored = stored;
  105 + }
  106 +}
... ...
src/main/java/com/genersoft/iot/vmp/service/impl/GbStreamServiceImpl.java
... ... @@ -47,13 +47,15 @@ public class GbStreamServiceImpl implements IGbStreamService {
47 47  
48 48  
49 49 @Override
50   - public boolean addPlatformInfo(List<GbStream> gbStreams, String platformId) {
  50 + public boolean addPlatformInfo(List<GbStream> gbStreams, String platformId, String catalogId) {
51 51 // 放在事务内执行
52 52 boolean result = false;
53 53 TransactionStatus transactionStatus = dataSourceTransactionManager.getTransaction(transactionDefinition);
54 54 try {
55 55 for (GbStream gbStream : gbStreams) {
  56 + gbStream.setCatalogId(catalogId);
56 57 gbStream.setPlatformId(platformId);
  58 + // TODO 修改为批量提交
57 59 platformGbStreamMapper.add(gbStream);
58 60 }
59 61 dataSourceTransactionManager.commit(transactionStatus); //手动提交
... ...
src/main/java/com/genersoft/iot/vmp/service/impl/RedisGPSMsgListener.java 0 → 100644
  1 +package com.genersoft.iot.vmp.service.impl;
  2 +
  3 +import com.alibaba.fastjson.JSON;
  4 +import com.genersoft.iot.vmp.service.bean.GPSMsgInfo;
  5 +import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
  6 +import org.springframework.beans.factory.annotation.Autowired;
  7 +import org.springframework.data.redis.connection.Message;
  8 +import org.springframework.data.redis.connection.MessageListener;
  9 +import org.springframework.stereotype.Component;
  10 +
  11 +@Component
  12 +public class RedisGPSMsgListener implements MessageListener {
  13 +
  14 + @Autowired
  15 + private IRedisCatchStorage redisCatchStorage;
  16 +
  17 + @Override
  18 + public void onMessage(Message message, byte[] bytes) {
  19 + GPSMsgInfo gpsMsgInfo = JSON.parseObject(message.getBody(), GPSMsgInfo.class);
  20 + redisCatchStorage.updateGpsMsgInfo(gpsMsgInfo);
  21 + }
  22 +}
... ...
src/main/java/com/genersoft/iot/vmp/service/impl/StreamProxyServiceImpl.java
... ... @@ -130,7 +130,7 @@ public class StreamProxyServiceImpl implements IStreamProxyService {
130 130 if ( !StringUtils.isEmpty(param.getPlatformGbId()) && streamLive) {
131 131 List<GbStream> gbStreams = new ArrayList<>();
132 132 gbStreams.add(param);
133   - if (gbStreamService.addPlatformInfo(gbStreams, param.getPlatformGbId())){
  133 + if (gbStreamService.addPlatformInfo(gbStreams, param.getPlatformGbId(), param.getCatalogId())){
134 134 result.append(", 关联国标平台[ " + param.getPlatformGbId() + " ]成功");
135 135 }else {
136 136 result.append(", 关联国标平台[ " + param.getPlatformGbId() + " ]失败");
... ... @@ -141,6 +141,7 @@ public class StreamProxyServiceImpl implements IStreamProxyService {
141 141 if (parentPlatforms.size() > 0) {
142 142 for (ParentPlatform parentPlatform : parentPlatforms) {
143 143 param.setPlatformId(parentPlatform.getServerGBId());
  144 + param.setCatalogId(parentPlatform.getCatalogId());
144 145 String stream = param.getStream();
145 146 StreamProxyItem streamProxyItems = platformGbStreamMapper.selectOne(param.getApp(), stream, parentPlatform.getServerGBId());
146 147 if (streamProxyItems == null) {
... ... @@ -278,18 +279,18 @@ public class StreamProxyServiceImpl implements IStreamProxyService {
278 279 String type = "PULL";
279 280  
280 281 // 发送redis消息
281   - List<StreamInfo> streamInfoList = redisCatchStorage.getStreams(mediaServerId, type);
282   - if (streamInfoList.size() > 0) {
283   - for (StreamInfo streamInfo : streamInfoList) {
  282 + List<MediaItem> mediaItems = redisCatchStorage.getStreams(mediaServerId, type);
  283 + if (mediaItems.size() > 0) {
  284 + for (MediaItem mediaItem : mediaItems) {
284 285 JSONObject jsonObject = new JSONObject();
285 286 jsonObject.put("serverId", userSetup.getServerId());
286   - jsonObject.put("app", streamInfo.getApp());
287   - jsonObject.put("stream", streamInfo.getStreamId());
  287 + jsonObject.put("app", mediaItem.getApp());
  288 + jsonObject.put("stream", mediaItem.getStream());
288 289 jsonObject.put("register", false);
289 290 jsonObject.put("mediaServerId", mediaServerId);
290 291 redisCatchStorage.sendStreamChangeMsg(type, jsonObject);
291 292 // 移除redis内流的信息
292   - redisCatchStorage.removeStream(mediaServerId, type, streamInfo.getApp(), streamInfo.getStreamId());
  293 + redisCatchStorage.removeStream(mediaServerId, type, mediaItem.getApp(), mediaItem.getStream());
293 294 }
294 295 }
295 296 }
... ...
src/main/java/com/genersoft/iot/vmp/service/impl/StreamPushServiceImpl.java
... ... @@ -119,6 +119,7 @@ public class StreamPushServiceImpl implements IStreamPushService {
119 119 List<ParentPlatform> parentPlatforms = parentPlatformMapper.selectAllAhareAllLiveStream();
120 120 if (parentPlatforms.size() > 0) {
121 121 for (ParentPlatform parentPlatform : parentPlatforms) {
  122 + stream.setCatalogId(parentPlatform.getCatalogId());
122 123 stream.setPlatformId(parentPlatform.getServerGBId());
123 124 String streamId = stream.getStream();
124 125 StreamProxyItem streamProxyItems = platformGbStreamMapper.selectOne(stream.getApp(), streamId, parentPlatform.getServerGBId());
... ... @@ -172,16 +173,16 @@ public class StreamPushServiceImpl implements IStreamPushService {
172 173 List<StreamPushItem> pushList = getPushList(mediaServerId);
173 174 Map<String, StreamPushItem> pushItemMap = new HashMap<>();
174 175 // redis记录
175   - List<StreamInfo> streamInfoPushList = redisCatchStorage.getStreams(mediaServerId, "PUSH");
176   - Map<String, StreamInfo> streamInfoPushItemMap = new HashMap<>();
  176 + List<MediaItem> mediaItems = redisCatchStorage.getStreams(mediaServerId, "PUSH");
  177 + Map<String, MediaItem> streamInfoPushItemMap = new HashMap<>();
177 178 if (pushList.size() > 0) {
178 179 for (StreamPushItem streamPushItem : pushList) {
179 180 pushItemMap.put(streamPushItem.getApp() + streamPushItem.getStream(), streamPushItem);
180 181 }
181 182 }
182   - if (streamInfoPushList.size() > 0) {
183   - for (StreamInfo streamInfo : streamInfoPushList) {
184   - streamInfoPushItemMap.put(streamInfo.getApp() + streamInfo.getStreamId(), streamInfo);
  183 + if (mediaItems.size() > 0) {
  184 + for (MediaItem mediaItem : mediaItems) {
  185 + streamInfoPushItemMap.put(mediaItem.getApp() + mediaItem.getStream(), mediaItem);
185 186 }
186 187 }
187 188 zlmresTfulUtils.getMediaList(mediaServerItem, (mediaList ->{
... ... @@ -220,19 +221,19 @@ public class StreamPushServiceImpl implements IStreamPushService {
220 221 }
221 222  
222 223 }
223   - Collection<StreamInfo> offlineStreamInfoItems = streamInfoPushItemMap.values();
224   - if (offlineStreamInfoItems.size() > 0) {
  224 + Collection<MediaItem> offlineMediaItemList = streamInfoPushItemMap.values();
  225 + if (offlineMediaItemList.size() > 0) {
225 226 String type = "PUSH";
226   - for (StreamInfo offlineStreamInfoItem : offlineStreamInfoItems) {
  227 + for (MediaItem offlineMediaItem : offlineMediaItemList) {
227 228 JSONObject jsonObject = new JSONObject();
228 229 jsonObject.put("serverId", userSetup.getServerId());
229   - jsonObject.put("app", offlineStreamInfoItem.getApp());
230   - jsonObject.put("stream", offlineStreamInfoItem.getStreamId());
  230 + jsonObject.put("app", offlineMediaItem.getApp());
  231 + jsonObject.put("stream", offlineMediaItem.getStream());
231 232 jsonObject.put("register", false);
232 233 jsonObject.put("mediaServerId", mediaServerId);
233 234 redisCatchStorage.sendStreamChangeMsg(type, jsonObject);
234 235 // 移除redis内流的信息
235   - redisCatchStorage.removeStream(mediaServerItem.getId(), "PUSH", offlineStreamInfoItem.getApp(), offlineStreamInfoItem.getStreamId());
  236 + redisCatchStorage.removeStream(mediaServerItem.getId(), "PUSH", offlineMediaItem.getApp(), offlineMediaItem.getStream());
236 237 }
237 238 }
238 239 }));
... ... @@ -249,15 +250,15 @@ public class StreamPushServiceImpl implements IStreamPushService {
249 250 // 发送流停止消息
250 251 String type = "PUSH";
251 252 // 发送redis消息
252   - List<StreamInfo> streamInfoList = redisCatchStorage.getStreams(mediaServerId, type);
  253 + List<MediaItem> streamInfoList = redisCatchStorage.getStreams(mediaServerId, type);
253 254 if (streamInfoList.size() > 0) {
254   - for (StreamInfo streamInfo : streamInfoList) {
  255 + for (MediaItem mediaItem : streamInfoList) {
255 256 // 移除redis内流的信息
256   - redisCatchStorage.removeStream(mediaServerId, type, streamInfo.getApp(), streamInfo.getStreamId());
  257 + redisCatchStorage.removeStream(mediaServerId, type, mediaItem.getApp(), mediaItem.getStream());
257 258 JSONObject jsonObject = new JSONObject();
258 259 jsonObject.put("serverId", userSetup.getServerId());
259   - jsonObject.put("app", streamInfo.getApp());
260   - jsonObject.put("stream", streamInfo.getStreamId());
  260 + jsonObject.put("app", mediaItem.getApp());
  261 + jsonObject.put("stream", mediaItem.getStream());
261 262 jsonObject.put("register", false);
262 263 jsonObject.put("mediaServerId", mediaServerId);
263 264 redisCatchStorage.sendStreamChangeMsg(type, jsonObject);
... ...
src/main/java/com/genersoft/iot/vmp/storager/IRedisCatchStorage.java
... ... @@ -2,11 +2,11 @@ package com.genersoft.iot.vmp.storager;
2 2  
3 3 import com.alibaba.fastjson.JSONObject;
4 4 import com.genersoft.iot.vmp.common.StreamInfo;
5   -import com.genersoft.iot.vmp.gb28181.bean.Device;
6   -import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform;
7   -import com.genersoft.iot.vmp.gb28181.bean.ParentPlatformCatch;
8   -import com.genersoft.iot.vmp.gb28181.bean.SendRtpItem;
  5 +import com.genersoft.iot.vmp.gb28181.bean.*;
  6 +import com.genersoft.iot.vmp.media.zlm.dto.MediaItem;
9 7 import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
  8 +import com.genersoft.iot.vmp.media.zlm.dto.StreamPushItem;
  9 +import com.genersoft.iot.vmp.service.bean.GPSMsgInfo;
10 10 import com.genersoft.iot.vmp.service.bean.ThirdPartyGB;
11 11  
12 12 import java.util.List;
... ... @@ -145,7 +145,7 @@ public interface IRedisCatchStorage {
145 145 * @param app
146 146 * @param streamId
147 147 */
148   - void addStream(MediaServerItem mediaServerItem, String type, String app, String streamId, StreamInfo streamInfo);
  148 + void addStream(MediaServerItem mediaServerItem, String type, String app, String streamId, MediaItem item);
149 149  
150 150 /**
151 151 * 移除流信息从redis
... ... @@ -177,7 +177,7 @@ public interface IRedisCatchStorage {
177 177 */
178 178 ThirdPartyGB queryMemberNoGBId(String queryKey);
179 179  
180   - List<StreamInfo> getStreams(String mediaServerId, String pull);
  180 + List<MediaItem> getStreams(String mediaServerId, String pull);
181 181  
182 182 /**
183 183 * 将device信息写入redis
... ... @@ -185,10 +185,29 @@ public interface IRedisCatchStorage {
185 185 */
186 186 void updateDevice(Device device);
187 187  
  188 + void removeDevice(String deviceId);
  189 +
188 190 /**
189 191 * 获取Device
190 192 */
191 193 Device getDevice(String deviceId);
192 194  
193 195 void resetAllCSEQ();
  196 +
  197 + void updateGpsMsgInfo(GPSMsgInfo gpsMsgInfo);
  198 +
  199 + GPSMsgInfo getGpsMsgInfo(String gbId);
  200 + List<GPSMsgInfo> getAllGpsMsgInfo();
  201 +
  202 + Long getSN(String method);
  203 +
  204 + void resetAllSN();
  205 +
  206 + void updateSubscribe(String key, SubscribeInfo subscribeInfo);
  207 +
  208 + SubscribeInfo getSubscribe(String key);
  209 +
  210 + void delSubscribe(String key);
  211 +
  212 + MediaItem getStreamInfo(String app, String streamId, String mediaServerId);
194 213 }
... ...
src/main/java/com/genersoft/iot/vmp/storager/IVideoManagerStorager.java
... ... @@ -4,6 +4,7 @@ import com.genersoft.iot.vmp.gb28181.bean.*;
4 4 import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
5 5 import com.genersoft.iot.vmp.media.zlm.dto.StreamProxyItem;
6 6 import com.genersoft.iot.vmp.media.zlm.dto.StreamPushItem;
  7 +import com.genersoft.iot.vmp.service.bean.GPSMsgInfo;
7 8 import com.genersoft.iot.vmp.vmanager.gb28181.platform.bean.ChannelReduce;
8 9 import com.github.pagehelper.PageInfo;
9 10  
... ... @@ -243,7 +244,7 @@ public interface IVideoManagerStorager {
243 244 * @param channelReduces
244 245 * @return
245 246 */
246   - int updateChannelForGB(String platformId, List<ChannelReduce> channelReduces);
  247 + int updateChannelForGB(String platformId, List<ChannelReduce> channelReduces, String catalogId);
247 248  
248 249 /**
249 250 * 移除上级平台的通道信息
... ... @@ -256,6 +257,9 @@ public interface IVideoManagerStorager {
256 257  
257 258 DeviceChannel queryChannelInParentPlatform(String platformId, String channelId);
258 259  
  260 + List<PlatformCatalog> queryChannelInParentPlatformAndCatalog(String platformId, String catalogId);
  261 + List<PlatformCatalog> queryStreamInParentPlatformAndCatalog(String platformId, String catalogId);
  262 +
259 263 Device queryVideoDeviceByPlatformIdAndChannelId(String platformId, String channelId);
260 264  
261 265  
... ... @@ -431,4 +435,28 @@ public interface IVideoManagerStorager {
431 435 * @param deviceChannelList
432 436 */
433 437 boolean resetChannels(String deviceId, List<DeviceChannel> deviceChannelList);
  438 +
  439 + /**
  440 + * 获取目录信息
  441 + * @param platformId
  442 + * @param parentId
  443 + * @return
  444 + */
  445 + List<PlatformCatalog> getChildrenCatalogByPlatform(String platformId, String parentId);
  446 +
  447 + int addCatalog(PlatformCatalog platformCatalog);
  448 +
  449 + PlatformCatalog getCatalog(String id);
  450 +
  451 + int delCatalog(String id);
  452 +
  453 + int updateCatalog(PlatformCatalog platformCatalog);
  454 +
  455 + int setDefaultCatalog(String platformId, String catalogId);
  456 +
  457 + List<PlatformCatalog> queryCatalogInPlatform(String serverGBId);
  458 +
  459 + int delRelation(PlatformCatalog platformCatalog);
  460 +
  461 + int updateStreamGPS(List<GPSMsgInfo> gpsMsgInfo);
434 462 }
... ...
src/main/java/com/genersoft/iot/vmp/storager/dao/DeviceChannelMapper.java
... ... @@ -91,7 +91,8 @@ public interface DeviceChannelMapper {
91 91 "SELECT * FROM ( "+
92 92 " SELECT dc.channelId, dc.deviceId, dc.name, de.manufacturer, de.hostAddress, " +
93 93 "(SELECT count(0) FROM device_channel WHERE parentId=dc.channelId) as subCount, " +
94   - "(SELECT pc.platformId FROM platform_gb_channel pc WHERE pc.deviceId=dc.deviceId AND pc.channelId = dc.channelId ) as platformId " +
  94 + "(SELECT pc.platformId FROM platform_gb_channel pc WHERE pc.deviceId=dc.deviceId AND pc.channelId = dc.channelId ) as platformId, " +
  95 + "(SELECT pc.catalogId FROM platform_gb_channel pc WHERE pc.deviceId=dc.deviceId AND pc.channelId = dc.channelId ) as catalogId " +
95 96 "FROM device_channel dc " +
96 97 "LEFT JOIN device de ON dc.deviceId = de.deviceId " +
97 98 " WHERE 1=1 " +
... ...
src/main/java/com/genersoft/iot/vmp/storager/dao/GbStreamMapper.java
... ... @@ -3,6 +3,7 @@ package com.genersoft.iot.vmp.storager.dao;
3 3 import com.genersoft.iot.vmp.gb28181.bean.GbStream;
4 4 import com.genersoft.iot.vmp.media.zlm.dto.StreamProxyItem;
5 5 import com.genersoft.iot.vmp.media.zlm.dto.StreamPushItem;
  6 +import com.genersoft.iot.vmp.service.bean.GPSMsgInfo;
6 7 import org.apache.ibatis.annotations.*;
7 8 import org.springframework.stereotype.Repository;
8 9  
... ... @@ -35,7 +36,7 @@ public interface GbStreamMapper {
35 36 @Delete("DELETE FROM gb_stream WHERE app=#{app} AND stream=#{stream}")
36 37 int del(String app, String stream);
37 38  
38   - @Select("SELECT gs.*, pgs.platformId FROM gb_stream gs LEFT JOIN platform_gb_stream pgs ON gs.app = pgs.app AND gs.stream = pgs.stream")
  39 + @Select("SELECT gs.*, pgs.platformId AS platformId, pgs.catalogId AS catalogId FROM gb_stream gs LEFT JOIN platform_gb_stream pgs ON gs.app = pgs.app AND gs.stream = pgs.stream")
39 40 List<GbStream> selectAll();
40 41  
41 42 @Select("SELECT * FROM gb_stream WHERE app=#{app} AND stream=#{stream}")
... ... @@ -44,32 +45,31 @@ public interface GbStreamMapper {
44 45 @Select("SELECT * FROM gb_stream WHERE gbId=#{gbId}")
45 46 List<GbStream> selectByGBId(String gbId);
46 47  
47   - @Select("SELECT gs.*, pgs.platformId FROM gb_stream gs " +
  48 + @Select("SELECT gs.*, pgs.platformId as platformId, pgs.catalogId as catalogId FROM gb_stream gs " +
48 49 "LEFT JOIN platform_gb_stream pgs ON gs.app = pgs.app AND gs.stream = pgs.stream " +
49 50 "WHERE gs.gbId = '${gbId}' AND pgs.platformId = '${platformId}'")
50 51 List<GbStream> queryStreamInPlatform(String platformId, String gbId);
51 52  
52   - @Select("SELECT gs.*, pgs.platformId FROM gb_stream gs " +
  53 + @Select("SELECT gs.*, pgs.platformId as platformId, pgs.catalogId as catalogId FROM gb_stream gs " +
53 54 "LEFT JOIN platform_gb_stream pgs ON gs.app = pgs.app AND gs.stream = pgs.stream " +
54 55 "WHERE pgs.platformId = '${platformId}'")
55 56 List<GbStream> queryGbStreamListInPlatform(String platformId);
56 57  
  58 +
  59 + @Select("SELECT gs.*, pgs.platformId as platformId, pgs.catalogId as catalogId FROM gb_stream gs LEFT JOIN platform_gb_stream pgs " +
  60 + "ON gs.app = pgs.app and gs.stream = pgs.stream WHERE pgs.app is NULL and pgs.stream is NULL")
  61 + List<GbStream> queryStreamNotInPlatform();
  62 +
57 63 @Update("UPDATE gb_stream " +
58 64 "SET status=${status} " +
59 65 "WHERE app=#{app} AND stream=#{stream}")
60 66 int setStatus(String app, String stream, boolean status);
61 67  
62   - @Select("SELECT gs.*, pgs.platformId FROM gb_stream gs LEFT JOIN platform_gb_stream pgs ON gs.app = pgs.app AND gs.stream = pgs.stream WHERE mediaServerId=#{mediaServerId} ")
63   - List<GbStream> selectAllByMediaServerId(String mediaServerId);
64   -
65 68 @Update("UPDATE gb_stream " +
66 69 "SET status=${status} " +
67 70 "WHERE mediaServerId=#{mediaServerId} ")
68 71 void updateStatusByMediaServerId(String mediaServerId, boolean status);
69 72  
70   - @Select("SELECT * FROM gb_stream WHERE mediaServerId=#{mediaServerId}")
71   - void delByMediaServerId(String mediaServerId);
72   -
73 73 @Delete("DELETE FROM gb_stream WHERE streamType=#{type} AND gbId=NULL AND mediaServerId=#{mediaServerId}")
74 74 void deleteWithoutGBId(String type, String mediaServerId);
75 75  
... ... @@ -93,4 +93,15 @@ public interface GbStreamMapper {
93 93 "</foreach> " +
94 94 "</script>")
95 95 void batchAdd(List<StreamPushItem> subList);
  96 +
  97 +
  98 + @Update({"<script>" +
  99 + "<foreach collection='gpsMsgInfos' item='item' separator=';'>" +
  100 + " UPDATE" +
  101 + " gb_stream" +
  102 + " SET longitude=${item.lng}, latitude=${item.lat} " +
  103 + "WHERE gbId=#{item.id}"+
  104 + "</foreach>" +
  105 + "</script>"})
  106 + int updateStreamGPS(List<GPSMsgInfo> gpsMsgInfos);
96 107 }
... ...
src/main/java/com/genersoft/iot/vmp/storager/dao/ParentPlatformMapper.java
... ... @@ -15,10 +15,10 @@ public interface ParentPlatformMapper {
15 15  
16 16 @Insert("INSERT INTO parent_platform (enable, name, serverGBId, serverGBDomain, serverIP, serverPort, deviceGBId, deviceIp, " +
17 17 " devicePort, username, password, expires, keepTimeout, transport, characterSet, ptz, rtcp, " +
18   - " status, shareAllLiveStream) " +
  18 + " status, shareAllLiveStream, catalogId) " +
19 19 " VALUES (${enable}, '${name}', '${serverGBId}', '${serverGBDomain}', '${serverIP}', ${serverPort}, '${deviceGBId}', '${deviceIp}', " +
20 20 " '${devicePort}', '${username}', '${password}', '${expires}', '${keepTimeout}', '${transport}', '${characterSet}', ${ptz}, ${rtcp}, " +
21   - " ${status}, ${shareAllLiveStream})")
  21 + " ${status}, ${shareAllLiveStream}, #{catalogId})")
22 22 int addParentPlatform(ParentPlatform parentPlatform);
23 23  
24 24 @Update("UPDATE parent_platform " +
... ... @@ -40,7 +40,8 @@ public interface ParentPlatformMapper {
40 40 "ptz=#{ptz}, " +
41 41 "rtcp=#{rtcp}, " +
42 42 "status=#{status}, " +
43   - "shareAllLiveStream=#{shareAllLiveStream} " +
  43 + "shareAllLiveStream=#{shareAllLiveStream}, " +
  44 + "catalogId=#{catalogId} " +
44 45 "WHERE id=#{id}")
45 46 int updateParentPlatform(ParentPlatform parentPlatform);
46 47  
... ... @@ -74,4 +75,11 @@ public interface ParentPlatformMapper {
74 75  
75 76 @Select("SELECT * FROM parent_platform WHERE shareAllLiveStream=true")
76 77 List<ParentPlatform> selectAllAhareAllLiveStream();
  78 +
  79 + @Update(value = {" <script>" +
  80 + "UPDATE parent_platform " +
  81 + "SET catalogId=#{catalogId}" +
  82 + "WHERE serverGBId=#{platformId}"+
  83 + "</script>"})
  84 + int setDefaultCatalog(String platformId, String catalogId);
77 85 }
... ...
src/main/java/com/genersoft/iot/vmp/storager/dao/PlatformCatalogMapper.java 0 → 100644
  1 +package com.genersoft.iot.vmp.storager.dao;
  2 +
  3 +import com.genersoft.iot.vmp.gb28181.bean.GbStream;
  4 +import com.genersoft.iot.vmp.gb28181.bean.PlatformCatalog;
  5 +import com.genersoft.iot.vmp.gb28181.bean.PlatformGbStream;
  6 +import com.genersoft.iot.vmp.media.zlm.dto.StreamProxyItem;
  7 +import org.apache.ibatis.annotations.*;
  8 +import org.springframework.stereotype.Repository;
  9 +
  10 +import java.util.List;
  11 +
  12 +
  13 +@Mapper
  14 +@Repository
  15 +public interface PlatformCatalogMapper {
  16 +
  17 + @Insert("INSERT INTO platform_catalog (id, name, platformId, parentId) VALUES" +
  18 + "(#{id}, #{name}, #{platformId}, #{parentId})")
  19 + int add(PlatformCatalog platformCatalog);
  20 +
  21 + @Delete("DELETE FROM platform_catalog WHERE id=#{id}")
  22 + int del(String id);
  23 +
  24 + @Delete("DELETE FROM platform_catalog WHERE platformId=#{platformId}")
  25 + int delByPlatformId(String platformId);
  26 +
  27 + @Select("SELECT *, (SELECT COUNT(1) from platform_catalog where parentId = pc.id AND platformId=#{platformId}) as childrenCount FROM platform_catalog pc WHERE parentId=#{parentId} AND platformId=#{platformId}")
  28 + List<PlatformCatalog> selectByParentId(String platformId, String parentId);
  29 +
  30 + @Select("SELECT *, (SELECT COUNT(1) from platform_catalog where parentId = pc.id) as childrenCount FROM platform_catalog pc WHERE pc.id=#{id}")
  31 + PlatformCatalog select(String id);
  32 +
  33 + @Update(value = {" <script>" +
  34 + "UPDATE platform_catalog " +
  35 + "SET name=#{name}" +
  36 + "WHERE id=#{id}"+
  37 + "</script>"})
  38 + int update(PlatformCatalog platformCatalog);
  39 +
  40 + @Select("SELECT *, (SELECT COUNT(1) from platform_catalog where parentId = pc.id) as childrenCount FROM platform_catalog pc WHERE pc.platformId=#{platformId}")
  41 + List<PlatformCatalog> selectByPlatForm(String platformId);
  42 +}
... ...
src/main/java/com/genersoft/iot/vmp/storager/dao/PlatformChannelMapper.java
... ... @@ -2,6 +2,7 @@ package com.genersoft.iot.vmp.storager.dao;
2 2  
3 3 import com.genersoft.iot.vmp.gb28181.bean.Device;
4 4 import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel;
  5 +import com.genersoft.iot.vmp.gb28181.bean.PlatformCatalog;
5 6 import com.genersoft.iot.vmp.vmanager.gb28181.platform.bean.ChannelReduce;
6 7 import org.apache.ibatis.annotations.Delete;
7 8 import org.apache.ibatis.annotations.Insert;
... ... @@ -25,9 +26,9 @@ public interface PlatformChannelMapper {
25 26 List<String> findChannelRelatedPlatform(String platformId, List<String> deviceAndChannelIds);
26 27  
27 28 @Insert("<script> "+
28   - "INSERT INTO platform_gb_channel (channelId, deviceId, platformId, deviceAndChannelId) VALUES" +
  29 + "INSERT INTO platform_gb_channel (channelId, deviceId, platformId, deviceAndChannelId, catalogId) VALUES" +
29 30 "<foreach collection='channelReducesToAdd' item='item' separator=','>" +
30   - " ('${item.channelId}','${item.deviceId}', '${platformId}', '${item.deviceId}_${item.channelId}' )" +
  31 + " ('${item.channelId}','${item.deviceId}', '${platformId}', '${item.deviceId}_${item.channelId}' , '${item.catalogId}' )" +
31 32 "</foreach>" +
32 33 "</script>")
33 34 int addChannels(String platformId, List<ChannelReduce> channelReducesToAdd);
... ... @@ -54,6 +55,22 @@ public interface PlatformChannelMapper {
54 55 "platformId='${platformId}' AND channelId='${channelId}' ) AND channelId='${channelId}'")
55 56 DeviceChannel queryChannelInParentPlatform(String platformId, String channelId);
56 57  
  58 +
  59 + @Select("select dc.channelId as id, dc.name as name, pgc.platformId as platformId, pgc.catalogId as parentId, 0 as childrenCount, 1 as type " +
  60 + "from device_channel dc left join platform_gb_channel pgc on dc.deviceId = pgc.deviceId and dc.channelId = pgc.channelId " +
  61 + "where pgc.platformId=#{platformId} and pgc.catalogId=#{catalogId}")
  62 + List<PlatformCatalog> queryChannelInParentPlatformAndCatalog(String platformId, String catalogId);
  63 +
57 64 @Select("SELECT * FROM device WHERE deviceId = (SELECT deviceId FROM platform_gb_channel WHERE platformId='${platformId}' AND channelId='${channelId}')")
58 65 Device queryVideoDeviceByPlatformIdAndChannelId(String platformId, String channelId);
  66 +
  67 + @Delete("<script> "+
  68 + "DELETE FROM platform_gb_channel WHERE catalogId=#{id}" +
  69 + "</script>")
  70 + int delByCatalogId(String id);
  71 +
  72 + @Delete("<script> "+
  73 + "DELETE FROM platform_gb_channel WHERE catalogId=#{parentId} AND platformId=#{platformId} AND channelId=#{id}" +
  74 + "</script>")
  75 + int delByCatalogIdAndChannelIdAndPlatformId(PlatformCatalog platformCatalog);
59 76 }
... ...
src/main/java/com/genersoft/iot/vmp/storager/dao/PlatformGbStreamMapper.java
1 1 package com.genersoft.iot.vmp.storager.dao;
2 2  
  3 +import com.genersoft.iot.vmp.gb28181.bean.GbStream;
  4 +import com.genersoft.iot.vmp.gb28181.bean.PlatformCatalog;
3 5 import com.genersoft.iot.vmp.gb28181.bean.PlatformGbStream;
4 6 import com.genersoft.iot.vmp.media.zlm.dto.StreamProxyItem;
5 7 import org.apache.ibatis.annotations.*;
... ... @@ -12,8 +14,8 @@ import java.util.List;
12 14 @Repository
13 15 public interface PlatformGbStreamMapper {
14 16  
15   - @Insert("INSERT INTO platform_gb_stream (app, stream, platformId) VALUES" +
16   - "('${app}', '${stream}', '${platformId}')")
  17 + @Insert("INSERT INTO platform_gb_stream (app, stream, platformId, catalogId) VALUES" +
  18 + "('${app}', '${stream}', '${platformId}', '${catalogId}')")
17 19 int add(PlatformGbStream platformGbStream);
18 20  
19 21 @Delete("DELETE FROM platform_gb_stream WHERE app=#{app} AND stream=#{stream}")
... ... @@ -27,4 +29,22 @@ public interface PlatformGbStreamMapper {
27 29  
28 30 @Select("SELECT * FROM platform_gb_stream WHERE app=#{app} AND stream=#{stream} AND platformId=#{serverGBId}")
29 31 StreamProxyItem selectOne(String app, String stream, String serverGBId);
  32 +
  33 + @Select("select gs.* \n" +
  34 + "from gb_stream gs\n" +
  35 + " left join platform_gb_stream pgs\n" +
  36 + " on gs.app = pgs.app and gs.stream = pgs.stream\n" +
  37 + "where pgs.platformId=#{platformId} and pgs.catalogId=#{catalogId}")
  38 + List<GbStream> queryChannelInParentPlatformAndCatalog(String platformId, String catalogId);
  39 +
  40 + @Select("select gs.gbId as id, gs.name as name, pgs.platformId as platformId, pgs.catalogId as catalogId , 0 as childrenCount, 2 as type\n" +
  41 + "from gb_stream gs\n" +
  42 + " left join platform_gb_stream pgs\n" +
  43 + " on gs.app = pgs.app and gs.stream = pgs.stream\n" +
  44 + "where pgs.platformId=#{platformId} and pgs.catalogId=#{catalogId}")
  45 + List<PlatformCatalog> queryChannelInParentPlatformAndCatalogForCatlog(String platformId, String catalogId);
  46 +
  47 + @Delete("DELETE FROM platform_gb_stream WHERE catalogId=#{id}")
  48 + int delByCatalogId(String id);
  49 +
30 50 }
... ...
src/main/java/com/genersoft/iot/vmp/storager/impl/RedisCatchStorageImpl.java
... ... @@ -5,7 +5,10 @@ import com.genersoft.iot.vmp.common.StreamInfo;
5 5 import com.genersoft.iot.vmp.common.VideoManagerConstants;
6 6 import com.genersoft.iot.vmp.conf.UserSetup;
7 7 import com.genersoft.iot.vmp.gb28181.bean.*;
  8 +import com.genersoft.iot.vmp.media.zlm.dto.MediaItem;
8 9 import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
  10 +import com.genersoft.iot.vmp.media.zlm.dto.StreamPushItem;
  11 +import com.genersoft.iot.vmp.service.bean.GPSMsgInfo;
9 12 import com.genersoft.iot.vmp.service.bean.ThirdPartyGB;
10 13 import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
11 14 import com.genersoft.iot.vmp.storager.dao.DeviceChannelMapper;
... ... @@ -49,6 +52,18 @@ public class RedisCatchStorageImpl implements IRedisCatchStorage {
49 52 }
50 53  
51 54 @Override
  55 + public Long getSN(String method) {
  56 + String key = VideoManagerConstants.SIP_SN_PREFIX + userSetup.getServerId() + "_" + method;
  57 +
  58 + long result = redis.incr(key, 1L);
  59 + if (result > Integer.MAX_VALUE) {
  60 + redis.set(key, 1);
  61 + result = 1;
  62 + }
  63 + return result;
  64 + }
  65 +
  66 + @Override
52 67 public void resetAllCSEQ() {
53 68 String scanKey = VideoManagerConstants.SIP_CSEQ_PREFIX + userSetup.getServerId() + "_*";
54 69 List<Object> keys = redis.scan(scanKey);
... ... @@ -58,6 +73,16 @@ public class RedisCatchStorageImpl implements IRedisCatchStorage {
58 73 }
59 74 }
60 75  
  76 + @Override
  77 + public void resetAllSN() {
  78 + String scanKey = VideoManagerConstants.SIP_SN_PREFIX + userSetup.getServerId() + "_*";
  79 + List<Object> keys = redis.scan(scanKey);
  80 + for (int i = 0; i < keys.size(); i++) {
  81 + String key = (String) keys.get(i);
  82 + redis.set(key, 1);
  83 + }
  84 + }
  85 +
61 86 /**
62 87 * 开始播放时将流存入redis
63 88 *
... ... @@ -318,6 +343,15 @@ public class RedisCatchStorageImpl implements IRedisCatchStorage {
318 343 redis.del(key.toString());
319 344 }
320 345 }
  346 +
  347 + List<Object> deviceCache = redis.scan(String.format("%S%s_%s", VideoManagerConstants.DEVICE_PREFIX,
  348 + userSetup.getServerId(),
  349 + deviceId));
  350 + if (deviceCache.size() > 0) {
  351 + for (Object key : deviceCache) {
  352 + redis.del(key.toString());
  353 + }
  354 + }
321 355 }
322 356  
323 357 @Override
... ... @@ -354,9 +388,9 @@ public class RedisCatchStorageImpl implements IRedisCatchStorage {
354 388 }
355 389  
356 390 @Override
357   - public void addStream(MediaServerItem mediaServerItem, String type, String app, String streamId, StreamInfo streamInfo) {
  391 + public void addStream(MediaServerItem mediaServerItem, String type, String app, String streamId, MediaItem mediaItem) {
358 392 String key = VideoManagerConstants.WVP_SERVER_STREAM_PREFIX + userSetup.getServerId() + "_" + type + "_" + app + "_" + streamId + "_" + mediaServerItem.getId();
359   - redis.set(key, streamInfo);
  393 + redis.set(key, mediaItem);
360 394 }
361 395  
362 396 @Override
... ... @@ -389,13 +423,13 @@ public class RedisCatchStorageImpl implements IRedisCatchStorage {
389 423 }
390 424  
391 425 @Override
392   - public List<StreamInfo> getStreams(String mediaServerId, String type) {
393   - List<StreamInfo> result = new ArrayList<>();
  426 + public List<MediaItem> getStreams(String mediaServerId, String type) {
  427 + List<MediaItem> result = new ArrayList<>();
394 428 String key = VideoManagerConstants.WVP_SERVER_STREAM_PREFIX + userSetup.getServerId() + "_" + type + "_*_*_" + mediaServerId;
395 429 List<Object> streams = redis.scan(key);
396 430 for (Object stream : streams) {
397   - StreamInfo streamInfo = (StreamInfo)redis.get((String) stream);
398   - result.add(streamInfo);
  431 + MediaItem mediaItem = (MediaItem)redis.get((String) stream);
  432 + result.add(mediaItem);
399 433 }
400 434 return result;
401 435 }
... ... @@ -407,8 +441,71 @@ public class RedisCatchStorageImpl implements IRedisCatchStorage {
407 441 }
408 442  
409 443 @Override
  444 + public void removeDevice(String deviceId) {
  445 + String key = VideoManagerConstants.DEVICE_PREFIX + userSetup.getServerId() + "_" + deviceId;
  446 + redis.del(key);
  447 + }
  448 +
  449 + @Override
410 450 public Device getDevice(String deviceId) {
411 451 String key = VideoManagerConstants.DEVICE_PREFIX + userSetup.getServerId() + "_" + deviceId;
412 452 return (Device)redis.get(key);
413 453 }
  454 +
  455 + @Override
  456 + public void updateGpsMsgInfo(GPSMsgInfo gpsMsgInfo) {
  457 + String key = VideoManagerConstants.WVP_STREAM_GPS_MSG_PREFIX + userSetup.getServerId() + "_" + gpsMsgInfo.getId();
  458 + redis.set(key, gpsMsgInfo, 60); // 默认GPS消息保存1分钟
  459 + }
  460 +
  461 + @Override
  462 + public GPSMsgInfo getGpsMsgInfo(String gbId) {
  463 + String key = VideoManagerConstants.WVP_STREAM_GPS_MSG_PREFIX + userSetup.getServerId() + "_" + gbId;
  464 + return (GPSMsgInfo)redis.get(key);
  465 + }
  466 +
  467 + @Override
  468 + public void updateSubscribe(String key, SubscribeInfo subscribeInfo) {
  469 + redis.set(key, subscribeInfo, subscribeInfo.getExpires());
  470 + }
  471 +
  472 + @Override
  473 + public SubscribeInfo getSubscribe(String key) {
  474 + return (SubscribeInfo)redis.get(key);
  475 + }
  476 +
  477 + @Override
  478 + public void delSubscribe(String key) {
  479 + redis.del(key);
  480 + }
  481 +
  482 + @Override
  483 + public List<GPSMsgInfo> getAllGpsMsgInfo() {
  484 + String scanKey = VideoManagerConstants.WVP_STREAM_GPS_MSG_PREFIX + userSetup.getServerId() + "_*";
  485 + List<GPSMsgInfo> result = new ArrayList<>();
  486 + List<Object> keys = redis.scan(scanKey);
  487 + for (int i = 0; i < keys.size(); i++) {
  488 + String key = (String) keys.get(i);
  489 + GPSMsgInfo gpsMsgInfo = (GPSMsgInfo) redis.get(key);
  490 + if (!gpsMsgInfo.isStored()) { // 只取没有存过得
  491 + result.add((GPSMsgInfo)redis.get(key));
  492 + }
  493 + }
  494 +
  495 + return result;
  496 + }
  497 +
  498 + @Override
  499 + public MediaItem getStreamInfo(String app, String streamId, String mediaServerId) {
  500 + String scanKey = VideoManagerConstants.WVP_SERVER_STREAM_PREFIX + userSetup.getServerId() + "_*_" + app + "_" + streamId + "_" + mediaServerId;
  501 +
  502 + MediaItem result = null;
  503 + List<Object> keys = redis.scan(scanKey);
  504 + if (keys.size() > 0) {
  505 + String key = (String) keys.get(0);
  506 + result = (MediaItem)redis.get(key);
  507 + }
  508 +
  509 + return result;
  510 + }
414 511 }
... ...
src/main/java/com/genersoft/iot/vmp/storager/impl/VideoManagerStoragerImpl.java
... ... @@ -6,6 +6,7 @@ import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
6 6 import com.genersoft.iot.vmp.media.zlm.dto.StreamProxyItem;
7 7 import com.genersoft.iot.vmp.media.zlm.dto.StreamPushItem;
8 8 import com.genersoft.iot.vmp.service.IGbStreamService;
  9 +import com.genersoft.iot.vmp.service.bean.GPSMsgInfo;
9 10 import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
10 11 import com.genersoft.iot.vmp.storager.IVideoManagerStorager;
11 12 import com.genersoft.iot.vmp.storager.dao.*;
... ... @@ -68,6 +69,9 @@ public class VideoManagerStoragerImpl implements IVideoManagerStorager {
68 69  
69 70 @Autowired
70 71 private GbStreamMapper gbStreamMapper;
  72 +
  73 + @Autowired
  74 + private PlatformCatalogMapper catalogMapper;
71 75 ;
72 76  
73 77 @Autowired
... ... @@ -466,6 +470,9 @@ public class VideoManagerStoragerImpl implements IVideoManagerStorager {
466 470  
467 471 @Override
468 472 public boolean addParentPlatform(ParentPlatform parentPlatform) {
  473 + if (parentPlatform.getCatalogId() == null) {
  474 + parentPlatform.setCatalogId(parentPlatform.getServerGBId());
  475 + }
469 476 int result = platformMapper.addParentPlatform(parentPlatform);
470 477 return result > 0;
471 478 }
... ... @@ -475,6 +482,9 @@ public class VideoManagerStoragerImpl implements IVideoManagerStorager {
475 482 int result = 0;
476 483 ParentPlatformCatch parentPlatformCatch = redisCatchStorage.queryPlatformCatchInfo(parentPlatform.getServerGBId()); // .getDeviceGBId());
477 484 if (parentPlatform.getId() == null ) {
  485 + if (parentPlatform.getCatalogId() == null) {
  486 + parentPlatform.setCatalogId(parentPlatform.getServerGBId());
  487 + }
478 488 result = platformMapper.addParentPlatform(parentPlatform);
479 489 if (parentPlatformCatch == null) {
480 490 parentPlatformCatch = new ParentPlatformCatch();
... ... @@ -494,15 +504,21 @@ public class VideoManagerStoragerImpl implements IVideoManagerStorager {
494 504 // 更新缓存
495 505 parentPlatformCatch.setParentPlatform(parentPlatform);
496 506 redisCatchStorage.updatePlatformCatchInfo(parentPlatformCatch);
497   - // 共享所有视频流,需要将现有视频流添加到此平台
498   - List<GbStream> gbStreams = gbStreamMapper.selectAll();
499   - if (gbStreams.size() > 0) {
500   - if (parentPlatform.isShareAllLiveStream()) {
501   - gbStreamService.addPlatformInfo(gbStreams, parentPlatform.getServerGBId());
502   - }else {
503   - gbStreamService.delPlatformInfo(gbStreams);
  507 + if (parentPlatform.isEnable()) {
  508 + // 共享所有视频流,需要将现有视频流添加到此平台
  509 + List<GbStream> gbStreams = gbStreamMapper.queryStreamNotInPlatform();
  510 + if (gbStreams.size() > 0) {
  511 + for (GbStream gbStream : gbStreams) {
  512 + gbStream.setCatalogId(parentPlatform.getCatalogId());
  513 + }
  514 + if (parentPlatform.isShareAllLiveStream()) {
  515 + gbStreamService.addPlatformInfo(gbStreams, parentPlatform.getServerGBId(), parentPlatform.getCatalogId());
  516 + }else {
  517 + gbStreamService.delPlatformInfo(gbStreams);
  518 + }
504 519 }
505 520 }
  521 +
506 522 return result > 0;
507 523 }
508 524  
... ... @@ -553,10 +569,11 @@ public class VideoManagerStoragerImpl implements IVideoManagerStorager {
553 569 }
554 570  
555 571 @Override
556   - public int updateChannelForGB(String platformId, List<ChannelReduce> channelReduces) {
  572 + public int updateChannelForGB(String platformId, List<ChannelReduce> channelReduces, String catalogId) {
557 573  
558 574 Map<String, ChannelReduce> deviceAndChannels = new HashMap<>();
559 575 for (ChannelReduce channelReduce : channelReduces) {
  576 + channelReduce.setCatalogId(catalogId);
560 577 deviceAndChannels.put(channelReduce.getDeviceId() + "_" + channelReduce.getChannelId(), channelReduce);
561 578 }
562 579 List<String> deviceAndChannelList = new ArrayList<>(deviceAndChannels.keySet());
... ... @@ -594,6 +611,18 @@ public class VideoManagerStoragerImpl implements IVideoManagerStorager {
594 611 }
595 612  
596 613 @Override
  614 + public List<PlatformCatalog> queryChannelInParentPlatformAndCatalog(String platformId, String catalogId) {
  615 + List<PlatformCatalog> catalogs = platformChannelMapper.queryChannelInParentPlatformAndCatalog(platformId, catalogId);
  616 + return catalogs;
  617 + }
  618 +
  619 + @Override
  620 + public List<PlatformCatalog> queryStreamInParentPlatformAndCatalog(String platformId, String catalogId) {
  621 + List<PlatformCatalog> catalogs = platformGbStreamMapper.queryChannelInParentPlatformAndCatalogForCatlog(platformId, catalogId);
  622 + return catalogs;
  623 + }
  624 +
  625 + @Override
597 626 public Device queryVideoDeviceByPlatformIdAndChannelId(String platformId, String channelId) {
598 627 Device device = platformChannelMapper.queryVideoDeviceByPlatformIdAndChannelId(platformId, channelId);
599 628 return device;
... ... @@ -756,6 +785,7 @@ public class VideoManagerStoragerImpl implements IVideoManagerStorager {
756 785 List<ParentPlatform> parentPlatforms = parentPlatformMapper.selectAllAhareAllLiveStream();
757 786 if (parentPlatforms.size() > 0) {
758 787 for (ParentPlatform parentPlatform : parentPlatforms) {
  788 + streamPushItem.setCatalogId(parentPlatform.getCatalogId());
759 789 streamPushItem.setPlatformId(parentPlatform.getServerGBId());
760 790 String stream = streamPushItem.getStream();
761 791 StreamProxyItem streamProxyItems = platformGbStreamMapper.selectOne(streamPushItem.getApp(), stream, parentPlatform.getServerGBId());
... ... @@ -821,4 +851,74 @@ public class VideoManagerStoragerImpl implements IVideoManagerStorager {
821 851 return streamProxyMapper.selectOne(app, streamId);
822 852 }
823 853  
  854 + @Override
  855 + public List<PlatformCatalog> getChildrenCatalogByPlatform(String platformId, String parentId) {
  856 + return catalogMapper.selectByParentId(platformId, parentId);
  857 + }
  858 +
  859 + @Override
  860 + public int addCatalog(PlatformCatalog platformCatalog) {
  861 + return catalogMapper.add(platformCatalog);
  862 + }
  863 +
  864 + @Override
  865 + public PlatformCatalog getCatalog(String id) {
  866 + return catalogMapper.select(id);
  867 + }
  868 +
  869 + @Override
  870 + public int delCatalog(String id) {
  871 + PlatformCatalog platformCatalog = catalogMapper.select(id);
  872 + if (platformCatalog.getChildrenCount() > 0) {
  873 + List<PlatformCatalog> platformCatalogList = catalogMapper.selectByParentId(platformCatalog.getPlatformId(), platformCatalog.getId());
  874 + for (PlatformCatalog catalog : platformCatalogList) {
  875 + if (catalog.getChildrenCount() == 0) {
  876 + catalogMapper.del(catalog.getId());
  877 + platformGbStreamMapper.delByCatalogId(catalog.getId());
  878 + platformChannelMapper.delByCatalogId(catalog.getId());
  879 + }else {
  880 + delCatalog(catalog.getId());
  881 + }
  882 + }
  883 + }
  884 + int delresult = catalogMapper.del(id);
  885 + int delStreamresult = platformGbStreamMapper.delByCatalogId(id);
  886 + int delChanneresult = platformChannelMapper.delByCatalogId(id);
  887 + return delresult + delChanneresult + delStreamresult;
  888 + }
  889 +
  890 + @Override
  891 + public int updateCatalog(PlatformCatalog platformCatalog) {
  892 + return catalogMapper.update(platformCatalog);
  893 + }
  894 +
  895 + @Override
  896 + public int setDefaultCatalog(String platformId, String catalogId) {
  897 + return platformMapper.setDefaultCatalog(platformId, catalogId);
  898 + }
  899 +
  900 + @Override
  901 + public List<PlatformCatalog> queryCatalogInPlatform(String platformId) {
  902 + return catalogMapper.selectByPlatForm(platformId);
  903 + }
  904 +
  905 + @Override
  906 + public int delRelation(PlatformCatalog platformCatalog) {
  907 + if (platformCatalog.getType() == 1) {
  908 + return platformChannelMapper.delByCatalogIdAndChannelIdAndPlatformId(platformCatalog);
  909 + }else if (platformCatalog.getType() == 2) {
  910 + List<GbStream> gbStreams = platformGbStreamMapper.queryChannelInParentPlatformAndCatalog(platformCatalog.getPlatformId(), platformCatalog.getParentId());
  911 + for (GbStream gbStream : gbStreams) {
  912 + if (gbStream.getGbId().equals(platformCatalog.getId())) {
  913 + return platformGbStreamMapper.delByAppAndStream(gbStream.getApp(), gbStream.getStream());
  914 + }
  915 + }
  916 + }
  917 + return 0;
  918 + }
  919 +
  920 + @Override
  921 + public int updateStreamGPS(List<GPSMsgInfo> gpsMsgInfos) {
  922 + return gbStreamMapper.updateStreamGPS(gpsMsgInfos);
  923 + }
824 924 }
... ...
src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/device/DeviceQuery.java
... ... @@ -153,12 +153,15 @@ public class DeviceQuery {
153 153 // 默认超时时间为30分钟
154 154 DeferredResult<ResponseEntity<Device>> result = new DeferredResult<ResponseEntity<Device>>(30*60*1000L);
155 155 result.onTimeout(()->{
156   - logger.warn(String.format("设备通道信息同步超时"));
  156 + logger.warn("设备[{}]通道信息同步超时", deviceId);
  157 + // 释放rtpserver
157 158 RequestMessage msg = new RequestMessage();
158 159 msg.setKey(key);
  160 + msg.setId(uuid);
159 161 WVPResult<Object> wvpResult = new WVPResult<>();
160   - wvpResult.setCode(0);
161   - wvpResult.setMsg("Timeout");
  162 + wvpResult.setCode(-1);
  163 + wvpResult.setData(device);
  164 + wvpResult.setMsg("更新超时");
162 165 msg.setData(wvpResult);
163 166 resultHolder.invokeAllResult(msg);
164 167  
... ... @@ -170,8 +173,10 @@ public class DeviceQuery {
170 173 cmder.catalogQuery(device, event -> {
171 174 RequestMessage msg = new RequestMessage();
172 175 msg.setKey(key);
  176 + msg.setId(uuid);
173 177 WVPResult<Object> wvpResult = new WVPResult<>();
174   - wvpResult.setCode(0);
  178 + wvpResult.setCode(-1);
  179 + wvpResult.setData(device);
175 180 wvpResult.setMsg(String.format("同步通道失败,错误码: %s, %s", event.statusCode, event.msg));
176 181 msg.setData(wvpResult);
177 182 resultHolder.invokeAllResult(msg);
... ...
src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/gbStream/GbStreamController.java
... ... @@ -82,7 +82,7 @@ public class GbStreamController {
82 82 @PostMapping(value = "/add")
83 83 @ResponseBody
84 84 public Object add(@RequestBody GbStreamParam gbStreamParam){
85   - if (gbStreamService.addPlatformInfo(gbStreamParam.getGbStreams(), gbStreamParam.getPlatformId())) {
  85 + if (gbStreamService.addPlatformInfo(gbStreamParam.getGbStreams(), gbStreamParam.getPlatformId(), gbStreamParam.getCatalogId())) {
86 86 return "success";
87 87 }else {
88 88 return "fail";
... ...
src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/gbStream/bean/GbStreamParam.java
... ... @@ -8,12 +8,22 @@ public class GbStreamParam {
8 8  
9 9 private String platformId;
10 10  
  11 + private String catalogId;
  12 +
11 13 private List<GbStream> gbStreams;
12 14  
13 15 public String getPlatformId() {
14 16 return platformId;
15 17 }
16 18  
  19 + public String getCatalogId() {
  20 + return catalogId;
  21 + }
  22 +
  23 + public void setCatalogId(String catalogId) {
  24 + this.catalogId = catalogId;
  25 + }
  26 +
17 27 public void setPlatformId(String platformId) {
18 28 this.platformId = platformId;
19 29 }
... ...
src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/platform/PlatformController.java
1 1 package com.genersoft.iot.vmp.vmanager.gb28181.platform;
2 2  
  3 +import com.alibaba.fastjson.JSON;
3 4 import com.alibaba.fastjson.JSONObject;
  5 +import com.genersoft.iot.vmp.gb28181.bean.CatalogData;
  6 +import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel;
4 7 import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform;
  8 +import com.genersoft.iot.vmp.gb28181.bean.PlatformCatalog;
5 9 import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform;
6 10 import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
7 11 import com.genersoft.iot.vmp.storager.IVideoManagerStorager;
  12 +import com.genersoft.iot.vmp.vmanager.bean.WVPResult;
8 13 import com.genersoft.iot.vmp.vmanager.gb28181.platform.bean.ChannelReduce;
9 14 import com.genersoft.iot.vmp.vmanager.gb28181.platform.bean.UpdateChannelParam;
10 15 import com.github.pagehelper.PageInfo;
... ... @@ -21,6 +26,8 @@ import org.springframework.util.StringUtils;
21 26 import org.springframework.web.bind.annotation.*;
22 27 import com.genersoft.iot.vmp.conf.SipConfig;
23 28  
  29 +import java.util.List;
  30 +
24 31 /**
25 32 * 级联平台管理
26 33 */
... ... @@ -253,7 +260,7 @@ public class PlatformController {
253 260 if (logger.isDebugEnabled()) {
254 261 logger.debug("给上级平台添加国标通道API调用");
255 262 }
256   - int result = storager.updateChannelForGB(param.getPlatformId(), param.getChannelReduces());
  263 + int result = storager.updateChannelForGB(param.getPlatformId(), param.getChannelReduces(), param.getCatalogId());
257 264  
258 265 return new ResponseEntity<>(String.valueOf(result > 0), HttpStatus.OK);
259 266 }
... ... @@ -279,5 +286,197 @@ public class PlatformController {
279 286 return new ResponseEntity<>(String.valueOf(result > 0), HttpStatus.OK);
280 287 }
281 288  
  289 + /**
  290 + * 获取目录
  291 + * @param platformId 平台ID
  292 + * @param parentId 目录父ID
  293 + * @return
  294 + */
  295 + @ApiOperation("获取目录")
  296 + @ApiImplicitParams({
  297 + @ApiImplicitParam(name = "platformId", value = "平台ID", dataTypeClass = String.class, required = true),
  298 + @ApiImplicitParam(name = "parentId", value = "目录父ID", dataTypeClass = String.class, required = true),
  299 + })
  300 + @GetMapping("/catalog")
  301 + @ResponseBody
  302 + public ResponseEntity<WVPResult<List<PlatformCatalog>>> getCatalogByPlatform(String platformId, String parentId){
  303 +
  304 + if (logger.isDebugEnabled()) {
  305 + logger.debug("查询目录,platformId: {}, parentId: {}", platformId, parentId);
  306 + }
  307 + List<PlatformCatalog> platformCatalogList = storager.getChildrenCatalogByPlatform(platformId, parentId);
  308 + // 查询下属的国标通道
  309 + List<PlatformCatalog> catalogsForChannel = storager.queryChannelInParentPlatformAndCatalog(platformId, parentId);
  310 + List<PlatformCatalog> catalogsForStream = storager.queryStreamInParentPlatformAndCatalog(platformId, parentId);
  311 + platformCatalogList.addAll(catalogsForChannel);
  312 + platformCatalogList.addAll(catalogsForStream);
  313 + WVPResult<List<PlatformCatalog>> result = new WVPResult<>();
  314 + result.setCode(0);
  315 + result.setMsg("success");
  316 + result.setData(platformCatalogList);
  317 + return new ResponseEntity<>(result, HttpStatus.OK);
  318 + }
  319 +
  320 + /**
  321 + * 添加目录
  322 + * @param platformCatalog 目录
  323 + * @return
  324 + */
  325 + @ApiOperation("添加目录")
  326 + @ApiImplicitParams({
  327 + @ApiImplicitParam(name = "platformCatalog", value = "目录信息", dataTypeClass = PlatformCatalog.class, required = true),
  328 + })
  329 + @PostMapping("/catalog/add")
  330 + @ResponseBody
  331 + public ResponseEntity<WVPResult<List<PlatformCatalog>>> addCatalog(@RequestBody PlatformCatalog platformCatalog){
  332 +
  333 + if (logger.isDebugEnabled()) {
  334 + logger.debug("添加目录,{}", JSON.toJSONString(platformCatalog));
  335 + }
  336 + PlatformCatalog platformCatalogInStore = storager.getCatalog(platformCatalog.getId());
  337 + WVPResult<List<PlatformCatalog>> result = new WVPResult<>();
  338 +
  339 +
  340 + if (platformCatalogInStore != null) {
  341 + result.setCode(-1);
  342 + result.setMsg( platformCatalog.getId() + " already exists");
  343 + return new ResponseEntity<>(result, HttpStatus.OK);
  344 + }
  345 + int addResult = storager.addCatalog(platformCatalog);
  346 + if (addResult > 0) {
  347 + result.setCode(0);
  348 + result.setMsg("success");
  349 + return new ResponseEntity<>(result, HttpStatus.OK);
  350 + }else {
  351 + result.setCode(-500);
  352 + result.setMsg("save error");
  353 + return new ResponseEntity<>(result, HttpStatus.OK);
  354 + }
  355 + }
  356 +
  357 + /**
  358 + * 编辑目录
  359 + * @param platformCatalog 目录
  360 + * @return
  361 + */
  362 + @ApiOperation("编辑目录")
  363 + @ApiImplicitParams({
  364 + @ApiImplicitParam(name = "platformCatalog", value = "目录信息", dataTypeClass = PlatformCatalog.class, required = true),
  365 + })
  366 + @PostMapping("/catalog/edit")
  367 + @ResponseBody
  368 + public ResponseEntity<WVPResult<List<PlatformCatalog>>> editCatalog(@RequestBody PlatformCatalog platformCatalog){
  369 +
  370 + if (logger.isDebugEnabled()) {
  371 + logger.debug("编辑目录,{}", JSON.toJSONString(platformCatalog));
  372 + }
  373 + PlatformCatalog platformCatalogInStore = storager.getCatalog(platformCatalog.getId());
  374 + WVPResult<List<PlatformCatalog>> result = new WVPResult<>();
  375 + result.setCode(0);
  376 +
  377 + if (platformCatalogInStore == null) {
  378 + result.setMsg( platformCatalog.getId() + " not exists");
  379 + return new ResponseEntity<>(result, HttpStatus.OK);
  380 + }
  381 + int addResult = storager.updateCatalog(platformCatalog);
  382 + if (addResult > 0) {
  383 + result.setMsg("success");
  384 + return new ResponseEntity<>(result, HttpStatus.OK);
  385 + }else {
  386 + result.setMsg("save error");
  387 + return new ResponseEntity<>(result, HttpStatus.OK);
  388 + }
  389 + }
  390 +
  391 + /**
  392 + * 删除目录
  393 + * @param id 目录Id
  394 + * @return
  395 + */
  396 + @ApiOperation("删除目录")
  397 + @ApiImplicitParams({
  398 + @ApiImplicitParam(name = "id", value = "目录Id", dataTypeClass = String.class, required = true),
  399 + })
  400 + @DeleteMapping("/catalog/del")
  401 + @ResponseBody
  402 + public ResponseEntity<WVPResult<List<PlatformCatalog>>> delCatalog(String id){
  403 +
  404 + if (logger.isDebugEnabled()) {
  405 + logger.debug("删除目录,{}", id);
  406 + }
  407 + int delResult = storager.delCatalog(id);
  408 + WVPResult<List<PlatformCatalog>> result = new WVPResult<>();
  409 + result.setCode(0);
  410 +
  411 + if (delResult > 0) {
  412 + result.setMsg("success");
  413 + return new ResponseEntity<>(result, HttpStatus.OK);
  414 + }else {
  415 + result.setMsg("save error");
  416 + return new ResponseEntity<>(result, HttpStatus.OK);
  417 + }
  418 + }
  419 +
  420 + /**
  421 + * 删除关联
  422 + * @param platformCatalog 关联的信息
  423 + * @return
  424 + */
  425 + @ApiOperation("删除关联")
  426 + @ApiImplicitParams({
  427 + @ApiImplicitParam(name = "platformCatalog", value = "关联的信息", dataTypeClass = PlatformCatalog.class, required = true),
  428 + })
  429 + @DeleteMapping("/catalog/relation/del")
  430 + @ResponseBody
  431 + public ResponseEntity<WVPResult<List<PlatformCatalog>>> delRelation(@RequestBody PlatformCatalog platformCatalog){
  432 +
  433 + if (logger.isDebugEnabled()) {
  434 + logger.debug("删除关联,{}", JSON.toJSONString(platformCatalog));
  435 + }
  436 + int delResult = storager.delRelation(platformCatalog);
  437 + WVPResult<List<PlatformCatalog>> result = new WVPResult<>();
  438 + result.setCode(0);
  439 +
  440 + if (delResult > 0) {
  441 + result.setMsg("success");
  442 + return new ResponseEntity<>(result, HttpStatus.OK);
  443 + }else {
  444 + result.setMsg("save error");
  445 + return new ResponseEntity<>(result, HttpStatus.OK);
  446 + }
  447 + }
  448 +
  449 +
  450 + /**
  451 + * 修改默认目录
  452 + * @param platformId 平台Id
  453 + * @param catalogId 目录Id
  454 + * @return
  455 + */
  456 + @ApiOperation("修改默认目录")
  457 + @ApiImplicitParams({
  458 + @ApiImplicitParam(name = "platformId", value = "平台Id", dataTypeClass = String.class, required = true),
  459 + @ApiImplicitParam(name = "catalogId", value = "目录Id", dataTypeClass = String.class, required = true),
  460 + })
  461 + @PostMapping("/catalog/default/update")
  462 + @ResponseBody
  463 + public ResponseEntity<WVPResult<String>> setDefaultCatalog(String platformId, String catalogId){
  464 +
  465 + if (logger.isDebugEnabled()) {
  466 + logger.debug("修改默认目录,{},{}", platformId, catalogId);
  467 + }
  468 + int updateResult = storager.setDefaultCatalog(platformId, catalogId);
  469 + WVPResult<String> result = new WVPResult<>();
  470 + result.setCode(0);
  471 +
  472 + if (updateResult > 0) {
  473 + result.setMsg("success");
  474 + return new ResponseEntity<>(result, HttpStatus.OK);
  475 + }else {
  476 + result.setMsg("save error");
  477 + return new ResponseEntity<>(result, HttpStatus.OK);
  478 + }
  479 + }
  480 +
282 481  
283 482 }
... ...
src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/platform/bean/ChannelReduce.java
... ... @@ -40,6 +40,11 @@ public class ChannelReduce {
40 40 */
41 41 private String platformId;
42 42  
  43 + /**
  44 + * 目录Id
  45 + */
  46 + private String catalogId;
  47 +
43 48  
44 49 public String getChannelId() {
45 50 return channelId;
... ... @@ -96,4 +101,12 @@ public class ChannelReduce {
96 101 public void setPlatformId(String platformId) {
97 102 this.platformId = platformId;
98 103 }
  104 +
  105 + public String getCatalogId() {
  106 + return catalogId;
  107 + }
  108 +
  109 + public void setCatalogId(String catalogId) {
  110 + this.catalogId = catalogId;
  111 + }
99 112 }
... ...
src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/platform/bean/UpdateChannelParam.java
... ... @@ -4,6 +4,7 @@ import java.util.List;
4 4  
5 5 public class UpdateChannelParam {
6 6 private String platformId;
  7 + private String catalogId;
7 8 private List<ChannelReduce> channelReduces;
8 9  
9 10 public String getPlatformId() {
... ... @@ -21,4 +22,12 @@ public class UpdateChannelParam {
21 22 public void setChannelReduces(List<ChannelReduce> channelReduces) {
22 23 this.channelReduces = channelReduces;
23 24 }
  25 +
  26 + public String getCatalogId() {
  27 + return catalogId;
  28 + }
  29 +
  30 + public void setCatalogId(String catalogId) {
  31 + this.catalogId = catalogId;
  32 + }
24 33 }
... ...
src/main/resources/all-application.yml
... ... @@ -27,7 +27,7 @@ spring:
27 27 datasource:
28 28 # 使用mysql 打开23-28行注释, 删除29-36行
29 29 # name: wvp
30   - # url: jdbc:mysql://127.0.0.1:3306/wvp?useUnicode=true&characterEncoding=UTF8&rewriteBatchedStatements=true
  30 + # url: jdbc:mysql://127.0.0.1:3306/wvp?useUnicode=true&characterEncoding=UTF8&rewriteBatchedStatements=true&allowMultiQueries=true
31 31 # username:
32 32 # password:
33 33 # type: com.alibaba.druid.pool.DruidDataSource
... ...
src/main/resources/application-dev.yml
... ... @@ -15,7 +15,7 @@ spring:
15 15 datasource:
16 16 # 使用mysql 打开23-28行注释, 删除29-36行
17 17 # name: wvp
18   - # url: jdbc:mysql://127.0.0.1:3306/wvp?useUnicode=true&characterEncoding=UTF8&rewriteBatchedStatements=true
  18 + # url: jdbc:mysql://127.0.0.1:3306/wvp?useUnicode=true&characterEncoding=UTF8&rewriteBatchedStatements=true&allowMultiQueries=true
19 19 # username:
20 20 # password:
21 21 # type: com.alibaba.druid.pool.DruidDataSource
... ...
src/main/resources/application-docker.yml
... ... @@ -15,7 +15,7 @@ spring:
15 15 datasource:
16 16 # 使用mysql 打开23-28行注释, 删除29-36行
17 17 # name: wvp
18   - # url: jdbc:mysql://127.0.0.1:3306/wvp?useUnicode=true&characterEncoding=UTF8&rewriteBatchedStatements=true
  18 + # url: jdbc:mysql://127.0.0.1:3306/wvp?useUnicode=true&characterEncoding=UTF8&rewriteBatchedStatements=true&allowMultiQueries=true
19 19 # username:
20 20 # password:
21 21 # type: com.alibaba.druid.pool.DruidDataSource
... ...
src/main/resources/wvp.sqlite
No preview for this file type