Commit dea44dcd78418ed3e7f191a73cee2b81a7a0019f

Authored by 648540858
2 parents e14cef80 ebcd2320

Merge branch 'wvp-28181-2.0'

# Conflicts:
#	src/main/java/com/genersoft/iot/vmp/conf/UserSetting.java
#	src/main/java/com/genersoft/iot/vmp/gb28181/session/VideoStreamSessionManager.java
#	src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java
#	src/main/java/com/genersoft/iot/vmp/gb28181/utils/SipUtils.java
#	src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java
#	src/main/java/com/genersoft/iot/vmp/service/IPlayService.java
#	src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java
#	src/main/resources/all-application.yml
#	web_src/src/components/dialog/devicePlayer.vue
Showing 81 changed files with 1832 additions and 1260 deletions
README.md
1   -![logo](https://raw.githubusercontent.com/648540858/wvp-GB28181-pro/wvp-28181-2.0/web_src/static/logo.png)
  1 +![logo](doc/_media/logo.png)
2 2 # 撘蝞勗28181悅閫像
3 3  
4 4 [![Build Status](https://travis-ci.org/xia-chu/ZLMediaKit.svg?branch=master)](https://travis-ci.org/xia-chu/ZLMediaKit)
... ... @@ -17,7 +17,7 @@ WEB VIDEO PLATFORM銝銝芸鈭B28181-2016蝞勗
17 17 # 摨嚗
18 18 辣仍閫
19 19 像VR蝑挽憭
20   -漣
  20 +漣像蝥扯楊蝵
21 21 tsp/rtmp蝑蓮像
22 22 tsp/rtmp蝑瘚蓮像
23 23  
... ... @@ -31,62 +31,49 @@ WEB VIDEO PLATFORM銝銝芸鈭B28181-2016蝞勗
31 31 https://gitee.com/pan648540858/wvp-GB28181-pro.git
32 32  
33 33 #
34   -![build_1.png](https://images.gitee.com/uploads/images/2022/0304/101513_79632720_1018729.png "2022-03-04_09-51.png")
35   -![build_1.png](https://images.gitee.com/uploads/images/2022/0304/103025_5df016f9_1018729.png "2022-03-04_10-27.png")
36   -![build_1.png](https://images.gitee.com/uploads/images/2022/0304/101706_088fbafa_1018729.png "2022-03-04_09-52_1.png")
37   -![build_1.png](https://images.gitee.com/uploads/images/2022/0304/101756_3d662828_1018729.png "2022-03-04_10-00_1.png")
38   -![build_1.png](https://images.gitee.com/uploads/images/2022/0304/101823_19050c66_1018729.png "2022-03-04_10-12_1.png")
39   -![build_1.png](https://images.gitee.com/uploads/images/2022/0304/101848_e5a39557_1018729.png "2022-03-04_10-12_2.png")
40   -![build_1.png](https://images.gitee.com/uploads/images/2022/0304/101919_ee5b8c79_1018729.png "2022-03-04_10-13.png")
41   -
42   -# 1.0 蝖
43   -1. 閫;
44   -2. 鈭嚗憬嚗;
45   -3. 閫挽憭縑郊;
46   -4. 蝳餃蝥輻;
47   -5. 敶霂V嚗鈭VR\DVR嚗翰餈eek;
48   -6. 犖閫瘚;
49   -7. DPCP銝斤縑隞支芋撘;
50   -8. eb, 銝閬蝵脣垢, wvp蔭辣蝵, vp銝韏琿蝵;
51   -9. 像, 笆憭批像憭折挽憭餈;
52   -10. 蝝,;
53   -11. 蔭ZLM慦, 蔭憸憸;
54   -12. udp憭垢璅∪, dp璅∪扯;
55   -13. 憸挽蝵;
56   -14. 敶霂;
57   -15. dp/tcp芋撘;
58   -16. 颲RTSPTMPTTP-FLVebsocket-FLVLS憭悅瘚
59   -17.
60   -18. 蝵蝵, vp銝lm蝵
61   -19. h265, g.711撘(閬loseWaitRTPInfo霈曆蛹false)
62   -20. 霅虫縑憭垢霅虫縑
63   -
64   -# 1.0
65   -1. eb, 銝閬蝵脣垢, wvp蔭辣蝵, vp銝韏琿蝵;
66   -2. 像, 笆憭批像憭折挽憭餈;
67   -3. 蝝,;
68   -4. 蔭ZLM慦, 蔭憸憸;
69   -5. udp憭垢璅∪, dp璅∪扯;
70   -6. 憸挽蝵;
71   -7. 敶霂;
72   -8. dp/tcp芋撘;
73   -9. 颲RTSPTMPTTP-FLVebsocket-FLVLS憭悅瘚
74   -10.
75   -11. 蝵蝵, vp銝lm蝵
76   -12. h265, g.711撘
77   -13. 摰嚗瘚嚗誨絲. ( [IKI](https://github.com/648540858/wvp-GB28181-pro/wiki/%E5%A6%82%E4%BD%95%E4%BD%BF%E7%94%A8%E5%9B%BA%E5%AE%9A%E6%92%AD%E6%94%BE%E5%9C%B0%E5%9D%80%E4%B8%8E%E8%87%AA%E5%8A%A8%E7%82%B9%E6%92%AD)嚗
78   -14. 霅虫縑憭垢霅虫縑
79   -15. 恥瘜
80   - - [X] 蝘餃雿蔭霈a
81   - - [X] 蝘餃雿蔭憭
82   - - [X] 霅虫辣霈a
83   - - [X] 霅虫辣憭
84   - - [X] 霈曉敶恥
85   - - [X] 霈曉敶憭
86   -16. 蝘餃雿蔭霂W蝷綽蔭辣霈曄蔭蝘餃雿蔭摮
87   -
88   -# 2.0
89   -- [X] 漣
  34 +![index](doc/_media/index.png "index.png")
  35 +![2](doc/_media/2.png "2.png")
  36 +![3](doc/_media/3.png "3.png")
  37 +![3-1](doc/_media/3-1.png "3-1.png")
  38 +![3-2](doc/_media/3-2.png "3-2.png")
  39 +![3-3](doc/_media/3-3.png "3-3.png")
  40 +![build_1](https://images.gitee.com/uploads/images/2022/0304/101919_ee5b8c79_1018729.png "2022-03-04_10-13.png")
  41 +
  42 +#
  43 +- [X] eb
  44 +- [X] 摰寞扯憟
  45 +- [X] 摮嚗WGS84CJ02銝斤頂嚗僎銝頧砍蛹頂餈內
  46 +- [X] 霈曉
  47 + - [X] 閫
  48 + - [X] 頝舀嚗憭挽憭鈭扯
  49 + - [X] 鈭嚗霈曉蓮
  50 + - [X] 憸蔭雿霂g蝙銝挽蝵
  51 + - [X] 霂﹫VR/IPC銝嚗銝蝸
  52 + - [X] 犖閫瘚
  53 + - [X] 閫挽憭縑郊
  54 + - [X] 蝳餃蝥輻
  55 + - [X] 颲RTSPTMPTTP-FLVebsocket-FLVLS憭悅瘚
  56 + - [X] 銝芣閫仍嚗敶誑隞颱
  57 + - [X] DPCP銝斤縑隞支芋撘
  58 + - [X] DPCP銝斤芋撘
  59 + - [X] 蝝,
  60 + - [X] 敶霂
  61 + - [X] 誘憸甇X敶勗
  62 + - [X]
  63 + - [X] H264265
  64 + - [X] 霅虫縑憭垢霅虫縑
  65 + - [X] 恥瘜
  66 + - [X] 蝘餃雿蔭霈a
  67 + - [X] 蝘餃雿蔭憭
  68 + - [X] 霅虫辣霈a
  69 + - [X] 霅虫辣憭
  70 + - [X] 霈曉敶恥
  71 + - [X] 霈曉敶憭
  72 + - [X] 蝘餃雿蔭霂W蝷
  73 + - [X] 瘛餃挽憭挽憭挽蝵桀
  74 +- [X] 像撖寞
  75 +- [X] 漣
  76 + - [X] 漣
90 77 - [X] WEB瘛餃漣撟喳
91 78 - [X] 瘜典
92 79 - [X] 敹歲靽暑
... ... @@ -101,61 +88,33 @@ https://gitee.com/pan648540858/wvp-GB28181-pro.git
101 88 - [X] 敶恥
102 89 - [X] 敶
103 90 - [X] GPS霈a嚗瘚
104   -- [X] 瘛餃挽憭挽憭挽蝵桀
105   -- [X] 瘛餃TSP閫
106   -- [X] 瘛餃
107   -- [X] 瘛餃TMP閫
108   -- [X] 鈭垢敶閬蝵脣蝙嚗
  91 +- [X] 蔭ZLM慦, 蔭憸憸;
109 92 - [X] 憭嚗韐蝸雿雿輻
110   -- [X] WEB蝡舀H264銝265嚗憸.711A/G.711U/AAC,閬虜蝻撘
111   -- [X] 摮
112   -- [X] WGS84CJ02銝斤頂
113   -
114   -[//]: # (# docker敹恍)
115   -
116   -[//]: # (ocker-compose蛹輕銝嚗洵銝之摰嗡蝙嚗輕銝之摰嗉扇敺撈銝泅tar )
117   -
118   -[//]: # (https://github.com/SaltFish001/wvp_pro_compose)
119   -
120   -[//]: # ([https://github.com/SaltFish001/wvp_pro_compose](https://github.com/SaltFish001/wvp_pro_compose))
121   -
122   -[//]: # (餈雿輕銝芷摮銝憸)
123   -
124   -[//]: # (```shell)
125   -
126   -[//]: # (docker pull 648540858/wvp_pro)
127   -
128   -[//]: # ()
129   -[//]: # (docker run --env WVP_IP="雿P" -it -p 18080:18080 -p 30000-30500:30000-30500/udp -p 30000-30500:30000-30500/tcp -p 80:80 -p 5060:5060 -p 5060:5060/udp 648540858/wvp_pro)
130   -
131   -[//]: # (```)
132   -
133   -[//]: # (docker雿輻霂行https://hub.docker.com/r/648540858/wvp_pro](https://hub.docker.com/r/648540858/wvp_pro))
134   -
135   -# gitee郊隞
136   -https://gitee.com/pan648540858/wvp-GB28181-pro.git
137   -
138   -# 憸
  93 +- [X] udp憭垢璅∪, dp璅∪扯;
  94 +- [X] 蝵蝵莎
  95 +- [X] vp銝lm蝵莎像撟嗅
  96 +- [X] TSP/RTMP嚗蛹撘隞像
  97 +- [X] 瘚TSP/RTMP嚗蛹撘隞像
  98 +- [X] 瘚
  99 +- [X]
  100 +- [X] 鈭垢敶瘚/隞/隞亙鈭垢嚗蝸
  101 +
  102 +
  103 +# 憸圾
139 104 暻餌鈭挽憭摰寞改隞仿閬之挽憭瘚挽憭偌撟單隞仿憸
140 105 1. iki嚗粉隞亙葬雿憸
141 106 2. 揣issues嚗之
142   -3. Q蝢歹之敹撈嚗撣歇蝏粉鈭iki揣鈭ssues
  107 +3. Q蝢歹901799015嚗之敹撈嚗撣歇蝏粉鈭iki揣鈭ssues
143 108 4. 雿隞亥窈雿蛹雿圾蝑晶
144 109 5. 雿隞交憸挽憭隞交摰寞憸
145 110  
146   -
147   -#
148   -蝘摰之摰嗅之銝瓷移憸隞乩晶圾蝑隞交R
149   -嚗笆隞遣霈桀隞交SSUE嚗隞亙黎銝韏瑁賑甈Z頞憿寧銝剜犖
150   -
151   -
152   -
153 111 # 雿輻撣桀
154 112 QQ蝢: 901799015, ZLM雿輻﹝[https://github.com/ZLMediaKit/ZLMediaKit](https://github.com/ZLMediaKit/ZLMediaKit)
155 113 QQ蝘縑銝銝, 蝎曉.甈Z之摰嗅蝢日悄霈.閫★撖嫣葬嚗洽餈tar漱pr
156 114  
157 115 # 悅
158 116 憿寧誨蝙摰賣IT悅嚗靽縑銝隞亥摨鈭★ 雿憿寧銋蝣蝙鈭鈭隞皞誨銝窈銵隞嚗 鈭蝙憿寧漣熒噩蛹銝璁憿寧嚗窈銵 雿輻憿寧隞嚗砲悅銝剖銵冽憿寧靘洵銝摨悅
  117 +
159 118 # 靚
160 119 陝雿憭(https://github.com/xia-chu) 皞獢,撟嗅撘葉蝏葬
161 120 陝雿dexter langhuihui](https://github.com/langhuihui) 撘皞末EB
... ...
doc/_media/2.png 0 → 100644

469 KB

doc/_media/3-1.png 0 → 100644

136 KB

doc/_media/3-2.png 0 → 100644

650 KB

doc/_media/3-3.png 0 → 100644

1.04 MB

doc/_media/3.png 0 → 100644

146 KB

doc/_media/index.png 0 → 100644

154 KB

... ... @@ -11,7 +11,7 @@
11 11  
12 12 <groupId>com.genersoft</groupId>
13 13 <artifactId>wvp-pro</artifactId>
14   - <version>2.6.6</version>
  14 + <version>2.6.7</version>
15 15 <name>web video platform</name>
16 16 <description>国标28181视频平台</description>
17 17  
... ...
sql/mysql.sql
... ... @@ -54,7 +54,7 @@ CREATE TABLE `device` (
54 54 `localIp` varchar(50) COLLATE utf8mb4_general_ci DEFAULT NULL,
55 55 PRIMARY KEY (`id`),
56 56 UNIQUE KEY `device_deviceId_uindex` (`deviceId`)
57   -) ENGINE=InnoDB AUTO_INCREMENT=57 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
  57 +) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
58 58 /*!40101 SET character_set_client = @saved_cs_client */;
59 59  
60 60 --
... ... @@ -86,7 +86,7 @@ CREATE TABLE `device_alarm` (
86 86 `alarmType` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,
87 87 `createTime` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,
88 88 PRIMARY KEY (`id`) USING BTREE
89   -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC;
  89 +) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC;
90 90 /*!40101 SET character_set_client = @saved_cs_client */;
91 91  
92 92 --
... ... @@ -146,7 +146,7 @@ CREATE TABLE `device_channel` (
146 146 PRIMARY KEY (`id`),
147 147 UNIQUE KEY `device_channel_id_uindex` (`id`),
148 148 UNIQUE KEY `device_channel_pk` (`channelId`,`deviceId`)
149   -) ENGINE=InnoDB AUTO_INCREMENT=74416 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
  149 +) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
150 150 /*!40101 SET character_set_client = @saved_cs_client */;
151 151  
152 152 --
... ... @@ -183,7 +183,7 @@ CREATE TABLE `device_mobile_position` (
183 183 `latitudeWgs84` double DEFAULT NULL,
184 184 `createTime` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,
185 185 PRIMARY KEY (`id`)
186   -) ENGINE=InnoDB AUTO_INCREMENT=55589 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
  186 +) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
187 187 /*!40101 SET character_set_client = @saved_cs_client */;
188 188  
189 189 --
... ... @@ -216,7 +216,7 @@ CREATE TABLE `gb_stream` (
216 216 PRIMARY KEY (`gbStreamId`) USING BTREE,
217 217 UNIQUE KEY `app` (`app`,`stream`) USING BTREE,
218 218 UNIQUE KEY `gbId` (`gbId`) USING BTREE
219   -) ENGINE=InnoDB AUTO_INCREMENT=331060 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC;
  219 +) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC;
220 220 /*!40101 SET character_set_client = @saved_cs_client */;
221 221  
222 222 --
... ... @@ -246,7 +246,7 @@ CREATE TABLE `log` (
246 246 `username` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
247 247 `createTime` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
248 248 PRIMARY KEY (`id`) USING BTREE
249   -) ENGINE=InnoDB AUTO_INCREMENT=760908 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC;
  249 +) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC;
250 250 /*!40101 SET character_set_client = @saved_cs_client */;
251 251  
252 252 --
... ... @@ -338,7 +338,7 @@ CREATE TABLE `parent_platform` (
338 338 PRIMARY KEY (`id`),
339 339 UNIQUE KEY `parent_platform_id_uindex` (`id`),
340 340 UNIQUE KEY `parent_platform_pk` (`serverGBId`)
341   -) ENGINE=InnoDB AUTO_INCREMENT=47 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC;
  341 +) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC;
342 342 /*!40101 SET character_set_client = @saved_cs_client */;
343 343  
344 344 --
... ... @@ -390,7 +390,7 @@ CREATE TABLE `platform_gb_channel` (
390 390 `catalogId` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
391 391 `deviceChannelId` int NOT NULL,
392 392 PRIMARY KEY (`id`)
393   -) ENGINE=InnoDB AUTO_INCREMENT=3146 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
  393 +) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
394 394 /*!40101 SET character_set_client = @saved_cs_client */;
395 395  
396 396 --
... ... @@ -410,13 +410,13 @@ DROP TABLE IF EXISTS `platform_gb_stream`;
410 410 /*!40101 SET @saved_cs_client = @@character_set_client */;
411 411 /*!50503 SET character_set_client = utf8mb4 */;
412 412 CREATE TABLE `platform_gb_stream` (
  413 + `id` int NOT NULL AUTO_INCREMENT,
413 414 `platformId` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
414 415 `catalogId` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
415 416 `gbStreamId` int NOT NULL,
416   - `id` int NOT NULL AUTO_INCREMENT,
417 417 PRIMARY KEY (`id`),
418 418 UNIQUE KEY `platform_gb_stream_pk` (`platformId`,`catalogId`,`gbStreamId`)
419   -) ENGINE=InnoDB AUTO_INCREMENT=391772 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC;
  419 +) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC;
420 420 /*!40101 SET character_set_client = @saved_cs_client */;
421 421  
422 422 --
... ... @@ -458,7 +458,7 @@ CREATE TABLE `stream_proxy` (
458 458 `enable_disable_none_reader` bit(1) DEFAULT NULL,
459 459 PRIMARY KEY (`id`),
460 460 UNIQUE KEY `stream_proxy_pk` (`app`,`stream`)
461   -) ENGINE=InnoDB AUTO_INCREMENT=568 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
  461 +) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
462 462 /*!40101 SET character_set_client = @saved_cs_client */;
463 463  
464 464 --
... ... @@ -495,7 +495,7 @@ CREATE TABLE `stream_push` (
495 495 `self` int DEFAULT NULL,
496 496 PRIMARY KEY (`id`),
497 497 UNIQUE KEY `stream_push_pk` (`app`,`stream`)
498   -) ENGINE=InnoDB AUTO_INCREMENT=361492 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
  498 +) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
499 499 /*!40101 SET character_set_client = @saved_cs_client */;
500 500  
501 501 --
... ... @@ -524,7 +524,7 @@ CREATE TABLE `user` (
524 524 `pushKey` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,
525 525 PRIMARY KEY (`id`) USING BTREE,
526 526 UNIQUE KEY `user_username_uindex` (`username`) USING BTREE
527   -) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC;
  527 +) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC;
528 528 /*!40101 SET character_set_client = @saved_cs_client */;
529 529  
530 530 --
... ... @@ -533,7 +533,7 @@ CREATE TABLE `user` (
533 533  
534 534 LOCK TABLES `user` WRITE;
535 535 /*!40000 ALTER TABLE `user` DISABLE KEYS */;
536   -INSERT INTO `user` VALUES (1,'admin','21232f297a57a5a743894a0e4a801fc3',1,'2021 - 04 - 13 14:14:57','2021 - 04 - 13 14:14:57','3e80d1762a324d5b0ff636e0bd16f1e3');
  536 +INSERT INTO `user` VALUES (1,'admin','21232f297a57a5a743894a0e4a801fc3',1,'2021-04-13 14:14:57','2021-04-13 14:14:57','3e80d1762a324d5b0ff636e0bd16f1e3');
537 537 /*!40000 ALTER TABLE `user` ENABLE KEYS */;
538 538 UNLOCK TABLES;
539 539  
... ... @@ -551,7 +551,7 @@ CREATE TABLE `user_role` (
551 551 `createTime` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
552 552 `updateTime` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
553 553 PRIMARY KEY (`id`) USING BTREE
554   -) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC;
  554 +) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC;
555 555 /*!40101 SET character_set_client = @saved_cs_client */;
556 556  
557 557 --
... ...
sql/update.sql
1   -alter table media_server
2   - drop column streamNoneReaderDelayMS;
3   -
4   -alter table media_server
5   - drop column sendRtpPortRange;
6   -
7   -alter table stream_proxy
8   - add enable_disable_none_reader bit(1) default null;
9   -
  1 +-- 2.6.6->2.6.7
10 2 alter table device
11   - add mediaServerId varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT 'auto';
12   -
13   -alter table device
14   - add custom_name varchar(255) default null;
15   -
16   -alter table device
17   - add sdpIp varchar(50) default null;
18   -
19   -alter table device
20   - add localIp varchar(50) default null;
21   -
22   -alter table device
23   - add password varchar(255) default null;
24   -
25   -alter table device
26   - modify ip varchar(50) null;
27   -
28   -alter table device
29   - modify port int null;
30   -
31   -alter table device
32   - modify expires int null;
33   -
34   -alter table device
35   - modify subscribeCycleForCatalog int null;
36   -
37   -alter table device
38   - modify hostAddress varchar(50) null;
39   -
40   -alter table stream_proxy
41   - change enable_hls enable_audio bit null;
42   -
43   -
  3 + add keepaliveIntervalTime int default null;
44 4 \ No newline at end of file
... ...
src/main/java/com/genersoft/iot/vmp/common/VideoManagerConstants.java
... ... @@ -71,6 +71,8 @@ public class VideoManagerConstants {
71 71 public static final String SYSTEM_INFO_DISK_PREFIX = "VMP_SYSTEM_INFO_DISK_";
72 72 public static final String BROADCAST_WAITE_INVITE = "task_broadcast_waite_invite_";
73 73  
  74 + public static final String REGISTER_EXPIRE_TASK_KEY_PREFIX = "VMP_device_register_expire_";
  75 +
74 76  
75 77  
76 78  
... ...
src/main/java/com/genersoft/iot/vmp/conf/ApiAccessFilter.java
... ... @@ -10,6 +10,7 @@ import org.slf4j.Logger;
10 10 import org.slf4j.LoggerFactory;
11 11 import org.springframework.beans.factory.annotation.Autowired;
12 12 import org.springframework.http.HttpStatus;
  13 +import org.springframework.util.ObjectUtils;
13 14 import org.springframework.web.filter.OncePerRequestFilter;
14 15  
15 16 import javax.servlet.*;
... ... @@ -51,6 +52,9 @@ public class ApiAccessFilter extends OncePerRequestFilter {
51 52  
52 53 LogDto logDto = new LogDto();
53 54 logDto.setName(uriName);
  55 + if (ObjectUtils.isEmpty(username)) {
  56 + username = "";
  57 + }
54 58 logDto.setUsername(username);
55 59 logDto.setAddress(servletRequest.getRemoteAddr());
56 60 logDto.setResult(HttpStatus.valueOf(servletResponse.getStatus()).toString());
... ...
src/main/java/com/genersoft/iot/vmp/conf/UserSetting.java
... ... @@ -35,6 +35,8 @@ public class UserSetting {
35 35  
36 36 private Boolean useSourceIpAsStreamIp = Boolean.FALSE;
37 37  
  38 + private Boolean sipUseSourceIpAsRemoteAddress = Boolean.FALSE;
  39 +
38 40 private Boolean streamOnDemand = Boolean.TRUE;
39 41  
40 42 private Boolean pushAuthority = Boolean.TRUE;
... ... @@ -45,6 +47,8 @@ public class UserSetting {
45 47  
46 48 private Boolean pushStreamAfterAck = Boolean.FALSE;
47 49  
  50 + private Boolean sipLog = Boolean.FALSE;
  51 +
48 52 private String serverId = "000000";
49 53  
50 54 private String thirdPartyGBIdReg = "[\\s\\S]*";
... ... @@ -206,4 +210,20 @@ public class UserSetting {
206 210 public void setPushStreamAfterAck(Boolean pushStreamAfterAck) {
207 211 this.pushStreamAfterAck = pushStreamAfterAck;
208 212 }
  213 +
  214 + public Boolean getSipUseSourceIpAsRemoteAddress() {
  215 + return sipUseSourceIpAsRemoteAddress;
  216 + }
  217 +
  218 + public void setSipUseSourceIpAsRemoteAddress(Boolean sipUseSourceIpAsRemoteAddress) {
  219 + this.sipUseSourceIpAsRemoteAddress = sipUseSourceIpAsRemoteAddress;
  220 + }
  221 +
  222 + public Boolean getSipLog() {
  223 + return sipLog;
  224 + }
  225 +
  226 + public void setSipLog(Boolean sipLog) {
  227 + this.sipLog = sipLog;
  228 + }
209 229 }
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/SipLayer.java
1 1 package com.genersoft.iot.vmp.gb28181;
2 2  
3 3 import com.genersoft.iot.vmp.conf.SipConfig;
  4 +import com.genersoft.iot.vmp.conf.UserSetting;
4 5 import com.genersoft.iot.vmp.gb28181.conf.DefaultProperties;
5 6 import com.genersoft.iot.vmp.gb28181.transmit.ISIPProcessorObserver;
6 7 import gov.nist.javax.sip.SipProviderImpl;
... ... @@ -29,6 +30,9 @@ public class SipLayer implements CommandLineRunner {
29 30 @Autowired
30 31 private ISIPProcessorObserver sipProcessorObserver;
31 32  
  33 + @Autowired
  34 + private UserSetting userSetting;
  35 +
32 36 private final Map<String, SipProviderImpl> tcpSipProviderMap = new ConcurrentHashMap<>();
33 37 private final Map<String, SipProviderImpl> udpSipProviderMap = new ConcurrentHashMap<>();
34 38  
... ... @@ -61,7 +65,7 @@ public class SipLayer implements CommandLineRunner {
61 65 private void addListeningPoint(String monitorIp, int port){
62 66 SipStackImpl sipStack;
63 67 try {
64   - sipStack = (SipStackImpl)sipFactory.createSipStack(DefaultProperties.getProperties(monitorIp, false));
  68 + sipStack = (SipStackImpl)sipFactory.createSipStack(DefaultProperties.getProperties(monitorIp, false, userSetting.getSipLog()));
65 69 } catch (PeerUnavailableException e) {
66 70 logger.error("[Sip Server] SIP服务启动失败, 监听地址{}失败,请检查ip是否正确", monitorIp);
67 71 return;
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/bean/Device.java
... ... @@ -94,6 +94,13 @@ public class Device {
94 94 @Schema(description = "心跳时间")
95 95 private String keepaliveTime;
96 96  
  97 +
  98 + /**
  99 + * 心跳间隔
  100 + */
  101 + @Schema(description = "心跳间隔")
  102 + private int keepaliveIntervalTime;
  103 +
97 104 /**
98 105 * 通道个数
99 106 */
... ... @@ -414,4 +421,12 @@ public class Device {
414 421 public void setLocalIp(String localIp) {
415 422 this.localIp = localIp;
416 423 }
  424 +
  425 + public int getKeepaliveIntervalTime() {
  426 + return keepaliveIntervalTime;
  427 + }
  428 +
  429 + public void setKeepaliveIntervalTime(int keepaliveIntervalTime) {
  430 + this.keepaliveIntervalTime = keepaliveIntervalTime;
  431 + }
417 432 }
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/bean/RemoteAddressInfo.java 0 → 100644
  1 +package com.genersoft.iot.vmp.gb28181.bean;
  2 +
  3 +public class RemoteAddressInfo {
  4 + private String ip;
  5 + private int port;
  6 +
  7 + public RemoteAddressInfo(String ip, int port) {
  8 + this.ip = ip;
  9 + this.port = port;
  10 + }
  11 +
  12 + public String getIp() {
  13 + return ip;
  14 + }
  15 +
  16 + public void setIp(String ip) {
  17 + this.ip = ip;
  18 + }
  19 +
  20 + public int getPort() {
  21 + return port;
  22 + }
  23 +
  24 + public void setPort(int port) {
  25 + this.port = port;
  26 + }
  27 +}
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/conf/DefaultProperties.java
1 1 package com.genersoft.iot.vmp.gb28181.conf;
2 2  
  3 +import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.notify.cmd.AlarmNotifyMessageHandler;
  4 +import org.slf4j.Logger;
  5 +import org.slf4j.LoggerFactory;
  6 +
3 7 import java.util.Properties;
4 8  
5 9 /**
... ... @@ -8,10 +12,11 @@ import java.util.Properties;
8 12 */
9 13 public class DefaultProperties {
10 14  
11   - public static Properties getProperties(String ip, boolean isDebug) {
  15 + public static Properties getProperties(String ip, boolean isDebug, boolean sipLog) {
12 16 Properties properties = new Properties();
13 17 properties.setProperty("javax.sip.STACK_NAME", "GB28181_SIP");
14 18 properties.setProperty("javax.sip.IP_ADDRESS", ip);
  19 + // 关闭自动会话
15 20 properties.setProperty("javax.sip.AUTOMATIC_DIALOG_SUPPORT", "off");
16 21 /**
17 22 * 完整配置参考 gov.nist.javax.sip.SipStackImpl,需要下载源码
... ... @@ -26,7 +31,7 @@ public class DefaultProperties {
26 31 // 接收所有notify请求,即使没有订阅
27 32 properties.setProperty("gov.nist.javax.sip.DELIVER_UNSOLICITED_NOTIFY", "true");
28 33 properties.setProperty("gov.nist.javax.sip.AUTOMATIC_DIALOG_ERROR_HANDLING", "false");
29   - properties.setProperty("gov.nist.javax.sip.CANCEL_CLIENT_TRANSACTION_CHECKED", "false");
  34 + properties.setProperty("gov.nist.javax.sip.CANCEL_CLIENT_TRANSACTION_CHECKED", "true");
30 35 // 为_NULL _对话框传递_终止的_事件
31 36 properties.setProperty("gov.nist.javax.sip.DELIVER_TERMINATED_EVENT_FOR_NULL_DIALOG", "true");
32 37 // 会话清理策略
... ... @@ -35,11 +40,38 @@ public class DefaultProperties {
35 40 properties.setProperty("gov.nist.javax.sip.RELIABLE_CONNECTION_KEEP_ALIVE_TIMEOUT", "60");
36 41 // 获取实际内容长度,不使用header中的长度信息
37 42 properties.setProperty("gov.nist.javax.sip.COMPUTE_CONTENT_LENGTH_FROM_MESSAGE_BODY", "true");
  43 + // 线程可重入
  44 + properties.setProperty("gov.nist.javax.sip.REENTRANT_LISTENER", "true");
  45 + // 定义应用程序打算多久审计一次 SIP 堆栈,了解其内部线程的健康状况(该属性指定连续审计之间的时间(以毫秒为单位))
  46 + properties.setProperty("gov.nist.javax.sip.THREAD_AUDIT_INTERVAL_IN_MILLISECS", "30000");
38 47  
39 48 /**
40 49 * sip_server_log.log 和 sip_debug_log.log ERROR, INFO, WARNING, OFF, DEBUG, TRACE
41 50 */
42   - properties.setProperty("gov.nist.javax.sip.TRACE_LEVEL", "ERROR");
  51 + Logger logger = LoggerFactory.getLogger(AlarmNotifyMessageHandler.class);
  52 + if (sipLog) {
  53 + if (logger.isDebugEnabled()) {
  54 + System.out.println("DEBUG");
  55 + properties.setProperty("gov.nist.javax.sip.TRACE_LEVEL", "DEBUG");
  56 + }else if (logger.isInfoEnabled()) {
  57 + System.out.println("INFO1");
  58 + properties.setProperty("gov.nist.javax.sip.TRACE_LEVEL", "INFO");
  59 + }else if (logger.isWarnEnabled()) {
  60 + System.out.println("WARNING");
  61 + properties.setProperty("gov.nist.javax.sip.TRACE_LEVEL", "WARNING");
  62 + }else if (logger.isErrorEnabled()) {
  63 + System.out.println("ERROR");
  64 + properties.setProperty("gov.nist.javax.sip.TRACE_LEVEL", "ERROR");
  65 + }else {
  66 + System.out.println("INFO2");
  67 + properties.setProperty("gov.nist.javax.sip.TRACE_LEVEL", "INFO");
  68 + }
  69 + logger.info("[SIP日志]级别为: {}", properties.getProperty("gov.nist.javax.sip.TRACE_LEVEL"));
  70 + }else {
  71 + logger.info("[SIP日志]已关闭");
  72 + }
  73 +
  74 +
43 75  
44 76 return properties;
45 77 }
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/conf/SipLoggerPass.java deleted 100644 → 0
1   -package com.genersoft.iot.vmp.gb28181.conf;
2   -
3   -import gov.nist.core.StackLogger;
4   -
5   -import java.util.Properties;
6   -
7   -/**
8   - * sip日志格式化
9   - * 暂不使用
10   - */
11   -public class SipLoggerPass implements StackLogger {
12   -
13   - @Override
14   - public void logStackTrace() {
15   -
16   - }
17   -
18   - @Override
19   - public void logStackTrace(int traceLevel) {
20   -
21   - }
22   -
23   - @Override
24   - public int getLineCount() {
25   - return 0;
26   - }
27   -
28   - @Override
29   - public void logException(Throwable ex) {
30   -
31   - }
32   -
33   - @Override
34   - public void logDebug(String message) {
35   -
36   - }
37   -
38   - @Override
39   - public void logDebug(String message, Exception ex) {
40   -
41   - }
42   -
43   - @Override
44   - public void logTrace(String message) {
45   -
46   - }
47   -
48   - @Override
49   - public void logFatalError(String message) {
50   -
51   - }
52   -
53   - @Override
54   - public void logError(String message) {
55   -
56   - }
57   -
58   - @Override
59   - public boolean isLoggingEnabled() {
60   - return false;
61   - }
62   -
63   - @Override
64   - public boolean isLoggingEnabled(int logLevel) {
65   - return false;
66   - }
67   -
68   - @Override
69   - public void logError(String message, Exception ex) {
70   -
71   - }
72   -
73   - @Override
74   - public void logWarning(String string) {
75   -
76   - }
77   -
78   - @Override
79   - public void logInfo(String string) {
80   -
81   - }
82   -
83   - @Override
84   - public void disableLogging() {
85   -
86   - }
87   -
88   - @Override
89   - public void enableLogging() {
90   -
91   - }
92   -
93   - @Override
94   - public void setBuildTimeStamp(String buildTimeStamp) {
95   -
96   - }
97   -
98   - @Override
99   - public void setStackProperties(Properties stackProperties) {
100   -
101   - }
102   -
103   - @Override
104   - public String getLoggerName() {
105   - return null;
106   - }
107   -}
src/main/java/com/genersoft/iot/vmp/gb28181/session/VideoStreamSessionManager.java
... ... @@ -13,7 +13,7 @@ import org.springframework.util.ObjectUtils;
13 13 import java.util.ArrayList;
14 14 import java.util.List;
15 15  
16   -/**
  16 +/**
17 17 * @description:视频流session管理器,管理视频预览、预览回放的通信句柄
18 18 * @author: swwheihei
19 19 * @date: 2020年5月13日 下午4:03:02
... ... @@ -51,6 +51,7 @@ public class VideoStreamSessionManager {
51 51 ssrcTransaction.setSsrc(ssrc);
52 52 ssrcTransaction.setMediaServerId(mediaServerId);
53 53 ssrcTransaction.setType(type);
  54 +
54 55 RedisUtil.set(VideoManagerConstants.MEDIA_TRANSACTION_USED_PREFIX + userSetting.getServerId()
55 56 + "_" + deviceId + "_" + channelId + "_" + callId + "_" + stream, ssrcTransaction);
56 57 }
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/ISIPCommanderForPlatform.java
... ... @@ -64,7 +64,7 @@ public interface ISIPCommanderForPlatform {
64 64 * @param fromTag
65 65 * @return
66 66 */
67   - void deviceStatusResponse(ParentPlatform parentPlatform, String sn, String fromTag) throws SipException, InvalidArgumentException, ParseException;
  67 + void deviceStatusResponse(ParentPlatform parentPlatform,String channelId, String sn, String fromTag,int status) throws SipException, InvalidArgumentException, ParseException;
68 68  
69 69 /**
70 70 * 向上级回复移动位置订阅消息
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java
... ... @@ -574,10 +574,11 @@ public class SIPCommander implements ISIPCommander {
574 574 if (inviteStreamCallback != null) {
575 575 inviteStreamCallback.call(new InviteStreamInfo(mediaServerItem, null,sipSender.getNewCallIdHeader(sipLayer.getLocalIp(device.getLocalIp()),device.getTransport()).getCallId(), "rtp", ssrcInfo.getStream()));
576 576 }
  577 +
577 578 sipSender.transmitRequest(sipLayer.getLocalIp(device.getLocalIp()), request, errorEvent, okEvent -> {
578 579 ResponseEvent responseEvent = (ResponseEvent) okEvent.event;
579 580 SIPResponse response = (SIPResponse) responseEvent.getResponse();
580   - streamSession.put(device.getDeviceId(), channelId,sipSender.getNewCallIdHeader(sipLayer.getLocalIp(device.getLocalIp()),device.getTransport()).getCallId(), ssrcInfo.getStream(), ssrcInfo.getSsrc(), mediaServerItem.getId(), response, VideoStreamSessionManager.SessionType.download);
  581 + streamSession.put(device.getDeviceId(), channelId, response.getCallIdHeader().getCallId(), ssrcInfo.getStream(), ssrcInfo.getSsrc(), mediaServerItem.getId(), response, VideoStreamSessionManager.SessionType.download);
581 582 });
582 583 }
583 584  
... ... @@ -774,7 +775,7 @@ public class SIPCommander implements ISIPCommander {
774 775 cmdXml.append("<GuardCmd>" + guardCmdStr + "</GuardCmd>\r\n");
775 776 cmdXml.append("</Control>\r\n");
776 777  
777   -
  778 +
778 779  
779 780 Request request = headerProvider.createMessageRequest(device, cmdXml.toString(), null, SipUtils.getNewFromTag(), null,sipSender.getNewCallIdHeader(sipLayer.getLocalIp(device.getLocalIp()),device.getTransport()));
780 781 sipSender.transmitRequest(sipLayer.getLocalIp(device.getLocalIp()), request, errorEvent);
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommanderFroPlatform.java
... ... @@ -287,19 +287,20 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform {
287 287 * @return
288 288 */
289 289 @Override
290   - public void deviceStatusResponse(ParentPlatform parentPlatform, String sn, String fromTag) throws SipException, InvalidArgumentException, ParseException {
  290 + public void deviceStatusResponse(ParentPlatform parentPlatform,String channelId, String sn, String fromTag,int status) throws SipException, InvalidArgumentException, ParseException {
291 291 if (parentPlatform == null) {
292 292 return ;
293 293 }
  294 + String statusStr = (status==1)?"ONLINE":"OFFLINE";
294 295 String characterSet = parentPlatform.getCharacterSet();
295 296 StringBuffer deviceStatusXml = new StringBuffer(600);
296 297 deviceStatusXml.append("<?xml version=\"1.0\" encoding=\"" + characterSet + "\"?>\r\n");
297 298 deviceStatusXml.append("<Response>\r\n");
298 299 deviceStatusXml.append("<CmdType>DeviceStatus</CmdType>\r\n");
299 300 deviceStatusXml.append("<SN>" +sn + "</SN>\r\n");
300   - deviceStatusXml.append("<DeviceID>" + parentPlatform.getDeviceGBId() + "</DeviceID>\r\n");
  301 + deviceStatusXml.append("<DeviceID>" + channelId + "</DeviceID>\r\n");
301 302 deviceStatusXml.append("<Result>OK</Result>\r\n");
302   - deviceStatusXml.append("<Online>ONLINE</Online>\r\n");
  303 + deviceStatusXml.append("<Online>"+statusStr+"</Online>\r\n");
303 304 deviceStatusXml.append("<Status>OK</Status>\r\n");
304 305 deviceStatusXml.append("</Response>\r\n");
305 306  
... ... @@ -307,7 +308,6 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform {
307 308  
308 309 Request request = headerProviderPlatformProvider.createMessageRequest(parentPlatform, deviceStatusXml.toString(), fromTag, SipUtils.getNewViaTag(), callIdHeader);
309 310 sipSender.transmitRequest(parentPlatform.getDeviceIp(), request);
310   -
311 311 }
312 312  
313 313 @Override
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/RegisterRequestProcessor.java
1 1 package com.genersoft.iot.vmp.gb28181.transmit.event.request.impl;
2 2  
3 3 import com.genersoft.iot.vmp.conf.SipConfig;
  4 +import com.genersoft.iot.vmp.conf.UserSetting;
4 5 import com.genersoft.iot.vmp.gb28181.auth.DigestServerAuthenticationHelper;
5 6 import com.genersoft.iot.vmp.gb28181.bean.Device;
  7 +import com.genersoft.iot.vmp.gb28181.bean.RemoteAddressInfo;
6 8 import com.genersoft.iot.vmp.gb28181.bean.WvpSipDate;
7 9 import com.genersoft.iot.vmp.gb28181.transmit.SIPProcessorObserver;
8 10 import com.genersoft.iot.vmp.gb28181.transmit.SIPSender;
9 11 import com.genersoft.iot.vmp.gb28181.transmit.event.request.ISIPRequestProcessor;
10 12 import com.genersoft.iot.vmp.gb28181.transmit.event.request.SIPRequestProcessorParent;
  13 +import com.genersoft.iot.vmp.gb28181.utils.SipUtils;
11 14 import com.genersoft.iot.vmp.service.IDeviceService;
12 15 import com.genersoft.iot.vmp.utils.DateUtil;
13 16 import gov.nist.javax.sip.RequestEventExt;
... ... @@ -59,6 +62,9 @@ public class RegisterRequestProcessor extends SIPRequestProcessorParent implemen
59 62 @Autowired
60 63 private SIPSender sipSender;
61 64  
  65 + @Autowired
  66 + private UserSetting userSetting;
  67 +
62 68 @Override
63 69 public void afterPropertiesSet() throws Exception {
64 70 // 添加消息处理的订阅
... ... @@ -128,15 +134,9 @@ public class RegisterRequestProcessor extends SIPRequestProcessorParent implemen
128 134 // 添加Expires头
129 135 response.addHeader(request.getExpires());
130 136  
131   - // 获取到通信地址等信息
132   - ViaHeader viaHeader = (ViaHeader) request.getHeader(ViaHeader.NAME);
133   - String received = viaHeader.getReceived();
134   - int rPort = viaHeader.getRPort();
135   - // 解析本地地址替代
136   - if (ObjectUtils.isEmpty(received) || rPort == -1) {
137   - received = viaHeader.getHost();
138   - rPort = viaHeader.getPort();
139   - }
  137 + RemoteAddressInfo remoteAddressInfo = SipUtils.getRemoteAddressFromRequest(request,
  138 + userSetting.getSipUseSourceIpAsRemoteAddress());
  139 +
140 140 if (device == null) {
141 141 device = new Device();
142 142 device.setStreamMode("UDP");
... ... @@ -146,9 +146,9 @@ public class RegisterRequestProcessor extends SIPRequestProcessorParent implemen
146 146 device.setDeviceId(deviceId);
147 147 device.setOnline(0);
148 148 }
149   - device.setIp(received);
150   - device.setPort(rPort);
151   - device.setHostAddress(received.concat(":").concat(String.valueOf(rPort)));
  149 + device.setIp(remoteAddressInfo.getIp());
  150 + device.setPort(remoteAddressInfo.getPort());
  151 + device.setHostAddress(remoteAddressInfo.getIp().concat(":").concat(String.valueOf(remoteAddressInfo.getPort())));
152 152 device.setLocalIp(request.getLocalAddress().getHostAddress());
153 153 if (request.getExpires().getExpires() == 0) {
154 154 // 注销成功
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/MessageRequestProcessor.java
... ... @@ -67,6 +67,7 @@ public class MessageRequestProcessor extends SIPRequestProcessorParent implement
67 67 @Override
68 68 public void process(RequestEvent evt) {
69 69 SIPRequest sipRequest = (SIPRequest)evt.getRequest();
  70 + logger.info("接收到消息:" + evt.getRequest());
70 71 logger.debug("接收到消息:" + evt.getRequest());
71 72 String deviceId = SipUtils.getUserIdFromFromHeader(evt.getRequest());
72 73 CallIdHeader callIdHeader = sipRequest.getCallIdHeader();
... ... @@ -94,7 +95,7 @@ public class MessageRequestProcessor extends SIPRequestProcessorParent implement
94 95 if (device == null && parentPlatform == null) {
95 96 // 不存在则回复404
96 97 responseAck(request, Response.NOT_FOUND, "device "+ deviceId +" not found");
97   - logger.warn("[设备未找到 ]: {}", deviceId);
  98 + logger.warn("[设备未找到 ]deviceId: {}, callId: {}", deviceId, callIdHeader.getCallId());
98 99 if (sipSubscribe.getErrorSubscribe(callIdHeader.getCallId()) != null){
99 100 DeviceNotFoundEvent deviceNotFoundEvent = new DeviceNotFoundEvent(evt.getDialog());
100 101 deviceNotFoundEvent.setCallId(callIdHeader.getCallId());
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/KeepaliveNotifyMessageHandler.java
1 1 package com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.notify.cmd;
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.UserSetting;
3 6 import com.genersoft.iot.vmp.gb28181.bean.Device;
4 7 import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform;
5   -import com.genersoft.iot.vmp.gb28181.event.EventPublisher;
  8 +import com.genersoft.iot.vmp.gb28181.bean.RemoteAddressInfo;
6 9 import com.genersoft.iot.vmp.gb28181.transmit.event.request.SIPRequestProcessorParent;
7 10 import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.IMessageHandler;
8 11 import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.notify.NotifyMessageHandler;
  12 +import com.genersoft.iot.vmp.gb28181.utils.SipUtils;
9 13 import com.genersoft.iot.vmp.service.IDeviceService;
10   -import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
11   -import com.genersoft.iot.vmp.storager.IVideoManagerStorage;
12 14 import com.genersoft.iot.vmp.utils.DateUtil;
13 15 import gov.nist.javax.sip.message.SIPRequest;
14 16 import org.dom4j.Element;
... ... @@ -17,13 +19,10 @@ import org.slf4j.LoggerFactory;
17 19 import org.springframework.beans.factory.InitializingBean;
18 20 import org.springframework.beans.factory.annotation.Autowired;
19 21 import org.springframework.stereotype.Component;
20   -import org.springframework.util.ObjectUtils;
21   -import org.springframework.util.StringUtils;
22 22  
23 23 import javax.sip.InvalidArgumentException;
24 24 import javax.sip.RequestEvent;
25 25 import javax.sip.SipException;
26   -import javax.sip.header.ViaHeader;
27 26 import javax.sip.message.Response;
28 27 import java.text.ParseException;
29 28  
... ... @@ -33,6 +32,7 @@ import java.text.ParseException;
33 32 @Component
34 33 public class KeepaliveNotifyMessageHandler extends SIPRequestProcessorParent implements InitializingBean, IMessageHandler {
35 34  
  35 +
36 36 private Logger logger = LoggerFactory.getLogger(KeepaliveNotifyMessageHandler.class);
37 37 private final static String cmdType = "Keepalive";
38 38  
... ... @@ -42,6 +42,12 @@ public class KeepaliveNotifyMessageHandler extends SIPRequestProcessorParent imp
42 42 @Autowired
43 43 private IDeviceService deviceService;
44 44  
  45 + @Autowired
  46 + private UserSetting userSetting;
  47 +
  48 + @Autowired
  49 + private DynamicTask dynamicTask;
  50 +
45 51 @Override
46 52 public void afterPropertiesSet() throws Exception {
47 53 notifyMessageHandler.addHandler(cmdType, this);
... ... @@ -53,26 +59,27 @@ public class KeepaliveNotifyMessageHandler extends SIPRequestProcessorParent imp
53 59 // 未注册的设备不做处理
54 60 return;
55 61 }
  62 + SIPRequest request = (SIPRequest) evt.getRequest();
56 63 // 回复200 OK
57 64 try {
58   - responseAck((SIPRequest) evt.getRequest(), Response.OK);
  65 + responseAck(request, Response.OK);
59 66 } catch (SipException | InvalidArgumentException | ParseException e) {
60   - logger.error("[命令发送失败] 国标级联 心跳回复: {}", e.getMessage());
  67 + logger.error("[命令发送失败] 心跳回复: {}", e.getMessage());
61 68 }
62   - // 判断RPort是否改变,改变则说明路由nat信息变化,修改设备信息
63   - // 获取到通信地址等信息
64   - ViaHeader viaHeader = (ViaHeader) evt.getRequest().getHeader(ViaHeader.NAME);
65   - String received = viaHeader.getReceived();
66   - int rPort = viaHeader.getRPort();
67   - // 解析本地地址替代
68   - if (ObjectUtils.isEmpty(received) || rPort == -1) {
69   - received = viaHeader.getHost();
70   - rPort = viaHeader.getPort();
  69 +
  70 + RemoteAddressInfo remoteAddressInfo = SipUtils.getRemoteAddressFromRequest(request, userSetting.getSipUseSourceIpAsRemoteAddress());
  71 + if (!device.getIp().equalsIgnoreCase(remoteAddressInfo.getIp()) || device.getPort() != remoteAddressInfo.getPort()) {
  72 + device.setPort(remoteAddressInfo.getPort());
  73 + device.setHostAddress(remoteAddressInfo.getIp().concat(":").concat(String.valueOf(remoteAddressInfo.getPort())));
  74 + device.setIp(remoteAddressInfo.getIp());
71 75 }
72   - if (device.getPort() != rPort) {
73   - device.setPort(rPort);
74   - device.setHostAddress(received.concat(":").concat(String.valueOf(rPort)));
  76 + if (device.getKeepaliveTime() == null) {
  77 + device.setKeepaliveIntervalTime(60);
  78 + }else {
  79 + long lastTime = DateUtil.yyyy_MM_dd_HH_mm_ssToTimestamp(device.getKeepaliveTime());
  80 + device.setKeepaliveIntervalTime(new Long(System.currentTimeMillis()/1000-lastTime).intValue());
75 81 }
  82 +
76 83 device.setKeepaliveTime(DateUtil.getNow());
77 84  
78 85 if (device.getOnline() == 1) {
... ... @@ -80,9 +87,15 @@ public class KeepaliveNotifyMessageHandler extends SIPRequestProcessorParent imp
80 87 }else {
81 88 // 对于已经离线的设备判断他的注册是否已经过期
82 89 if (!deviceService.expire(device)){
  90 + device.setOnline(0);
83 91 deviceService.online(device);
84 92 }
85 93 }
  94 + // 刷新过期任务
  95 + String registerExpireTaskKey = VideoManagerConstants.REGISTER_EXPIRE_TASK_KEY_PREFIX + device.getDeviceId();
  96 + // 如果三次心跳失败,则设置设备离线
  97 + dynamicTask.startDelay(registerExpireTaskKey, ()-> deviceService.offline(device.getDeviceId()), device.getKeepaliveIntervalTime()*1000*3);
  98 +
86 99 }
87 100  
88 101 @Override
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/query/cmd/DeviceStatusQueryMessageHandler.java
... ... @@ -2,6 +2,7 @@ package com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.query.
2 2  
3 3 import com.genersoft.iot.vmp.conf.SipConfig;
4 4 import com.genersoft.iot.vmp.gb28181.bean.Device;
  5 +import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel;
5 6 import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform;
6 7 import com.genersoft.iot.vmp.gb28181.event.EventPublisher;
7 8 import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommanderFroPlatform;
... ... @@ -24,6 +25,8 @@ import javax.sip.header.FromHeader;
24 25 import javax.sip.message.Response;
25 26 import java.text.ParseException;
26 27  
  28 +import static com.genersoft.iot.vmp.gb28181.utils.XmlUtil.getText;
  29 +
27 30 @Component
28 31 public class DeviceStatusQueryMessageHandler extends SIPRequestProcessorParent implements InitializingBean, IMessageHandler {
29 32  
... ... @@ -62,13 +65,19 @@ public class DeviceStatusQueryMessageHandler extends SIPRequestProcessorParent i
62 65 FromHeader fromHeader = (FromHeader) evt.getRequest().getHeader(FromHeader.NAME);
63 66 // 回复200 OK
64 67 try {
65   - responseAck((SIPRequest) evt.getRequest(), Response.OK);
  68 + responseAck((SIPRequest) evt.getRequest(), Response.OK);
66 69 } catch (SipException | InvalidArgumentException | ParseException e) {
67 70 logger.error("[命令发送失败] 国标级联 DeviceStatus查询回复200OK: {}", e.getMessage());
68 71 }
69 72 String sn = rootElement.element("SN").getText();
  73 + String channelId = getText(rootElement, "DeviceID");
  74 + DeviceChannel deviceChannel = storager.queryChannelInParentPlatform(parentPlatform.getServerGBId(), channelId);
  75 + if (deviceChannel ==null){
  76 + logger.error("[平台没有该通道的使用权限]:platformId"+parentPlatform.getServerGBId()+" deviceID:"+channelId);
  77 + return;
  78 + }
70 79 try {
71   - cmderFroPlatform.deviceStatusResponse(parentPlatform, sn, fromHeader.getTag());
  80 + cmderFroPlatform.deviceStatusResponse(parentPlatform,channelId, sn, fromHeader.getTag(),deviceChannel.getStatus());
72 81 } catch (SipException | InvalidArgumentException | ParseException e) {
73 82 logger.error("[命令发送失败] 国标级联 DeviceStatus查询回复: {}", e.getMessage());
74 83 }
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/utils/SipUtils.java
1 1 package com.genersoft.iot.vmp.gb28181.utils;
2 2  
  3 +import com.genersoft.iot.vmp.gb28181.bean.RemoteAddressInfo;
3 4 import com.genersoft.iot.vmp.utils.GitUtil;
4 5 import gov.nist.javax.sip.address.AddressImpl;
5 6 import gov.nist.javax.sip.address.SipUri;
6 7 import gov.nist.javax.sip.header.Subject;
  8 +import gov.nist.javax.sip.message.SIPRequest;
7 9 import org.springframework.util.ObjectUtils;
8 10  
9 11 import javax.sip.PeerUnavailableException;
... ... @@ -139,4 +141,31 @@ public class SipUtils {
139 141 int typeCodeFromGbCode = getTypeCodeFromGbCode(deviceId);
140 142 return typeCodeFromGbCode > 130 && typeCodeFromGbCode < 199;
141 143 }
  144 + /**
  145 + * 从请求中获取设备ip地址和端口号
  146 + * @param request 请求
  147 + * @param sipUseSourceIpAsRemoteAddress false 从via中获取地址, true 直接获取远程地址
  148 + * @return 地址信息
  149 + */
  150 + public static RemoteAddressInfo getRemoteAddressFromRequest(SIPRequest request, boolean sipUseSourceIpAsRemoteAddress) {
  151 +
  152 + String remoteAddress;
  153 + int remotePort;
  154 + if (sipUseSourceIpAsRemoteAddress) {
  155 + remoteAddress = request.getRemoteAddress().getHostAddress();
  156 + remotePort = request.getRemotePort();
  157 + }else {
  158 + // 判断RPort是否改变,改变则说明路由nat信息变化,修改设备信息
  159 + // 获取到通信地址等信息
  160 + remoteAddress = request.getTopmostViaHeader().getReceived();
  161 + remotePort = request.getTopmostViaHeader().getRPort();
  162 + // 解析本地地址替代
  163 + if (ObjectUtils.isEmpty(remoteAddress) || remotePort == -1) {
  164 + remoteAddress = request.getTopmostViaHeader().getHost();
  165 + remotePort = request.getTopmostViaHeader().getPort();
  166 + }
  167 + }
  168 +
  169 + return new RemoteAddressInfo(remoteAddress, remotePort);
  170 + }
142 171 }
... ...
src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java
... ... @@ -19,6 +19,7 @@ import com.genersoft.iot.vmp.media.zlm.dto.hook.*;
19 19 import com.genersoft.iot.vmp.service.*;
20 20 import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
21 21 import com.genersoft.iot.vmp.storager.IVideoManagerStorage;
  22 +import com.genersoft.iot.vmp.vmanager.bean.StreamContent;
22 23 import org.slf4j.Logger;
23 24 import org.slf4j.LoggerFactory;
24 25 import org.springframework.beans.factory.annotation.Autowired;
... ... @@ -445,7 +446,7 @@ public class ZLMHttpHookListener {
445 446 }
446 447 StreamInfo streamInfoByAppAndStream = mediaService.getStreamInfoByAppAndStream(mediaServerItem,
447 448 param.getApp(), param.getStream(), param.getTracks(), callId);
448   - param.setStreamInfo(streamInfoByAppAndStream);
  449 + param.setStreamInfo(new StreamContent(streamInfoByAppAndStream));
449 450 redisCatchStorage.addStream(mediaServerItem, type, param.getApp(), param.getStream(), param);
450 451 if (param.getOriginType() == OriginType.RTSP_PUSH.ordinal()
451 452 || param.getOriginType() == OriginType.RTMP_PUSH.ordinal()
... ... @@ -463,7 +464,7 @@ public class ZLMHttpHookListener {
463 464 }
464 465 GbStream gbStream = storager.getGbStream(param.getApp(), param.getStream());
465 466 if (gbStream != null) {
466   -// eventPublisher.catalogEventPublishForStream(null, gbStream, CatalogEvent.OFF);
  467 +// eventPublisher.catalogEventPublishForStream(null, gbStream, CatalogEvent.OFF);
467 468 }
468 469 zlmMediaListManager.removeMedia(param.getApp(), param.getStream());
469 470 }
... ... @@ -534,7 +535,7 @@ public class ZLMHttpHookListener {
534 535 logger.info("[ZLM HOOK]流无人观看:{]->{}->{}/{}" + param.getMediaServerId(), param.getSchema(), param.getApp(), param.getStream());
535 536 JSONObject ret = new JSONObject();
536 537 ret.put("code", 0);
537   - // 录像下载
  538 + // 国标类型的流
538 539 if ("rtp".equals(param.getApp())){
539 540 ret.put("close", userSetting.getStreamOnDemand());
540 541 // 国标流, 点播/录像回放/录像下载
... ... @@ -641,7 +642,7 @@ public class ZLMHttpHookListener {
641 642 @ResponseBody
642 643 @PostMapping(value = "/on_stream_not_found", produces = "application/json;charset=UTF-8")
643 644 public JSONObject onStreamNotFound(@RequestBody OnStreamNotFoundHookParam param){
644   - logger.info("[ZLM HOOK] 流未找到:{}->{}->{}/{}" + param.getMediaServerId(), param.getSchema(), param.getApp(), param.getStream());
  645 + logger.info("[ZLM HOOK] 流未找到:{}->{}->{}/{}", param.getMediaServerId(), param.getSchema(), param.getApp(), param.getStream());
645 646 taskExecutor.execute(()->{
646 647 MediaServerItem mediaInfo = mediaServerService.getOne(param.getMediaServerId());
647 648 if (userSetting.isAutoApplyPlay() && mediaInfo != null) {
... ... @@ -709,7 +710,7 @@ public class ZLMHttpHookListener {
709 710 @PostMapping(value = "/on_send_rtp_stopped", produces = "application/json;charset=UTF-8")
710 711 public JSONObject onSendRtpStopped(HttpServletRequest request, @RequestBody OnSendRtpStoppedHookParam param){
711 712  
712   - logger.info("[ZLM HOOK] 发送rtp被动关闭:{}->{}/{}", param.getMediaServerId(), param.getApp(), param.getStream());
  713 + logger.info("[ZLM HOOK] rtp发送关闭:{}->{}/{}", param.getMediaServerId(), param.getApp(), param.getStream());
713 714  
714 715 JSONObject ret = new JSONObject();
715 716 ret.put("code", 0);
... ...
src/main/java/com/genersoft/iot/vmp/media/zlm/dto/hook/OnStreamChangedHookParam.java
1 1 package com.genersoft.iot.vmp.media.zlm.dto.hook;
2 2  
3   -import com.genersoft.iot.vmp.common.StreamInfo;
  3 +import com.genersoft.iot.vmp.vmanager.bean.StreamContent;
4 4  
5 5 import java.util.List;
6 6  
... ... @@ -291,7 +291,7 @@ public class OnStreamChangedHookParam extends HookParam{
291 291 }
292 292 }
293 293  
294   - private StreamInfo streamInfo;
  294 + private StreamContent streamInfo;
295 295  
296 296 public String getApp() {
297 297 return app;
... ... @@ -407,11 +407,11 @@ public class OnStreamChangedHookParam extends HookParam{
407 407 this.docker = docker;
408 408 }
409 409  
410   - public StreamInfo getStreamInfo() {
  410 + public StreamContent getStreamInfo() {
411 411 return streamInfo;
412 412 }
413 413  
414   - public void setStreamInfo(StreamInfo streamInfo) {
  414 + public void setStreamInfo(StreamContent streamInfo) {
415 415 this.streamInfo = streamInfo;
416 416 }
417 417  
... ...
src/main/java/com/genersoft/iot/vmp/service/IMediaServerService.java
... ... @@ -37,7 +37,7 @@ public interface IMediaServerService {
37 37 */
38 38 void zlmServerOffline(String mediaServerId);
39 39  
40   - MediaServerItem getMediaServerForMinimumLoad();
  40 + MediaServerItem getMediaServerForMinimumLoad(Boolean hasAssist);
41 41  
42 42 void setZLMConfig(MediaServerItem mediaServerItem, boolean restart);
43 43  
... ...
src/main/java/com/genersoft/iot/vmp/service/IPlayService.java
... ... @@ -40,15 +40,20 @@ public interface IPlayService {
40 40  
41 41 MediaServerItem getNewMediaServerItem(Device device);
42 42  
  43 + /**
  44 + * 获取包含assist服务的节点
  45 + */
  46 + MediaServerItem getNewMediaServerItemHasAssist(Device device);
  47 +
43 48 void onPublishHandlerForDownload(InviteStreamInfo inviteStreamInfo, String deviceId, String channelId, String toString);
44 49  
45   - DeferredResult<WVPResult<StreamInfo>> playBack(String deviceId, String channelId, String startTime, String endTime, InviteStreamCallback infoCallBack, PlayBackCallback hookCallBack);
46   - DeferredResult<WVPResult<StreamInfo>> playBack(MediaServerItem mediaServerItem, SSRCInfo ssrcInfo,String deviceId, String channelId, String startTime, String endTime, InviteStreamCallback infoCallBack, PlayBackCallback hookCallBack);
  50 + void playBack(String deviceId, String channelId, String startTime, String endTime, InviteStreamCallback infoCallBack, PlayBackCallback playBackCallback);
  51 + void playBack(MediaServerItem mediaServerItem, SSRCInfo ssrcInfo, String deviceId, String channelId, String startTime, String endTime, InviteStreamCallback infoCallBack, PlayBackCallback hookCallBack);
47 52  
48 53 void zlmServerOffline(String mediaServerId);
49 54  
50   - DeferredResult<WVPResult<StreamInfo>> download(String deviceId, String channelId, String startTime, String endTime, int downloadSpeed, InviteStreamCallback infoCallBack, PlayBackCallback hookCallBack);
51   - DeferredResult<WVPResult<StreamInfo>> download(MediaServerItem mediaServerItem, SSRCInfo ssrcInfo,String deviceId, String channelId, String startTime, String endTime, int downloadSpeed, InviteStreamCallback infoCallBack, PlayBackCallback hookCallBack);
  55 + void download(String deviceId, String channelId, String startTime, String endTime, int downloadSpeed, InviteStreamCallback infoCallBack, PlayBackCallback playBackCallback);
  56 + void download(MediaServerItem mediaServerItem, SSRCInfo ssrcInfo,String deviceId, String channelId, String startTime, String endTime, int downloadSpeed, InviteStreamCallback infoCallBack, PlayBackCallback hookCallBack);
52 57  
53 58 StreamInfo getDownLoadInfo(String deviceId, String channelId, String stream);
54 59  
... ...
src/main/java/com/genersoft/iot/vmp/service/bean/PlayBackCallback.java
1 1 package com.genersoft.iot.vmp.service.bean;
2 2  
3   -import com.genersoft.iot.vmp.gb28181.transmit.callback.RequestMessage;
4   -import com.genersoft.iot.vmp.vmanager.bean.WVPResult;
  3 +public interface PlayBackCallback<T> {
5 4  
6   -public interface PlayBackCallback {
7   -
8   - void call(PlayBackResult<RequestMessage> msg);
  5 + void call(PlayBackResult<T> msg);
9 6  
10 7 }
... ...
src/main/java/com/genersoft/iot/vmp/service/impl/DeviceChannelServiceImpl.java
... ... @@ -99,7 +99,7 @@ public class DeviceChannelServiceImpl implements IDeviceChannelService {
99 99 HashMap<String, DeviceChannel> channelsInStore = new HashMap<>();
100 100 Device device = deviceMapper.getDeviceByDeviceId(deviceId);
101 101 if (channels != null && channels.size() > 0) {
102   - List<DeviceChannel> channelList = channelMapper.queryChannels(deviceId, null, null, null, null);
  102 + List<DeviceChannel> channelList = channelMapper.queryChannels(deviceId, null, null, null, null,null);
103 103 if (channelList.size() == 0) {
104 104 for (DeviceChannel channel : channels) {
105 105 channel.setDeviceId(deviceId);
... ...
src/main/java/com/genersoft/iot/vmp/service/impl/DeviceServiceImpl.java
1 1 package com.genersoft.iot.vmp.service.impl;
2 2  
  3 +import com.genersoft.iot.vmp.common.VideoManagerConstants;
3 4 import com.genersoft.iot.vmp.conf.DynamicTask;
4 5 import com.genersoft.iot.vmp.conf.UserSetting;
5 6 import com.genersoft.iot.vmp.gb28181.bean.*;
... ... @@ -46,8 +47,6 @@ public class DeviceServiceImpl implements IDeviceService {
46 47  
47 48 private final static Logger logger = LoggerFactory.getLogger(DeviceServiceImpl.class);
48 49  
49   - private final String registerExpireTaskKeyPrefix = "device-register-expire-";
50   -
51 50 @Autowired
52 51 private DynamicTask dynamicTask;
53 52  
... ... @@ -108,7 +107,10 @@ public class DeviceServiceImpl implements IDeviceService {
108 107 redisCatchStorage.clearCatchByDeviceId(device.getDeviceId());
109 108 }
110 109 device.setUpdateTime(now);
111   -
  110 + if (device.getKeepaliveIntervalTime() == 0) {
  111 + // 默认心跳间隔60
  112 + device.setKeepaliveIntervalTime(60);
  113 + }
112 114 // 第一次上线 或则设备之前是离线状态--进行通道同步和设备信息查询
113 115 if (device.getCreateTime() == null) {
114 116 device.setOnline(1);
... ... @@ -123,7 +125,6 @@ public class DeviceServiceImpl implements IDeviceService {
123 125 }
124 126 sync(device);
125 127 }else {
126   -
127 128 if(device.getOnline() == 0){
128 129 device.setOnline(1);
129 130 device.setCreateTime(now);
... ... @@ -160,18 +161,19 @@ public class DeviceServiceImpl implements IDeviceService {
160 161 addMobilePositionSubscribe(device);
161 162 }
162 163 // 刷新过期任务
163   - String registerExpireTaskKey = registerExpireTaskKeyPrefix + device.getDeviceId();
164   - dynamicTask.startDelay(registerExpireTaskKey, ()-> offline(device.getDeviceId()), device.getExpires() * 1000);
  164 + String registerExpireTaskKey = VideoManagerConstants.REGISTER_EXPIRE_TASK_KEY_PREFIX + device.getDeviceId();
  165 + // 如果第一次注册那么必须在60 * 3时间内收到一个心跳,否则设备离线
  166 + dynamicTask.startDelay(registerExpireTaskKey, ()-> offline(device.getDeviceId()), device.getKeepaliveIntervalTime() * 1000 * 3);
165 167 }
166 168  
167 169 @Override
168 170 public void offline(String deviceId) {
169   - logger.info("[设备离线], device:{}", deviceId);
  171 + logger.error("[设备离线], device:{}", deviceId);
170 172 Device device = deviceMapper.getDeviceByDeviceId(deviceId);
171 173 if (device == null) {
172 174 return;
173 175 }
174   - String registerExpireTaskKey = registerExpireTaskKeyPrefix + deviceId;
  176 + String registerExpireTaskKey = VideoManagerConstants.REGISTER_EXPIRE_TASK_KEY_PREFIX + deviceId;
175 177 dynamicTask.stop(registerExpireTaskKey);
176 178 device.setOnline(0);
177 179 redisCatchStorage.updateDevice(device);
... ... @@ -356,7 +358,6 @@ public class DeviceServiceImpl implements IDeviceService {
356 358 device.setUpdateTime(DateUtil.getNow());
357 359 if (deviceMapper.update(device) > 0) {
358 360 redisCatchStorage.updateDevice(device);
359   -
360 361 }
361 362 }
362 363  
... ... @@ -432,7 +433,7 @@ public class DeviceServiceImpl implements IDeviceService {
432 433 if (parentId.length() < 14 ) {
433 434 return null;
434 435 }
435   - List<DeviceChannel> deviceChannels = deviceChannelMapper.queryChannels(deviceId, parentId, null, null, null);
  436 + List<DeviceChannel> deviceChannels = deviceChannelMapper.queryChannels(deviceId, parentId, null, null, null,null);
436 437 List<BaseTree<DeviceChannel>> trees = transportChannelsToTree(deviceChannels, parentId);
437 438 return trees;
438 439 }
... ... @@ -477,7 +478,7 @@ public class DeviceServiceImpl implements IDeviceService {
477 478 if (parentId.length() < 14 ) {
478 479 return null;
479 480 }
480   - List<DeviceChannel> deviceChannels = deviceChannelMapper.queryChannels(deviceId, parentId, null, null, null);
  481 + List<DeviceChannel> deviceChannels = deviceChannelMapper.queryChannels(deviceId, parentId, null, null, null,null);
481 482 return deviceChannels;
482 483 }
483 484  
... ... @@ -541,7 +542,7 @@ public class DeviceServiceImpl implements IDeviceService {
541 542 }
542 543 }else {
543 544 if (haveChannel) {
544   - List<DeviceChannel> deviceChannels = deviceChannelMapper.queryChannels(deviceId, null, null, null, null);
  545 + List<DeviceChannel> deviceChannels = deviceChannelMapper.queryChannels(deviceId, null, null, null, null,null);
545 546 if (deviceChannels != null && deviceChannels.size() > 0) {
546 547 result.addAll(deviceChannels);
547 548 }
... ...
src/main/java/com/genersoft/iot/vmp/service/impl/MediaServerServiceImpl.java
... ... @@ -501,7 +501,7 @@ public class MediaServerServiceImpl implements IMediaServerService {
501 501 * @return MediaServerItem
502 502 */
503 503 @Override
504   - public MediaServerItem getMediaServerForMinimumLoad() {
  504 + public MediaServerItem getMediaServerForMinimumLoad(Boolean hasAssist) {
505 505 String key = VideoManagerConstants.MEDIA_SERVERS_ONLINE_PREFIX + userSetting.getServerId();
506 506  
507 507 if (RedisUtil.zSize(key) == null || RedisUtil.zSize(key) == 0) {
... ... @@ -514,9 +514,31 @@ public class MediaServerServiceImpl implements IMediaServerService {
514 514 // 获取分数最低的,及并发最低的
515 515 Set<Object> objects = RedisUtil.zRange(key, 0, -1);
516 516 ArrayList<Object> mediaServerObjectS = new ArrayList<>(objects);
  517 + MediaServerItem mediaServerItem = null;
  518 + if (hasAssist == null) {
  519 + String mediaServerId = (String)mediaServerObjectS.get(0);
  520 + mediaServerItem = getOne(mediaServerId);
  521 + }else if (hasAssist) {
  522 + for (Object mediaServerObject : mediaServerObjectS) {
  523 + String mediaServerId = (String)mediaServerObject;
  524 + MediaServerItem serverItem = getOne(mediaServerId);
  525 + if (serverItem.getRecordAssistPort() > 0) {
  526 + mediaServerItem = serverItem;
  527 + break;
  528 + }
  529 + }
  530 + }else if (!hasAssist) {
  531 + for (Object mediaServerObject : mediaServerObjectS) {
  532 + String mediaServerId = (String)mediaServerObject;
  533 + MediaServerItem serverItem = getOne(mediaServerId);
  534 + if (serverItem.getRecordAssistPort() == 0) {
  535 + mediaServerItem = serverItem;
  536 + break;
  537 + }
  538 + }
  539 + }
517 540  
518   - String mediaServerId = (String)mediaServerObjectS.get(0);
519   - return getOne(mediaServerId);
  541 + return mediaServerItem;
520 542 }
521 543  
522 544 /**
... ...
src/main/java/com/genersoft/iot/vmp/service/impl/PlatformServiceImpl.java
... ... @@ -135,14 +135,7 @@ public class PlatformServiceImpl implements IPlatformService {
135 135 dynamicTask.startCron(registerTaskKey,
136 136 // 注册失败(注册成功时由程序直接调用了online方法)
137 137 ()-> {
138   - try {
139   - logger.info("[国标级联] 平台:{}注册即将到期,重新注册", parentPlatform.getServerGBId());
140   - commanderForPlatform.register(parentPlatform, eventResult -> {
141   - offline(parentPlatform, false);
142   - },null);
143   - } catch (InvalidArgumentException | ParseException | SipException e) {
144   - logger.error("[命令发送失败] 国标级联定时注册: {}", e.getMessage());
145   - }
  138 + registerTask(parentPlatform);
146 139 },
147 140 (parentPlatform.getExpires() - 10) *1000);
148 141 }
... ... @@ -194,6 +187,28 @@ public class PlatformServiceImpl implements IPlatformService {
194 187 }
195 188 }
196 189  
  190 + private void registerTask(ParentPlatform parentPlatform){
  191 + try {
  192 + // 设置超时重发, 后续从底层支持消息重发
  193 + String key = KEEPALIVE_KEY_PREFIX + parentPlatform.getServerGBId() + "_timeout";
  194 + if (dynamicTask.isAlive(key)) {
  195 + return;
  196 + }
  197 + dynamicTask.startDelay(key, ()->{
  198 + registerTask(parentPlatform);
  199 + }, 1000);
  200 + logger.info("[国标级联] 平台:{}注册即将到期,重新注册", parentPlatform.getServerGBId());
  201 + commanderForPlatform.register(parentPlatform, eventResult -> {
  202 + dynamicTask.stop(key);
  203 + offline(parentPlatform, false);
  204 + },eventResult -> {
  205 + dynamicTask.stop(key);
  206 + });
  207 + } catch (InvalidArgumentException | ParseException | SipException e) {
  208 + logger.error("[命令发送失败] 国标级联定时注册: {}", e.getMessage());
  209 + }
  210 + }
  211 +
197 212 @Override
198 213 public void offline(ParentPlatform parentPlatform, boolean stopRegister) {
199 214 logger.info("[平台离线]:{}", parentPlatform.getServerGBId());
... ...
src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java
... ... @@ -45,11 +45,8 @@ import gov.nist.javax.sip.message.SIPResponse;
45 45 import org.slf4j.Logger;
46 46 import org.slf4j.LoggerFactory;
47 47 import org.springframework.beans.factory.annotation.Autowired;
48   -import org.springframework.beans.factory.annotation.Qualifier;
49   -import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
50 48 import org.springframework.stereotype.Service;
51 49 import org.springframework.util.ObjectUtils;
52   -import org.springframework.web.context.request.async.DeferredResult;
53 50  
54 51 import javax.sip.InvalidArgumentException;
55 52 import javax.sip.ResponseEvent;
... ... @@ -454,6 +451,9 @@ public class PlayServiceImpl implements IPlayService {
454 451 mediaServerService.closeRTPServer(mediaServerItem, ssrcInfo.getStream());
455 452 streamSession.remove(device.getDeviceId(), channelId, ssrcInfo.getStream());
456 453 mediaServerService.closeRTPServer(mediaServerItem, ssrcInfo.getStream());
  454 + // 取消订阅消息监听
  455 + HookSubscribeForStreamChange hookSubscribe = HookSubscribeFactory.on_stream_changed("rtp", ssrcInfo.getStream(), true, "rtsp", mediaServerItem.getId());
  456 + subscribe.removeSubscribe(hookSubscribe);
457 457 }
458 458 }
459 459 }, userSetting.getPlayTimeout());
... ... @@ -463,7 +463,6 @@ public class PlayServiceImpl implements IPlayService {
463 463 dynamicTask.stop(timeOutTaskKey);
464 464 // 释放ssrc
465 465 mediaServerService.releaseSsrc(mediaServerItem.getId(), ssrcInfo.getSsrc());
466   -
467 466 streamSession.remove(device.getDeviceId(), channelId, ssrcInfo.getStream());
468 467  
469 468 RequestMessage msg = new RequestMessage();
... ... @@ -481,7 +480,7 @@ public class PlayServiceImpl implements IPlayService {
481 480 onPublishHandlerForPlay(mediaServerItemInuse, response, device.getDeviceId(), channelId);
482 481 hookEvent.response(mediaServerItemInuse, response);
483 482 logger.info("[点播成功] deviceId: {}, channelId: {}", device.getDeviceId(), channelId);
484   - String streamUrl = String.format("rtsp://127.0.0.1:%s/%s/%s", mediaServerItemInuse.getRtspPort(), "rtp", ssrcInfo.getStream());
  483 + String streamUrl = String.format("http://127.0.0.1:%s/%s/%s.live.flv", mediaServerItemInuse.getHttpPort(), "rtp", ssrcInfo.getStream());
485 484 String path = "snap";
486 485 String fileName = device.getDeviceId() + "_" + channelId + ".jpg";
487 486 // 请求截图
... ... @@ -589,14 +588,10 @@ public class PlayServiceImpl implements IPlayService {
589 588 }
590 589 }
591 590  
592   - private void onPublishHandlerForPlayback(MediaServerItem mediaServerItem, JSONObject response, String deviceId, String channelId, String uuid) {
593   - RequestMessage msg = new RequestMessage();
594   - msg.setKey(DeferredResultHolder.CALLBACK_CMD_PLAY + deviceId + channelId);
595   - if (!ObjectUtils.isEmpty(uuid)) {
596   - msg.setId(uuid);
597   - }
598   - StreamInfo streamInfo = onPublishHandler(mediaServerItem, response, deviceId, channelId);
  591 + private void onPublishHandlerForPlayback(MediaServerItem mediaServerItem, JSONObject response, String deviceId, String channelId, PlayBackCallback playBackCallback) {
599 592  
  593 + StreamInfo streamInfo = onPublishHandler(mediaServerItem, response, deviceId, channelId);
  594 + PlayBackResult<StreamInfo> playBackResult = new PlayBackResult<>();
600 595 if (streamInfo != null) {
601 596 DeviceChannel deviceChannel = storager.queryChannel(deviceId, channelId);
602 597 if (deviceChannel != null) {
... ... @@ -605,17 +600,16 @@ public class PlayServiceImpl implements IPlayService {
605 600 }
606 601 redisCatchStorage.startPlay(streamInfo);
607 602  
608   - WVPResult wvpResult = new WVPResult();
609   - wvpResult.setCode(ErrorCode.SUCCESS.getCode());
610   - wvpResult.setMsg(ErrorCode.SUCCESS.getMsg());
611   - wvpResult.setData(streamInfo);
612   - msg.setData(wvpResult);
613 603  
614   - resultHolder.invokeAllResult(msg);
  604 + playBackResult.setCode(ErrorCode.SUCCESS.getCode());
  605 + playBackResult.setMsg(ErrorCode.SUCCESS.getMsg());
  606 + playBackResult.setData(streamInfo);
  607 + playBackCallback.call(playBackResult);
615 608 } else {
616 609 logger.warn("录像回放调用失败!");
617   - msg.setData(WVPResult.fail(ErrorCode.ERROR100.getCode(), "录像回放调用失败!"));
618   - resultHolder.invokeAllResult(msg);
  610 + playBackResult.setCode(ErrorCode.ERROR100.getCode());
  611 + playBackResult.setMsg("录像回放调用失败!");
  612 + playBackCallback.call(playBackResult);
619 613 }
620 614 }
621 615  
... ... @@ -626,7 +620,7 @@ public class PlayServiceImpl implements IPlayService {
626 620 }
627 621 MediaServerItem mediaServerItem;
628 622 if (ObjectUtils.isEmpty(device.getMediaServerId()) || "auto".equals(device.getMediaServerId())) {
629   - mediaServerItem = mediaServerService.getMediaServerForMinimumLoad();
  623 + mediaServerItem = mediaServerService.getMediaServerForMinimumLoad(null);
630 624 } else {
631 625 mediaServerItem = mediaServerService.getOne(device.getMediaServerId());
632 626 }
... ... @@ -637,45 +631,56 @@ public class PlayServiceImpl implements IPlayService {
637 631 }
638 632  
639 633 @Override
640   - public DeferredResult<WVPResult<StreamInfo>> playBack(String deviceId, String channelId, String startTime,
  634 + public MediaServerItem getNewMediaServerItemHasAssist(Device device) {
  635 + if (device == null) {
  636 + return null;
  637 + }
  638 + MediaServerItem mediaServerItem;
  639 + if (ObjectUtils.isEmpty(device.getMediaServerId()) || "auto".equals(device.getMediaServerId())) {
  640 + mediaServerItem = mediaServerService.getMediaServerForMinimumLoad(true);
  641 + } else {
  642 + mediaServerItem = mediaServerService.getOne(device.getMediaServerId());
  643 + }
  644 + if (mediaServerItem == null) {
  645 + logger.warn("[获取可用的ZLM节点]未找到可使用的ZLM...");
  646 + }
  647 + return mediaServerItem;
  648 + }
  649 +
  650 + @Override
  651 + public void playBack(String deviceId, String channelId, String startTime,
641 652 String endTime, InviteStreamCallback inviteStreamCallback,
642 653 PlayBackCallback callback) {
643 654 Device device = storager.queryVideoDevice(deviceId);
644 655 if (device == null) {
645   - return null;
  656 + return;
646 657 }
647 658 MediaServerItem newMediaServerItem = getNewMediaServerItem(device);
648 659 SSRCInfo ssrcInfo = mediaServerService.openRTPServer(newMediaServerItem, null, device.isSsrcCheck(), true);
649 660  
650   - return playBack(newMediaServerItem, ssrcInfo, deviceId, channelId, startTime, endTime, inviteStreamCallback, callback);
  661 + playBack(newMediaServerItem, ssrcInfo, deviceId, channelId, startTime, endTime, inviteStreamCallback, callback);
651 662 }
652 663  
653 664 @Override
654   - public DeferredResult<WVPResult<StreamInfo>> playBack(MediaServerItem mediaServerItem, SSRCInfo ssrcInfo,
  665 + public void playBack(MediaServerItem mediaServerItem, SSRCInfo ssrcInfo,
655 666 String deviceId, String channelId, String startTime,
656 667 String endTime, InviteStreamCallback infoCallBack,
657 668 PlayBackCallback playBackCallback) {
658 669 if (mediaServerItem == null || ssrcInfo == null) {
659   - return null;
  670 + return;
660 671 }
661   - String uuid = UUID.randomUUID().toString();
662   - String key = DeferredResultHolder.CALLBACK_CMD_PLAYBACK + deviceId + channelId;
  672 +
663 673 Device device = storager.queryVideoDevice(deviceId);
664 674 if (device == null) {
665 675 throw new ControllerException(ErrorCode.ERROR100.getCode(), "设备: " + deviceId + "不存在");
666 676 }
667   - DeferredResult<WVPResult<StreamInfo>> result = new DeferredResult<>(30000L);
668   - resultHolder.put(DeferredResultHolder.CALLBACK_CMD_PLAYBACK + deviceId + channelId, uuid, result);
669   - RequestMessage requestMessage = new RequestMessage();
670   - requestMessage.setId(uuid);
671   - requestMessage.setKey(key);
672   - PlayBackResult<RequestMessage> playBackResult = new PlayBackResult<>();
  677 +
  678 + PlayBackResult<StreamInfo> playBackResult = new PlayBackResult<>();
673 679 String playBackTimeOutTaskKey = UUID.randomUUID().toString();
674 680 dynamicTask.startDelay(playBackTimeOutTaskKey, () -> {
675 681 logger.warn(String.format("设备回放超时,deviceId:%s ,channelId:%s", deviceId, channelId));
676 682 playBackResult.setCode(ErrorCode.ERROR100.getCode());
677 683 playBackResult.setMsg("回放超时");
678   - playBackResult.setData(requestMessage);
679 684  
680 685 try {
681 686 cmder.streamByeCmd(device, channelId, ssrcInfo.getStream(), null);
... ... @@ -687,19 +692,14 @@ public class PlayServiceImpl implements IPlayService {
687 692 mediaServerService.closeRTPServer(mediaServerItem, ssrcInfo.getStream());
688 693 streamSession.remove(deviceId, channelId, ssrcInfo.getStream());
689 694 }
690   -
691 695 // 回复之前所有的点播请求
692 696 playBackCallback.call(playBackResult);
693   - result.setResult(WVPResult.fail(ErrorCode.ERROR100.getCode(), "回放超时"));
694   - resultHolder.exist(DeferredResultHolder.CALLBACK_CMD_PLAYBACK + deviceId + channelId, uuid);
695 697 }, userSetting.getPlayTimeout());
696 698  
697 699 SipSubscribe.Event errorEvent = event -> {
698 700 dynamicTask.stop(playBackTimeOutTaskKey);
699   - requestMessage.setData(WVPResult.fail(ErrorCode.ERROR100.getCode(), String.format("回放失败, 错误码: %s, %s", event.statusCode, event.msg)));
700 701 playBackResult.setCode(ErrorCode.ERROR100.getCode());
701 702 playBackResult.setMsg(String.format("回放失败, 错误码: %s, %s", event.statusCode, event.msg));
702   - playBackResult.setData(requestMessage);
703 703 playBackResult.setEvent(event);
704 704 playBackCallback.call(playBackResult);
705 705 streamSession.remove(device.getDeviceId(), channelId, ssrcInfo.getStream());
... ... @@ -717,11 +717,9 @@ public class PlayServiceImpl implements IPlayService {
717 717 return;
718 718 }
719 719 redisCatchStorage.startPlayback(streamInfo, inviteStreamInfo.getCallId());
720   - WVPResult<StreamInfo> success = WVPResult.success(streamInfo);
721   - requestMessage.setData(success);
722 720 playBackResult.setCode(ErrorCode.SUCCESS.getCode());
723 721 playBackResult.setMsg(ErrorCode.SUCCESS.getMsg());
724   - playBackResult.setData(requestMessage);
  722 + playBackResult.setData(streamInfo);
725 723 playBackResult.setMediaServerItem(inviteStreamInfo.getMediaServerItem());
726 724 playBackResult.setResponse(inviteStreamInfo.getResponse());
727 725 playBackCallback.call(playBackResult);
... ... @@ -768,7 +766,7 @@ public class PlayServiceImpl implements IPlayService {
768 766 logger.info("[ZLM HOOK] ssrc修正后收到订阅消息: " + response.toJSONString());
769 767 dynamicTask.stop(playBackTimeOutTaskKey);
770 768 // hook响应
771   - onPublishHandlerForPlayback(mediaServerItemInUse, response, device.getDeviceId(), channelId, uuid);
  769 + onPublishHandlerForPlayback(mediaServerItemInUse, response, device.getDeviceId(), channelId, playBackCallback);
772 770 hookEvent.call(new InviteStreamInfo(mediaServerItem, null, eventResult.callId, "rtp", ssrcInfo.getStream()));
773 771 });
774 772 }
... ... @@ -788,50 +786,45 @@ public class PlayServiceImpl implements IPlayService {
788 786 eventResult.msg = "命令发送失败";
789 787 errorEvent.response(eventResult);
790 788 }
791   - return result;
792 789 }
793 790  
794 791  
795 792  
796 793 @Override
797   - public DeferredResult<WVPResult<StreamInfo>> download(String deviceId, String channelId, String startTime, String endTime, int downloadSpeed, InviteStreamCallback infoCallBack, PlayBackCallback hookCallBack) {
  794 + public void download(String deviceId, String channelId, String startTime, String endTime, int downloadSpeed, InviteStreamCallback infoCallBack, PlayBackCallback playBackCallback) {
798 795 Device device = storager.queryVideoDevice(deviceId);
799 796 if (device == null) {
800   - return null;
  797 + return;
  798 + }
  799 + MediaServerItem newMediaServerItem = getNewMediaServerItemHasAssist(device);
  800 + if (newMediaServerItem == null) {
  801 + PlayBackResult<StreamInfo> downloadResult = new PlayBackResult<>();
  802 + downloadResult.setCode(ErrorCode.ERROR100.getCode());
  803 + downloadResult.setMsg("未找到assist服务");
  804 + playBackCallback.call(downloadResult);
  805 + return;
801 806 }
802   - MediaServerItem newMediaServerItem = getNewMediaServerItem(device);
803 807 SSRCInfo ssrcInfo = mediaServerService.openRTPServer(newMediaServerItem, null, device.isSsrcCheck(), true);
804 808  
805   - return download(newMediaServerItem, ssrcInfo, deviceId, channelId, startTime, endTime, downloadSpeed, infoCallBack, hookCallBack);
  809 + download(newMediaServerItem, ssrcInfo, deviceId, channelId, startTime, endTime, downloadSpeed, infoCallBack, playBackCallback);
806 810 }
807 811  
  812 +
808 813 @Override
809   - public DeferredResult<WVPResult<StreamInfo>> download(MediaServerItem mediaServerItem, SSRCInfo ssrcInfo, String deviceId, String channelId, String startTime, String endTime, int downloadSpeed, InviteStreamCallback infoCallBack, PlayBackCallback hookCallBack) {
  814 + public void download(MediaServerItem mediaServerItem, SSRCInfo ssrcInfo, String deviceId, String channelId, String startTime, String endTime, int downloadSpeed, InviteStreamCallback infoCallBack, PlayBackCallback hookCallBack) {
810 815 if (mediaServerItem == null || ssrcInfo == null) {
811   - return null;
  816 + return;
812 817 }
813   - String uuid = UUID.randomUUID().toString();
814   - String key = DeferredResultHolder.CALLBACK_CMD_DOWNLOAD + deviceId + channelId;
815   - DeferredResult<WVPResult<StreamInfo>> result = new DeferredResult<>(30000L);
  818 +
816 819 Device device = storager.queryVideoDevice(deviceId);
817 820 if (device == null) {
818 821 throw new ControllerException(ErrorCode.ERROR400.getCode(), "设备:" + deviceId + "不存在");
819 822 }
820   -
821   - resultHolder.put(key, uuid, result);
822   - RequestMessage requestMessage = new RequestMessage();
823   - requestMessage.setId(uuid);
824   - requestMessage.setKey(key);
825   - WVPResult<StreamInfo> wvpResult = new WVPResult<>();
826   - requestMessage.setData(wvpResult);
827   - PlayBackResult<RequestMessage> downloadResult = new PlayBackResult<>();
828   - downloadResult.setData(requestMessage);
  823 + PlayBackResult<StreamInfo> downloadResult = new PlayBackResult<>();
829 824  
830 825 String downLoadTimeOutTaskKey = UUID.randomUUID().toString();
831 826 dynamicTask.startDelay(downLoadTimeOutTaskKey, () -> {
832 827 logger.warn(String.format("录像下载请求超时,deviceId:%s ,channelId:%s", deviceId, channelId));
833   - wvpResult.setCode(ErrorCode.ERROR100.getCode());
834   - wvpResult.setMsg("录像下载请求超时");
835 828 downloadResult.setCode(ErrorCode.ERROR100.getCode());
836 829 downloadResult.setMsg("录像下载请求超时");
837 830 hookCallBack.call(downloadResult);
... ... @@ -846,16 +839,12 @@ public class PlayServiceImpl implements IPlayService {
846 839 mediaServerService.closeRTPServer(mediaServerItem, ssrcInfo.getStream());
847 840 streamSession.remove(deviceId, channelId, ssrcInfo.getStream());
848 841 }
849   - // 回复之前所有的点播请求
850   - hookCallBack.call(downloadResult);
851 842 }, userSetting.getPlayTimeout());
852 843  
853 844 SipSubscribe.Event errorEvent = event -> {
854 845 dynamicTask.stop(downLoadTimeOutTaskKey);
855 846 downloadResult.setCode(ErrorCode.ERROR100.getCode());
856 847 downloadResult.setMsg(String.format("录像下载失败, 错误码: %s, %s", event.statusCode, event.msg));
857   - wvpResult.setCode(ErrorCode.ERROR100.getCode());
858   - wvpResult.setMsg(String.format("录像下载失败, 错误码: %s, %s", event.statusCode, event.msg));
859 848 downloadResult.setEvent(event);
860 849 hookCallBack.call(downloadResult);
861 850 streamSession.remove(device.getDeviceId(), channelId, ssrcInfo.getStream());
... ... @@ -870,11 +859,9 @@ public class PlayServiceImpl implements IPlayService {
870 859 streamInfo.setStartTime(startTime);
871 860 streamInfo.setEndTime(endTime);
872 861 redisCatchStorage.startDownload(streamInfo, inviteStreamInfo.getCallId());
873   - wvpResult.setCode(ErrorCode.SUCCESS.getCode());
874   - wvpResult.setMsg(ErrorCode.SUCCESS.getMsg());
875   - wvpResult.setData(streamInfo);
876 862 downloadResult.setCode(ErrorCode.SUCCESS.getCode());
877 863 downloadResult.setMsg(ErrorCode.SUCCESS.getMsg());
  864 + downloadResult.setData(streamInfo);
878 865 downloadResult.setMediaServerItem(inviteStreamInfo.getMediaServerItem());
879 866 downloadResult.setResponse(inviteStreamInfo.getResponse());
880 867 hookCallBack.call(downloadResult);
... ... @@ -886,7 +873,6 @@ public class PlayServiceImpl implements IPlayService {
886 873 eventResult.msg = "命令发送失败";
887 874 errorEvent.response(eventResult);
888 875 }
889   - return result;
890 876 }
891 877  
892 878 @Override
... ... @@ -906,7 +892,10 @@ public class PlayServiceImpl implements IPlayService {
906 892 }
907 893 if (mediaServerItem.getRecordAssistPort() > 0) {
908 894 JSONObject jsonObject = assistRESTfulUtils.fileDuration(mediaServerItem, streamInfo.getApp(), streamInfo.getStream(), null);
909   - if (jsonObject != null && jsonObject.getInteger("code") == 0) {
  895 + if (jsonObject == null) {
  896 + throw new ControllerException(ErrorCode.ERROR100.getCode(), "连接Assist服务失败");
  897 + }
  898 + if (jsonObject.getInteger("code") == 0) {
910 899 long duration = jsonObject.getLong("data");
911 900  
912 901 if (duration == 0) {
... ...
src/main/java/com/genersoft/iot/vmp/service/impl/StreamProxyServiceImpl.java
... ... @@ -90,7 +90,7 @@ public class StreamProxyServiceImpl implements IStreamProxyService {
90 90 public StreamInfo save(StreamProxyItem param) {
91 91 MediaServerItem mediaInfo;
92 92 if (ObjectUtils.isEmpty(param.getMediaServerId()) || "auto".equals(param.getMediaServerId())){
93   - mediaInfo = mediaServerService.getMediaServerForMinimumLoad();
  93 + mediaInfo = mediaServerService.getMediaServerForMinimumLoad(null);
94 94 }else {
95 95 mediaInfo = mediaServerService.getOne(param.getMediaServerId());
96 96 }
... ...
src/main/java/com/genersoft/iot/vmp/service/redisMsg/RedisGbPlayMsgListener.java
... ... @@ -117,7 +117,7 @@ public class RedisGbPlayMsgListener implements MessageListener {
117 117 Message msg = taskQueue.poll();
118 118 try {
119 119 JSONObject msgJSON = JSON.parseObject(msg.getBody(), JSONObject.class);
120   - WvpRedisMsg wvpRedisMsg = JSON.toJavaObject(msgJSON, WvpRedisMsg.class);
  120 + WvpRedisMsg wvpRedisMsg = JSON.to(WvpRedisMsg.class, msgJSON);
121 121 if (!userSetting.getServerId().equals(wvpRedisMsg.getToId())) {
122 122 continue;
123 123 }
... ... @@ -126,11 +126,11 @@ public class RedisGbPlayMsgListener implements MessageListener {
126 126  
127 127 switch (wvpRedisMsg.getCmd()){
128 128 case WvpRedisMsgCmd.GET_SEND_ITEM:
129   - RequestSendItemMsg content = JSON.toJavaObject((JSONObject)wvpRedisMsg.getContent(), RequestSendItemMsg.class);
  129 + RequestSendItemMsg content = JSON.to(RequestSendItemMsg.class, wvpRedisMsg.getContent());
130 130 requestSendItemMsgHand(content, wvpRedisMsg.getFromId(), wvpRedisMsg.getSerial());
131 131 break;
132 132 case WvpRedisMsgCmd.REQUEST_PUSH_STREAM:
133   - RequestPushStreamMsg param = JSON.toJavaObject((JSONObject)wvpRedisMsg.getContent(), RequestPushStreamMsg.class);;
  133 + RequestPushStreamMsg param = JSON.to(RequestPushStreamMsg.class, wvpRedisMsg.getContent());
134 134 requestPushStreamMsgHand(param, wvpRedisMsg.getFromId(), wvpRedisMsg.getSerial());
135 135 break;
136 136 default:
... ... @@ -142,12 +142,12 @@ public class RedisGbPlayMsgListener implements MessageListener {
142 142 switch (wvpRedisMsg.getCmd()){
143 143 case WvpRedisMsgCmd.GET_SEND_ITEM:
144 144  
145   - WVPResult content = JSON.toJavaObject((JSONObject)wvpRedisMsg.getContent(), WVPResult.class);
  145 + WVPResult content = JSON.to(WVPResult.class, wvpRedisMsg.getContent());
146 146  
147 147 String key = wvpRedisMsg.getSerial();
148 148 switch (content.getCode()) {
149 149 case 0:
150   - ResponseSendItemMsg responseSendItemMsg =JSON.toJavaObject((JSONObject)content.getData(), ResponseSendItemMsg.class);
  150 + ResponseSendItemMsg responseSendItemMsg =JSON.to(ResponseSendItemMsg.class, content.getData());
151 151 PlayMsgCallback playMsgCallback = callbacks.get(key);
152 152 if (playMsgCallback != null) {
153 153 callbacksForError.remove(key);
... ... @@ -172,7 +172,7 @@ public class RedisGbPlayMsgListener implements MessageListener {
172 172 }
173 173 break;
174 174 case WvpRedisMsgCmd.REQUEST_PUSH_STREAM:
175   - WVPResult wvpResult = JSON.toJavaObject((JSONObject)wvpRedisMsg.getContent(), WVPResult.class);
  175 + WVPResult wvpResult = JSON.to(WVPResult.class, wvpRedisMsg.getContent());
176 176 String serial = wvpRedisMsg.getSerial();
177 177 switch (wvpResult.getCode()) {
178 178 case 0:
... ... @@ -199,6 +199,7 @@ public class RedisGbPlayMsgListener implements MessageListener {
199 199 default:
200 200 break;
201 201 }
  202 +
202 203 }
203 204 }catch (Exception e) {
204 205 logger.warn("[RedisGbPlayMsg] 发现未处理的异常, {}",e.getMessage());
... ...
src/main/java/com/genersoft/iot/vmp/storager/IVideoManagerStorage.java
... ... @@ -59,7 +59,7 @@ public interface IVideoManagerStorage {
59 59 */
60 60 public PageInfo queryChannelsByDeviceId(String deviceId, String query, Boolean hasSubChannel, Boolean online, Boolean catalogUnderDevice, int page, int count);
61 61  
62   - public List<DeviceChannel> queryChannelsByDeviceIdWithStartAndLimit(String deviceId, String query, Boolean hasSubChannel, Boolean online, int start, int limit);
  62 + public List<DeviceChannel> queryChannelsByDeviceIdWithStartAndLimit(String deviceId, String query, Boolean hasSubChannel, Boolean online, int start, int limit,List<String> channelIds);
63 63  
64 64  
65 65 /**
... ... @@ -68,7 +68,7 @@ public interface IVideoManagerStorage {
68 68 * @param deviceId 设备ID
69 69 * @return
70 70 */
71   - public List<DeviceChannel> queryChannelsByDeviceId(String deviceId);
  71 + public List<DeviceChannel> queryChannelsByDeviceId(String deviceId,Boolean online,List<String> channelIds);
72 72 public List<DeviceChannel> queryOnlineChannelsByDeviceId(String deviceId);
73 73  
74 74 /**
... ... @@ -91,14 +91,14 @@ public interface IVideoManagerStorage {
91 91 * @param count 每页数量
92 92 * @return List<Device> 设备对象数组
93 93 */
94   - public PageInfo<Device> queryVideoDeviceList(int page, int count);
  94 + public PageInfo<Device> queryVideoDeviceList(int page, int count,Boolean online);
95 95  
96 96 /**
97 97 * 获取多个设备
98 98 *
99 99 * @return List<Device> 设备对象数组
100 100 */
101   - public List<Device> queryVideoDeviceList();
  101 + public List<Device> queryVideoDeviceList(Boolean online);
102 102  
103 103  
104 104  
... ...
src/main/java/com/genersoft/iot/vmp/storager/dao/DeviceAlarmMapper.java
... ... @@ -16,19 +16,19 @@ import java.util.List;
16 16 public interface DeviceAlarmMapper {
17 17  
18 18 @Insert("INSERT INTO device_alarm (deviceId, channelId, alarmPriority, alarmMethod, alarmTime, alarmDescription, longitude, latitude, alarmType , createTime ) " +
19   - "VALUES ('${deviceId}', '${channelId}', '${alarmPriority}', '${alarmMethod}', '${alarmTime}', '${alarmDescription}', ${longitude}, ${latitude}, '${alarmType}', '${createTime}')")
  19 + "VALUES (#{deviceId}, #{channelId}, #{alarmPriority}, #{alarmMethod}, #{alarmTime}, #{alarmDescription}, #{longitude}, #{latitude}, #{alarmType}, #{createTime})")
20 20 int add(DeviceAlarm alarm);
21 21  
22 22  
23 23 @Select(value = {" <script>" +
24 24 " SELECT * FROM device_alarm " +
25 25 " WHERE 1=1 " +
26   - " <if test=\"deviceId != null\" > AND deviceId = '${deviceId}'</if>" +
27   - " <if test=\"alarmPriority != null\" > AND alarmPriority = '${alarmPriority}' </if>" +
28   - " <if test=\"alarmMethod != null\" > AND alarmMethod = '${alarmMethod}' </if>" +
29   - " <if test=\"alarmType != null\" > AND alarmType = '${alarmType}' </if>" +
30   - " <if test=\"startTime != null\" > AND alarmTime &gt;= '${startTime}' </if>" +
31   - " <if test=\"endTime != null\" > AND alarmTime &lt;= '${endTime}' </if>" +
  26 + " <if test=\"deviceId != null\" > AND deviceId = #{deviceId}</if>" +
  27 + " <if test=\"alarmPriority != null\" > AND alarmPriority = #{alarmPriority} </if>" +
  28 + " <if test=\"alarmMethod != null\" > AND alarmMethod = #{alarmMethod} </if>" +
  29 + " <if test=\"alarmType != null\" > AND alarmType = #{alarmType} </if>" +
  30 + " <if test=\"startTime != null\" > AND alarmTime &gt;= #{startTime} </if>" +
  31 + " <if test=\"endTime != null\" > AND alarmTime &lt;= #{endTime} </if>" +
32 32 " ORDER BY alarmTime ASC " +
33 33 " </script>"})
34 34 List<DeviceAlarm> query(String deviceId, String alarmPriority, String alarmMethod,
... ... @@ -38,10 +38,10 @@ public interface DeviceAlarmMapper {
38 38 @Delete(" <script>" +
39 39 "DELETE FROM device_alarm WHERE 1=1 " +
40 40 " <if test=\"deviceIdList != null and id == null \" > AND deviceId in " +
41   - "<foreach collection='deviceIdList' item='item' open='(' separator=',' close=')' > '${item}'</foreach>" +
  41 + "<foreach collection='deviceIdList' item='item' open='(' separator=',' close=')' > #{item}</foreach>" +
42 42 "</if>" +
43   - " <if test=\"time != null and id == null \" > AND alarmTime &lt;= '${time}'</if>" +
44   - " <if test=\"id != null\" > AND id = ${id}</if>" +
  43 + " <if test=\"time != null and id == null \" > AND alarmTime &lt;= #{time}</if>" +
  44 + " <if test=\"id != null\" > AND id = #{id}</if>" +
45 45 " </script>"
46 46 )
47 47 int clearAlarmBeforeTime(Integer id, List<String> deviceIdList, String time);
... ...
src/main/java/com/genersoft/iot/vmp/storager/dao/DeviceChannelMapper.java
... ... @@ -20,46 +20,46 @@ public interface DeviceChannelMapper {
20 20 "address, parental, parentId, safetyWay, registerWay, certNum, certifiable, errCode, secrecy, " +
21 21 "ipAddress, port, password, PTZType, status, streamId, longitude, latitude, longitudeGcj02, latitudeGcj02, " +
22 22 "longitudeWgs84, latitudeWgs84, hasAudio, createTime, updateTime, businessGroupId, gpsTime) " +
23   - "VALUES ('${channelId}', '${deviceId}', '${name}', '${manufacture}', '${model}', '${owner}', '${civilCode}', '${block}'," +
24   - "'${address}', ${parental}, '${parentId}', ${safetyWay}, ${registerWay}, '${certNum}', ${certifiable}, ${errCode}, '${secrecy}', " +
25   - "'${ipAddress}', ${port}, '${password}', ${PTZType}, ${status}, '${streamId}', ${longitude}, ${latitude}, ${longitudeGcj02}, " +
26   - "${latitudeGcj02}, ${longitudeWgs84}, ${latitudeWgs84}, ${hasAudio}, '${createTime}', '${updateTime}', '${businessGroupId}', '${gpsTime}')")
  23 + "VALUES (#{channelId}, #{deviceId}, #{name}, #{manufacture}, #{model}, #{owner}, #{civilCode}, #{block}," +
  24 + "#{address}, #{parental}, #{parentId}, #{safetyWay}, #{registerWay}, #{certNum}, #{certifiable}, #{errCode}, #{secrecy}, " +
  25 + "#{ipAddress}, #{port}, #{password}, #{PTZType}, #{status}, #{streamId}, #{longitude}, #{latitude}, #{longitudeGcj02}, " +
  26 + "#{latitudeGcj02}, #{longitudeWgs84}, #{latitudeWgs84}, #{hasAudio}, #{createTime}, #{updateTime}, #{businessGroupId}, #{gpsTime})")
27 27 int add(DeviceChannel channel);
28 28  
29 29 @Update(value = {" <script>" +
30 30 "UPDATE device_channel " +
31   - "SET updateTime='${updateTime}'" +
32   - "<if test='name != null'>, name='${name}'</if>" +
33   - "<if test='manufacture != null'>, manufacture='${manufacture}'</if>" +
34   - "<if test='model != null'>, model='${model}'</if>" +
35   - "<if test='owner != null'>, owner='${owner}'</if>" +
36   - "<if test='civilCode != null'>, civilCode='${civilCode}'</if>" +
37   - "<if test='block != null'>, block='${block}'</if>" +
38   - "<if test='address != null'>, address='${address}'</if>" +
39   - "<if test='parental != null'>, parental=${parental}</if>" +
40   - "<if test='parentId != null'>, parentId='${parentId}'</if>" +
41   - "<if test='safetyWay != null'>, safetyWay=${safetyWay}</if>" +
42   - "<if test='registerWay != null'>, registerWay=${registerWay}</if>" +
43   - "<if test='certNum != null'>, certNum='${certNum}'</if>" +
44   - "<if test='certifiable != null'>, certifiable=${certifiable}</if>" +
45   - "<if test='errCode != null'>, errCode=${errCode}</if>" +
46   - "<if test='secrecy != null'>, secrecy='${secrecy}'</if>" +
47   - "<if test='ipAddress != null'>, ipAddress='${ipAddress}'</if>" +
48   - "<if test='port != null'>, port=${port}</if>" +
49   - "<if test='password != null'>, password='${password}'</if>" +
50   - "<if test='PTZType != null'>, PTZType=${PTZType}</if>" +
51   - "<if test='status != null'>, status='${status}'</if>" +
52   - "<if test='streamId != null'>, streamId='${streamId}'</if>" +
53   - "<if test='hasAudio != null'>, hasAudio=${hasAudio}</if>" +
54   - "<if test='longitude != null'>, longitude=${longitude}</if>" +
55   - "<if test='latitude != null'>, latitude=${latitude}</if>" +
56   - "<if test='longitudeGcj02 != null'>, longitudeGcj02=${longitudeGcj02}</if>" +
57   - "<if test='latitudeGcj02 != null'>, latitudeGcj02=${latitudeGcj02}</if>" +
58   - "<if test='longitudeWgs84 != null'>, longitudeWgs84=${longitudeWgs84}</if>" +
59   - "<if test='latitudeWgs84 != null'>, latitudeWgs84=${latitudeWgs84}</if>" +
  31 + "SET updateTime=#{updateTime}" +
  32 + "<if test='name != null'>, name=#{name}</if>" +
  33 + "<if test='manufacture != null'>, manufacture=#{manufacture}</if>" +
  34 + "<if test='model != null'>, model=#{model}</if>" +
  35 + "<if test='owner != null'>, owner=#{owner}</if>" +
  36 + "<if test='civilCode != null'>, civilCode=#{civilCode}</if>" +
  37 + "<if test='block != null'>, block=#{block}</if>" +
  38 + "<if test='address != null'>, address=#{address}</if>" +
  39 + "<if test='parental != null'>, parental=#{parental}</if>" +
  40 + "<if test='parentId != null'>, parentId=#{parentId}</if>" +
  41 + "<if test='safetyWay != null'>, safetyWay=#{safetyWay}</if>" +
  42 + "<if test='registerWay != null'>, registerWay=#{registerWay}</if>" +
  43 + "<if test='certNum != null'>, certNum=#{certNum}</if>" +
  44 + "<if test='certifiable != null'>, certifiable=#{certifiable}</if>" +
  45 + "<if test='errCode != null'>, errCode=#{errCode}</if>" +
  46 + "<if test='secrecy != null'>, secrecy=#{secrecy}</if>" +
  47 + "<if test='ipAddress != null'>, ipAddress=#{ipAddress}</if>" +
  48 + "<if test='port != null'>, port=#{port}</if>" +
  49 + "<if test='password != null'>, password=#{password}</if>" +
  50 + "<if test='PTZType != null'>, PTZType=#{PTZType}</if>" +
  51 + "<if test='status != null'>, status=#{status}</if>" +
  52 + "<if test='streamId != null'>, streamId=#{streamId}</if>" +
  53 + "<if test='hasAudio != null'>, hasAudio=#{hasAudio}</if>" +
  54 + "<if test='longitude != null'>, longitude=#{longitude}</if>" +
  55 + "<if test='latitude != null'>, latitude=#{latitude}</if>" +
  56 + "<if test='longitudeGcj02 != null'>, longitudeGcj02=#{longitudeGcj02}</if>" +
  57 + "<if test='latitudeGcj02 != null'>, latitudeGcj02=#{latitudeGcj02}</if>" +
  58 + "<if test='longitudeWgs84 != null'>, longitudeWgs84=#{longitudeWgs84}</if>" +
  59 + "<if test='latitudeWgs84 != null'>, latitudeWgs84=#{latitudeWgs84}</if>" +
60 60 "<if test='businessGroupId != null'>, businessGroupId=#{businessGroupId}</if>" +
61 61 "<if test='gpsTime != null'>, gpsTime=#{gpsTime}</if>" +
62   - "WHERE deviceId='${deviceId}' AND channelId='${channelId}'"+
  62 + "WHERE deviceId=#{deviceId} AND channelId=#{channelId}"+
63 63 " </script>"})
64 64 int update(DeviceChannel channel);
65 65  
... ... @@ -70,15 +70,18 @@ public interface DeviceChannelMapper {
70 70 "device_channel dc " +
71 71 "WHERE " +
72 72 "dc.deviceId = #{deviceId} " +
73   - " <if test='query != null'> AND (dc.channelId LIKE '%${query}%' OR dc.name LIKE '%${query}%' OR dc.name LIKE '%${query}%')</if> " +
  73 +" <if test='query != null'> AND (dc.channelId LIKE concat('%',#{query},'%') OR dc.name LIKE concat('%',#{query},'%') OR dc.name LIKE concat('%',#{query},'%'))</if> " +
74 74 " <if test='parentChannelId != null'> AND (dc.parentId=#{parentChannelId} OR dc.civilCode = #{parentChannelId}) </if> " +
75 75 " <if test='online == true' > AND dc.status=1</if>" +
76 76 " <if test='online == false' > AND dc.status=0</if>" +
77 77 " <if test='hasSubChannel == true' > AND dc.subCount > 0 </if>" +
78 78 " <if test='hasSubChannel == false' > AND dc.subCount = 0 </if>" +
  79 + "<if test='channelIds != null'> AND dc.channelId in <foreach item='item' index='index' collection='channelIds' open='(' separator=',' close=')'>" +
  80 + "#{item} " +
  81 + "</foreach> </if>" +
79 82 "ORDER BY dc.channelId " +
80 83 " </script>"})
81   - List<DeviceChannel> queryChannels(String deviceId, String parentChannelId, String query, Boolean hasSubChannel, Boolean online);
  84 + List<DeviceChannel> queryChannels(String deviceId, String parentChannelId, String query, Boolean hasSubChannel, Boolean online,List<String> channelIds);
82 85  
83 86 @Select("SELECT * FROM device_channel WHERE deviceId=#{deviceId} AND channelId=#{channelId}")
84 87 DeviceChannel queryChannel(String deviceId, String channelId);
... ... @@ -110,7 +113,7 @@ public interface DeviceChannelMapper {
110 113 " LEFT JOIN device de ON dc.deviceId = de.deviceId " +
111 114 " LEFT JOIN platform_gb_channel pgc on pgc.deviceChannelId = dc.id " +
112 115 " WHERE 1=1 " +
113   - " <if test='query != null'> AND (dc.channelId LIKE '%${query}%' OR dc.name LIKE '%${query}%' OR dc.name LIKE '%${query}%')</if> " +
  116 + " <if test='query != null'> AND (dc.channelId LIKE concat('%',#{query},'%') OR dc.name LIKE concat('%',#{query},'%') OR dc.name LIKE concat('%',#{query},'%'))</if> " +
114 117 " <if test='online == true' > AND dc.status=1</if> " +
115 118 " <if test='online == false' > AND dc.status=0</if> " +
116 119 " <if test='hasSubChannel!= null and hasSubChannel == true' > AND dc.subCount > 0</if> " +
... ... @@ -151,14 +154,14 @@ public interface DeviceChannelMapper {
151 154 " longitudeWgs84, latitudeWgs84, hasAudio, createTime, updateTime, businessGroupId, gpsTime) " +
152 155 "values " +
153 156 "<foreach collection='addChannels' index='index' item='item' separator=','> " +
154   - "('${item.channelId}', '${item.deviceId}', '${item.name}', '${item.manufacture}', '${item.model}', " +
155   - "'${item.owner}', '${item.civilCode}', '${item.block}',${item.subCount}," +
156   - "'${item.address}', ${item.parental}, '${item.parentId}', ${item.safetyWay}, ${item.registerWay}, " +
157   - "'${item.certNum}', ${item.certifiable}, ${item.errCode}, '${item.secrecy}', " +
158   - "'${item.ipAddress}', ${item.port}, '${item.password}', ${item.PTZType}, ${item.status}, " +
159   - "'${item.streamId}', ${item.longitude}, ${item.latitude},${item.longitudeGcj02}, " +
160   - "${item.latitudeGcj02},${item.longitudeWgs84}, ${item.latitudeWgs84}, ${item.hasAudio},'${item.createTime}', '${item.updateTime}', " +
161   - "'${item.businessGroupId}', '${item.gpsTime}') " +
  157 + "(#{item.channelId}, #{item.deviceId}, #{item.name}, #{item.manufacture}, #{item.model}, " +
  158 + "#{item.owner}, #{item.civilCode}, #{item.block},#{item.subCount}," +
  159 + "#{item.address}, #{item.parental}, #{item.parentId}, #{item.safetyWay}, #{item.registerWay}, " +
  160 + "#{item.certNum}, #{item.certifiable}, #{item.errCode}, #{item.secrecy}, " +
  161 + "#{item.ipAddress}, #{item.port}, #{item.password}, #{item.PTZType}, #{item.status}, " +
  162 + "#{item.streamId}, #{item.longitude}, #{item.latitude},#{item.longitudeGcj02}, " +
  163 + "#{item.latitudeGcj02},#{item.longitudeWgs84}, #{item.latitudeWgs84}, #{item.hasAudio}, now(), now(), " +
  164 + "#{item.businessGroupId}, #{item.gpsTime}) " +
162 165 "</foreach> " +
163 166 "ON DUPLICATE KEY UPDATE " +
164 167 "updateTime=VALUES(updateTime), " +
... ... @@ -203,39 +206,39 @@ public interface DeviceChannelMapper {
203 206 "<foreach collection='updateChannels' item='item' separator=';'>" +
204 207 " UPDATE" +
205 208 " device_channel" +
206   - " SET updateTime='${item.updateTime}'" +
207   - "<if test='item.name != null'>, name='${item.name}'</if>" +
208   - "<if test='item.manufacture != null'>, manufacture='${item.manufacture}'</if>" +
209   - "<if test='item.model != null'>, model='${item.model}'</if>" +
210   - "<if test='item.owner != null'>, owner='${item.owner}'</if>" +
211   - "<if test='item.civilCode != null'>, civilCode='${item.civilCode}'</if>" +
212   - "<if test='item.block != null'>, block='${item.block}'</if>" +
213   - "<if test='item.subCount != null'>, block=${item.subCount}</if>" +
214   - "<if test='item.address != null'>, address='${item.address}'</if>" +
215   - "<if test='item.parental != null'>, parental=${item.parental}</if>" +
216   - "<if test='item.parentId != null'>, parentId='${item.parentId}'</if>" +
217   - "<if test='item.safetyWay != null'>, safetyWay=${item.safetyWay}</if>" +
218   - "<if test='item.registerWay != null'>, registerWay=${item.registerWay}</if>" +
219   - "<if test='item.certNum != null'>, certNum='${item.certNum}'</if>" +
220   - "<if test='item.certifiable != null'>, certifiable=${item.certifiable}</if>" +
221   - "<if test='item.errCode != null'>, errCode=${item.errCode}</if>" +
222   - "<if test='item.secrecy != null'>, secrecy='${item.secrecy}'</if>" +
223   - "<if test='item.ipAddress != null'>, ipAddress='${item.ipAddress}'</if>" +
224   - "<if test='item.port != null'>, port=${item.port}</if>" +
225   - "<if test='item.password != null'>, password='${item.password}'</if>" +
226   - "<if test='item.PTZType != null'>, PTZType=${item.PTZType}</if>" +
227   - "<if test='item.status != null'>, status='${item.status}'</if>" +
228   - "<if test='item.streamId != null'>, streamId='${item.streamId}'</if>" +
229   - "<if test='item.hasAudio != null'>, hasAudio=${item.hasAudio}</if>" +
230   - "<if test='item.longitude != null'>, longitude=${item.longitude}</if>" +
231   - "<if test='item.latitude != null'>, latitude=${item.latitude}</if>" +
232   - "<if test='item.longitudeGcj02 != null'>, longitudeGcj02=${item.longitudeGcj02}</if>" +
233   - "<if test='item.latitudeGcj02 != null'>, latitudeGcj02=${item.latitudeGcj02}</if>" +
234   - "<if test='item.longitudeWgs84 != null'>, longitudeWgs84=${item.longitudeWgs84}</if>" +
235   - "<if test='item.latitudeWgs84 != null'>, latitudeWgs84=${item.latitudeWgs84}</if>" +
  209 + " SET updateTime=#{item.updateTime}" +
  210 + "<if test='item.name != null'>, name=#{item.name}</if>" +
  211 + "<if test='item.manufacture != null'>, manufacture=#{item.manufacture}</if>" +
  212 + "<if test='item.model != null'>, model=#{item.model}</if>" +
  213 + "<if test='item.owner != null'>, owner=#{item.owner}</if>" +
  214 + "<if test='item.civilCode != null'>, civilCode=#{item.civilCode}</if>" +
  215 + "<if test='item.block != null'>, block=#{item.block}</if>" +
  216 + "<if test='item.subCount != null'>, block=#{item.subCount}</if>" +
  217 + "<if test='item.address != null'>, address=#{item.address}</if>" +
  218 + "<if test='item.parental != null'>, parental=#{item.parental}</if>" +
  219 + "<if test='item.parentId != null'>, parentId=#{item.parentId}</if>" +
  220 + "<if test='item.safetyWay != null'>, safetyWay=#{item.safetyWay}</if>" +
  221 + "<if test='item.registerWay != null'>, registerWay=#{item.registerWay}</if>" +
  222 + "<if test='item.certNum != null'>, certNum=#{item.certNum}</if>" +
  223 + "<if test='item.certifiable != null'>, certifiable=#{item.certifiable}</if>" +
  224 + "<if test='item.errCode != null'>, errCode=#{item.errCode}</if>" +
  225 + "<if test='item.secrecy != null'>, secrecy=#{item.secrecy}</if>" +
  226 + "<if test='item.ipAddress != null'>, ipAddress=#{item.ipAddress}</if>" +
  227 + "<if test='item.port != null'>, port=#{item.port}</if>" +
  228 + "<if test='item.password != null'>, password=#{item.password}</if>" +
  229 + "<if test='item.PTZType != null'>, PTZType=#{item.PTZType}</if>" +
  230 + "<if test='item.status != null'>, status=#{item.status}</if>" +
  231 + "<if test='item.streamId != null'>, streamId=#{item.streamId}</if>" +
  232 + "<if test='item.hasAudio != null'>, hasAudio=#{item.hasAudio}</if>" +
  233 + "<if test='item.longitude != null'>, longitude=#{item.longitude}</if>" +
  234 + "<if test='item.latitude != null'>, latitude=#{item.latitude}</if>" +
  235 + "<if test='item.longitudeGcj02 != null'>, longitudeGcj02=#{item.longitudeGcj02}</if>" +
  236 + "<if test='item.latitudeGcj02 != null'>, latitudeGcj02=#{item.latitudeGcj02}</if>" +
  237 + "<if test='item.longitudeWgs84 != null'>, longitudeWgs84=#{item.longitudeWgs84}</if>" +
  238 + "<if test='item.latitudeWgs84 != null'>, latitudeWgs84=#{item.latitudeWgs84}</if>" +
236 239 "<if test='item.businessGroupId != null'>, businessGroupId=#{item.businessGroupId}</if>" +
237 240 "<if test='item.gpsTime != null'>, gpsTime=#{item.gpsTime}</if>" +
238   - "WHERE deviceId='${item.deviceId}' AND channelId='${item.channelId}'"+
  241 + "WHERE deviceId=#{item.deviceId} AND channelId=#{item.channelId}"+
239 242 "</foreach>" +
240 243 "</script>"})
241 244 int batchUpdate(List<DeviceChannel> updateChannels);
... ... @@ -248,17 +251,20 @@ public interface DeviceChannelMapper {
248 251 "device_channel dc1 " +
249 252 "WHERE " +
250 253 "dc1.deviceId = #{deviceId} " +
251   - " <if test='query != null'> AND (dc1.channelId LIKE '%${query}%' OR dc1.name LIKE '%${query}%' OR dc1.name LIKE '%${query}%')</if> " +
  254 + " <if test='query != null'> AND (dc1.channelId LIKE concat('%',#{query},'%') OR dc1.name LIKE concat('%',#{query},'%') OR dc1.name LIKE concat('%',#{query},'%'))</if> " +
252 255 " <if test='parentChannelId != null'> AND dc1.parentId=#{parentChannelId} </if> " +
253 256 " <if test='online == true' > AND dc1.status=1</if>" +
254 257 " <if test='online == false' > AND dc1.status=0</if>" +
255 258 " <if test='hasSubChannel == true' > AND dc1.subCount >0</if>" +
256 259 " <if test='hasSubChannel == false' > AND dc1.subCount=0</if>" +
  260 + "<if test='channelIds != null'> AND dc1.channelId in <foreach item='item' index='index' collection='channelIds' open='(' separator=',' close=')'>" +
  261 + "#{item} " +
  262 + "</foreach> </if>" +
257 263 "ORDER BY dc1.channelId ASC " +
258 264 "Limit #{limit} OFFSET #{start}" +
259 265 " </script>"})
260 266 List<DeviceChannel> queryChannelsByDeviceIdWithStartAndLimit(String deviceId, String parentChannelId, String query,
261   - Boolean hasSubChannel, Boolean online, int start, int limit);
  267 + Boolean hasSubChannel, Boolean online, int start, int limit,List<String> channelIds);
262 268  
263 269 @Select("SELECT * FROM device_channel WHERE deviceId=#{deviceId} AND status=1")
264 270 List<DeviceChannel> queryOnlineChannelsByDeviceId(String deviceId);
... ... @@ -286,13 +292,13 @@ public interface DeviceChannelMapper {
286 292 @Update(value = {" <script>" +
287 293 "UPDATE device_channel " +
288 294 "SET " +
289   - "latitude=${latitude}, " +
290   - "longitude=${longitude}, " +
291   - "longitudeGcj02=${longitudeGcj02}, " +
292   - "latitudeGcj02=${latitudeGcj02}, " +
293   - "longitudeWgs84=${longitudeWgs84}, " +
294   - "latitudeWgs84=${latitudeWgs84}, " +
295   - "gpsTime='${gpsTime}' " +
  295 + "latitude=#{latitude}, " +
  296 + "longitude=#{longitude}, " +
  297 + "longitudeGcj02=#{longitudeGcj02}, " +
  298 + "latitudeGcj02=#{latitudeGcj02}, " +
  299 + "longitudeWgs84=#{longitudeWgs84}, " +
  300 + "latitudeWgs84=#{latitudeWgs84}, " +
  301 + "gpsTime=#{gpsTime} " +
296 302 "WHERE deviceId=#{deviceId} " +
297 303 " <if test='channelId != null' > AND channelId=#{channelId}</if>" +
298 304 " </script>"})
... ... @@ -309,10 +315,10 @@ public interface DeviceChannelMapper {
309 315 "select * " +
310 316 "from device_channel " +
311 317 "where deviceId=#{deviceId}" +
312   - " <if test='parentId != null and length != null' > and parentId = #{parentId} or left(channelId, ${parentId.length()}) = #{parentId} and length(channelId)=${length} </if>" +
313   - " <if test='parentId == null and length != null' > and parentId = #{parentId} or length(channelId)=${length} </if>" +
  318 + " <if test='parentId != null and length != null' > and parentId = #{parentId} or left(channelId, #{parentId.length()}) = #{parentId} and length(channelId)=#{length} </if>" +
  319 + " <if test='parentId == null and length != null' > and parentId = #{parentId} or length(channelId)=#{length} </if>" +
314 320 " <if test='parentId == null and length == null' > and parentId = #{parentId} </if>" +
315   - " <if test='parentId != null and length == null' > and parentId = #{parentId} or left(channelId, ${parentId.length()}) = #{parentId} </if>" +
  321 + " <if test='parentId != null and length == null' > and parentId = #{parentId} or left(channelId, #{parentId.length()}) = #{parentId} </if>" +
316 322 " </script>"})
317 323 List<DeviceChannel> getChannelsWithCivilCodeAndLength(String deviceId, String parentId, Integer length);
318 324  
... ...
src/main/java/com/genersoft/iot/vmp/storager/dao/DeviceMapper.java
... ... @@ -61,6 +61,7 @@ public interface DeviceMapper {
61 61 "expires," +
62 62 "registerTime," +
63 63 "keepaliveTime," +
  64 + "keepaliveIntervalTime," +
64 65 "createTime," +
65 66 "updateTime," +
66 67 "charset," +
... ... @@ -88,6 +89,7 @@ public interface DeviceMapper {
88 89 "#{expires}," +
89 90 "#{registerTime}," +
90 91 "#{keepaliveTime}," +
  92 + "#{keepaliveIntervalTime}," +
91 93 "#{createTime}," +
92 94 "#{updateTime}," +
93 95 "#{charset}," +
... ... @@ -104,25 +106,28 @@ public interface DeviceMapper {
104 106  
105 107 @Update(value = {" <script>" +
106 108 "UPDATE device " +
107   - "SET updateTime='${updateTime}'" +
108   - "<if test=\"name != null\">, name='${name}'</if>" +
109   - "<if test=\"manufacturer != null\">, manufacturer='${manufacturer}'</if>" +
110   - "<if test=\"model != null\">, model='${model}'</if>" +
111   - "<if test=\"firmware != null\">, firmware='${firmware}'</if>" +
112   - "<if test=\"transport != null\">, transport='${transport}'</if>" +
113   - "<if test=\"ip != null\">, ip='${ip}'</if>" +
114   - "<if test=\"localIp != null\">, localIp='${localIp}'</if>" +
115   - "<if test=\"port != null\">, port=${port}</if>" +
116   - "<if test=\"hostAddress != null\">, hostAddress='${hostAddress}'</if>" +
117   - "<if test=\"online != null\">, online=${online}</if>" +
118   - "<if test=\"registerTime != null\">, registerTime='${registerTime}'</if>" +
119   - "<if test=\"keepaliveTime != null\">, keepaliveTime='${keepaliveTime}'</if>" +
120   - "<if test=\"expires != null\">, expires=${expires}</if>" +
121   - "WHERE deviceId='${deviceId}'"+
  109 + "SET updateTime=#{updateTime}" +
  110 + "<if test=\"name != null\">, name=#{name}</if>" +
  111 + "<if test=\"manufacturer != null\">, manufacturer=#{manufacturer}</if>" +
  112 + "<if test=\"model != null\">, model=#{model}</if>" +
  113 + "<if test=\"firmware != null\">, firmware=#{firmware}</if>" +
  114 + "<if test=\"transport != null\">, transport=#{transport}</if>" +
  115 + "<if test=\"ip != null\">, ip=#{ip}</if>" +
  116 + "<if test=\"localIp != null\">, localIp=#{localIp}</if>" +
  117 + "<if test=\"port != null\">, port=#{port}</if>" +
  118 + "<if test=\"hostAddress != null\">, hostAddress=#{hostAddress}</if>" +
  119 + "<if test=\"online != null\">, online=#{online}</if>" +
  120 + "<if test=\"registerTime != null\">, registerTime=#{registerTime}</if>" +
  121 + "<if test=\"keepaliveTime != null\">, keepaliveTime=#{keepaliveTime}</if>" +
  122 + "<if test=\"keepaliveIntervalTime != null\">, keepaliveIntervalTime=#{keepaliveIntervalTime}</if>" +
  123 + "<if test=\"expires != null\">, expires=#{expires}</if>" +
  124 + "WHERE deviceId=#{deviceId}"+
122 125 " </script>"})
123 126 int update(Device device);
124 127  
125   - @Select("SELECT " +
  128 + @Select(
  129 + " <script>" +
  130 + "SELECT " +
126 131 "deviceId, " +
127 132 "coalesce(custom_name, name) as name, " +
128 133 "password, " +
... ... @@ -150,8 +155,11 @@ public interface DeviceMapper {
150 155 "geoCoordSys," +
151 156 "treeType," +
152 157 "online," +
153   - "(SELECT count(0) FROM device_channel WHERE deviceId=de.deviceId) as channelCount FROM device de")
154   - List<Device> getDevices();
  158 + "(SELECT count(0) FROM device_channel WHERE deviceId=de.deviceId) as channelCount FROM device de" +
  159 + "<if test=\"online != null\"> where online=${online}</if>"+
  160 + " </script>"
  161 + )
  162 + List<Device> getDevices(Boolean online);
155 163  
156 164 @Delete("DELETE FROM device WHERE deviceId=#{deviceId}")
157 165 int del(String deviceId);
... ... @@ -217,28 +225,28 @@ public interface DeviceMapper {
217 225 "geoCoordSys," +
218 226 "treeType," +
219 227 "online" +
220   - " FROM device WHERE ip = #{host} AND port=${port}")
  228 + " FROM device WHERE ip = #{host} AND port=#{port}")
221 229 Device getDeviceByHostAndPort(String host, int port);
222 230  
223 231 @Update(value = {" <script>" +
224 232 "UPDATE device " +
225   - "SET updateTime='${updateTime}'" +
226   - "<if test=\"name != null\">, custom_name='${name}'</if>" +
227   - "<if test=\"password != null\">, password='${password}'</if>" +
228   - "<if test=\"streamMode != null\">, streamMode='${streamMode}'</if>" +
229   - "<if test=\"ip != null\">, ip='${ip}'</if>" +
230   - "<if test=\"sdpIp != null\">, sdpIp='${sdpIp}'</if>" +
231   - "<if test=\"port != null\">, port=${port}</if>" +
232   - "<if test=\"charset != null\">, charset='${charset}'</if>" +
233   - "<if test=\"subscribeCycleForCatalog != null\">, subscribeCycleForCatalog=${subscribeCycleForCatalog}</if>" +
234   - "<if test=\"subscribeCycleForMobilePosition != null\">, subscribeCycleForMobilePosition=${subscribeCycleForMobilePosition}</if>" +
235   - "<if test=\"mobilePositionSubmissionInterval != null\">, mobilePositionSubmissionInterval=${mobilePositionSubmissionInterval}</if>" +
236   - "<if test=\"subscribeCycleForAlarm != null\">, subscribeCycleForAlarm=${subscribeCycleForAlarm}</if>" +
237   - "<if test=\"ssrcCheck != null\">, ssrcCheck=${ssrcCheck}</if>" +
  233 + "SET updateTime=#{updateTime}" +
  234 + "<if test=\"name != null\">, custom_name=#{name}</if>" +
  235 + "<if test=\"password != null\">, password=#{password}</if>" +
  236 + "<if test=\"streamMode != null\">, streamMode=#{streamMode}</if>" +
  237 + "<if test=\"ip != null\">, ip=#{ip}</if>" +
  238 + "<if test=\"sdpIp != null\">, sdpIp=#{sdpIp}</if>" +
  239 + "<if test=\"port != null\">, port=#{port}</if>" +
  240 + "<if test=\"charset != null\">, charset=#{charset}</if>" +
  241 + "<if test=\"subscribeCycleForCatalog != null\">, subscribeCycleForCatalog=#{subscribeCycleForCatalog}</if>" +
  242 + "<if test=\"subscribeCycleForMobilePosition != null\">, subscribeCycleForMobilePosition=#{subscribeCycleForMobilePosition}</if>" +
  243 + "<if test=\"mobilePositionSubmissionInterval != null\">, mobilePositionSubmissionInterval=#{mobilePositionSubmissionInterval}</if>" +
  244 + "<if test=\"subscribeCycleForAlarm != null\">, subscribeCycleForAlarm=#{subscribeCycleForAlarm}</if>" +
  245 + "<if test=\"ssrcCheck != null\">, ssrcCheck=#{ssrcCheck}</if>" +
238 246 "<if test=\"geoCoordSys != null\">, geoCoordSys=#{geoCoordSys}</if>" +
239 247 "<if test=\"treeType != null\">, treeType=#{treeType}</if>" +
240 248 "<if test=\"mediaServerId != null\">, mediaServerId=#{mediaServerId}</if>" +
241   - "WHERE deviceId='${deviceId}'"+
  249 + "WHERE deviceId=#{deviceId}"+
242 250 " </script>"})
243 251 int updateCustom(Device device);
244 252  
... ...
src/main/java/com/genersoft/iot/vmp/storager/dao/DeviceMobilePositionMapper.java
... ... @@ -9,7 +9,7 @@ import org.apache.ibatis.annotations.*;
9 9 public interface DeviceMobilePositionMapper {
10 10  
11 11 @Insert("INSERT INTO device_mobile_position (deviceId,channelId, deviceName, time, longitude, latitude, altitude, speed, direction, reportSource, longitudeGcj02, latitudeGcj02, longitudeWgs84, latitudeWgs84, createTime) " +
12   - "VALUES ('${deviceId}','${channelId}', '${deviceName}', '${time}', ${longitude}, ${latitude}, ${altitude}, ${speed}, ${direction}, '${reportSource}', ${longitudeGcj02}, ${latitudeGcj02}, ${longitudeWgs84}, ${latitudeWgs84}, '${createTime}')")
  12 + "VALUES (#{deviceId},#{channelId}, #{deviceName}, #{time}, #{longitude}, #{latitude}, #{altitude}, #{speed}, #{direction}, #{reportSource}, #{longitudeGcj02}, #{latitudeGcj02}, #{longitudeWgs84}, #{latitudeWgs84}, #{createTime})")
13 13 int insertNewPosition(MobilePosition mobilePosition);
14 14  
15 15 @Select(value = {" <script>" +
... ...
src/main/java/com/genersoft/iot/vmp/storager/dao/GbStreamMapper.java
... ... @@ -16,9 +16,9 @@ public interface GbStreamMapper {
16 16  
17 17 @Insert("REPLACE INTO gb_stream (app, stream, gbId, name, " +
18 18 "longitude, latitude, streamType, mediaServerId, createTime) VALUES" +
19   - "('${app}', '${stream}', '${gbId}', '${name}', " +
20   - "'${longitude}', '${latitude}', '${streamType}', " +
21   - "'${mediaServerId}', '${createTime}')")
  19 + "(#{app}, #{stream}, #{gbId}, #{name}, " +
  20 + "#{longitude}, #{latitude}, #{streamType}, " +
  21 + "#{mediaServerId}, #{createTime})")
22 22 @Options(useGeneratedKeys = true, keyProperty = "gbStreamId", keyColumn = "gbStreamId")
23 23 int add(GbStream gbStream);
24 24  
... ... @@ -57,7 +57,7 @@ public interface GbStreamMapper {
57 57 "(select pgs.gbStreamId from platform_gb_stream pgs where pgs.platformId = #{platformId} and pgs.catalogId=#{catalogId})</if> " +
58 58 " <if test='catalogId == null'> AND gs.gbStreamId not in" +
59 59 "(select pgs.gbStreamId from platform_gb_stream pgs where pgs.platformId = #{platformId}) </if> " +
60   - " <if test='query != null'> AND (gs.app LIKE '%${query}%' OR gs.stream LIKE '%${query}%' OR gs.gbId LIKE '%${query}%' OR gs.name LIKE '%${query}%')</if> " +
  60 + " <if test='query != null'> AND (gs.app LIKE concat('%',#{query},'%') OR gs.stream LIKE concat('%',#{query},'%') OR gs.gbId LIKE concat('%',#{query},'%') OR gs.name LIKE concat('%',#{query},'%'))</if> " +
61 61 " <if test='mediaServerId != null' > AND gs.mediaServerId=#{mediaServerId} </if>" +
62 62 " order by gs.gbStreamId asc " +
63 63 "</script>")
... ... @@ -71,7 +71,7 @@ public interface GbStreamMapper {
71 71  
72 72 @Select("SELECT gs.*, pgs.platformId as platformId, pgs.catalogId as catalogId FROM gb_stream gs " +
73 73 "LEFT JOIN platform_gb_stream pgs ON gs.gbStreamId = pgs.gbStreamId " +
74   - "WHERE gs.gbId = '${gbId}' AND pgs.platformId = '${platformId}'")
  74 + "WHERE gs.gbId = #{gbId} AND pgs.platformId = #{platformId}")
75 75 GbStream queryStreamInPlatform(String platformId, String gbId);
76 76  
77 77 @Select("<script> "+
... ... @@ -122,9 +122,9 @@ public interface GbStreamMapper {
122 122 "longitude, latitude, streamType, mediaServerId, createTime)" +
123 123 "values " +
124 124 "<foreach collection='subList' index='index' item='item' separator=','> " +
125   - "('${item.app}', '${item.stream}', '${item.gbId}', '${item.name}', " +
126   - "'${item.longitude}', '${item.latitude}', '${item.streamType}', " +
127   - "'${item.mediaServerId}', '${item.createTime}') "+
  125 + "(#{item.app}, #{item.stream}, #{item.gbId}, #{item.name}, " +
  126 + "#{item.longitude}, #{item.latitude}, #{item.streamType}, " +
  127 + "#{item.mediaServerId}, #{item.createTime}) "+
128 128 "</foreach> " +
129 129 "</script>")
130 130 @Options(useGeneratedKeys = true, keyProperty = "gbStreamId", keyColumn = "gbStreamId")
... ... @@ -134,7 +134,7 @@ public interface GbStreamMapper {
134 134 "<foreach collection='gpsMsgInfos' item='item' separator=';'>" +
135 135 " UPDATE" +
136 136 " gb_stream" +
137   - " SET longitude=${item.lng}, latitude=${item.lat} " +
  137 + " SET longitude=#{item.lng}, latitude=#{item.lat} " +
138 138 "WHERE gbId=#{item.id}"+
139 139 "</foreach>" +
140 140 "</script>"})
... ...
src/main/java/com/genersoft/iot/vmp/storager/dao/LogMapper.java
... ... @@ -18,16 +18,16 @@ import java.util.List;
18 18 public interface LogMapper {
19 19  
20 20 @Insert("insert into log ( name, type, uri, address, result, timing, username, createTime) " +
21   - "values ('${name}', '${type}', '${uri}', '${address}', '${result}', ${timing}, '${username}', '${createTime}')")
  21 + "values (#{name}, #{type}, #{uri}, #{address}, #{result}, #{timing}, #{username}, #{createTime})")
22 22 int add(LogDto logDto);
23 23  
24 24 @Select(value = {"<script>" +
25 25 " SELECT * FROM log " +
26 26 " WHERE 1=1 " +
27   - " <if test=\"query != null\"> AND (name LIKE '%${query}%')</if> " +
28   - " <if test=\"type != null\" > AND type = '${type}'</if>" +
29   - " <if test=\"startTime != null\" > AND createTime &gt;= '${startTime}' </if>" +
30   - " <if test=\"endTime != null\" > AND createTime &lt;= '${endTime}' </if>" +
  27 + " <if test=\"query != null\"> AND (name LIKE concat('%',#{query},'%'))</if> " +
  28 + " <if test=\"type != null\" > AND type = #{type}</if>" +
  29 + " <if test=\"startTime != null\" > AND createTime &gt;= #{startTime} </if>" +
  30 + " <if test=\"endTime != null\" > AND createTime &lt;= #{endTime} </if>" +
31 31 " ORDER BY createTime DESC " +
32 32 " </script>"})
33 33 List<LogDto> query(String query, String type, String startTime, String endTime);
... ...
src/main/java/com/genersoft/iot/vmp/storager/dao/MediaServerMapper.java
... ... @@ -35,92 +35,92 @@ public interface MediaServerMapper {
35 35 "hookAliveInterval" +
36 36 ") VALUES " +
37 37 "(" +
38   - "'${id}', " +
39   - "'${ip}', " +
40   - "'${hookIp}', " +
41   - "'${sdpIp}', " +
42   - "'${streamIp}', " +
43   - "${httpPort}, " +
44   - "${httpSSlPort}, " +
45   - "${rtmpPort}, " +
46   - "${rtmpSSlPort}, " +
47   - "${rtpProxyPort}, " +
48   - "${rtspPort}, " +
49   - "${rtspSSLPort}, " +
50   - "${autoConfig}, " +
51   - "'${secret}', " +
52   - "${rtpEnable}, " +
53   - "'${rtpPortRange}', " +
54   - "${recordAssistPort}, " +
55   - "${defaultServer}, " +
56   - "'${createTime}', " +
57   - "'${updateTime}', " +
58   - "${hookAliveInterval})")
  38 + "#{id}, " +
  39 + "#{ip}, " +
  40 + "#{hookIp}, " +
  41 + "#{sdpIp}, " +
  42 + "#{streamIp}, " +
  43 + "#{httpPort}, " +
  44 + "#{httpSSlPort}, " +
  45 + "#{rtmpPort}, " +
  46 + "#{rtmpSSlPort}, " +
  47 + "#{rtpProxyPort}, " +
  48 + "#{rtspPort}, " +
  49 + "#{rtspSSLPort}, " +
  50 + "#{autoConfig}, " +
  51 + "#{secret}, " +
  52 + "#{rtpEnable}, " +
  53 + "#{rtpPortRange}, " +
  54 + "#{recordAssistPort}, " +
  55 + "#{defaultServer}, " +
  56 + "#{createTime}, " +
  57 + "#{updateTime}, " +
  58 + "#{hookAliveInterval})")
59 59 int add(MediaServerItem mediaServerItem);
60 60  
61 61 @Update(value = {" <script>" +
62 62 "UPDATE media_server " +
63   - "SET updateTime='${updateTime}'" +
64   - "<if test=\"ip != null\">, ip='${ip}'</if>" +
65   - "<if test=\"hookIp != null\">, hookIp='${hookIp}'</if>" +
66   - "<if test=\"sdpIp != null\">, sdpIp='${sdpIp}'</if>" +
67   - "<if test=\"streamIp != null\">, streamIp='${streamIp}'</if>" +
68   - "<if test=\"httpPort != null\">, httpPort=${httpPort}</if>" +
69   - "<if test=\"httpSSlPort != null\">, httpSSlPort=${httpSSlPort}</if>" +
70   - "<if test=\"rtmpPort != null\">, rtmpPort=${rtmpPort}</if>" +
71   - "<if test=\"rtmpSSlPort != null\">, rtmpSSlPort=${rtmpSSlPort}</if>" +
72   - "<if test=\"rtpProxyPort != null\">, rtpProxyPort=${rtpProxyPort}</if>" +
73   - "<if test=\"rtspPort != null\">, rtspPort=${rtspPort}</if>" +
74   - "<if test=\"rtspSSLPort != null\">, rtspSSLPort=${rtspSSLPort}</if>" +
75   - "<if test=\"autoConfig != null\">, autoConfig=${autoConfig}</if>" +
76   - "<if test=\"rtpEnable != null\">, rtpEnable=${rtpEnable}</if>" +
77   - "<if test=\"rtpPortRange != null\">, rtpPortRange='${rtpPortRange}'</if>" +
78   - "<if test=\"secret != null\">, secret='${secret}'</if>" +
79   - "<if test=\"recordAssistPort != null\">, recordAssistPort=${recordAssistPort}</if>" +
80   - "<if test=\"hookAliveInterval != null\">, hookAliveInterval=${hookAliveInterval}</if>" +
81   - "WHERE id='${id}'"+
  63 + "SET updateTime=#{updateTime}" +
  64 + "<if test=\"ip != null\">, ip=#{ip}</if>" +
  65 + "<if test=\"hookIp != null\">, hookIp=#{hookIp}</if>" +
  66 + "<if test=\"sdpIp != null\">, sdpIp=#{sdpIp}</if>" +
  67 + "<if test=\"streamIp != null\">, streamIp=#{streamIp}</if>" +
  68 + "<if test=\"httpPort != null\">, httpPort=#{httpPort}</if>" +
  69 + "<if test=\"httpSSlPort != null\">, httpSSlPort=#{httpSSlPort}</if>" +
  70 + "<if test=\"rtmpPort != null\">, rtmpPort=#{rtmpPort}</if>" +
  71 + "<if test=\"rtmpSSlPort != null\">, rtmpSSlPort=#{rtmpSSlPort}</if>" +
  72 + "<if test=\"rtpProxyPort != null\">, rtpProxyPort=#{rtpProxyPort}</if>" +
  73 + "<if test=\"rtspPort != null\">, rtspPort=#{rtspPort}</if>" +
  74 + "<if test=\"rtspSSLPort != null\">, rtspSSLPort=#{rtspSSLPort}</if>" +
  75 + "<if test=\"autoConfig != null\">, autoConfig=#{autoConfig}</if>" +
  76 + "<if test=\"rtpEnable != null\">, rtpEnable=#{rtpEnable}</if>" +
  77 + "<if test=\"rtpPortRange != null\">, rtpPortRange=#{rtpPortRange}</if>" +
  78 + "<if test=\"secret != null\">, secret=#{secret}</if>" +
  79 + "<if test=\"recordAssistPort != null\">, recordAssistPort=#{recordAssistPort}</if>" +
  80 + "<if test=\"hookAliveInterval != null\">, hookAliveInterval=#{hookAliveInterval}</if>" +
  81 + "WHERE id=#{id}"+
82 82 " </script>"})
83 83 int update(MediaServerItem mediaServerItem);
84 84  
85 85 @Update(value = {" <script>" +
86 86 "UPDATE media_server " +
87   - "SET updateTime='${updateTime}'" +
88   - "<if test=\"id != null\">, id='${id}'</if>" +
89   - "<if test=\"hookIp != null\">, hookIp='${hookIp}'</if>" +
90   - "<if test=\"sdpIp != null\">, sdpIp='${sdpIp}'</if>" +
91   - "<if test=\"streamIp != null\">, streamIp='${streamIp}'</if>" +
92   - "<if test=\"httpSSlPort != null\">, httpSSlPort=${httpSSlPort}</if>" +
93   - "<if test=\"rtmpPort != null\">, rtmpPort=${rtmpPort}</if>" +
94   - "<if test=\"rtmpSSlPort != null\">, rtmpSSlPort=${rtmpSSlPort}</if>" +
95   - "<if test=\"rtpProxyPort != null\">, rtpProxyPort=${rtpProxyPort}</if>" +
96   - "<if test=\"rtspPort != null\">, rtspPort=${rtspPort}</if>" +
97   - "<if test=\"rtspSSLPort != null\">, rtspSSLPort=${rtspSSLPort}</if>" +
98   - "<if test=\"autoConfig != null\">, autoConfig=${autoConfig}</if>" +
99   - "<if test=\"rtpEnable != null\">, rtpEnable=${rtpEnable}</if>" +
100   - "<if test=\"rtpPortRange != null\">, rtpPortRange='${rtpPortRange}'</if>" +
101   - "<if test=\"secret != null\">, secret='${secret}'</if>" +
102   - "<if test=\"recordAssistPort != null\">, recordAssistPort=${recordAssistPort}</if>" +
103   - "<if test=\"hookAliveInterval != null\">, hookAliveInterval=${hookAliveInterval}</if>" +
104   - "WHERE ip='${ip}' and httpPort=${httpPort}"+
  87 + "SET updateTime=#{updateTime}" +
  88 + "<if test=\"id != null\">, id=#{id}</if>" +
  89 + "<if test=\"hookIp != null\">, hookIp=#{hookIp}</if>" +
  90 + "<if test=\"sdpIp != null\">, sdpIp=#{sdpIp}</if>" +
  91 + "<if test=\"streamIp != null\">, streamIp=#{streamIp}</if>" +
  92 + "<if test=\"httpSSlPort != null\">, httpSSlPort=#{httpSSlPort}</if>" +
  93 + "<if test=\"rtmpPort != null\">, rtmpPort=#{rtmpPort}</if>" +
  94 + "<if test=\"rtmpSSlPort != null\">, rtmpSSlPort=#{rtmpSSlPort}</if>" +
  95 + "<if test=\"rtpProxyPort != null\">, rtpProxyPort=#{rtpProxyPort}</if>" +
  96 + "<if test=\"rtspPort != null\">, rtspPort=#{rtspPort}</if>" +
  97 + "<if test=\"rtspSSLPort != null\">, rtspSSLPort=#{rtspSSLPort}</if>" +
  98 + "<if test=\"autoConfig != null\">, autoConfig=#{autoConfig}</if>" +
  99 + "<if test=\"rtpEnable != null\">, rtpEnable=#{rtpEnable}</if>" +
  100 + "<if test=\"rtpPortRange != null\">, rtpPortRange=#{rtpPortRange}</if>" +
  101 + "<if test=\"secret != null\">, secret=#{secret}</if>" +
  102 + "<if test=\"recordAssistPort != null\">, recordAssistPort=#{recordAssistPort}</if>" +
  103 + "<if test=\"hookAliveInterval != null\">, hookAliveInterval=#{hookAliveInterval}</if>" +
  104 + "WHERE ip=#{ip} and httpPort=#{httpPort}"+
105 105 " </script>"})
106 106 int updateByHostAndPort(MediaServerItem mediaServerItem);
107 107  
108   - @Select("SELECT * FROM media_server WHERE id='${id}'")
  108 + @Select("SELECT * FROM media_server WHERE id=#{id}")
109 109 MediaServerItem queryOne(String id);
110 110  
111 111 @Select("SELECT * FROM media_server")
112 112 List<MediaServerItem> queryAll();
113 113  
114   - @Delete("DELETE FROM media_server WHERE id='${id}'")
  114 + @Delete("DELETE FROM media_server WHERE id=#{id}")
115 115 void delOne(String id);
116 116  
117   - @Select("DELETE FROM media_server WHERE ip='${host}' and httpPort=${port}")
  117 + @Select("DELETE FROM media_server WHERE ip=#{host} and httpPort=#{port}")
118 118 void delOneByIPAndPort(String host, int port);
119 119  
120 120 @Delete("DELETE FROM media_server WHERE defaultServer=1")
121 121 int delDefault();
122 122  
123   - @Select("SELECT * FROM media_server WHERE ip='${host}' and httpPort=${port}")
  123 + @Select("SELECT * FROM media_server WHERE ip=#{host} and httpPort=#{port}")
124 124 MediaServerItem queryOneByHostAndPort(String host, int port);
125 125  
126 126 @Select("SELECT * FROM media_server WHERE defaultServer=1")
... ...
src/main/java/com/genersoft/iot/vmp/storager/dao/ParentPlatformMapper.java
... ... @@ -17,9 +17,9 @@ public interface ParentPlatformMapper {
17 17 @Insert("INSERT INTO parent_platform (enable, name, serverGBId, serverGBDomain, serverIP, serverPort, deviceGBId, deviceIp, " +
18 18 " devicePort, username, password, expires, keepTimeout, transport, characterSet, ptz, rtcp, " +
19 19 " status, startOfflinePush, catalogId, administrativeDivision, catalogGroup, createTime, updateTime, treeType) " +
20   - " VALUES (${enable}, '${name}', '${serverGBId}', '${serverGBDomain}', '${serverIP}', ${serverPort}, '${deviceGBId}', '${deviceIp}', " +
21   - " '${devicePort}', '${username}', '${password}', '${expires}', '${keepTimeout}', '${transport}', '${characterSet}', ${ptz}, ${rtcp}, " +
22   - " ${status}, ${startOfflinePush}, #{catalogId}, #{administrativeDivision}, #{catalogGroup}, #{createTime}, #{updateTime}, #{treeType})")
  20 + " VALUES (#{enable}, #{name}, #{serverGBId}, #{serverGBDomain}, #{serverIP}, #{serverPort}, #{deviceGBId}, #{deviceIp}, " +
  21 + " #{devicePort}, #{username}, #{password}, #{expires}, #{keepTimeout}, #{transport}, #{characterSet}, #{ptz}, #{rtcp}, " +
  22 + " #{status}, #{startOfflinePush}, #{catalogId}, #{administrativeDivision}, #{catalogGroup}, #{createTime}, #{updateTime}, #{treeType})")
23 23 int addParentPlatform(ParentPlatform parentPlatform);
24 24  
25 25 @Update("UPDATE parent_platform " +
... ... @@ -41,7 +41,7 @@ public interface ParentPlatformMapper {
41 41 "ptz=#{ptz}, " +
42 42 "rtcp=#{rtcp}, " +
43 43 "status=#{status}, " +
44   - "startOfflinePush=${startOfflinePush}, " +
  44 + "startOfflinePush=#{startOfflinePush}, " +
45 45 "catalogGroup=#{catalogGroup}, " +
46 46 "administrativeDivision=#{administrativeDivision}, " +
47 47 "createTime=#{createTime}, " +
... ...
src/main/java/com/genersoft/iot/vmp/storager/dao/PlatformChannelMapper.java
... ... @@ -21,22 +21,22 @@ public interface PlatformChannelMapper {
21 21 * 查询列表里已经关联的
22 22 */
23 23 @Select("<script> "+
24   - "SELECT deviceChannelId FROM platform_gb_channel WHERE platformId='${platformId}' AND deviceChannelId in" +
25   - "<foreach collection='channelReduces' open='(' item='item' separator=',' close=')'> '${item.id}'</foreach>" +
  24 + "SELECT deviceChannelId FROM platform_gb_channel WHERE platformId=#{platformId} AND deviceChannelId in" +
  25 + "<foreach collection='channelReduces' open='(' item='item' separator=',' close=')'> #{item.id}</foreach>" +
26 26 "</script>")
27 27 List<Integer> findChannelRelatedPlatform(String platformId, List<ChannelReduce> channelReduces);
28 28  
29 29 @Insert("<script> "+
30 30 "INSERT INTO platform_gb_channel (platformId, deviceChannelId, catalogId) VALUES" +
31 31 "<foreach collection='channelReducesToAdd' item='item' separator=','>" +
32   - " ('${platformId}', '${item.id}' , '${item.catalogId}' )" +
  32 + " (#{platformId}, #{item.id} , #{item.catalogId} )" +
33 33 "</foreach>" +
34 34 "</script>")
35 35 int addChannels(String platformId, List<ChannelReduce> channelReducesToAdd);
36 36  
37 37 @Delete("<script> "+
38   - "DELETE FROM platform_gb_channel WHERE platformId='${platformId}' AND deviceChannelId in" +
39   - "<foreach collection='channelReducesToDel' item='item' open='(' separator=',' close=')' > '${item.id}'</foreach>" +
  38 + "DELETE FROM platform_gb_channel WHERE platformId=#{platformId} AND deviceChannelId in" +
  39 + "<foreach collection='channelReducesToDel' item='item' open='(' separator=',' close=')' > #{item.id}</foreach>" +
40 40 "</script>")
41 41 int delChannelForGB(String platformId, List<ChannelReduce> channelReducesToDel);
42 42  
... ... @@ -50,14 +50,14 @@ public interface PlatformChannelMapper {
50 50 int delChannelForDeviceId(String deviceId);
51 51  
52 52 @Delete("<script> "+
53   - "DELETE FROM platform_gb_channel WHERE platformId='${platformId}'" +
  53 + "DELETE FROM platform_gb_channel WHERE platformId=#{platformId}" +
54 54 "</script>")
55 55 int cleanChannelForGB(String platformId);
56 56  
57   - @Select("SELECT dc.* FROM platform_gb_channel pgc left join device_channel dc on dc.id = pgc.deviceChannelId WHERE dc.channelId='${channelId}' and pgc.platformId='${platformId}'")
  57 + @Select("SELECT dc.* FROM platform_gb_channel pgc left join device_channel dc on dc.id = pgc.deviceChannelId WHERE dc.channelId=#{channelId} and pgc.platformId=#{platformId}")
58 58 List<DeviceChannel> queryChannelInParentPlatform(String platformId, String channelId);
59 59  
60   - @Select("SELECT dc.* FROM platform_gb_channel pgc left join device_channel dc on dc.id = pgc.deviceChannelId WHERE pgc.platformId='${platformId}' and pgc.catalogId=#{catalogId}")
  60 + @Select("SELECT dc.* FROM platform_gb_channel pgc left join device_channel dc on dc.id = pgc.deviceChannelId WHERE pgc.platformId=#{platformId} and pgc.catalogId=#{catalogId}")
61 61 List<DeviceChannel> queryAllChannelInCatalog(String platformId, String catalogId);
62 62  
63 63 @Select(" select dc.channelId as id, dc.name as name, pgc.platformId as platformId, pgc.catalogId as parentId, 0 as childrenCount, 1 as type " +
... ...
src/main/java/com/genersoft/iot/vmp/storager/dao/PlatformGbStreamMapper.java
... ... @@ -26,7 +26,7 @@ public interface PlatformGbStreamMapper {
26 26 "(gbStreamId, platformId, catalogId) " +
27 27 "values " +
28 28 "<foreach collection='streamPushItems' index='index' item='item' separator=','> " +
29   - "(${item.gbStreamId}, '${item.platformId}', '${item.catalogId}')" +
  29 + "(#{item.gbStreamId}, #{item.platformId}, #{item.catalogId})" +
30 30 "</foreach> " +
31 31 "</script>")
32 32 int batchAdd(List<StreamPushItem> streamPushItems);
... ...
src/main/java/com/genersoft/iot/vmp/storager/dao/RecordInfoDao.java
... ... @@ -14,10 +14,10 @@ import java.util.List;
14 14 public interface RecordInfoDao {
15 15  
16 16 @Insert("INSERT INTO recordInfo (app, stream, mediaServerId, createTime, type, deviceId, channelId, name) VALUES" +
17   - "('${app}', '${stream}', '${mediaServerId}', datetime('now','localtime')), '${type}', '${deviceId}', '${channelId}', '${name}'")
  17 + "(#{app}, #{stream}, #{mediaServerId}, datetime('now','localtime')), #{type}, #{deviceId}, #{channelId}, #{name}")
18 18 int add(RecordInfo recordInfo);
19 19  
20   - @Delete("DELETE FROM user WHERE createTime < '${beforeTime}'")
  20 + @Delete("DELETE FROM user WHERE createTime < #{beforeTime}")
21 21 int deleteBefore(String beforeTime);
22 22  
23 23 @Select("select * FROM recordInfo")
... ...
src/main/java/com/genersoft/iot/vmp/storager/dao/RoleMapper.java
... ... @@ -12,14 +12,14 @@ import java.util.List;
12 12 public interface RoleMapper {
13 13  
14 14 @Insert("INSERT INTO user_role (name, authority, createTime, updateTime) VALUES" +
15   - "('${name}', '${authority}', '${createTime}', '${updateTime}')")
  15 + "(#{name}, #{authority}, #{createTime}, #{updateTime})")
16 16 int add(Role role);
17 17  
18 18 @Update(value = {" <script>" +
19 19 "UPDATE user_role " +
20   - "SET updateTime='${updateTime}' " +
21   - "<if test=\"name != null\">, name='${name}'</if>" +
22   - "<if test=\"authority != null\">, authority='${authority}'</if>" +
  20 + "SET updateTime=#{updateTime} " +
  21 + "<if test=\"name != null\">, name=#{name}</if>" +
  22 + "<if test=\"authority != null\">, authority=#{authority}</if>" +
23 23 "WHERE id != 1 and id=#{id}" +
24 24 " </script>"})
25 25 int update(Role role);
... ...
src/main/java/com/genersoft/iot/vmp/storager/dao/StreamProxyMapper.java
... ... @@ -13,9 +13,9 @@ public interface StreamProxyMapper {
13 13  
14 14 @Insert("INSERT INTO stream_proxy (type, name, app, stream,mediaServerId, url, src_url, dst_url, " +
15 15 "timeout_ms, ffmpeg_cmd_key, rtp_type, enable_audio, enable_mp4, enable, status, enable_remove_none_reader, enable_disable_none_reader, createTime) VALUES" +
16   - "('${type}','${name}', '${app}', '${stream}', '${mediaServerId}','${url}', '${src_url}', '${dst_url}', " +
17   - "'${timeout_ms}', '${ffmpeg_cmd_key}', '${rtp_type}', ${enable_audio}, ${enable_mp4}, ${enable}, ${status}, " +
18   - "${enable_remove_none_reader}, ${enable_disable_none_reader}, '${createTime}' )")
  16 + "(#{type}, #{name}, #{app}, #{stream}, #{mediaServerId}, #{url}, #{src_url}, #{dst_url}, " +
  17 + "#{timeout_ms}, #{ffmpeg_cmd_key}, #{rtp_type}, #{enable_audio}, #{enable_mp4}, #{enable}, #{status}, " +
  18 + "#{enable_remove_none_reader}, #{enable_disable_none_reader}, #{createTime} )")
19 19 int add(StreamProxyItem streamProxyDto);
20 20  
21 21 @Update("UPDATE stream_proxy " +
... ... @@ -45,7 +45,7 @@ public interface StreamProxyMapper {
45 45 @Select("SELECT st.*, pgs.gbId, pgs.name, pgs.longitude, pgs.latitude FROM stream_proxy st LEFT JOIN gb_stream pgs on st.app = pgs.app AND st.stream = pgs.stream order by st.createTime desc")
46 46 List<StreamProxyItem> selectAll();
47 47  
48   - @Select("SELECT st.*, pgs.gbId, pgs.name, pgs.longitude, pgs.latitude FROM stream_proxy st LEFT JOIN gb_stream pgs on st.app = pgs.app AND st.stream = pgs.stream WHERE st.enable=${enable} order by st.createTime desc")
  48 + @Select("SELECT st.*, pgs.gbId, pgs.name, pgs.longitude, pgs.latitude FROM stream_proxy st LEFT JOIN gb_stream pgs on st.app = pgs.app AND st.stream = pgs.stream WHERE st.enable=#{enable} order by st.createTime desc")
49 49 List<StreamProxyItem> selectForEnable(boolean enable);
50 50  
51 51 @Select("SELECT st.*, pgs.gbId, pgs.name, pgs.longitude, pgs.latitude FROM stream_proxy st LEFT JOIN gb_stream pgs on st.app = pgs.app AND st.stream = pgs.stream WHERE st.app=#{app} AND st.stream=#{stream} order by st.createTime desc")
... ... @@ -53,12 +53,12 @@ public interface StreamProxyMapper {
53 53  
54 54 @Select("SELECT st.*, pgs.gbId, pgs.name, pgs.longitude, pgs.latitude FROM stream_proxy st " +
55 55 "LEFT JOIN gb_stream pgs on st.app = pgs.app AND st.stream = pgs.stream " +
56   - "WHERE st.enable=${enable} and st.mediaServerId = #{id} order by st.createTime desc")
  56 + "WHERE st.enable=#{enable} and st.mediaServerId = #{id} order by st.createTime desc")
57 57 List<StreamProxyItem> selectForEnableInMediaServer(String id, boolean enable);
58 58  
59 59 @Select("SELECT st.*, pgs.gbId, pgs.name, pgs.longitude, pgs.latitude FROM stream_proxy st " +
60 60 "LEFT JOIN gb_stream pgs on st.app = pgs.app AND st.stream = pgs.stream " +
61   - "WHERE st.mediaServerId = '${id}' order by st.createTime desc")
  61 + "WHERE st.mediaServerId = #{id} order by st.createTime desc")
62 62 List<StreamProxyItem> selectInMediaServer(String id);
63 63  
64 64 @Update("UPDATE stream_proxy " +
... ... @@ -67,7 +67,7 @@ public interface StreamProxyMapper {
67 67 void updateStatusByMediaServerId(String mediaServerId, boolean status);
68 68  
69 69 @Update("UPDATE stream_proxy " +
70   - "SET status=${status} " +
  70 + "SET status=#{status} " +
71 71 "WHERE app=#{app} AND stream=#{stream}")
72 72 int updateStatus(String app, String stream, boolean status);
73 73  
... ...
src/main/java/com/genersoft/iot/vmp/storager/dao/StreamPushMapper.java
... ... @@ -17,23 +17,23 @@ public interface StreamPushMapper {
17 17  
18 18 @Insert("INSERT INTO stream_push (app, stream, totalReaderCount, originType, originTypeStr, " +
19 19 "pushTime, aliveSecond, mediaServerId, serverId, updateTime, createTime, pushIng, self) VALUES" +
20   - "('${app}', '${stream}', '${totalReaderCount}', '${originType}', '${originTypeStr}', " +
21   - "'${pushTime}', '${aliveSecond}', '${mediaServerId}' , '${serverId}' , '${updateTime}' , '${createTime}', " +
22   - "${pushIng}, ${self} )")
  20 + "(#{app}, #{stream}, #{totalReaderCount}, #{originType}, #{originTypeStr}, " +
  21 + "#{pushTime}, #{aliveSecond}, #{mediaServerId} , #{serverId} , #{updateTime} , #{createTime}, " +
  22 + "#{pushIng}, #{self} )")
23 23 int add(StreamPushItem streamPushItem);
24 24  
25 25  
26 26 @Update(value = {" <script>" +
27 27 "UPDATE stream_push " +
28   - "SET updateTime='${updateTime}'" +
29   - "<if test=\"mediaServerId != null\">, mediaServerId='${mediaServerId}'</if>" +
30   - "<if test=\"totalReaderCount != null\">, totalReaderCount='${totalReaderCount}'</if>" +
31   - "<if test=\"originType != null\">, originType=${originType}</if>" +
32   - "<if test=\"originTypeStr != null\">, originTypeStr='${originTypeStr}'</if>" +
33   - "<if test=\"pushTime != null\">, pushTime='${pushTime}'</if>" +
34   - "<if test=\"aliveSecond != null\">, aliveSecond='${aliveSecond}'</if>" +
35   - "<if test=\"pushIng != null\">, pushIng=${pushIng}</if>" +
36   - "<if test=\"self != null\">, self=${self}</if>" +
  28 + "SET updateTime=#{updateTime}" +
  29 + "<if test=\"mediaServerId != null\">, mediaServerId=#{mediaServerId}</if>" +
  30 + "<if test=\"totalReaderCount != null\">, totalReaderCount=#{totalReaderCount}</if>" +
  31 + "<if test=\"originType != null\">, originType=#{originType}</if>" +
  32 + "<if test=\"originTypeStr != null\">, originTypeStr=#{originTypeStr}</if>" +
  33 + "<if test=\"pushTime != null\">, pushTime=#{pushTime}</if>" +
  34 + "<if test=\"aliveSecond != null\">, aliveSecond=#{aliveSecond}</if>" +
  35 + "<if test=\"pushIng != null\">, pushIng=#{pushIng}</if>" +
  36 + "<if test=\"self != null\">, self=#{self}</if>" +
37 37 "WHERE app=#{app} AND stream=#{stream}"+
38 38 " </script>"})
39 39 int update(StreamPushItem streamPushItem);
... ... @@ -76,7 +76,7 @@ public interface StreamPushMapper {
76 76 "on st.app = gs.app AND st.stream = gs.stream " +
77 77 "WHERE " +
78 78 "1=1 " +
79   - " <if test='query != null'> AND (st.app LIKE '%${query}%' OR st.stream LIKE '%${query}%' OR gs.gbId LIKE '%${query}%' OR gs.name LIKE '%${query}%')</if> " +
  79 + " <if test='query != null'> AND (st.app LIKE concat('%',#{query},'%') OR st.stream LIKE concat('%',#{query},'%') OR gs.gbId LIKE concat('%',#{query},'%') OR gs.name LIKE concat('%',#{query},'%'))</if> " +
80 80 " <if test='pushing == true' > AND (gs.gbId is null OR st.pushIng=1)</if>" +
81 81 " <if test='pushing == false' > AND (st.pushIng is null OR st.pushIng=0) </if>" +
82 82 " <if test='mediaServerId != null' > AND st.mediaServerId=#{mediaServerId} </if>" +
... ... @@ -94,9 +94,9 @@ public interface StreamPushMapper {
94 94 "Insert IGNORE INTO stream_push (app, stream, totalReaderCount, originType, originTypeStr, " +
95 95 "createTime, aliveSecond, mediaServerId, status, pushIng) " +
96 96 "VALUES <foreach collection='streamPushItems' item='item' index='index' separator=','>" +
97   - "( '${item.app}', '${item.stream}', '${item.totalReaderCount}', #{item.originType}, " +
98   - "'${item.originTypeStr}',#{item.createTime}, #{item.aliveSecond}, '${item.mediaServerId}', ${item.status} ," +
99   - " ${item.pushIng} )" +
  97 + "( #{item.app}, #{item.stream}, #{item.totalReaderCount}, #{item.originType}, " +
  98 + "#{item.originTypeStr},#{item.createTime}, #{item.aliveSecond}, #{item.mediaServerId}, #{item.status} ," +
  99 + " #{item.pushIng} )" +
100 100 " </foreach>" +
101 101 "</script>")
102 102 @Options(useGeneratedKeys = true, keyProperty = "id", keyColumn = "id")
... ... @@ -115,12 +115,12 @@ public interface StreamPushMapper {
115 115 List<StreamPushItem> selectAllByMediaServerIdWithOutGbID(String mediaServerId);
116 116  
117 117 @Update("UPDATE stream_push " +
118   - "SET status=${status} " +
  118 + "SET status=#{status} " +
119 119 "WHERE app=#{app} AND stream=#{stream}")
120 120 int updateStatus(String app, String stream, boolean status);
121 121  
122 122 @Update("UPDATE stream_push " +
123   - "SET pushIng=${pushIng} " +
  123 + "SET pushIng=#{pushIng} " +
124 124 "WHERE app=#{app} AND stream=#{stream}")
125 125 int updatePushStatus(String app, String stream, boolean pushIng);
126 126  
... ...
src/main/java/com/genersoft/iot/vmp/storager/dao/UserMapper.java
... ... @@ -11,16 +11,16 @@ import java.util.List;
11 11 public interface UserMapper {
12 12  
13 13 @Insert("INSERT INTO user (username, password, roleId, pushKey, createTime, updateTime) VALUES" +
14   - "('${username}', '${password}', '${role.id}', '${pushKey}', '${createTime}', '${updateTime}')")
  14 + "(#{username}, #{password}, #{role.id}, #{pushKey}, #{createTime}, #{updateTime})")
15 15 int add(User user);
16 16  
17 17 @Update(value = {" <script>" +
18 18 "UPDATE user " +
19   - "SET updateTime='${updateTime}' " +
20   - "<if test=\"pushKey != null\">, pushKey='${pushKey}'</if>" +
21   - "<if test=\"role != null\">, roleId='${role.id}'</if>" +
22   - "<if test=\"password != null\">, password='${password}'</if>" +
23   - "<if test=\"username != null\">, username='${username}'</if>" +
  19 + "SET updateTime=#{updateTime} " +
  20 + "<if test=\"pushKey != null\">, pushKey=#{pushKey}</if>" +
  21 + "<if test=\"role != null\">, roleId=#{role.id}</if>" +
  22 + "<if test=\"password != null\">, password=#{password}</if>" +
  23 + "<if test=\"username != null\">, username=#{username}</if>" +
24 24 "WHERE id=#{id}" +
25 25 " </script>"})
26 26 int update(User user);
... ... @@ -50,10 +50,10 @@ public interface UserMapper {
50 50 @ResultMap(value="roleMap")
51 51 List<User> selectAll();
52 52  
53   - @Select("select * from (select user.*, concat('${callId}_', pushKey) as str1 from user) as u where md5(u.str1) = '${sign}'")
  53 + @Select("select * from (select user.*, concat(concat(#{callId}, '_'), pushKey) as str1 from user) as u where md5(u.str1) = #{sign}")
54 54 List<User> checkPushAuthorityByCallIdAndSign(String callId, String sign);
55 55  
56   - @Select("select * from user where md5(pushKey) = '${sign}'")
  56 + @Select("select * from user where md5(pushKey) = #{sign}")
57 57 List<User> checkPushAuthorityByCallId(String sign);
58 58  
59 59 @Select("select u.id, u.username,u.pushKey,u.roleId, r.id as roleID, r.name as roleName, r.authority as roleAuthority , r.createTime as roleCreateTime , r.updateTime as roleUpdateTime FROM user u join user_role r on u.roleId=r.id")
... ...
src/main/java/com/genersoft/iot/vmp/storager/impl/VideoManagerStorageImpl.java
... ... @@ -224,31 +224,31 @@ public class VideoManagerStorageImpl implements IVideoManagerStorage {
224 224 PageHelper.startPage(page, count);
225 225 List<DeviceChannel> all;
226 226 if (catalogUnderDevice != null && catalogUnderDevice) {
227   - all = deviceChannelMapper.queryChannels(deviceId, deviceId, query, hasSubChannel, online);
  227 + all = deviceChannelMapper.queryChannels(deviceId, deviceId, query, hasSubChannel, online,null);
228 228 // 海康设备的parentId是SIP id
229   - List<DeviceChannel> deviceChannels = deviceChannelMapper.queryChannels(deviceId, sipConfig.getId(), query, hasSubChannel, online);
  229 + List<DeviceChannel> deviceChannels = deviceChannelMapper.queryChannels(deviceId, sipConfig.getId(), query, hasSubChannel, online,null);
230 230 all.addAll(deviceChannels);
231 231 }else {
232   - all = deviceChannelMapper.queryChannels(deviceId, null, query, hasSubChannel, online);
  232 + all = deviceChannelMapper.queryChannels(deviceId, null, query, hasSubChannel, online,null);
233 233 }
234 234 return new PageInfo<>(all);
235 235 }
236 236  
237 237 @Override
238   - public List<DeviceChannel> queryChannelsByDeviceIdWithStartAndLimit(String deviceId, String query, Boolean hasSubChannel, Boolean online, int start, int limit) {
239   - return deviceChannelMapper.queryChannelsByDeviceIdWithStartAndLimit(deviceId, null, query, hasSubChannel, online, start, limit);
  238 + public List<DeviceChannel> queryChannelsByDeviceIdWithStartAndLimit(String deviceId, String query, Boolean hasSubChannel, Boolean online, int start, int limit,List<String> channelIds) {
  239 + return deviceChannelMapper.queryChannelsByDeviceIdWithStartAndLimit(deviceId, null, query, hasSubChannel, online, start, limit,channelIds);
240 240 }
241 241  
242 242  
243 243 @Override
244   - public List<DeviceChannel> queryChannelsByDeviceId(String deviceId) {
245   - return deviceChannelMapper.queryChannels(deviceId, null,null, null, null);
  244 + public List<DeviceChannel> queryChannelsByDeviceId(String deviceId,Boolean online,List<String> channelIds) {
  245 + return deviceChannelMapper.queryChannels(deviceId, null,null, null, online,channelIds);
246 246 }
247 247  
248 248 @Override
249 249 public PageInfo<DeviceChannel> querySubChannels(String deviceId, String parentChannelId, String query, Boolean hasSubChannel, Boolean online, int page, int count) {
250 250 PageHelper.startPage(page, count);
251   - List<DeviceChannel> all = deviceChannelMapper.queryChannels(deviceId, parentChannelId, query, hasSubChannel, online);
  251 + List<DeviceChannel> all = deviceChannelMapper.queryChannels(deviceId, parentChannelId, query, hasSubChannel, online,null);
252 252 return new PageInfo<>(all);
253 253 }
254 254  
... ... @@ -271,9 +271,9 @@ public class VideoManagerStorageImpl implements IVideoManagerStorage {
271 271 * @return PageInfo<Device> 分页设备对象数组
272 272 */
273 273 @Override
274   - public PageInfo<Device> queryVideoDeviceList(int page, int count) {
  274 + public PageInfo<Device> queryVideoDeviceList(int page, int count,Boolean online) {
275 275 PageHelper.startPage(page, count);
276   - List<Device> all = deviceMapper.getDevices();
  276 + List<Device> all = deviceMapper.getDevices(online);
277 277 return new PageInfo<>(all);
278 278 }
279 279  
... ... @@ -283,9 +283,9 @@ public class VideoManagerStorageImpl implements IVideoManagerStorage {
283 283 * @return List<Device> 设备对象数组
284 284 */
285 285 @Override
286   - public List<Device> queryVideoDeviceList() {
  286 + public List<Device> queryVideoDeviceList(Boolean online) {
287 287  
288   - List<Device> deviceList = deviceMapper.getDevices();
  288 + List<Device> deviceList = deviceMapper.getDevices(online);
289 289 return deviceList;
290 290 }
291 291  
... ...
src/main/java/com/genersoft/iot/vmp/utils/redis/RedisUtil.java
1 1 package com.genersoft.iot.vmp.utils.redis;
2 2  
3   -import java.util.*;
4   -import java.util.concurrent.TimeUnit;
5   -
6 3 import com.alibaba.fastjson2.JSONObject;
7 4 import com.genersoft.iot.vmp.utils.SpringBeanFactory;
8   -import gov.nist.javax.sip.stack.UDPMessageChannel;
9 5 import org.springframework.data.redis.core.*;
10 6 import org.springframework.util.CollectionUtils;
11 7  
  8 +import java.util.*;
  9 +import java.util.concurrent.TimeUnit;
  10 +
12 11 /**
13 12 * Redis工具类
14 13 * @author swwheihei
... ...
src/main/java/com/genersoft/iot/vmp/vmanager/bean/ErrorCode.java
1 1 package com.genersoft.iot.vmp.vmanager.bean;
2 2  
3   -import io.swagger.v3.oas.annotations.media.Schema;
4   -
5 3 /**
6 4 * 全局错误码
7 5 */
... ... @@ -9,6 +7,7 @@ public enum ErrorCode {
9 7 SUCCESS(0, "成功"),
10 8 ERROR100(100, "失败"),
11 9 ERROR400(400, "参数不全或者错误"),
  10 + ERROR404(404, "资源未找到"),
12 11 ERROR403(403, "无权限操作"),
13 12 ERROR401(401, "请登录后重新请求"),
14 13 ERROR500(500, "系统异常");
... ...
src/main/java/com/genersoft/iot/vmp/vmanager/bean/StreamContent.java 0 → 100644
  1 +package com.genersoft.iot.vmp.vmanager.bean;
  2 +
  3 +import com.genersoft.iot.vmp.common.StreamInfo;
  4 +
  5 +public class StreamContent {
  6 +
  7 + private String app;
  8 + private String stream;
  9 +
  10 + private String ip;
  11 +
  12 + private String flv;
  13 +
  14 + private String https_flv;
  15 + private String ws_flv;
  16 + private String wss_flv;
  17 + private String fmp4;
  18 + private String https_fmp4;
  19 + private String ws_fmp4;
  20 + private String wss_fmp4;
  21 + private String hls;
  22 + private String https_hls;
  23 + private String ws_hls;
  24 + private String wss_hls;
  25 + private String ts;
  26 + private String https_ts;
  27 + private String ws_ts;
  28 + private String wss_ts;
  29 + private String rtmp;
  30 + private String rtmps;
  31 + private String rtsp;
  32 + private String rtsps;
  33 + private String rtc;
  34 +
  35 + private String rtcs;
  36 + private String mediaServerId;
  37 + private Object tracks;
  38 +
  39 + private String startTime;
  40 +
  41 + private String endTime;
  42 +
  43 + private double progress;
  44 +
  45 + public StreamContent(StreamInfo streamInfo) {
  46 + if (streamInfo == null) {
  47 + return;
  48 + }
  49 + this.app = streamInfo.getApp();
  50 + this.stream = streamInfo.getStream();
  51 + if (streamInfo.getFlv() != null) {
  52 + this.flv = streamInfo.getFlv().getUrl();
  53 + }
  54 + if (streamInfo.getHttps_flv() != null) {
  55 + this.https_flv = streamInfo.getHttps_flv().getUrl();
  56 + }
  57 + if (streamInfo.getWs_flv() != null) {
  58 + this.ws_flv = streamInfo.getWs_flv().getUrl();
  59 + }
  60 + if (streamInfo.getWss_flv() != null) {
  61 + this.wss_flv = streamInfo.getWss_flv().getUrl();
  62 + }
  63 + if (streamInfo.getFmp4() != null) {
  64 + this.fmp4 = streamInfo.getFmp4().getUrl();
  65 + }
  66 + if (streamInfo.getWs_fmp4() != null) {
  67 + this.ws_fmp4 = streamInfo.getWs_fmp4().getUrl();
  68 + }
  69 + if (streamInfo.getWss_fmp4() != null) {
  70 + this.wss_fmp4 = streamInfo.getWss_fmp4().getUrl();
  71 + }
  72 + if (streamInfo.getHls() != null) {
  73 + this.hls = streamInfo.getHls().getUrl();
  74 + }
  75 + if (streamInfo.getHttps_hls() != null) {
  76 + this.https_hls = streamInfo.getHttps_hls().getUrl();
  77 + }
  78 + if (streamInfo.getWs_hls() != null) {
  79 + this.ws_hls = streamInfo.getWs_hls().getUrl();
  80 + }
  81 + if (streamInfo.getWss_hls() != null) {
  82 + this.wss_hls = streamInfo.getWss_hls().getUrl();
  83 + }
  84 + if (streamInfo.getTs() != null) {
  85 + this.ts = streamInfo.getTs().getUrl();
  86 + }
  87 + if (streamInfo.getHttps_ts() != null) {
  88 + this.https_ts = streamInfo.getHttps_ts().getUrl();
  89 + }
  90 + if (streamInfo.getWs_ts() != null) {
  91 + this.ws_ts = streamInfo.getWs_ts().getUrl();
  92 + }
  93 + if (streamInfo.getRtmp() != null) {
  94 + this.rtmp = streamInfo.getRtmp().getUrl();
  95 + }
  96 + if (streamInfo.getRtmps() != null) {
  97 + this.rtmps = streamInfo.getRtmps().getUrl();
  98 + }
  99 + if (streamInfo.getRtsp() != null) {
  100 + this.rtsp = streamInfo.getRtsp().getUrl();
  101 + }
  102 + if (streamInfo.getRtsps() != null) {
  103 + this.rtsps = streamInfo.getRtsps().getUrl();
  104 + }
  105 + if (streamInfo.getRtc() != null) {
  106 + this.rtc = streamInfo.getRtc().getUrl();
  107 + }
  108 + if (streamInfo.getRtcs() != null) {
  109 + this.rtcs = streamInfo.getRtcs().getUrl();
  110 + }
  111 +
  112 + this.mediaServerId = streamInfo.getMediaServerId();
  113 + this.tracks = streamInfo.getTracks();
  114 + this.startTime = streamInfo.getStartTime();
  115 + this.endTime = streamInfo.getEndTime();
  116 + this.progress = streamInfo.getProgress();
  117 + }
  118 +
  119 + public String getApp() {
  120 + return app;
  121 + }
  122 +
  123 + public void setApp(String app) {
  124 + this.app = app;
  125 + }
  126 +
  127 + public String getStream() {
  128 + return stream;
  129 + }
  130 +
  131 + public void setStream(String stream) {
  132 + this.stream = stream;
  133 + }
  134 +
  135 + public String getIp() {
  136 + return ip;
  137 + }
  138 +
  139 + public void setIp(String ip) {
  140 + this.ip = ip;
  141 + }
  142 +
  143 + public String getFlv() {
  144 + return flv;
  145 + }
  146 +
  147 + public void setFlv(String flv) {
  148 + this.flv = flv;
  149 + }
  150 +
  151 + public String getHttps_flv() {
  152 + return https_flv;
  153 + }
  154 +
  155 + public void setHttps_flv(String https_flv) {
  156 + this.https_flv = https_flv;
  157 + }
  158 +
  159 + public String getWs_flv() {
  160 + return ws_flv;
  161 + }
  162 +
  163 + public void setWs_flv(String ws_flv) {
  164 + this.ws_flv = ws_flv;
  165 + }
  166 +
  167 + public String getWss_flv() {
  168 + return wss_flv;
  169 + }
  170 +
  171 + public void setWss_flv(String wss_flv) {
  172 + this.wss_flv = wss_flv;
  173 + }
  174 +
  175 + public String getFmp4() {
  176 + return fmp4;
  177 + }
  178 +
  179 + public void setFmp4(String fmp4) {
  180 + this.fmp4 = fmp4;
  181 + }
  182 +
  183 + public String getHttps_fmp4() {
  184 + return https_fmp4;
  185 + }
  186 +
  187 + public void setHttps_fmp4(String https_fmp4) {
  188 + this.https_fmp4 = https_fmp4;
  189 + }
  190 +
  191 + public String getWs_fmp4() {
  192 + return ws_fmp4;
  193 + }
  194 +
  195 + public void setWs_fmp4(String ws_fmp4) {
  196 + this.ws_fmp4 = ws_fmp4;
  197 + }
  198 +
  199 + public String getWss_fmp4() {
  200 + return wss_fmp4;
  201 + }
  202 +
  203 + public void setWss_fmp4(String wss_fmp4) {
  204 + this.wss_fmp4 = wss_fmp4;
  205 + }
  206 +
  207 + public String getHls() {
  208 + return hls;
  209 + }
  210 +
  211 + public void setHls(String hls) {
  212 + this.hls = hls;
  213 + }
  214 +
  215 + public String getHttps_hls() {
  216 + return https_hls;
  217 + }
  218 +
  219 + public void setHttps_hls(String https_hls) {
  220 + this.https_hls = https_hls;
  221 + }
  222 +
  223 + public String getWs_hls() {
  224 + return ws_hls;
  225 + }
  226 +
  227 + public void setWs_hls(String ws_hls) {
  228 + this.ws_hls = ws_hls;
  229 + }
  230 +
  231 + public String getWss_hls() {
  232 + return wss_hls;
  233 + }
  234 +
  235 + public void setWss_hls(String wss_hls) {
  236 + this.wss_hls = wss_hls;
  237 + }
  238 +
  239 + public String getTs() {
  240 + return ts;
  241 + }
  242 +
  243 + public void setTs(String ts) {
  244 + this.ts = ts;
  245 + }
  246 +
  247 + public String getHttps_ts() {
  248 + return https_ts;
  249 + }
  250 +
  251 + public void setHttps_ts(String https_ts) {
  252 + this.https_ts = https_ts;
  253 + }
  254 +
  255 + public String getWs_ts() {
  256 + return ws_ts;
  257 + }
  258 +
  259 + public void setWs_ts(String ws_ts) {
  260 + this.ws_ts = ws_ts;
  261 + }
  262 +
  263 + public String getWss_ts() {
  264 + return wss_ts;
  265 + }
  266 +
  267 + public void setWss_ts(String wss_ts) {
  268 + this.wss_ts = wss_ts;
  269 + }
  270 +
  271 + public String getRtmp() {
  272 + return rtmp;
  273 + }
  274 +
  275 + public void setRtmp(String rtmp) {
  276 + this.rtmp = rtmp;
  277 + }
  278 +
  279 + public String getRtmps() {
  280 + return rtmps;
  281 + }
  282 +
  283 + public void setRtmps(String rtmps) {
  284 + this.rtmps = rtmps;
  285 + }
  286 +
  287 + public String getRtsp() {
  288 + return rtsp;
  289 + }
  290 +
  291 + public void setRtsp(String rtsp) {
  292 + this.rtsp = rtsp;
  293 + }
  294 +
  295 + public String getRtsps() {
  296 + return rtsps;
  297 + }
  298 +
  299 + public void setRtsps(String rtsps) {
  300 + this.rtsps = rtsps;
  301 + }
  302 +
  303 + public String getRtc() {
  304 + return rtc;
  305 + }
  306 +
  307 + public void setRtc(String rtc) {
  308 + this.rtc = rtc;
  309 + }
  310 +
  311 + public String getRtcs() {
  312 + return rtcs;
  313 + }
  314 +
  315 + public void setRtcs(String rtcs) {
  316 + this.rtcs = rtcs;
  317 + }
  318 +
  319 + public String getMediaServerId() {
  320 + return mediaServerId;
  321 + }
  322 +
  323 + public void setMediaServerId(String mediaServerId) {
  324 + this.mediaServerId = mediaServerId;
  325 + }
  326 +
  327 + public Object getTracks() {
  328 + return tracks;
  329 + }
  330 +
  331 + public void setTracks(Object tracks) {
  332 + this.tracks = tracks;
  333 + }
  334 +
  335 + public String getStartTime() {
  336 + return startTime;
  337 + }
  338 +
  339 + public void setStartTime(String startTime) {
  340 + this.startTime = startTime;
  341 + }
  342 +
  343 + public String getEndTime() {
  344 + return endTime;
  345 + }
  346 +
  347 + public void setEndTime(String endTime) {
  348 + this.endTime = endTime;
  349 + }
  350 +
  351 + public double getProgress() {
  352 + return progress;
  353 + }
  354 +
  355 + public void setProgress(double progress) {
  356 + this.progress = progress;
  357 + }
  358 +}
... ...
src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/device/DeviceControl.java
... ... @@ -14,7 +14,6 @@ import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder;
14 14 import com.genersoft.iot.vmp.gb28181.transmit.callback.RequestMessage;
15 15 import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander;
16 16 import com.genersoft.iot.vmp.storager.IVideoManagerStorage;
17   -
18 17 import com.genersoft.iot.vmp.vmanager.bean.ErrorCode;
19 18 import io.swagger.v3.oas.annotations.Operation;
20 19 import io.swagger.v3.oas.annotations.Parameter;
... ... @@ -22,10 +21,8 @@ import io.swagger.v3.oas.annotations.tags.Tag;
22 21 import org.slf4j.Logger;
23 22 import org.slf4j.LoggerFactory;
24 23 import org.springframework.beans.factory.annotation.Autowired;
25   -import org.springframework.http.HttpStatus;
26 24 import org.springframework.http.ResponseEntity;
27 25 import org.springframework.util.ObjectUtils;
28   -import org.springframework.util.StringUtils;
29 26 import org.springframework.web.bind.annotation.*;
30 27 import org.springframework.web.context.request.async.DeferredResult;
31 28  
... ... @@ -130,15 +127,14 @@ public class DeviceControl {
130 127 */
131 128 @Operation(summary = "布防/撤防命令")
132 129 @Parameter(name = "deviceId", description = "设备国标编号", required = true)
133   - @Parameter(name = "channelId", description = "通道国标编号", required = true)
134 130 @Parameter(name = "guardCmdStr", description = "命令, 可选值:SetGuard(布防),ResetGuard(撤防)", required = true)
135 131 @GetMapping("/guard/{deviceId}/{guardCmdStr}")
136   - public DeferredResult<String> guardApi(@PathVariable String deviceId, String channelId, @PathVariable String guardCmdStr) {
  132 + public DeferredResult<String> guardApi(@PathVariable String deviceId, @PathVariable String guardCmdStr) {
137 133 if (logger.isDebugEnabled()) {
138 134 logger.debug("布防/撤防API调用");
139 135 }
140 136 Device device = storager.queryVideoDevice(deviceId);
141   - String key = DeferredResultHolder.CALLBACK_CMD_DEVICECONTROL + deviceId + channelId;
  137 + String key = DeferredResultHolder.CALLBACK_CMD_DEVICECONTROL + deviceId + deviceId;
142 138 String uuid =UUID.randomUUID().toString();
143 139 try {
144 140 cmder.guardCmd(device, guardCmdStr, event -> {
... ...
src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/device/DeviceQuery.java
... ... @@ -99,7 +99,7 @@ public class DeviceQuery {
99 99 @GetMapping("/devices")
100 100 public PageInfo<Device> devices(int page, int count){
101 101  
102   - return storager.queryVideoDeviceList(page, count);
  102 + return storager.queryVideoDeviceList(page, count,null);
103 103 }
104 104  
105 105 /**
... ...
src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/media/MediaController.java
... ... @@ -5,11 +5,11 @@ import com.genersoft.iot.vmp.conf.exception.ControllerException;
5 5 import com.genersoft.iot.vmp.conf.security.SecurityUtils;
6 6 import com.genersoft.iot.vmp.conf.security.dto.LoginUser;
7 7 import com.genersoft.iot.vmp.media.zlm.dto.StreamAuthorityInfo;
8   -import com.genersoft.iot.vmp.service.IStreamProxyService;
9 8 import com.genersoft.iot.vmp.service.IMediaService;
  9 +import com.genersoft.iot.vmp.service.IStreamProxyService;
10 10 import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
11 11 import com.genersoft.iot.vmp.vmanager.bean.ErrorCode;
12   -import com.genersoft.iot.vmp.vmanager.bean.WVPResult;
  12 +import com.genersoft.iot.vmp.vmanager.bean.StreamContent;
13 13 import io.swagger.v3.oas.annotations.Operation;
14 14 import io.swagger.v3.oas.annotations.Parameter;
15 15 import io.swagger.v3.oas.annotations.tags.Tag;
... ... @@ -53,11 +53,11 @@ public class MediaController {
53 53 @Parameter(name = "useSourceIpAsStreamIp", description = "是否使用请求IP作为返回的地址IP")
54 54 @GetMapping(value = "/stream_info_by_app_and_stream")
55 55 @ResponseBody
56   - public StreamInfo getStreamInfoByAppAndStream(HttpServletRequest request, @RequestParam String app,
57   - @RequestParam String stream,
58   - @RequestParam(required = false) String mediaServerId,
59   - @RequestParam(required = false) String callId,
60   - @RequestParam(required = false) Boolean useSourceIpAsStreamIp){
  56 + public StreamContent getStreamInfoByAppAndStream(HttpServletRequest request, @RequestParam String app,
  57 + @RequestParam String stream,
  58 + @RequestParam(required = false) String mediaServerId,
  59 + @RequestParam(required = false) String callId,
  60 + @RequestParam(required = false) Boolean useSourceIpAsStreamIp){
61 61 boolean authority = false;
62 62 if (callId != null) {
63 63 // 权限校验
... ... @@ -88,9 +88,8 @@ public class MediaController {
88 88 streamInfo = mediaService.getStreamInfoByAppAndStreamWithCheck(app, stream, mediaServerId, authority);
89 89 }
90 90  
91   - WVPResult<StreamInfo> result = new WVPResult<>();
92 91 if (streamInfo != null){
93   - return streamInfo;
  92 + return new StreamContent(streamInfo);
94 93 }else {
95 94 //获取流失败,重启拉流后重试一次
96 95 streamProxyService.stop(app,stream);
... ... @@ -109,7 +108,7 @@ public class MediaController {
109 108 streamInfo = mediaService.getStreamInfoByAppAndStreamWithCheck(app, stream, mediaServerId, authority);
110 109 }
111 110 if (streamInfo != null){
112   - return streamInfo;
  111 + return new StreamContent(streamInfo);
113 112 }else {
114 113 throw new ControllerException(ErrorCode.ERROR100);
115 114 }
... ...
src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/play/PlayController.java
... ... @@ -22,6 +22,7 @@ import com.genersoft.iot.vmp.storager.IVideoManagerStorage;
22 22 import com.genersoft.iot.vmp.vmanager.bean.DeferredResultEx;
23 23 import com.genersoft.iot.vmp.vmanager.bean.AudioBroadcastResult;
24 24 import com.genersoft.iot.vmp.vmanager.bean.ErrorCode;
  25 +import com.genersoft.iot.vmp.vmanager.bean.StreamContent;
25 26 import com.genersoft.iot.vmp.vmanager.bean.WVPResult;
26 27 import io.swagger.v3.oas.annotations.Operation;
27 28 import io.swagger.v3.oas.annotations.Parameter;
... ... @@ -85,8 +86,8 @@ public class PlayController {
85 86 @Parameter(name = "deviceId", description = "设备国标编号", required = true)
86 87 @Parameter(name = "channelId", description = "通道国标编号", required = true)
87 88 @GetMapping("/start/{deviceId}/{channelId}")
88   - public DeferredResult<WVPResult<StreamInfo>> play(HttpServletRequest request, @PathVariable String deviceId,
89   - @PathVariable String channelId) {
  89 + public DeferredResult<WVPResult<StreamContent>> play(HttpServletRequest request, @PathVariable String deviceId,
  90 + @PathVariable String channelId) {
90 91  
91 92 // 获取可用的zlm
92 93 Device device = storager.queryVideoDevice(deviceId);
... ... @@ -98,8 +99,8 @@ public class PlayController {
98 99 msg.setKey(key);
99 100 String uuid = UUID.randomUUID().toString();
100 101 msg.setId(uuid);
101   - DeferredResult<WVPResult<StreamInfo>> result = new DeferredResult<>(userSetting.getPlayTimeout().longValue());
102   - DeferredResultEx<WVPResult<StreamInfo>> deferredResultEx = new DeferredResultEx<>(result);
  102 + DeferredResult<WVPResult<StreamContent>> result = new DeferredResult<>(userSetting.getPlayTimeout().longValue());
  103 + DeferredResultEx<WVPResult<StreamContent>> deferredResultEx = new DeferredResultEx<>(result);
103 104  
104 105 result.onTimeout(()->{
105 106 logger.info("点播接口等待超时");
... ... @@ -110,25 +111,22 @@ public class PlayController {
110 111 msg.setData(wvpResult);
111 112 resultHolder.invokeResult(msg);
112 113 });
113   -
114   - if (userSetting.getUseSourceIpAsStreamIp()) {
115   - // TODO 在点播未成功的情况下在此调用接口点播会导致返回的流地址ip错误
116   - deferredResultEx.setFilter(result1 -> {
117   - WVPResult<StreamInfo> wvpResult1 = (WVPResult<StreamInfo>)result1;
118   - WVPResult<StreamInfo> clone = null;
119   - try {
120   - clone = (WVPResult<StreamInfo>)wvpResult1.clone();
121   - } catch (CloneNotSupportedException e) {
122   - throw new RuntimeException(e);
123   - }
124   - if (clone.getCode() == ErrorCode.SUCCESS.getCode()) {
125   - StreamInfo data = clone.getData().clone();
  114 + // TODO 在点播未成功的情况下在此调用接口点播会导致返回的流地址ip错误
  115 + deferredResultEx.setFilter(result1 -> {
  116 + WVPResult<StreamInfo> wvpResult1 = (WVPResult<StreamInfo>)result1;
  117 + WVPResult<StreamContent> resultStream = new WVPResult<>();
  118 + resultStream.setCode(wvpResult1.getCode());
  119 + resultStream.setMsg(wvpResult1.getMsg());
  120 + if (wvpResult1.getCode() == ErrorCode.SUCCESS.getCode()) {
  121 + StreamInfo data = wvpResult1.getData().clone();
  122 + if (userSetting.getUseSourceIpAsStreamIp()) {
126 123 data.channgeStreamIp(request.getLocalName());
127   - clone.setData(data);
128 124 }
129   - return clone;
130   - });
131   - }
  125 + resultStream.setData(new StreamContent(wvpResult1.getData()));
  126 + }
  127 + return resultStream;
  128 + });
  129 +
132 130  
133 131 // 录像查询以channelId作为deviceId查询
134 132 resultHolder.put(key, uuid, deferredResultEx);
... ...
src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/playback/PlaybackController.java
... ... @@ -10,6 +10,7 @@ import com.genersoft.iot.vmp.media.zlm.ZLMRTPServerFactory;
10 10 import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
11 11 import com.genersoft.iot.vmp.service.IPlayService;
12 12 import com.genersoft.iot.vmp.vmanager.bean.ErrorCode;
  13 +import com.genersoft.iot.vmp.vmanager.bean.StreamContent;
13 14 import com.genersoft.iot.vmp.vmanager.bean.WVPResult;
14 15 import io.swagger.v3.oas.annotations.Operation;
15 16 import io.swagger.v3.oas.annotations.Parameter;
... ... @@ -32,6 +33,7 @@ import org.springframework.web.context.request.async.DeferredResult;
32 33 import javax.sip.InvalidArgumentException;
33 34 import javax.sip.SipException;
34 35 import java.text.ParseException;
  36 +import java.util.UUID;
35 37  
36 38 /**
37 39 * @author lin
... ... @@ -68,24 +70,37 @@ public class PlaybackController {
68 70 @Parameter(name = "startTime", description = "开始时间", required = true)
69 71 @Parameter(name = "endTime", description = "结束时间", required = true)
70 72 @GetMapping("/start/{deviceId}/{channelId}")
71   - public DeferredResult<WVPResult<StreamInfo>> play(@PathVariable String deviceId, @PathVariable String channelId,
72   - String startTime, String endTime) {
  73 + public DeferredResult<WVPResult<StreamContent>> play(@PathVariable String deviceId, @PathVariable String channelId,
  74 + String startTime, String endTime) {
73 75  
74 76 if (logger.isDebugEnabled()) {
75 77 logger.debug(String.format("设备回放 API调用,deviceId:%s ,channelId:%s", deviceId, channelId));
76 78 }
77 79  
  80 + String uuid = UUID.randomUUID().toString();
  81 + String key = DeferredResultHolder.CALLBACK_CMD_PLAYBACK + deviceId + channelId;
  82 + DeferredResult<WVPResult<StreamContent>> result = new DeferredResult<>(30000L);
  83 + resultHolder.put(key, uuid, result);
78 84  
79   - return playService.playBack(deviceId, channelId, startTime, endTime, null,
  85 + WVPResult<StreamContent> wvpResult = new WVPResult<>();
  86 +
  87 + RequestMessage msg = new RequestMessage();
  88 + msg.setKey(key);
  89 + msg.setId(uuid);
  90 +
  91 + playService.playBack(deviceId, channelId, startTime, endTime, null,
80 92 playBackResult->{
81   - if (playBackResult.getCode() != ErrorCode.SUCCESS.getCode()) {
82   - RequestMessage data = playBackResult.getData();
83   - data.setData(WVPResult.fail(playBackResult.getCode(), playBackResult.getMsg()));
84   - resultHolder.invokeResult(data);
85   - }else {
86   - resultHolder.invokeResult(playBackResult.getData());
  93 + wvpResult.setCode(playBackResult.getCode());
  94 + wvpResult.setMsg(playBackResult.getMsg());
  95 + if (playBackResult.getCode() == ErrorCode.SUCCESS.getCode()) {
  96 + StreamInfo streamInfo = (StreamInfo)playBackResult.getData();
  97 + wvpResult.setData(new StreamContent(streamInfo));
87 98 }
  99 + msg.setData(wvpResult);
  100 + resultHolder.invokeResult(msg);
88 101 });
  102 +
  103 + return result;
89 104 }
90 105  
91 106  
... ...
src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/record/GBRecordController.java
... ... @@ -8,6 +8,7 @@ import com.genersoft.iot.vmp.service.IDeviceService;
8 8 import com.genersoft.iot.vmp.service.IPlayService;
9 9 import com.genersoft.iot.vmp.utils.DateUtil;
10 10 import com.genersoft.iot.vmp.vmanager.bean.ErrorCode;
  11 +import com.genersoft.iot.vmp.vmanager.bean.StreamContent;
11 12 import com.genersoft.iot.vmp.vmanager.bean.WVPResult;
12 13  
13 14 import io.swagger.v3.oas.annotations.Operation;
... ... @@ -121,15 +122,33 @@ public class GBRecordController {
121 122 @Parameter(name = "endTime", description = "结束时间", required = true)
122 123 @Parameter(name = "downloadSpeed", description = "下载倍速", required = true)
123 124 @GetMapping("/download/start/{deviceId}/{channelId}")
124   - public DeferredResult<WVPResult<StreamInfo>> download(@PathVariable String deviceId, @PathVariable String channelId,
  125 + public DeferredResult<WVPResult<StreamContent>> download(@PathVariable String deviceId, @PathVariable String channelId,
125 126 String startTime, String endTime, String downloadSpeed) {
126 127  
127 128 if (logger.isDebugEnabled()) {
128 129 logger.debug(String.format("历史媒体下载 API调用,deviceId:%s,channelId:%s,downloadSpeed:%s", deviceId, channelId, downloadSpeed));
129 130 }
130 131  
131   - DeferredResult<WVPResult<StreamInfo>> result = playService.download(deviceId, channelId, startTime, endTime, Integer.parseInt(downloadSpeed), null, hookCallBack->{
132   - resultHolder.invokeResult(hookCallBack.getData());
  132 + String uuid = UUID.randomUUID().toString();
  133 + String key = DeferredResultHolder.CALLBACK_CMD_DOWNLOAD + deviceId + channelId;
  134 + DeferredResult<WVPResult<StreamContent>> result = new DeferredResult<>(30000L);
  135 + resultHolder.put(key, uuid, result);
  136 + RequestMessage msg = new RequestMessage();
  137 + msg.setId(uuid);
  138 + msg.setKey(key);
  139 +
  140 + WVPResult<StreamContent> wvpResult = new WVPResult<>();
  141 +
  142 + playService.download(deviceId, channelId, startTime, endTime, Integer.parseInt(downloadSpeed), null, playBackResult->{
  143 +
  144 + wvpResult.setCode(playBackResult.getCode());
  145 + wvpResult.setMsg(playBackResult.getMsg());
  146 + if (playBackResult.getCode() == ErrorCode.SUCCESS.getCode()) {
  147 + StreamInfo streamInfo = (StreamInfo)playBackResult.getData();
  148 + wvpResult.setData(new StreamContent(streamInfo));
  149 + }
  150 + msg.setData(wvpResult);
  151 + resultHolder.invokeResult(msg);
133 152 });
134 153  
135 154 return result;
... ... @@ -168,7 +187,11 @@ public class GBRecordController {
168 187 @Parameter(name = "channelId", description = "通道国标编号", required = true)
169 188 @Parameter(name = "stream", description = "流ID", required = true)
170 189 @GetMapping("/download/progress/{deviceId}/{channelId}/{stream}")
171   - public StreamInfo getProgress(@PathVariable String deviceId, @PathVariable String channelId, @PathVariable String stream) {
172   - return playService.getDownLoadInfo(deviceId, channelId, stream);
  190 + public StreamContent getProgress(@PathVariable String deviceId, @PathVariable String channelId, @PathVariable String stream) {
  191 + StreamInfo downLoadInfo = playService.getDownLoadInfo(deviceId, channelId, stream);
  192 + if (downLoadInfo == null) {
  193 + throw new ControllerException(ErrorCode.ERROR404);
  194 + }
  195 + return new StreamContent(downLoadInfo);
173 196 }
174 197 }
... ...
src/main/java/com/genersoft/iot/vmp/vmanager/streamProxy/StreamProxyController.java
1 1 package com.genersoft.iot.vmp.vmanager.streamProxy;
2 2  
3 3 import com.alibaba.fastjson2.JSONObject;
4   -import com.genersoft.iot.vmp.common.StreamInfo;
5 4 import com.genersoft.iot.vmp.conf.exception.ControllerException;
6 5 import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
7 6 import com.genersoft.iot.vmp.media.zlm.dto.StreamProxyItem;
8 7 import com.genersoft.iot.vmp.service.IMediaServerService;
9 8 import com.genersoft.iot.vmp.service.IStreamProxyService;
10 9 import com.genersoft.iot.vmp.vmanager.bean.ErrorCode;
  10 +import com.genersoft.iot.vmp.vmanager.bean.StreamContent;
11 11 import com.github.pagehelper.PageInfo;
12 12 import io.swagger.v3.oas.annotations.Operation;
13 13 import io.swagger.v3.oas.annotations.Parameter;
... ... @@ -58,7 +58,7 @@ public class StreamProxyController {
58 58 })
59 59 @PostMapping(value = "/save")
60 60 @ResponseBody
61   - public StreamInfo save(@RequestBody StreamProxyItem param){
  61 + public StreamContent save(@RequestBody StreamProxyItem param){
62 62 logger.info("添加代理: " + JSONObject.toJSONString(param));
63 63 if (ObjectUtils.isEmpty(param.getMediaServerId())) {
64 64 param.setMediaServerId("auto");
... ... @@ -69,7 +69,7 @@ public class StreamProxyController {
69 69 if (ObjectUtils.isEmpty(param.getGbId())) {
70 70 param.setGbId(null);
71 71 }
72   - return streamProxyService.save(param);
  72 + return new StreamContent(streamProxyService.save(param));
73 73 }
74 74  
75 75 @GetMapping(value = "/ffmpeg_cmd/list")
... ...
src/main/java/com/genersoft/iot/vmp/vmanager/streamPush/StreamPushController.java
... ... @@ -11,22 +11,16 @@ import com.genersoft.iot.vmp.conf.security.dto.LoginUser;
11 11 import com.genersoft.iot.vmp.gb28181.bean.GbStream;
12 12 import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder;
13 13 import com.genersoft.iot.vmp.gb28181.transmit.callback.RequestMessage;
14   -import com.genersoft.iot.vmp.media.zlm.dto.StreamAuthorityInfo;
15 14 import com.genersoft.iot.vmp.media.zlm.dto.StreamPushItem;
16 15 import com.genersoft.iot.vmp.service.IMediaServerService;
17 16 import com.genersoft.iot.vmp.service.IMediaService;
18 17 import com.genersoft.iot.vmp.service.IStreamPushService;
19 18 import com.genersoft.iot.vmp.service.impl.StreamPushUploadFileHandler;
20   -import com.genersoft.iot.vmp.vmanager.bean.BatchGBStreamParam;
21   -import com.genersoft.iot.vmp.vmanager.bean.ErrorCode;
22   -import com.genersoft.iot.vmp.vmanager.bean.StreamPushExcelDto;
23   -import com.genersoft.iot.vmp.vmanager.bean.WVPResult;
  19 +import com.genersoft.iot.vmp.vmanager.bean.*;
24 20 import com.github.pagehelper.PageInfo;
25   -
26 21 import io.swagger.v3.oas.annotations.Operation;
27 22 import io.swagger.v3.oas.annotations.Parameter;
28 23 import io.swagger.v3.oas.annotations.tags.Tag;
29   -import org.apache.poi.sl.usermodel.Sheet;
30 24 import org.slf4j.Logger;
31 25 import org.slf4j.LoggerFactory;
32 26 import org.springframework.beans.factory.annotation.Autowired;
... ... @@ -34,12 +28,10 @@ import org.springframework.http.HttpStatus;
34 28 import org.springframework.http.ResponseEntity;
35 29 import org.springframework.stereotype.Controller;
36 30 import org.springframework.util.ObjectUtils;
37   -import org.springframework.util.StringUtils;
38 31 import org.springframework.web.bind.annotation.*;
39 32 import org.springframework.web.context.request.async.DeferredResult;
40 33 import org.springframework.web.multipart.MultipartFile;
41 34  
42   -import javax.servlet.http.HttpServletRequest;
43 35 import java.io.IOException;
44 36 import java.io.InputStream;
45 37 import java.util.HashMap;
... ... @@ -243,8 +235,8 @@ public class StreamPushController {
243 235 @Parameter(name = "app", description = "应用名", required = true)
244 236 @Parameter(name = "stream", description = "流id", required = true)
245 237 @Parameter(name = "mediaServerId", description = "媒体服务器id")
246   - public StreamInfo getPlayUrl(@RequestParam String app,@RequestParam String stream,
247   - @RequestParam(required = false) String mediaServerId){
  238 + public StreamContent getPlayUrl(@RequestParam String app, @RequestParam String stream,
  239 + @RequestParam(required = false) String mediaServerId){
248 240 boolean authority = false;
249 241 // 是否登陆用户, 登陆用户返回完整信息
250 242 LoginUser userInfo = SecurityUtils.getUserInfo();
... ... @@ -259,7 +251,7 @@ public class StreamPushController {
259 251 if (streamInfo == null){
260 252 throw new ControllerException(ErrorCode.ERROR100.getCode(), "获取播放地址失败");
261 253 }
262   - return streamInfo;
  254 + return new StreamContent(streamInfo);
263 255 }
264 256  
265 257 /**
... ...
src/main/java/com/genersoft/iot/vmp/web/gb28181/ApiDeviceController.java
... ... @@ -10,8 +10,10 @@ import com.github.pagehelper.PageInfo;
10 10 import org.slf4j.Logger;
11 11 import org.slf4j.LoggerFactory;
12 12 import org.springframework.beans.factory.annotation.Autowired;
  13 +import org.springframework.util.StringUtils;
13 14 import org.springframework.web.bind.annotation.*;
14 15  
  16 +import java.util.Arrays;
15 17 import java.util.List;
16 18  
17 19 /**
... ... @@ -59,10 +61,10 @@ public class ApiDeviceController {
59 61 JSONObject result = new JSONObject();
60 62 List<Device> devices;
61 63 if (start == null || limit ==null) {
62   - devices = storager.queryVideoDeviceList();
  64 + devices = storager.queryVideoDeviceList(online);
63 65 result.put("DeviceCount", devices.size());
64 66 }else {
65   - PageInfo<Device> deviceList = storager.queryVideoDeviceList(start/limit, limit);
  67 + PageInfo<Device> deviceList = storager.queryVideoDeviceList(start/limit, limit,online);
66 68 result.put("DeviceCount", deviceList.getTotal());
67 69 devices = deviceList.getList();
68 70 }
... ... @@ -94,6 +96,7 @@ public class ApiDeviceController {
94 96  
95 97 @RequestMapping(value = "/channellist")
96 98 public JSONObject channellist( String serial,
  99 + @RequestParam(required = false)String code,
97 100 @RequestParam(required = false)String channel_type,
98 101 @RequestParam(required = false)String dir_serial ,
99 102 @RequestParam(required = false)Integer start,
... ... @@ -113,12 +116,17 @@ public class ApiDeviceController {
113 116 return result;
114 117 }
115 118 List<DeviceChannel> deviceChannels;
116   - List<DeviceChannel> allDeviceChannelList = storager.queryChannelsByDeviceId(serial);
  119 + List<String> channelIds = null;
  120 + if (!StringUtils.isEmpty(code)) {
  121 + String[] split = code.trim().split(",");
  122 + channelIds = Arrays.asList(split);
  123 + }
  124 + List<DeviceChannel> allDeviceChannelList = storager.queryChannelsByDeviceId(serial,online,channelIds);
117 125 if (start == null || limit ==null) {
118 126 deviceChannels = allDeviceChannelList;
119 127 result.put("ChannelCount", deviceChannels.size());
120 128 }else {
121   - deviceChannels = storager.queryChannelsByDeviceIdWithStartAndLimit(serial, null, null, null,start, limit);
  129 + deviceChannels = storager.queryChannelsByDeviceIdWithStartAndLimit(serial, null, null, online,start, limit,channelIds);
122 130 int total = allDeviceChannelList.size();
123 131 result.put("ChannelCount", total);
124 132 }
... ... @@ -148,9 +156,9 @@ public class ApiDeviceController {
148 156 // 1-IETF RFC3261,
149 157 // 2-基于口令的双向认证,
150 158 // 3-基于数字证书的双向认证
151   - deviceJOSNChannel.put("Status", deviceChannel.getStatus());
152   - deviceJOSNChannel.put("Longitude", deviceChannel.getLongitudeWgs84());
153   - deviceJOSNChannel.put("Latitude", deviceChannel.getLatitudeWgs84());
  159 + deviceJOSNChannel.put("Status", deviceChannel.getStatus() == 1 ? "ON":"OFF");
  160 + deviceJOSNChannel.put("Longitude", deviceChannel.getLongitude());
  161 + deviceJOSNChannel.put("Latitude", deviceChannel.getLatitude());
154 162 deviceJOSNChannel.put("PTZType ", deviceChannel.getPTZType()); // 云台类型, 0 - 未知, 1 - 球机, 2 - 半球,
155 163 // 3 - 固定枪机, 4 - 遥控枪机
156 164 deviceJOSNChannel.put("CustomPTZType", "");
... ...
src/main/java/com/genersoft/iot/vmp/web/gb28181/ApiStreamController.java
... ... @@ -12,7 +12,6 @@ import com.genersoft.iot.vmp.service.IDeviceService;
12 12 import com.genersoft.iot.vmp.service.IPlayService;
13 13 import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
14 14 import com.genersoft.iot.vmp.storager.IVideoManagerStorage;
15   -import com.genersoft.iot.vmp.vmanager.gb28181.play.bean.PlayResult;
16 15 import org.slf4j.Logger;
17 16 import org.slf4j.LoggerFactory;
18 17 import org.springframework.beans.factory.annotation.Autowired;
... ... @@ -120,12 +119,12 @@ public class ApiStreamController {
120 119 result.put("ChannelID", code);
121 120 result.put("ChannelName", deviceChannel.getName());
122 121 result.put("ChannelCustomName", "");
123   - result.put("FLV", streamInfo.getFlv());
124   - result.put("WS_FLV", streamInfo.getWs_flv());
125   - result.put("RTMP", streamInfo.getRtmp());
126   - result.put("HLS", streamInfo.getHls());
127   - result.put("RTSP", streamInfo.getRtsp());
128   - result.put("WEBRTC", streamInfo.getRtc());
  122 + result.put("FLV", streamInfo.getFlv().getUrl());
  123 + result.put("WS_FLV", streamInfo.getWs_flv().getUrl());
  124 + result.put("RTMP", streamInfo.getRtmp().getUrl());
  125 + result.put("HLS", streamInfo.getHls().getUrl());
  126 + result.put("RTSP", streamInfo.getRtsp().getUrl());
  127 + result.put("WEBRTC", streamInfo.getRtc().getUrl());
129 128 result.put("CDN", "");
130 129 result.put("SnapURL", "");
131 130 result.put("Transport", device.getTransport());
... ...
src/main/resources/all-application.yml
... ... @@ -168,7 +168,7 @@ user-settings:
168 168 # 保存移动位置历史轨迹:true:保留历史数据,false:仅保留最后的位置(默认)
169 169 save-position-history: false
170 170 # 点播等待超时时间,单位:毫秒
171   - play-timeout: 3000
  171 + play-timeout: 18000
172 172 # 上级点播等待超时时间,单位:毫秒
173 173 platform-play-timeout: 60000
174 174 # 是否开启接口鉴权
... ... @@ -186,7 +186,7 @@ user-settings:
186 186 use-pushing-as-status: true
187 187 # 使用来源请求ip作为streamIp,当且仅当你只有zlm节点它与wvp在一起的情况下开启
188 188 use-source-ip-as-stream-ip: true
189   - # 按需拉流, true:有人观看拉流,无人观看释放, false:拉起后不自动释放
  189 + # 国标点播 按需拉流, true:有人观看拉流,无人观看释放, false:拉起后不自动释放
190 190 stream-on-demand: true
191 191 # 推流鉴权, 默认开启
192 192 push-authority: true
... ... @@ -195,6 +195,10 @@ user-settings:
195 195 gb-send-stream-strict: false
196 196 # 设备上线时是否自动同步通道
197 197 sync-channel-on-device-online: false
  198 + # 是否使用设备来源Ip作为回复IP, 不设置则为 false
  199 + sip-use-source-ip-as-remote-address: false
  200 + # 是否开启sip日志
  201 + sip-log: true
198 202 # 收到ack消息后开始发流,默认false, 回复200ok后直接开始发流
199 203 push-stream-after-ack: false
200 204  
... ...
web_src/src/components/CloudRecordDetail.vue
... ... @@ -30,7 +30,7 @@
30 30 </el-aside>
31 31 <el-main style="padding: 22px">
32 32 <div class="playBox" :style="playerStyle">
33   - <player ref="recordVideoPlayer" :videoUrl="videoUrl" fluent autoplay :height="true" ></player>
  33 + <player ref="recordVideoPlayer" :videoUrl="videoUrl" :height="true" style="width: 100%" ></player>
34 34 </div>
35 35 <div class="player-option-box" >
36 36 <el-slider
... ... @@ -310,7 +310,20 @@
310 310 let h = parseInt(val/3600);
311 311 let m = parseInt((val - h*3600)/60);
312 312 let s = parseInt(val - h*3600 - m*60);
313   - return h + ":" + m + ":" + s
  313 +
  314 + let hStr = h;
  315 + let mStr = m;
  316 + let sStr = s;
  317 + if (h < 10) {
  318 + hStr = "0" + hStr;
  319 + }
  320 + if (m < 10) {
  321 + mStr = "0" + mStr;s
  322 + }
  323 + if (s < 10) {
  324 + sStr = "0" + sStr;
  325 + }
  326 + return hStr + ":" + mStr + ":" + sStr
314 327 },
315 328 deleteRecord(){
316 329 // TODO
... ...
web_src/src/components/GBRecordDetail.vue 0 → 100644
  1 +<template>
  2 + <div style="width: 100%">
  3 + <div class="page-header" >
  4 + <div class="page-title">
  5 + <el-page-header @back="goBack" content="国标录像"></el-page-header>
  6 + </div>
  7 + </div>
  8 + <el-container>
  9 + <el-aside width="300px">
  10 + <div class="record-list-box-box">
  11 + <el-date-picker size="mini" v-model="chooseDate" type="date" value-format="yyyy-MM-dd" placeholder="日期" @change="dateChange()"></el-date-picker>
  12 + <div class="record-list-box" v-loading="recordsLoading" :style="recordListStyle">
  13 + <ul v-if="detailFiles.length >0" class="infinite-list record-list" >
  14 + <li v-for="item in detailFiles" class="infinite-list-item record-list-item" >
  15 +
  16 + <el-tag v-if="chooseFile != item" @click="checkedFile(item)">
  17 + <i class="el-icon-video-camera" ></i>
  18 + {{ moment(item.startTime).format('HH:mm:ss')}}-{{ moment(item.endTime).format('HH:mm:ss')}}
  19 + </el-tag>
  20 + <el-tag v-if="chooseFile == item" type="danger" >
  21 + <i class="el-icon-video-camera" ></i>
  22 + {{ moment(item.startTime).format('HH:mm:ss')}}-{{ moment(item.endTime).format('HH:mm:ss')}}
  23 + </el-tag>
  24 + <i style="color: #409EFF;margin-left: 5px;" class="el-icon-download" @click="downloadRecord(item)" ></i>
  25 + </li>
  26 + </ul>
  27 + </div>
  28 + <div size="mini" v-if="detailFiles.length ==0" class="record-list-no-val" >暂无数据</div>
  29 + </div>
  30 +
  31 + </el-aside>
  32 + <el-main style="padding-bottom: 10px;">
  33 + <div class="playBox" :style="playerStyle">
  34 + <player ref="recordVideoPlayer"
  35 + :videoUrl="videoUrl"
  36 + :error="videoError"
  37 + :message="videoError"
  38 + :hasAudio="hasAudio"
  39 + style="max-height: 100%"
  40 + fluent autoplay live ></player>
  41 + </div>
  42 + <div class="player-option-box">
  43 + <div>
  44 + <el-button-group >
  45 + <el-time-picker
  46 + size="mini"
  47 + is-range
  48 + align="left"
  49 + v-model="timeRange"
  50 + value-format="yyyy-MM-dd HH:mm:ss"
  51 + range-separator="至"
  52 + start-placeholder="开始时间"
  53 + end-placeholder="结束时间"
  54 + @change="timePickerChange"
  55 + placeholder="选择时间范围">
  56 + </el-time-picker>
  57 + </el-button-group>
  58 +
  59 + <el-button-group >
  60 + <el-button size="mini" class="iconfont icon-zanting" title="开始" @click="gbPause()"></el-button>
  61 + <el-button size="mini" class="iconfont icon-kaishi" title="暂停" @click="gbPlay()"></el-button>
  62 + <el-dropdown size="mini" title="播放倍速" @command="gbScale">
  63 + <el-button size="mini">
  64 + 倍速 <i class="el-icon-arrow-down el-icon--right"></i>
  65 + </el-button>
  66 + <el-dropdown-menu slot="dropdown">
  67 + <el-dropdown-item command="0.25">0.25倍速</el-dropdown-item>
  68 + <el-dropdown-item command="0.5">0.5倍速</el-dropdown-item>
  69 + <el-dropdown-item command="1.0">1倍速</el-dropdown-item>
  70 + <el-dropdown-item command="2.0">2倍速</el-dropdown-item>
  71 + <el-dropdown-item command="4.0">4倍速</el-dropdown-item>
  72 + </el-dropdown-menu>
  73 + </el-dropdown>
  74 + <el-button size="mini" class="iconfont icon-xiazai1" title="下载选定录像" @click="downloadRecord()"></el-button>
  75 + <el-button v-if="sliderMIn === 0 && sliderMax === 86400" size="mini" class="iconfont icon-slider" title="放大滑块" @click="setSliderFit()"></el-button>
  76 + <el-button v-if="sliderMIn !== 0 || sliderMax !== 86400" size="mini" class="iconfont icon-slider-right" title="恢复滑块" @click="setSliderFit()"></el-button>
  77 + </el-button-group>
  78 + </div>
  79 + <el-slider
  80 + class="playtime-slider"
  81 + v-model="playTime"
  82 + id="playtimeSlider"
  83 + :disabled="detailFiles.length === 0"
  84 + :min="sliderMIn"
  85 + :max="sliderMax"
  86 + :range="true"
  87 + :format-tooltip="playTimeFormat"
  88 + @change="playTimeChange"
  89 + :marks="playTimeSliderMarks">
  90 + </el-slider>
  91 + <div class="slider-val-box">
  92 + <div class="slider-val" v-for="item of detailFiles" :style="'width:' + getDataWidth(item) + '%; left:' + getDataLeft(item) + '%'"></div>
  93 + </div>
  94 + </div>
  95 +
  96 + </el-main>
  97 + </el-container>
  98 + <recordDownload ref="recordDownload"></recordDownload>
  99 + </div>
  100 +</template>
  101 +
  102 +
  103 +<script>
  104 + import uiHeader from '../layout/UiHeader.vue'
  105 + import player from './common/jessibuca.vue'
  106 + import moment from 'moment'
  107 + import recordDownload from './dialog/recordDownload.vue'
  108 + export default {
  109 + name: 'app',
  110 + components: {
  111 + uiHeader, player,recordDownload
  112 + },
  113 + data() {
  114 + return {
  115 + deviceId: this.$route.params.deviceId,
  116 + channelId: this.$route.params.channelId,
  117 + recordsLoading: false,
  118 + streamId: "",
  119 + hasAudio: false,
  120 + detailFiles: [],
  121 + chooseDate: null,
  122 + videoUrl: null,
  123 + chooseFile: null,
  124 + streamInfo: null,
  125 + app: null,
  126 + mediaServerId: null,
  127 + ssrc: null,
  128 +
  129 + sliderMIn: 0,
  130 + sliderMax: 86400,
  131 + autoPlay: true,
  132 + taskUpdate: null,
  133 + tabVal: "running",
  134 + recordListStyle: {
  135 + height: this.winHeight + "px",
  136 + overflow: "auto",
  137 + margin: "10px auto 10px auto"
  138 + },
  139 + playerStyle: {
  140 + "margin": "0 auto 20px auto",
  141 + "height": this.winHeight + "px",
  142 + },
  143 + winHeight: window.innerHeight - 240,
  144 + playTime: null,
  145 + timeRange: null,
  146 + startTime: null,
  147 + endTime: null,
  148 + playTimeSliderMarks: {
  149 + 0: "00:00",
  150 + 3600: "01:00",
  151 + 7200: "02:00",
  152 + 10800: "03:00",
  153 + 14400: "04:00",
  154 + 18000: "05:00",
  155 + 21600: "06:00",
  156 + 25200: "07:00",
  157 + 28800: "08:00",
  158 + 32400: "09:00",
  159 + 36000: "10:00",
  160 + 39600: "11:00",
  161 + 43200: "12:00",
  162 + 46800: "13:00",
  163 + 50400: "14:00",
  164 + 54000: "15:00",
  165 + 57600: "16:00",
  166 + 61200: "17:00",
  167 + 64800: "18:00",
  168 + 68400: "19:00",
  169 + 72000: "20:00",
  170 + 75600: "21:00",
  171 + 79200: "22:00",
  172 + 82800: "23:00",
  173 + 86400: "24:00",
  174 + },
  175 + };
  176 + },
  177 + computed: {
  178 +
  179 + },
  180 + mounted() {
  181 + this.recordListStyle.height = this.winHeight + "px";
  182 + this.playerStyle["height"] = this.winHeight + "px";
  183 + this.chooseDate = moment().format('YYYY-MM-DD')
  184 + this.dateChange();
  185 + },
  186 + destroyed() {
  187 + this.$destroy('recordVideoPlayer');
  188 + },
  189 + methods: {
  190 + dateChange(){
  191 + if (!this.chooseDate) {
  192 + return;
  193 + }
  194 +
  195 + this.setTime(this.chooseDate + " 00:00:00", this.chooseDate + " 23:59:59");
  196 + this.recordsLoading = true;
  197 + this.detailFiles = [];
  198 + this.$axios({
  199 + method: 'get',
  200 + url: '/api/gb_record/query/' + this.deviceId + '/' + this.channelId + '?startTime=' + this.startTime + '&endTime=' + this.endTime
  201 + }).then((res)=>{
  202 + this.recordsLoading = false;
  203 + if(res.data.code === 0) {
  204 + // 处理时间信息
  205 + this.detailFiles = res.data.data.recordList;
  206 +
  207 + }else {
  208 + this.$message({
  209 + showClose: true,
  210 + message: res.data.msg,
  211 + type: "error",
  212 + });
  213 + }
  214 +
  215 + }).catch((e)=> {
  216 + this.recordsLoading = false;
  217 + // that.videoHistory.searchHistoryResult = falsificationData.recordData;
  218 + });
  219 + },
  220 + moment: function (v) {
  221 + return moment(v)
  222 + },
  223 + setTime: function (startTime, endTime){
  224 + this.startTime = startTime;
  225 + this.endTime = endTime;
  226 + let start = (new Date(this.startTime).getTime() - new Date(this.chooseDate + " 00:00:00").getTime())/1000;
  227 + let end = (new Date(this.endTime).getTime() - new Date(this.chooseDate + " 00:00:00").getTime())/1000;
  228 + console.log(start)
  229 + console.log(end)
  230 + this.playTime = [start, end];
  231 + this.timeRange = [startTime, endTime];
  232 + },
  233 + videoError: function (e) {
  234 + console.log("播放器错误:" + JSON.stringify(e));
  235 + },
  236 + checkedFile(file){
  237 + this.chooseFile = file;
  238 + this.setTime(file.startTime, file.endTime);
  239 + // 开始回放
  240 + this.playRecord()
  241 + },
  242 + playRecord: function () {
  243 +
  244 + if (this.streamId !== "") {
  245 + this.stopPlayRecord(()=> {
  246 + this.streamId = "";
  247 + this.playRecord();
  248 + })
  249 + } else {
  250 + this.$axios({
  251 + method: 'get',
  252 + url: '/api/playback/start/' + this.deviceId + '/' + this.channelId + '?startTime=' + this.startTime + '&endTime=' +
  253 + this.endTime
  254 + }).then((res)=> {
  255 + if (res.data.code === 0) {
  256 + this.streamInfo = res.data.data;
  257 + this.app = this.streamInfo.app;
  258 + this.streamId = this.streamInfo.stream;
  259 + this.mediaServerId = this.streamInfo.mediaServerId;
  260 + this.ssrc = this.streamInfo.ssrc;
  261 + this.videoUrl = this.getUrlByStreamInfo();
  262 + }else {
  263 + this.$message({
  264 + showClose: true,
  265 + message: res.data.msg,
  266 + type: "error",
  267 + });
  268 + }
  269 + });
  270 + }
  271 + },
  272 + gbPlay(){
  273 + console.log('前端控制:播放');
  274 + this.$axios({
  275 + method: 'get',
  276 + url: '/api/playback/resume/' + this.streamId
  277 + }).then((res)=> {
  278 + this.$refs["recordVideoPlayer"].play(this.videoUrl)
  279 + });
  280 + },
  281 + gbPause(){
  282 + console.log('前端控制:暂停');
  283 + this.$axios({
  284 + method: 'get',
  285 + url: '/api/playback/pause/' + this.streamId
  286 + }).then(function (res) {});
  287 + },
  288 + gbScale(command){
  289 + console.log('前端控制:倍速 ' + command);
  290 + this.$axios({
  291 + method: 'get',
  292 + url: `/api/playback/speed/${this.streamId }/${command}`
  293 + }).then(function (res) {});
  294 + },
  295 + downloadRecord: function (row) {
  296 + if (!row) {
  297 + let startTimeStr = moment(new Date(this.chooseDate + " 00:00:00").getTime() + this.playTime[0]*1000).format("YYYY-MM-DD HH:mm:ss");
  298 + let endTimeStr = moment(new Date(this.chooseDate + " 00:00:00").getTime() + this.playTime[1]*1000).format("YYYY-MM-DD HH:mm:ss");
  299 + console.log(startTimeStr);
  300 + console.log(endTimeStr);
  301 + row = {
  302 + startTime: startTimeStr,
  303 + endTime: endTimeStr
  304 + }
  305 + }
  306 + if (this.streamId !== "") {
  307 + this.stopPlayRecord(()=> {
  308 + this.streamId = "";
  309 + this.downloadRecord(row);
  310 + })
  311 + }else {
  312 + this.$axios({
  313 + method: 'get',
  314 + url: '/api/gb_record/download/start/' + this.deviceId + '/' + this.channelId + '?startTime=' + row.startTime + '&endTime=' +
  315 + row.endTime + '&downloadSpeed=4'
  316 + }).then( (res)=> {
  317 + if (res.data.code === 0) {
  318 + let streamInfo = res.data.data;
  319 + this.$refs.recordDownload.openDialog(this.deviceId, this.channelId, streamInfo.app, streamInfo.stream, streamInfo.mediaServerId);
  320 + }else {
  321 + this.$message({
  322 + showClose: true,
  323 + message: res.data.msg,
  324 + type: "error",
  325 + });
  326 + }
  327 + });
  328 + }
  329 + },
  330 + stopDownloadRecord: function (callback) {
  331 + this.$refs["recordVideoPlayer"].pause();
  332 + this.videoUrl = '';
  333 + this.$axios({
  334 + method: 'get',
  335 + url: '/api/gb_record/download/stop/' + this.deviceId + "/" + this.channelId+ "/" + this.streamId
  336 + }).then((res)=> {
  337 + if (callback) callback(res)
  338 + });
  339 + },
  340 + stopPlayRecord: function (callback) {
  341 + this.$refs["recordVideoPlayer"].pause();
  342 + this.videoUrl = '';
  343 + this.$axios({
  344 + method: 'get',
  345 + url: '/api/playback/stop/' + this.deviceId + "/" + this.channelId + "/" + this.streamId
  346 + }).then(function (res) {
  347 + if (callback) callback()
  348 + });
  349 + },
  350 + getDataWidth(item){
  351 + let timeForFile = this.getTimeForFile(item);
  352 + let result = (timeForFile[2])/((this.sliderMax - this.sliderMIn)*1000)
  353 + return result*100
  354 + },
  355 + getDataLeft(item){
  356 + let timeForFile = this.getTimeForFile(item);
  357 + let differenceTime = timeForFile[0].getTime() - new Date(this.chooseDate + " 00:00:00").getTime()
  358 + return parseFloat((differenceTime - this.sliderMIn * 1000)/((this.sliderMax - this.sliderMIn)*1000))*100 ;
  359 + },
  360 + getUrlByStreamInfo(){
  361 + if (location.protocol === "https:") {
  362 + this.videoUrl = this.streamInfo["wss_flv"]
  363 + }else {
  364 + this.videoUrl = this.streamInfo["ws_flv"]
  365 + }
  366 + return this.videoUrl;
  367 +
  368 + },
  369 + timePickerChange: function (val){
  370 + this.setTime(val[0], val[1])
  371 + },
  372 + playTimeChange(val){
  373 + console.log(val)
  374 +
  375 + let startTimeStr = moment(new Date(this.chooseDate + " 00:00:00").getTime() + val[0]*1000).format("YYYY-MM-DD HH:mm:ss");
  376 + let endTimeStr = moment(new Date(this.chooseDate + " 00:00:00").getTime() + val[1]*1000).format("YYYY-MM-DD HH:mm:ss");
  377 +
  378 + this.setTime(startTimeStr, endTimeStr)
  379 +
  380 + this.playRecord();
  381 + },
  382 + setSliderFit() {
  383 + if (this.sliderMIn === 0 && this.sliderMax === 86400) {
  384 + if (this.detailFiles.length > 0){
  385 + let timeForFile = this.getTimeForFile(this.detailFiles[0]);
  386 + let lastTimeForFile = this.getTimeForFile(this.detailFiles[this.detailFiles.length - 1]);
  387 + let timeNum = timeForFile[0].getTime() - new Date(this.chooseDate + " " + "00:00:00").getTime()
  388 + let lastTimeNum = lastTimeForFile[1].getTime() - new Date(this.chooseDate + " " + "00:00:00").getTime()
  389 +
  390 + this.playTime = parseInt(timeNum/1000)
  391 + this.sliderMIn = parseInt(timeNum/1000 - timeNum/1000%(60*60))
  392 + this.sliderMax = parseInt(lastTimeNum/1000 - lastTimeNum/1000%(60*60)) + 60*60
  393 +
  394 + this.playTime = [this.sliderMIn, this.sliderMax];
  395 + }
  396 + }else {
  397 + this.sliderMIn = 0;
  398 + this.sliderMax = 86400;
  399 + }
  400 + },
  401 + getTimeForFile(file){
  402 + let startTime = new Date(file.startTime);
  403 + let endTime = new Date(file.endTime);
  404 + return [startTime, endTime, endTime.getTime() - startTime.getTime()];
  405 + },
  406 + playTimeFormat(val){
  407 + let h = parseInt(val/3600);
  408 + let m = parseInt((val - h*3600)/60);
  409 + let s = parseInt(val - h*3600 - m*60);
  410 +
  411 + let hStr = h;
  412 + let mStr = m;
  413 + let sStr = s;
  414 + if (h < 10) {
  415 + hStr = "0" + hStr;
  416 + }
  417 + if (m < 10) {
  418 + mStr = "0" + mStr;s
  419 + }
  420 + if (s < 10) {
  421 + sStr = "0" + sStr;
  422 + }
  423 + return hStr + ":" + mStr + ":" + sStr
  424 + },
  425 + goBack(){
  426 + window.history.go(-1);
  427 + }
  428 + }
  429 + };
  430 +</script>
  431 +
  432 +<style>
  433 + .el-slider__runway {
  434 + background-color:rgba(206, 206, 206, 0.47) !important;
  435 + }
  436 + .el-slider__bar {
  437 + background-color: rgba(153, 153, 153, 0) !important;
  438 + }
  439 + .playtime-slider {
  440 + position: relative;
  441 + z-index: 100;
  442 + }
  443 + .data-picker-true{
  444 +
  445 + }
  446 + .data-picker-true:after{
  447 + content: "";
  448 + position: absolute;
  449 + width: 4px;
  450 + height: 4px;
  451 + background-color: #606060;
  452 + border-radius: 4px;
  453 + left: 45%;
  454 + top: 74%;
  455 +
  456 + }
  457 + .data-picker-false{
  458 +
  459 + }
  460 + .slider-val-box{
  461 + height: 6px;
  462 + position: relative;
  463 + top: -22px;
  464 + }
  465 + .slider-val{
  466 + height: 6px;
  467 + background-color: #007CFF;
  468 + position: absolute;
  469 + }
  470 + .record-list-box-box{
  471 + width: 250px;
  472 + float: left;
  473 + }
  474 + .record-list-box{
  475 + overflow: auto;
  476 + width: 220px;
  477 + list-style: none;
  478 + padding: 0;
  479 + margin: 0;
  480 + margin-top: 0px;
  481 + padding: 1rem 0;
  482 + background-color: #FFF;
  483 + margin-top: 10px;
  484 + }
  485 + .record-list{
  486 + list-style: none;
  487 + padding: 0;
  488 + margin: 0;
  489 + background-color: #FFF;
  490 +
  491 + }
  492 + .record-list-no-val {
  493 + position: absolute;
  494 + color: #9f9f9f;
  495 + top: 50%;
  496 + left: 110px;
  497 + }
  498 + .record-list-item{
  499 + padding: 0;
  500 + margin: 0;
  501 + margin: 0.5rem 0;
  502 + cursor: pointer;
  503 + }
  504 + .record-list-option {
  505 + width: 10px;
  506 + float: left;
  507 + margin-top: 39px;
  508 +
  509 + }
  510 + .player-option-box{
  511 + padding: 0 20px;
  512 + }
  513 +</style>
... ...
web_src/src/components/channelList.vue
... ... @@ -269,10 +269,10 @@ export default {
269 269 });
270 270 },
271 271 queryRecords: function (itemData) {
272   - var format = moment().format("yyyy-MM-DD");
273 272 let deviceId = this.deviceId;
274 273 let channelId = itemData.channelId;
275   - this.$refs.devicePlayer.openDialog("record", deviceId, channelId, {date: format})
  274 +
  275 + this.$router.push(`/gbRecordDetail/${deviceId}/${channelId}`)
276 276 },
277 277 stopDevicePush: function (itemData) {
278 278 var that = this;
... ...
web_src/src/components/console.vue
... ... @@ -101,11 +101,14 @@ export default {
101 101 window.clearTimeout(this.timer);
102 102 }
103 103 this.timer = setTimeout(()=>{
104   - this.getSystemInfo();
105   - this.getLoad();
106   - this.timer = null;
107   - this.loopForSystemInfo()
108   - this.getResourceInfo()
  104 + if (this.$route.path === "/console") {
  105 + this.getSystemInfo();
  106 + this.getLoad();
  107 + this.timer = null;
  108 + this.loopForSystemInfo()
  109 + this.getResourceInfo()
  110 + }
  111 +
109 112 }, 2000)
110 113 },
111 114 getSystemInfo: function (){
... ...
web_src/src/components/console/ConsoleResource.vue
1 1 <template >
2 2 <div id="consoleResource" style="width: 100%; height: 100%; background: #FFFFFF; text-align: center">
3 3 <div style="width: 50%;height: 50%; float:left; ">
4   - <el-progress :width="100" :stroke-width="8" type="circle" :percentage="Math.floor(deviceInfo.online/deviceInfo.total*100)" style="margin-top: 20px; font-size: 18px"></el-progress>
  4 + <el-progress v-if="deviceInfo.total > 0" :width="100" :stroke-width="8" type="circle" :percentage="Math.floor(deviceInfo.online/deviceInfo.total*100)" style="margin-top: 20px; font-size: 18px"></el-progress>
  5 + <el-progress v-if="deviceInfo.total === 0" :width="100" :stroke-width="8" type="circle" :percentage="0" style="margin-top: 20px; font-size: 18px"></el-progress>
5 6 <div class="resourceInfo">
6 7 设备总数:{{deviceInfo.total}}<br/>
7 8 在线数:{{deviceInfo.online}}
8 9 </div>
9 10 </div>
10 11 <div style="width: 50%;height: 50%; float:left; ">
11   - <el-progress :width="100" :stroke-width="10" type="circle" :percentage="Math.floor(channelInfo.online/channelInfo.total*100)" style="margin-top: 20px"></el-progress>
  12 + <el-progress v-if="channelInfo.total > 0" :width="100" :stroke-width="10" type="circle" :percentage="Math.floor(channelInfo.online/channelInfo.total*100)" style="margin-top: 20px"></el-progress>
  13 + <el-progress v-if="channelInfo.total === 0" :width="100" :stroke-width="10" type="circle" :percentage="0" style="margin-top: 20px"></el-progress>
12 14 <div class="resourceInfo">
13 15 通道总数:{{channelInfo.total}}<br/>
14 16 在线数:{{channelInfo.online}}
15 17 </div>
16 18 </div>
17 19 <div style="width: 50%;height: 50%; float:left; ">
18   - <el-progress :width="100" :stroke-width="10" type="circle" :percentage="Math.floor(pushInfo.online/pushInfo.total*100)" style="margin-top: 20px"></el-progress>
  20 + <el-progress v-if="pushInfo.total > 0" :width="100" :stroke-width="10" type="circle" :percentage="Math.floor(pushInfo.online/pushInfo.total*100)" style="margin-top: 20px"></el-progress>
  21 + <el-progress v-if="pushInfo.total === 0" :width="100" :stroke-width="10" type="circle" :percentage="0" style="margin-top: 20px"></el-progress>
19 22 <div class="resourceInfo">
20 23 推流总数:{{pushInfo.total}}<br/>
21 24 在线数:{{pushInfo.online}}
22 25 </div>
23 26 </div>
24 27 <div style="width: 50%;height: 50%; float:left; ">
25   - <el-progress :width="100" :stroke-width="10" type="circle" :percentage="Math.floor(proxyInfo.online/proxyInfo.total*100)" style="margin-top: 20px"></el-progress>
  28 + <el-progress v-if="proxyInfo.total > 0" :width="100" :stroke-width="10" type="circle" :percentage="Math.floor(proxyInfo.online/proxyInfo.total*100)" style="margin-top: 20px"></el-progress>
  29 + <el-progress v-if="proxyInfo.total === 0" :width="100" :stroke-width="10" type="circle" :percentage="0" style="margin-top: 20px"></el-progress>
26 30 <div class="resourceInfo">
27 31 拉流代理总数:{{proxyInfo.total}}<br/>
28 32 在线数:{{proxyInfo.online}}
... ...
web_src/src/components/dialog/devicePlayer.vue
... ... @@ -20,11 +20,6 @@
20 20 <div id="shared" style="text-align: right; margin-top: 1rem;">
21 21 <el-tabs v-model="tabActiveName" @tab-click="tabHandleClick" >
22 22 <el-tab-pane label="实时视频" name="media">
23   - <div style="margin-bottom: 0.5rem;">
24   - <!-- <el-button type="primary" size="small" @click="playRecord(true, '')">播放</el-button>-->
25   - <!-- <el-button type="primary" size="small" @click="startRecord()">录制</el-button>-->
26   - <!-- <el-button type="primary" size="small" @click="stopRecord()">停止录制</el-button>-->
27   - </div>
28 23 <div style="display: flex; margin-bottom: 0.5rem; height: 2.5rem;">
29 24 <span style="width: 5rem; line-height: 2.5rem; text-align: right;">播放地址:</span>
30 25 <el-input v-model="getPlayerShared.sharedUrl" :disabled="true" >
... ... @@ -50,93 +45,93 @@
50 45 更多地址<i class="el-icon-arrow-down el-icon--right"></i>
51 46 </el-button>
52 47 <el-dropdown-menu slot="dropdown" >
53   - <el-dropdown-item v-if="streamInfo.flv" :command="streamInfo.flv.url">
  48 + <el-dropdown-item v-if="streamInfo.flv" :command="streamInfo.flv">
54 49 <el-tag >FLV:</el-tag>
55   - <span>{{ streamInfo.flv.url }}</span>
  50 + <span>{{ streamInfo.flv }}</span>
56 51 </el-dropdown-item>
57   - <el-dropdown-item v-if="streamInfo.https_flv" :command="streamInfo.https_flv.url">
  52 + <el-dropdown-item v-if="streamInfo.https_flv" :command="streamInfo.https_flv">
58 53 <el-tag >FLV(https):</el-tag>
59   - <span>{{ streamInfo.https_flv.url }}</span>
  54 + <span>{{ streamInfo.https_flv }}</span>
60 55 </el-dropdown-item>
61   - <el-dropdown-item v-if="streamInfo.ws_flv" :command="streamInfo.ws_flv.url">
  56 + <el-dropdown-item v-if="streamInfo.ws_flv" :command="streamInfo.ws_flv">
62 57 <el-tag >FLV(ws):</el-tag>
63   - <span >{{ streamInfo.ws_flv.url }}</span>
  58 + <span >{{ streamInfo.ws_flv }}</span>
64 59 </el-dropdown-item>
65   - <el-dropdown-item v-if="streamInfo.wss_flv" :command="streamInfo.wss_flv.url">
  60 + <el-dropdown-item v-if="streamInfo.wss_flv" :command="streamInfo.wss_flv">
66 61 <el-tag >FLV(wss):</el-tag>
67   - <span>{{ streamInfo.wss_flv.url }}</span>
  62 + <span>{{ streamInfo.wss_flv }}</span>
68 63 </el-dropdown-item>
69   - <el-dropdown-item v-if="streamInfo.fmp4" :command="streamInfo.fmp4.url">
  64 + <el-dropdown-item v-if="streamInfo.fmp4" :command="streamInfo.fmp4">
70 65 <el-tag >FMP4:</el-tag>
71   - <span>{{ streamInfo.fmp4.url }}</span>
  66 + <span>{{ streamInfo.fmp4 }}</span>
72 67 </el-dropdown-item>
73   - <el-dropdown-item v-if="streamInfo.https_fmp4" :command="streamInfo.https_fmp4.url">
  68 + <el-dropdown-item v-if="streamInfo.https_fmp4" :command="streamInfo.https_fmp4">
74 69 <el-tag >FMP4(https):</el-tag>
75   - <span>{{ streamInfo.https_fmp4.url }}</span>
  70 + <span>{{ streamInfo.https_fmp4 }}</span>
76 71 </el-dropdown-item>
77   - <el-dropdown-item v-if="streamInfo.ws_fmp4" :command="streamInfo.ws_fmp4.url">
  72 + <el-dropdown-item v-if="streamInfo.ws_fmp4" :command="streamInfo.ws_fmp4">
78 73 <el-tag >FMP4(ws):</el-tag>
79   - <span>{{ streamInfo.ws_fmp4.url }}</span>
  74 + <span>{{ streamInfo.ws_fmp4 }}</span>
80 75 </el-dropdown-item>
81   - <el-dropdown-item v-if="streamInfo.wss_fmp4" :command="streamInfo.wss_fmp4.url">
  76 + <el-dropdown-item v-if="streamInfo.wss_fmp4" :command="streamInfo.wss_fmp4">
82 77 <el-tag >FMP4(wss):</el-tag>
83   - <span>{{ streamInfo.wss_fmp4.url }}</span>
  78 + <span>{{ streamInfo.wss_fmp4 }}</span>
84 79 </el-dropdown-item>
85   - <el-dropdown-item v-if="streamInfo.hls" :command="streamInfo.hls.url">
  80 + <el-dropdown-item v-if="streamInfo.hls" :command="streamInfo.hls">
86 81 <el-tag>HLS:</el-tag>
87   - <span>{{ streamInfo.hls.url }}</span>
  82 + <span>{{ streamInfo.hls }}</span>
88 83 </el-dropdown-item>
89   - <el-dropdown-item v-if="streamInfo.https_hls" :command="streamInfo.https_hls.url">
  84 + <el-dropdown-item v-if="streamInfo.https_hls" :command="streamInfo.https_hls">
90 85 <el-tag >HLS(https):</el-tag>
91   - <span>{{ streamInfo.https_hls.url }}</span>
  86 + <span>{{ streamInfo.https_hls }}</span>
92 87 </el-dropdown-item>
93   - <el-dropdown-item v-if="streamInfo.ws_hls" :command="streamInfo.ws_hls.url">
  88 + <el-dropdown-item v-if="streamInfo.ws_hls" :command="streamInfo.ws_hls">
94 89 <el-tag >HLS(ws):</el-tag>
95   - <span>{{ streamInfo.ws_hls.url }}</span>
  90 + <span>{{ streamInfo.ws_hls }}</span>
96 91 </el-dropdown-item>
97   - <el-dropdown-item v-if="streamInfo.wss_hls" :command="streamInfo.wss_hls.url">
  92 + <el-dropdown-item v-if="streamInfo.wss_hls" :command="streamInfo.wss_hls">
98 93 <el-tag >HLS(wss):</el-tag>
99   - <span>{{ streamInfo.wss_hls.url }}</span>
  94 + <span>{{ streamInfo.wss_hls }}</span>
100 95 </el-dropdown-item>
101   - <el-dropdown-item v-if="streamInfo.ts" :command="streamInfo.ts.url">
  96 + <el-dropdown-item v-if="streamInfo.ts" :command="streamInfo.ts">
102 97 <el-tag>TS:</el-tag>
103   - <span>{{ streamInfo.ts.url }}</span>
  98 + <span>{{ streamInfo.ts }}</span>
104 99 </el-dropdown-item>
105   - <el-dropdown-item v-if="streamInfo.https_ts" :command="streamInfo.https_ts.url">
  100 + <el-dropdown-item v-if="streamInfo.https_ts" :command="streamInfo.https_ts">
106 101 <el-tag>TS(https):</el-tag>
107   - <span>{{ streamInfo.https_ts.url }}</span>
  102 + <span>{{ streamInfo.https_ts }}</span>
108 103 </el-dropdown-item>
109   - <el-dropdown-item v-if="streamInfo.ws_ts" :command="streamInfo.ws_ts.url">
  104 + <el-dropdown-item v-if="streamInfo.ws_ts" :command="streamInfo.ws_ts">
110 105 <el-tag>TS(ws):</el-tag>
111   - <span>{{ streamInfo.ws_ts.url }}</span>
  106 + <span>{{ streamInfo.ws_ts }}</span>
112 107 </el-dropdown-item>
113   - <el-dropdown-item v-if="streamInfo.wss_ts" :command="streamInfo.wss_ts.url">
  108 + <el-dropdown-item v-if="streamInfo.wss_ts" :command="streamInfo.wss_ts">
114 109 <el-tag>TS(wss):</el-tag>
115   - <span>{{ streamInfo.wss_ts.url }}</span>
  110 + <span>{{ streamInfo.wss_ts }}</span>
116 111 </el-dropdown-item>
117   - <el-dropdown-item v-if="streamInfo.rtc" :command="streamInfo.rtc.url">
  112 + <el-dropdown-item v-if="streamInfo.rtc" :command="streamInfo.rtc">
118 113 <el-tag >RTC:</el-tag>
119   - <span>{{ streamInfo.rtc.url }}</span>
  114 + <span>{{ streamInfo.rtc }}</span>
120 115 </el-dropdown-item>
121   - <el-dropdown-item v-if="streamInfo.rtcs" :command="streamInfo.rtcs.url">
  116 + <el-dropdown-item v-if="streamInfo.rtcs" :command="streamInfo.rtcs">
122 117 <el-tag >RTCS:</el-tag>
123 118 <span>{{ streamInfo.rtcs }}</span>
124 119 </el-dropdown-item>
125   - <el-dropdown-item v-if="streamInfo.rtmp" :command="streamInfo.rtmp.url">
  120 + <el-dropdown-item v-if="streamInfo.rtmp" :command="streamInfo.rtmp">
126 121 <el-tag >RTMP:</el-tag>
127   - <span>{{ streamInfo.rtmp.url }}</span>
  122 + <span>{{ streamInfo.rtmp }}</span>
128 123 </el-dropdown-item>
129   - <el-dropdown-item v-if="streamInfo.rtmps" :command="streamInfo.rtmps.url">
  124 + <el-dropdown-item v-if="streamInfo.rtmps" :command="streamInfo.rtmps">
130 125 <el-tag >RTMPS:</el-tag>
131   - <span>{{ streamInfo.rtmps.url }}</span>
  126 + <span>{{ streamInfo.rtmps }}</span>
132 127 </el-dropdown-item>
133   - <el-dropdown-item v-if="streamInfo.rtsp" :command="streamInfo.rtsp.url">
  128 + <el-dropdown-item v-if="streamInfo.rtsp" :command="streamInfo.rtsp">
134 129 <el-tag >RTSP:</el-tag>
135   - <span>{{ streamInfo.rtsp.url }}</span>
  130 + <span>{{ streamInfo.rtsp }}</span>
136 131 </el-dropdown-item>
137   - <el-dropdown-item v-if="streamInfo.rtsps" :command="streamInfo.rtsps.url">
  132 + <el-dropdown-item v-if="streamInfo.rtsps" :command="streamInfo.rtsps">
138 133 <el-tag >RTSPS:</el-tag>
139   - <span>{{ streamInfo.rtsps.url }}</span>
  134 + <span>{{ streamInfo.rtsps }}</span>
140 135 </el-dropdown-item>
141 136 </el-dropdown-menu>
142 137 </el-dropdown>
... ... @@ -145,51 +140,6 @@
145 140 </div>
146 141 </el-tab-pane>
147 142 <!--{"code":0,"data":{"paths":["22-29-30.mp4"],"rootPath":"/home/kkkkk/Documents/ZLMediaKit/release/linux/Debug/www/record/hls/kkkkk/2020-05-11/"}}-->
148   - <el-tab-pane label="录像查询" name="record" v-if="showRrecord">
149   - <div style="width: 100%;">
150   - <div style="width: 100%; text-align: left">
151   - <span>录像控制</span>
152   - <el-button-group style="margin-left: 1rem;">
153   - <el-button size="mini" class="iconfont icon-zanting" title="开始" @click="gbPause()"></el-button>
154   - <el-button size="mini" class="iconfont icon-kaishi" title="暂停" @click="gbPlay()"></el-button>
155   - <el-dropdown size="mini" title="播放倍速" style="margin-left: 1px;" @command="gbScale">
156   - <el-button size="mini">
157   - 倍速 <i class="el-icon-arrow-down el-icon--right"></i>
158   - </el-button>
159   - <el-dropdown-menu slot="dropdown">
160   - <el-dropdown-item command="0.25">0.25倍速</el-dropdown-item>
161   - <el-dropdown-item command="0.5">0.5倍速</el-dropdown-item>
162   - <el-dropdown-item command="1.0">1倍速</el-dropdown-item>
163   - <el-dropdown-item command="2.0">2倍速</el-dropdown-item>
164   - <el-dropdown-item command="4.0">4倍速</el-dropdown-item>
165   - </el-dropdown-menu>
166   - </el-dropdown>
167   - </el-button-group>
168   - <el-date-picker style="float: right;" size="mini" v-model="videoHistory.date" type="date" value-format="yyyy-MM-dd" placeholder="日期" @change="queryRecords()"></el-date-picker>
169   - </div>
170   - <div style="width: 100%; text-align: left">
171   - <span class="demonstration" style="padding: 12px 36px 12px 0;float: left;">{{showTimeText}}</span>
172   - <el-slider style="width: 80%; float:left;" v-model="sliderTime" @change="gbSeek" :show-tooltip="false"></el-slider>
173   - </div>
174   - </div>
175   -
176   -
177   - <el-table :data="videoHistory.searchHistoryResult" height="150" v-loading="recordsLoading">
178   - <el-table-column label="名称" prop="name"></el-table-column>
179   - <el-table-column label="文件" prop="filePath"></el-table-column>
180   - <el-table-column label="开始时间" prop="startTime" :formatter="timeFormatter"></el-table-column>
181   - <el-table-column label="结束时间" prop="endTime" :formatter="timeFormatter"></el-table-column>
182   -
183   - <el-table-column label="操作">
184   - <template slot-scope="scope">
185   - <el-button-group>
186   - <el-button icon="el-icon-video-play" size="mini" @click="playRecord(scope.row)">播放</el-button>
187   - <el-button icon="el-icon-download" size="mini" @click="downloadRecord(scope.row)">下载</el-button>
188   - </el-button-group>
189   - </template>
190   - </el-table-column>
191   - </el-table>
192   - </el-tab-pane>
193 143 <!--遥控界面-->
194 144 <el-tab-pane label="云台控制" name="control" v-if="showPtz">
195 145 <div style="display: flex; justify-content: left;">
... ... @@ -295,20 +245,19 @@
295 245 </el-tabs>
296 246 </div>
297 247 </el-dialog>
298   - <recordDownload ref="recordDownload"></recordDownload>
299 248 </div>
300 249 </template>
301 250  
302 251 <script>
303 252 import rtcPlayer from '../dialog/rtcPlayer.vue'
  253 +import LivePlayer from '@liveqing/liveplayer'
304 254 import crypto from 'crypto'
305 255 import jessibucaPlayer from '../common/jessibuca.vue'
306   -import recordDownload from '../dialog/recordDownload.vue'
307 256 export default {
308 257 name: 'devicePlayer',
309 258 props: {},
310 259 components: {
311   - jessibucaPlayer, rtcPlayer, recordDownload,
  260 + LivePlayer, jessibucaPlayer, rtcPlayer,
312 261 },
313 262 computed: {
314 263 getPlayerShared: function () {
... ... @@ -337,10 +286,6 @@ export default {
337 286 jessibuca : ["ws_flv", "wss_flv"],
338 287 webRTC: ["rtc", "rtcs"],
339 288 },
340   - videoHistory: {
341   - date: '',
342   - searchHistoryResult: [] //媒体流历史记录搜索结果
343   - },
344 289 showVideoDialog: false,
345 290 streamId: '',
346 291 app : '',
... ... @@ -366,7 +311,6 @@ export default {
366 311 tracks: [],
367 312 coverPlaying:false,
368 313 tracksLoading: false,
369   - recordPlay: "",
370 314 showPtz: true,
371 315 showRrecord: true,
372 316 tracksNotLoaded: false,
... ... @@ -429,11 +373,6 @@ export default {
429 373 case "media":
430 374 this.play(param.streamInfo, param.hasAudio)
431 375 break;
432   - case "record":
433   - this.showVideoDialog = true;
434   - this.videoHistory.date = param.date;
435   - this.queryRecords()
436   - break;
437 376 case "streamPlay":
438 377 this.tabActiveName = "media";
439 378 this.showRrecord = false;
... ... @@ -444,9 +383,6 @@ export default {
444 383 break;
445 384 }
446 385 },
447   - timeAxisSelTime: function (val) {
448   - console.log(val)
449   - },
450 386 play: function (streamInfo, hasAudio) {
451 387 this.streamInfo = streamInfo;
452 388 this.hasAudio = hasAudio;
... ... @@ -461,9 +397,9 @@ export default {
461 397 getUrlByStreamInfo(){
462 398 console.log(this.streamInfo)
463 399 if (location.protocol === "https:") {
464   - this.videoUrl = this.streamInfo[this.player[this.activePlayer][1]].url
  400 + this.videoUrl = this.streamInfo[this.player[this.activePlayer][1]]
465 401 }else {
466   - this.videoUrl = this.streamInfo[this.player[this.activePlayer][0]].url
  402 + this.videoUrl = this.streamInfo[this.player[this.activePlayer][0]]
467 403 }
468 404 return this.videoUrl;
469 405  
... ... @@ -542,10 +478,6 @@ export default {
542 478 this.convertStop();
543 479 }
544 480 this.convertKey = ''
545   - if (this.recordPlay != '') {
546   - this.stopPlayRecord();
547   - }
548   - this.recordPlay = ''
549 481 this.stopBroadcast()
550 482 },
551 483  
... ... @@ -571,137 +503,6 @@ export default {
571 503 }
572 504 );
573 505 },
574   -
575   - queryRecords: function () {
576   - if (!this.videoHistory.date) {
577   - return;
578   - }
579   - this.recordsLoading = true;
580   - this.videoHistory.searchHistoryResult = [];
581   - let that = this;
582   - var startTime = this.videoHistory.date + " 00:00:00";
583   - var endTime = this.videoHistory.date + " 23:59:59";
584   - this.$axios({
585   - method: 'get',
586   - url: '/api/gb_record/query/' + this.deviceId + '/' + this.channelId + '?startTime=' + startTime + '&endTime=' + endTime
587   - }).then(function (res) {
588   - console.log(res)
589   - that.recordsLoading = false;
590   - if(res.data.code === 0) {
591   - // 处理时间信息
592   - that.videoHistory.searchHistoryResult = res.data.data.recordList;
593   - }else {
594   - this.$message({
595   - showClose: true,
596   - message: res.data.msg,
597   - type: "error",
598   - });
599   - }
600   -
601   - }).catch(function (e) {
602   - console.log(e.message);
603   - // that.videoHistory.searchHistoryResult = falsificationData.recordData;
604   - });
605   -
606   - },
607   - onTimeChange: function (video) {
608   - // this.queryRecords()
609   - },
610   - playRecord: function (row) {
611   - let that = this;
612   -
613   - let startTime = row.startTime
614   - this.recordStartTime = row.startTime
615   - this.showTimeText = row.startTime.split(" ")[1]
616   - let endtime = row.endTime
617   - this.sliderTime = 0;
618   - this.seekTime = new Date(endtime).getTime() - new Date(startTime).getTime();
619   - console.log(this.seekTime)
620   - if (that.streamId != "") {
621   - that.stopPlayRecord(function () {
622   - that.streamId = "";
623   - that.playRecord(row);
624   - })
625   - } else {
626   - this.$axios({
627   - method: 'get',
628   - url: '/api/playback/start/' + this.deviceId + '/' + this.channelId + '?startTime=' + row.startTime + '&endTime=' +
629   - row.endTime
630   - }).then(function (res) {
631   - if (res.data.code === 0) {
632   - that.streamInfo = res.data.data;
633   - that.app = that.streamInfo.app;
634   - that.streamId = that.streamInfo.stream;
635   - that.mediaServerId = that.streamInfo.mediaServerId;
636   - that.ssrc = that.streamInfo.ssrc;
637   - that.videoUrl = that.getUrlByStreamInfo();
638   - }else {
639   - that.$message({
640   - showClose: true,
641   - message: res.data.msg,
642   - type: "error",
643   - });
644   - }
645   - that.recordPlay = true;
646   - });
647   - }
648   - },
649   - stopPlayRecord: function (callback) {
650   - this.$refs[this.activePlayer].pause();
651   - this.videoUrl = '';
652   - this.$axios({
653   - method: 'get',
654   - url: '/api/playback/stop/' + this.deviceId + "/" + this.channelId + "/" + this.streamId
655   - }).then(function (res) {
656   - if (callback) callback()
657   - });
658   - },
659   - downloadRecord: function (row) {
660   - let that = this;
661   - if (that.streamId != "") {
662   - that.stopDownloadRecord(function (res) {
663   - if (res.code == 0) {
664   - that.streamId = "";
665   - that.downloadRecord(row);
666   - }else {
667   - this.$message({
668   - showClose: true,
669   - message: res.data.msg,
670   - type: "error",
671   - });
672   - }
673   -
674   - })
675   - } else {
676   - this.$axios({
677   - method: 'get',
678   - url: '/api/gb_record/download/start/' + this.deviceId + '/' + this.channelId + '?startTime=' + row.startTime + '&endTime=' +
679   - row.endTime + '&downloadSpeed=4'
680   - }).then(function (res) {
681   - if (res.data.code == 0) {
682   - let streamInfo = res.data.data;
683   - that.recordPlay = false;
684   - that.$refs.recordDownload.openDialog(that.deviceId, that.channelId, streamInfo.app, streamInfo.stream, streamInfo.mediaServerId);
685   - }else {
686   - that.$message({
687   - showClose: true,
688   - message: res.data.msg,
689   - type: "error",
690   - });
691   - }
692   - });
693   - }
694   - },
695   - stopDownloadRecord: function (callback) {
696   - this.$refs[this.activePlayer].pause();
697   - this.videoUrl = '';
698   - this.$axios({
699   - method: 'get',
700   - url: '/api/gb_record/download/stop/' + this.deviceId + "/" + this.channelId+ "/" + this.streamId
701   - }).then((res)=> {
702   - if (callback) callback(res)
703   - });
704   - },
705 506 ptzCamera: function (command) {
706 507 console.log('云台控制:' + command);
707 508 let that = this;
... ... @@ -740,52 +541,6 @@ export default {
740 541 url: '/api/ptz/front_end_command/' + this.deviceId + '/' + this.channelId + '?cmdCode=' + cmdCode + '&parameter1=' + groupNum + '&parameter2=' + parameter + '&combindCode2=0'
741 542 }).then(function (res) {});
742 543 },
743   - formatTooltip: function (val) {
744   - var h = parseInt(val / 60);
745   - var hStr = h < 10 ? ("0" + h) : h;
746   - var s = val % 60;
747   - var sStr = s < 10 ? ("0" + s) : s;
748   - return h + ":" + sStr;
749   - },
750   - timeFormatter: function (row, column, cellValue, index) {
751   - return cellValue.split(" ")[1];
752   - },
753   - mergeTime: function (timeArray) {
754   - var resultArray = [];
755   - for (let i = 0; i < timeArray.length; i++) {
756   - var startTime = new Date(timeArray[i].startTime);
757   - var endTime = new Date(timeArray[i].endTime);
758   - if (i == 0) {
759   - resultArray[0] = {
760   - startTime: startTime,
761   - endTime: endTime
762   - }
763   - }
764   - for (let j = 0; j < resultArray.length; j++) {
765   - if (startTime > resultArray[j].endTime) { // 合并
766   - if (startTime - resultArray[j].endTime <= 1000) {
767   - resultArray[j].endTime = endTime;
768   - } else {
769   - resultArray[resultArray.length] = {
770   - startTime: startTime,
771   - endTime: endTime
772   - }
773   - }
774   - } else if (resultArray[j].startTime > endTime) { // 合并
775   - if (resultArray[j].startTime - endTime <= 1000) {
776   - resultArray[j].startTime = startTime;
777   - } else {
778   - resultArray[resultArray.length] = {
779   - startTime: startTime,
780   - endTime: endTime
781   - }
782   - }
783   - }
784   - }
785   - }
786   - console.log(resultArray)
787   - return resultArray;
788   - },
789 544 copyUrl: function (dropdownItem){
790 545 console.log(dropdownItem)
791 546 this.$copyText(dropdownItem).then((e)=> {
... ... @@ -794,140 +549,7 @@ export default {
794 549  
795 550 })
796 551 },
797   - gbPlay(){
798   - console.log('前端控制:播放');
799   - this.$axios({
800   - method: 'get',
801   - url: '/api/playback/resume/' + this.streamId
802   - }).then((res)=> {
803   - this.$refs[this.activePlayer].play(this.videoUrl)
804   - });
805   - },
806   - gbPause(){
807   - console.log('前端控制:暂停');
808   - this.$axios({
809   - method: 'get',
810   - url: '/api/playback/pause/' + this.streamId
811   - }).then(function (res) {});
812   - },
813   - gbScale(command){
814   - console.log('前端控制:倍速 ' + command);
815   - this.$axios({
816   - method: 'get',
817   - url: `/api/playback/speed/${this.streamId }/${command}`
818   - }).then(function (res) {});
819   - },
820   - gbSeek(val){
821   - console.log('前端控制:seek ');
822   - console.log(this.seekTime);
823   - console.log(this.sliderTime);
824   - let showTime = new Date(new Date(this.recordStartTime).getTime() + this.seekTime * val / 100)
825   - let hour = showTime.getHours();
826   - let minutes = showTime.getMinutes();
827   - let seconds = showTime.getSeconds();
828   - this.showTimeText = (hour < 10?("0" + hour):hour) + ":" + (minutes<10?("0" + minutes):minutes) + ":" + (seconds<10?("0" + seconds):seconds)
829   - this.$axios({
830   - method: 'get',
831   - url: `/api/playback/seek/${this.streamId }/` + Math.floor(this.seekTime * val / 100000)
832   - }).then( (res)=> {
833   - setTimeout(()=>{
834   - this.$refs[this.activePlayer].play(this.videoUrl)
835   - }, 600)
836   - });
837   - },
838   - getBroadcastStatus() {
839   - if (this.broadcastStatus == -2) {
840   - return "primary"
841   - }
842   - if (this.broadcastStatus == -1) {
843   - return "primary"
844   - }
845   - if (this.broadcastStatus == 0) {
846   - return "warning"
847   - }
848   - if (this.broadcastStatus == 1) {
849   - return "danger"
850   - }
851   -
852   - },
853   - broadcastStatusClick() {
854   - if (this.broadcastStatus == -1) {
855   - // 默认状态, 开始
856   - this.broadcastStatus = 0
857   - // 发起语音对讲
858   - this.$axios({
859   - method: 'get',
860   - url: '/api/play/broadcast/' + this.deviceId + '/' + this.channelId + "?timeout=30"
861   - }).then( (res)=> {
862   - if (res.data.code == 0) {
863   - let streamInfo = res.data.data.streamInfo;
864   - if (document.location.protocol.includes("https")) {
865   - this.startBroadcast(streamInfo.rtcs.url)
866   - }else {
867   - this.startBroadcast(streamInfo.rtc.url)
868   - }
869 552  
870   - }else {
871   - this.$message({
872   - showClose: true,
873   - message: res.data.msg,
874   - type: "error",
875   - });
876   - }
877   - });
878   - }else if (this.broadcastStatus === 1) {
879   - this.broadcastStatus = -1;
880   - this.broadcastRtc.close()
881   - }
882   - },
883   - startBroadcast(url){
884   - // 获取推流鉴权Key
885   - this.$axios({
886   - method: 'post',
887   - url: '/api/user/userInfo',
888   - }).then( (res)=> {
889   - if (res.data.code !== 0) {
890   - this.$message({
891   - showClose: true,
892   - message: "获取推流鉴权Key失败",
893   - type: "error",
894   - });
895   - this.broadcastStatus = -1;
896   - }else {
897   - let pushKey = res.data.data.pushKey;
898   - // 获取推流鉴权KEY
899   - url += "&sign=" + crypto.createHash('md5').update(pushKey, "utf8").digest('hex')
900   - console.log("开始语音对讲: " + url)
901   - this.broadcastRtc = new ZLMRTCClient.Endpoint({
902   - debug: true, // 是否打印日志
903   - zlmsdpUrl: url, //流地址
904   - simulecast: false,
905   - useCamera: false,
906   - audioEnable: true,
907   - videoEnable: false,
908   - recvOnly: false,
909   - })
910   -
911   - // webrtcPlayer.on(ZLMRTCClient.Events.WEBRTC_ON_REMOTE_STREAMS,(e)=>{//获取到了远端流,可以播放
912   - // console.error('播放成功',e.streams)
913   - // this.broadcastStatus = 1;
914   - // });
915   - //
916   - // webrtcPlayer.on(ZLMRTCClient.Events.WEBRTC_ON_LOCAL_STREAM,(s)=>{// 获取到了本地流
917   - // this.broadcastStatus = 1;
918   - // // document.getElementById('selfVideo').srcObject=s;
919   - // // this.eventcallbacK("LOCAL STREAM", "获取到了本地流")
920   - // });
921   -
922   - this.broadcastRtc.on(ZLMRTCClient.Events.WEBRTC_NOT_SUPPORT,(e)=>{// 获取到了本地流
923   - console.error('不支持webrtc',e)
924   - this.$message({
925   - showClose: true,
926   - message: '不支持webrtc, 无法进行语音对讲',
927   - type: 'error'
928   - });
929   - this.broadcastStatus = -1;
930   - });
931 553  
932 554 this.broadcastRtc.on(ZLMRTCClient.Events.WEBRTC_ICE_CANDIDATE_ERROR,(e)=>{// ICE 协商出错
933 555 console.error('ICE 协商出错')
... ...
web_src/src/components/dialog/recordDownload.vue
... ... @@ -6,18 +6,6 @@
6 6 <el-progress :percentage="percentage"></el-progress>
7 7 </el-col>
8 8 <el-col :span="6" >
9   -<!-- <el-dropdown size="mini" title="播放倍速" style="margin-left: 1px;" @command="gbScale">-->
10   -<!-- <el-button-group>-->
11   -<!-- <el-button size="mini" style="width: 100%">-->
12   -<!-- {{scale}}倍速 <i class="el-icon-arrow-down el-icon&#45;&#45;right"></i>-->
13   -<!-- </el-button>-->
14   -<!-- </el-button-group>-->
15   -<!-- <el-dropdown-menu slot="dropdown">-->
16   -<!-- <el-dropdown-item command="1">1倍速</el-dropdown-item>-->
17   -<!-- <el-dropdown-item command="2">2倍速</el-dropdown-item>-->
18   -<!-- <el-dropdown-item command="4">4倍速</el-dropdown-item>-->
19   -<!-- </el-dropdown-menu>-->
20   -<!-- </el-dropdown>-->
21 9 <el-button icon="el-icon-download" v-if="percentage < 100" size="mini" title="点击下载可将以缓存部分下载到本地" @click="download()">停止缓存并下载</el-button>
22 10 </el-col>
23 11 </el-row>
... ... @@ -51,6 +39,7 @@ export default {
51 39 taskId: null,
52 40 getProgressRun: false,
53 41 getProgressForFileRun: false,
  42 + timer: null
54 43  
55 44 };
56 45 },
... ... @@ -66,7 +55,7 @@ export default {
66 55 this.percentage = 0.0;
67 56 this.getProgressTimer()
68 57 },
69   - getProgressTimer(){
  58 + getProgressTimer: function (){
70 59 if (!this.getProgressRun) {
71 60 return;
72 61 }
... ... @@ -93,15 +82,24 @@ export default {
93 82 this.percentage = (parseFloat(res.data.data.progress)*100).toFixed(1);
94 83 }
95 84 if (callback)callback();
  85 + }else {
  86 + this.$message({
  87 + showClose: true,
  88 + message: res.data.msg,
  89 + type: "error",
  90 + });
  91 + this.close();
96 92 }
97 93  
98 94 }).catch((e) =>{
99   -
  95 + console.log(e)
100 96 });
101 97 },
102 98 close: function (){
103   - if (this.streamInfo.progress < 100) {
104   - this.stopDownloadRecord();
  99 + this.stopDownloadRecord();
  100 + if (this.timer !== null) {
  101 + window.clearTimeout(this.timer);
  102 + this.timer = null;
105 103 }
106 104 this.showDialog=false;
107 105 this.getProgressRun = false;
... ...
web_src/src/components/live.vue
... ... @@ -140,9 +140,9 @@ export default {
140 140 if (res.data.code === 0 && res.data.data) {
141 141 let videoUrl;
142 142 if (location.protocol === "https:") {
143   - videoUrl = res.data.data.wss_flv.url;
  143 + videoUrl = res.data.data.wss_flv;
144 144 } else {
145   - videoUrl = res.data.data.ws_flv.url;
  145 + videoUrl = res.data.data.ws_flv;
146 146 }
147 147 itemData.playUrl = videoUrl;
148 148 that.setPlayUrl(videoUrl, idxTmp);
... ...
web_src/src/router/index.js
... ... @@ -5,6 +5,7 @@ import Layout from &quot;../layout/index.vue&quot;
5 5 import console from '../components/console.vue'
6 6 import deviceList from '../components/DeviceList.vue'
7 7 import channelList from '../components/channelList.vue'
  8 +import gbRecordDetail from '../components/GBRecordDetail.vue'
8 9 import pushVideoList from '../components/PushVideoList.vue'
9 10 import streamProxyList from '../components/StreamProxyList.vue'
10 11 import map from '../components/map.vue'
... ... @@ -65,6 +66,11 @@ export default new VueRouter({
65 66 component: channelList,
66 67 },
67 68 {
  69 + path: '/gbRecordDetail/:deviceId/:channelId/',
  70 + name: 'gbRecordDetail',
  71 + component: gbRecordDetail,
  72 + },
  73 + {
68 74 path: '/parentPlatformList/:count/:page',
69 75 name: 'parentPlatformList',
70 76 component: parentPlatformList,
... ...
web_src/static/css/iconfont.css
1 1 @font-face {
2 2 font-family: "iconfont"; /* Project id 1291092 */
3   - src: url('iconfont.woff2?t=1655453611360') format('woff2'),
4   - url('iconfont.woff?t=1655453611360') format('woff'),
5   - url('iconfont.ttf?t=1655453611360') format('truetype');
  3 + src: url('iconfont.woff2?t=1673251105600') format('woff2'),
  4 + url('iconfont.woff?t=1673251105600') format('woff'),
  5 + url('iconfont.ttf?t=1673251105600') format('truetype');
6 6 }
7 7  
8 8 .iconfont {
... ... @@ -13,6 +13,14 @@
13 13 -moz-osx-font-smoothing: grayscale;
14 14 }
15 15  
  16 +.icon-slider:before {
  17 + content: "\e7e0";
  18 +}
  19 +
  20 +.icon-slider-right:before {
  21 + content: "\ea19";
  22 +}
  23 +
16 24 .icon-list:before {
17 25 content: "\e7de";
18 26 }
... ...
web_src/static/css/iconfont.woff2
No preview for this file type