Commit 21506440d22a2f77d4bbeb4bb646a27b03bb9022

Authored by mrjackwang
Committed by GitHub
2 parents bb50a243 a45bb7d9

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

Showing 39 changed files with 667 additions and 292 deletions

Too many changes to show.

To preserve performance only 39 of 41 files are displayed.

sql/mysql.sql
@@ -44,7 +44,7 @@ CREATE TABLE `device` ( @@ -44,7 +44,7 @@ CREATE TABLE `device` (
44 `charset` varchar(50) COLLATE utf8mb4_general_ci NOT NULL, 44 `charset` varchar(50) COLLATE utf8mb4_general_ci NOT NULL,
45 PRIMARY KEY (`id`), 45 PRIMARY KEY (`id`),
46 UNIQUE KEY `device_deviceId_uindex` (`deviceId`) 46 UNIQUE KEY `device_deviceId_uindex` (`deviceId`)
47 -) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; 47 +) ENGINE=InnoDB AUTO_INCREMENT=21 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
48 /*!40101 SET character_set_client = @saved_cs_client */; 48 /*!40101 SET character_set_client = @saved_cs_client */;
49 49
50 -- 50 --
@@ -129,7 +129,7 @@ CREATE TABLE `device_channel` ( @@ -129,7 +129,7 @@ CREATE TABLE `device_channel` (
129 PRIMARY KEY (`id`), 129 PRIMARY KEY (`id`),
130 UNIQUE KEY `device_channel_id_uindex` (`id`), 130 UNIQUE KEY `device_channel_id_uindex` (`id`),
131 UNIQUE KEY `device_channel_pk` (`channelId`,`deviceId`) 131 UNIQUE KEY `device_channel_pk` (`channelId`,`deviceId`)
132 -) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; 132 +) ENGINE=InnoDB AUTO_INCREMENT=46 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
133 /*!40101 SET character_set_client = @saved_cs_client */; 133 /*!40101 SET character_set_client = @saved_cs_client */;
134 134
135 -- 135 --
@@ -198,7 +198,7 @@ CREATE TABLE `gb_stream` ( @@ -198,7 +198,7 @@ CREATE TABLE `gb_stream` (
198 PRIMARY KEY (`gbStreamId`) USING BTREE, 198 PRIMARY KEY (`gbStreamId`) USING BTREE,
199 UNIQUE KEY `app` (`app`,`stream`) USING BTREE, 199 UNIQUE KEY `app` (`app`,`stream`) USING BTREE,
200 UNIQUE KEY `gbId` (`gbId`) USING BTREE 200 UNIQUE KEY `gbId` (`gbId`) USING BTREE
201 -) ENGINE=InnoDB AUTO_INCREMENT=375 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC; 201 +) ENGINE=InnoDB AUTO_INCREMENT=300766 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC;
202 /*!40101 SET character_set_client = @saved_cs_client */; 202 /*!40101 SET character_set_client = @saved_cs_client */;
203 203
204 -- 204 --
@@ -228,7 +228,7 @@ CREATE TABLE `log` ( @@ -228,7 +228,7 @@ CREATE TABLE `log` (
228 `username` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, 228 `username` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
229 `createTime` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, 229 `createTime` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
230 PRIMARY KEY (`id`) USING BTREE 230 PRIMARY KEY (`id`) USING BTREE
231 -) ENGINE=InnoDB AUTO_INCREMENT=313 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC; 231 +) ENGINE=InnoDB AUTO_INCREMENT=962 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC;
232 /*!40101 SET character_set_client = @saved_cs_client */; 232 /*!40101 SET character_set_client = @saved_cs_client */;
233 233
234 -- 234 --
@@ -317,7 +317,7 @@ CREATE TABLE `parent_platform` ( @@ -317,7 +317,7 @@ CREATE TABLE `parent_platform` (
317 PRIMARY KEY (`id`), 317 PRIMARY KEY (`id`),
318 UNIQUE KEY `parent_platform_id_uindex` (`id`), 318 UNIQUE KEY `parent_platform_id_uindex` (`id`),
319 UNIQUE KEY `parent_platform_pk` (`serverGBId`) 319 UNIQUE KEY `parent_platform_pk` (`serverGBId`)
320 -) ENGINE=InnoDB AUTO_INCREMENT=14 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC; 320 +) ENGINE=InnoDB AUTO_INCREMENT=23 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC;
321 /*!40101 SET character_set_client = @saved_cs_client */; 321 /*!40101 SET character_set_client = @saved_cs_client */;
322 322
323 -- 323 --
@@ -367,7 +367,7 @@ CREATE TABLE `platform_gb_channel` ( @@ -367,7 +367,7 @@ CREATE TABLE `platform_gb_channel` (
367 `catalogId` varchar(50) COLLATE utf8mb4_general_ci NOT NULL, 367 `catalogId` varchar(50) COLLATE utf8mb4_general_ci NOT NULL,
368 `deviceChannelId` int NOT NULL, 368 `deviceChannelId` int NOT NULL,
369 PRIMARY KEY (`id`) 369 PRIMARY KEY (`id`)
370 -) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; 370 +) ENGINE=InnoDB AUTO_INCREMENT=47 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
371 /*!40101 SET character_set_client = @saved_cs_client */; 371 /*!40101 SET character_set_client = @saved_cs_client */;
372 372
373 -- 373 --
@@ -393,7 +393,7 @@ CREATE TABLE `platform_gb_stream` ( @@ -393,7 +393,7 @@ CREATE TABLE `platform_gb_stream` (
393 `id` int NOT NULL AUTO_INCREMENT, 393 `id` int NOT NULL AUTO_INCREMENT,
394 PRIMARY KEY (`id`), 394 PRIMARY KEY (`id`),
395 UNIQUE KEY `platform_gb_stream_pk` (`platformId`,`catalogId`,`gbStreamId`) 395 UNIQUE KEY `platform_gb_stream_pk` (`platformId`,`catalogId`,`gbStreamId`)
396 -) ENGINE=InnoDB AUTO_INCREMENT=406 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC; 396 +) ENGINE=InnoDB AUTO_INCREMENT=301207 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC;
397 /*!40101 SET character_set_client = @saved_cs_client */; 397 /*!40101 SET character_set_client = @saved_cs_client */;
398 398
399 -- 399 --
@@ -415,7 +415,6 @@ DROP TABLE IF EXISTS `stream_proxy`; @@ -415,7 +415,6 @@ DROP TABLE IF EXISTS `stream_proxy`;
415 CREATE TABLE `stream_proxy` ( 415 CREATE TABLE `stream_proxy` (
416 `id` int NOT NULL AUTO_INCREMENT, 416 `id` int NOT NULL AUTO_INCREMENT,
417 `type` varchar(50) COLLATE utf8mb4_general_ci NOT NULL, 417 `type` varchar(50) COLLATE utf8mb4_general_ci NOT NULL,
418 - `name` varchar(255) COLLATE utf8mb4_general_ci NOT NULL,  
419 `app` varchar(255) COLLATE utf8mb4_general_ci NOT NULL, 418 `app` varchar(255) COLLATE utf8mb4_general_ci NOT NULL,
420 `name` varchar(255) COLLATE utf8mb4_general_ci NOT NULL, 419 `name` varchar(255) COLLATE utf8mb4_general_ci NOT NULL,
421 `stream` varchar(255) COLLATE utf8mb4_general_ci NOT NULL, 420 `stream` varchar(255) COLLATE utf8mb4_general_ci NOT NULL,
@@ -432,9 +431,10 @@ CREATE TABLE `stream_proxy` ( @@ -432,9 +431,10 @@ CREATE TABLE `stream_proxy` (
432 `status` bit(1) NOT NULL, 431 `status` bit(1) NOT NULL,
433 `enable_remove_none_reader` bit(1) NOT NULL, 432 `enable_remove_none_reader` bit(1) NOT NULL,
434 `createTime` varchar(50) COLLATE utf8mb4_general_ci NOT NULL, 433 `createTime` varchar(50) COLLATE utf8mb4_general_ci NOT NULL,
  434 + `name` varchar(255) COLLATE utf8mb4_general_ci DEFAULT NULL,
435 PRIMARY KEY (`id`), 435 PRIMARY KEY (`id`),
436 UNIQUE KEY `stream_proxy_pk` (`app`,`stream`) 436 UNIQUE KEY `stream_proxy_pk` (`app`,`stream`)
437 -) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; 437 +) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
438 /*!40101 SET character_set_client = @saved_cs_client */; 438 /*!40101 SET character_set_client = @saved_cs_client */;
439 439
440 -- 440 --
@@ -465,7 +465,7 @@ CREATE TABLE `stream_push` ( @@ -465,7 +465,7 @@ CREATE TABLE `stream_push` (
465 `mediaServerId` varchar(50) COLLATE utf8mb4_general_ci DEFAULT NULL, 465 `mediaServerId` varchar(50) COLLATE utf8mb4_general_ci DEFAULT NULL,
466 PRIMARY KEY (`id`), 466 PRIMARY KEY (`id`),
467 UNIQUE KEY `stream_push_pk` (`app`,`stream`) 467 UNIQUE KEY `stream_push_pk` (`app`,`stream`)
468 -) ENGINE=InnoDB AUTO_INCREMENT=394 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; 468 +) ENGINE=InnoDB AUTO_INCREMENT=300799 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
469 /*!40101 SET character_set_client = @saved_cs_client */; 469 /*!40101 SET character_set_client = @saved_cs_client */;
470 470
471 -- 471 --
@@ -502,7 +502,7 @@ CREATE TABLE `user` ( @@ -502,7 +502,7 @@ CREATE TABLE `user` (
502 502
503 LOCK TABLES `user` WRITE; 503 LOCK TABLES `user` WRITE;
504 /*!40000 ALTER TABLE `user` DISABLE KEYS */; 504 /*!40000 ALTER TABLE `user` DISABLE KEYS */;
505 -INSERT INTO `user` VALUES (1,'admin','21232f297a57a5a743894a0e4a801fc3',1,'2021-04-13 14:14:57','2021-04-13 14:14:57'); 505 +INSERT INTO `user` VALUES (1,'admin','21232f297a57a5a743894a0e4a801fc3',1,'2021 - 04 - 13 14:14:57','2021 - 04 - 13 14:14:57');
506 /*!40000 ALTER TABLE `user` ENABLE KEYS */; 506 /*!40000 ALTER TABLE `user` ENABLE KEYS */;
507 UNLOCK TABLES; 507 UNLOCK TABLES;
508 508
@@ -542,4 +542,4 @@ UNLOCK TABLES; @@ -542,4 +542,4 @@ UNLOCK TABLES;
542 /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; 542 /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
543 /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; 543 /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
544 544
545 --- Dump completed on 2022-02-25 20:32:21 545 +-- Dump completed on 2022-03-07 8:26:30
src/main/java/com/genersoft/iot/vmp/conf/DynamicTask.java
@@ -5,6 +5,7 @@ import org.springframework.context.annotation.Bean; @@ -5,6 +5,7 @@ import org.springframework.context.annotation.Bean;
5 import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler; 5 import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
6 import org.springframework.stereotype.Component; 6 import org.springframework.stereotype.Component;
7 7
  8 +import java.util.Date;
8 import java.util.Map; 9 import java.util.Map;
9 import java.util.concurrent.ConcurrentHashMap; 10 import java.util.concurrent.ConcurrentHashMap;
10 import java.util.concurrent.ScheduledFuture; 11 import java.util.concurrent.ScheduledFuture;
@@ -25,15 +26,38 @@ public class DynamicTask { @@ -25,15 +26,38 @@ public class DynamicTask {
25 return new ThreadPoolTaskScheduler(); 26 return new ThreadPoolTaskScheduler();
26 } 27 }
27 28
  29 + /**
  30 + * 循环执行的任务
  31 + * @param key 任务ID
  32 + * @param task 任务
  33 + * @param cycleForCatalog 间隔
  34 + * @return
  35 + */
28 public String startCron(String key, Runnable task, int cycleForCatalog) { 36 public String startCron(String key, Runnable task, int cycleForCatalog) {
29 - stopCron(key); 37 + stop(key);
30 // scheduleWithFixedDelay 必须等待上一个任务结束才开始计时period, cycleForCatalog表示执行的间隔 38 // scheduleWithFixedDelay 必须等待上一个任务结束才开始计时period, cycleForCatalog表示执行的间隔
31 ScheduledFuture future = threadPoolTaskScheduler.scheduleWithFixedDelay(task, cycleForCatalog * 1000L); 39 ScheduledFuture future = threadPoolTaskScheduler.scheduleWithFixedDelay(task, cycleForCatalog * 1000L);
32 futureMap.put(key, future); 40 futureMap.put(key, future);
33 return "startCron"; 41 return "startCron";
34 } 42 }
35 43
36 - public void stopCron(String key) { 44 + /**
  45 + * 延时任务
  46 + * @param key 任务ID
  47 + * @param task 任务
  48 + * @param delay 延时 /秒
  49 + * @return
  50 + */
  51 + public String startDelay(String key, Runnable task, int delay) {
  52 + stop(key);
  53 + Date starTime = new Date(System.currentTimeMillis() + delay * 1000);
  54 + // scheduleWithFixedDelay 必须等待上一个任务结束才开始计时period, cycleForCatalog表示执行的间隔
  55 + ScheduledFuture future = threadPoolTaskScheduler.schedule(task, starTime);
  56 + futureMap.put(key, future);
  57 + return "startCron";
  58 + }
  59 +
  60 + public void stop(String key) {
37 if (futureMap.get(key) != null && !futureMap.get(key).isCancelled()) { 61 if (futureMap.get(key) != null && !futureMap.get(key).isCancelled()) {
38 futureMap.get(key).cancel(true); 62 futureMap.get(key).cancel(true);
39 } 63 }
src/main/java/com/genersoft/iot/vmp/conf/SipPlatformRunner.java
@@ -59,8 +59,11 @@ public class SipPlatformRunner implements CommandLineRunner { @@ -59,8 +59,11 @@ public class SipPlatformRunner implements CommandLineRunner {
59 redisCatchStorage.updatePlatformCatchInfo(parentPlatformCatch); 59 redisCatchStorage.updatePlatformCatchInfo(parentPlatformCatch);
60 60
61 // 取消订阅 61 // 取消订阅
62 - sipCommanderForPlatform.unregister(parentPlatform, null, null);  
63 - Thread.sleep(500); 62 + sipCommanderForPlatform.unregister(parentPlatform, null, (eventResult)->{
  63 + ParentPlatform platform = storager.queryParentPlatByServerGBId(parentPlatform.getServerGBId());
  64 + sipCommanderForPlatform.register(platform, null, null);
  65 + });
  66 +
64 // 发送平台未注册消息 67 // 发送平台未注册消息
65 publisher.platformNotRegisterEventPublish(parentPlatform.getServerGBId()); 68 publisher.platformNotRegisterEventPublish(parentPlatform.getServerGBId());
66 } 69 }
src/main/java/com/genersoft/iot/vmp/conf/UserSetup.java
@@ -19,8 +19,6 @@ public class UserSetup { @@ -19,8 +19,6 @@ public class UserSetup {
19 19
20 private Long playTimeout = 18000L; 20 private Long playTimeout = 18000L;
21 21
22 - private Boolean waitTrack = Boolean.FALSE;  
23 -  
24 private Boolean interfaceAuthentication = Boolean.TRUE; 22 private Boolean interfaceAuthentication = Boolean.TRUE;
25 23
26 private Boolean recordPushLive = Boolean.TRUE; 24 private Boolean recordPushLive = Boolean.TRUE;
@@ -57,10 +55,6 @@ public class UserSetup { @@ -57,10 +55,6 @@ public class UserSetup {
57 return playTimeout; 55 return playTimeout;
58 } 56 }
59 57
60 - public Boolean isWaitTrack() {  
61 - return waitTrack;  
62 - }  
63 -  
64 public Boolean isInterfaceAuthentication() { 58 public Boolean isInterfaceAuthentication() {
65 return interfaceAuthentication; 59 return interfaceAuthentication;
66 } 60 }
@@ -89,10 +83,6 @@ public class UserSetup { @@ -89,10 +83,6 @@ public class UserSetup {
89 this.playTimeout = playTimeout; 83 this.playTimeout = playTimeout;
90 } 84 }
91 85
92 - public void setWaitTrack(Boolean waitTrack) {  
93 - this.waitTrack = waitTrack;  
94 - }  
95 -  
96 public void setInterfaceAuthentication(boolean interfaceAuthentication) { 86 public void setInterfaceAuthentication(boolean interfaceAuthentication) {
97 this.interfaceAuthentication = interfaceAuthentication; 87 this.interfaceAuthentication = interfaceAuthentication;
98 } 88 }
src/main/java/com/genersoft/iot/vmp/gb28181/auth/RegisterLogicHandler.java
1 package com.genersoft.iot.vmp.gb28181.auth; 1 package com.genersoft.iot.vmp.gb28181.auth;
2 2
  3 +import com.genersoft.iot.vmp.storager.impl.VideoManagerStoragerImpl;
3 import org.slf4j.Logger; 4 import org.slf4j.Logger;
4 import org.slf4j.LoggerFactory; 5 import org.slf4j.LoggerFactory;
5 import org.springframework.beans.factory.annotation.Autowired; 6 import org.springframework.beans.factory.annotation.Autowired;
@@ -20,13 +21,24 @@ public class RegisterLogicHandler { @@ -20,13 +21,24 @@ public class RegisterLogicHandler {
20 21
21 @Autowired 22 @Autowired
22 private SIPCommander cmder; 23 private SIPCommander cmder;
  24 +
  25 + @Autowired
  26 + private VideoManagerStoragerImpl storager;
23 27
24 public void onRegister(Device device) { 28 public void onRegister(Device device) {
25 // 只有第一次注册时调用查询设备信息,如需更新调用更新API接口 29 // 只有第一次注册时调用查询设备信息,如需更新调用更新API接口
  30 + // TODO 此处错误无法获取到通道
  31 + Device device1 = storager.queryVideoDevice(device.getDeviceId());
26 if (device.isFirsRegister()) { 32 if (device.isFirsRegister()) {
27 logger.info("[{}] 首次注册,查询设备信息以及通道信息", device.getDeviceId()); 33 logger.info("[{}] 首次注册,查询设备信息以及通道信息", device.getDeviceId());
28 - cmder.deviceInfoQuery(device);  
29 - cmder.catalogQuery(device, null); 34 + try {
  35 + Thread.sleep(100);
  36 + cmder.deviceInfoQuery(device);
  37 + Thread.sleep(100);
  38 + cmder.catalogQuery(device, null);
  39 + } catch (InterruptedException e) {
  40 + e.printStackTrace();
  41 + }
30 } 42 }
31 } 43 }
32 } 44 }
src/main/java/com/genersoft/iot/vmp/gb28181/bean/SendRtpItem.java
@@ -81,6 +81,10 @@ public class SendRtpItem { @@ -81,6 +81,10 @@ public class SendRtpItem {
81 */ 81 */
82 private boolean isPlay; 82 private boolean isPlay;
83 83
  84 + private byte[] transaction;
  85 +
  86 + private byte[] dialog;
  87 +
84 public String getIp() { 88 public String getIp() {
85 return ip; 89 return ip;
86 } 90 }
@@ -200,4 +204,20 @@ public class SendRtpItem { @@ -200,4 +204,20 @@ public class SendRtpItem {
200 public void setPlay(boolean play) { 204 public void setPlay(boolean play) {
201 isPlay = play; 205 isPlay = play;
202 } 206 }
  207 +
  208 + public byte[] getTransaction() {
  209 + return transaction;
  210 + }
  211 +
  212 + public void setTransaction(byte[] transaction) {
  213 + this.transaction = transaction;
  214 + }
  215 +
  216 + public byte[] getDialog() {
  217 + return dialog;
  218 + }
  219 +
  220 + public void setDialog(byte[] dialog) {
  221 + this.dialog = dialog;
  222 + }
203 } 223 }
src/main/java/com/genersoft/iot/vmp/gb28181/event/offline/KeepaliveTimeoutListenerForPlatform.java
@@ -2,7 +2,10 @@ package com.genersoft.iot.vmp.gb28181.event.offline; @@ -2,7 +2,10 @@ package com.genersoft.iot.vmp.gb28181.event.offline;
2 2
3 import com.genersoft.iot.vmp.conf.RedisKeyExpirationEventMessageListener; 3 import com.genersoft.iot.vmp.conf.RedisKeyExpirationEventMessageListener;
4 import com.genersoft.iot.vmp.conf.UserSetup; 4 import com.genersoft.iot.vmp.conf.UserSetup;
  5 +import com.genersoft.iot.vmp.gb28181.bean.Device;
  6 +import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform;
5 import com.genersoft.iot.vmp.gb28181.event.SipSubscribe; 7 import com.genersoft.iot.vmp.gb28181.event.SipSubscribe;
  8 +import com.genersoft.iot.vmp.storager.IVideoManagerStorager;
6 import org.slf4j.Logger; 9 import org.slf4j.Logger;
7 import org.slf4j.LoggerFactory; 10 import org.slf4j.LoggerFactory;
8 import org.springframework.beans.factory.InitializingBean; 11 import org.springframework.beans.factory.InitializingBean;
@@ -39,6 +42,9 @@ public class KeepaliveTimeoutListenerForPlatform extends RedisKeyExpirationEvent @@ -39,6 +42,9 @@ public class KeepaliveTimeoutListenerForPlatform extends RedisKeyExpirationEvent
39 @Autowired 42 @Autowired
40 private SipSubscribe sipSubscribe; 43 private SipSubscribe sipSubscribe;
41 44
  45 + @Autowired
  46 + private IVideoManagerStorager storager;
  47 +
42 public KeepaliveTimeoutListenerForPlatform(RedisMessageListenerContainer listenerContainer, UserSetup userSetup) { 48 public KeepaliveTimeoutListenerForPlatform(RedisMessageListenerContainer listenerContainer, UserSetup userSetup) {
43 super(listenerContainer, userSetup); 49 super(listenerContainer, userSetup);
44 } 50 }
@@ -61,15 +67,22 @@ public class KeepaliveTimeoutListenerForPlatform extends RedisKeyExpirationEvent @@ -61,15 +67,22 @@ public class KeepaliveTimeoutListenerForPlatform extends RedisKeyExpirationEvent
61 String REGISTER_INFO_PREFIX = VideoManagerConstants.PLATFORM_REGISTER_INFO_PREFIX + userSetup.getServerId() + "_"; 67 String REGISTER_INFO_PREFIX = VideoManagerConstants.PLATFORM_REGISTER_INFO_PREFIX + userSetup.getServerId() + "_";
62 if (expiredKey.startsWith(PLATFORM_KEEPLIVEKEY_PREFIX)) { 68 if (expiredKey.startsWith(PLATFORM_KEEPLIVEKEY_PREFIX)) {
63 String platformGBId = expiredKey.substring(PLATFORM_KEEPLIVEKEY_PREFIX.length(),expiredKey.length()); 69 String platformGBId = expiredKey.substring(PLATFORM_KEEPLIVEKEY_PREFIX.length(),expiredKey.length());
64 -  
65 - publisher.platformKeepaliveExpireEventPublish(platformGBId); 70 + ParentPlatform platform = storager.queryParentPlatByServerGBId(platformGBId);
  71 + if (platform != null) {
  72 + publisher.platformKeepaliveExpireEventPublish(platformGBId);
  73 + }
66 }else if (expiredKey.startsWith(PLATFORM_REGISTER_PREFIX)) { 74 }else if (expiredKey.startsWith(PLATFORM_REGISTER_PREFIX)) {
67 String platformGBId = expiredKey.substring(PLATFORM_REGISTER_PREFIX.length(),expiredKey.length()); 75 String platformGBId = expiredKey.substring(PLATFORM_REGISTER_PREFIX.length(),expiredKey.length());
68 -  
69 - publisher.platformRegisterCycleEventPublish(platformGBId); 76 + ParentPlatform platform = storager.queryParentPlatByServerGBId(platformGBId);
  77 + if (platform != null) {
  78 + publisher.platformRegisterCycleEventPublish(platformGBId);
  79 + }
70 }else if (expiredKey.startsWith(KEEPLIVEKEY_PREFIX)){ 80 }else if (expiredKey.startsWith(KEEPLIVEKEY_PREFIX)){
71 String deviceId = expiredKey.substring(KEEPLIVEKEY_PREFIX.length(),expiredKey.length()); 81 String deviceId = expiredKey.substring(KEEPLIVEKEY_PREFIX.length(),expiredKey.length());
72 - publisher.outlineEventPublish(deviceId, KEEPLIVEKEY_PREFIX); 82 + Device device = storager.queryVideoDevice(deviceId);
  83 + if (device != null) {
  84 + publisher.outlineEventPublish(deviceId, KEEPLIVEKEY_PREFIX);
  85 + }
73 }else if (expiredKey.startsWith(REGISTER_INFO_PREFIX)) { 86 }else if (expiredKey.startsWith(REGISTER_INFO_PREFIX)) {
74 String callid = expiredKey.substring(REGISTER_INFO_PREFIX.length()); 87 String callid = expiredKey.substring(REGISTER_INFO_PREFIX.length());
75 SipSubscribe.EventResult eventResult = new SipSubscribe.EventResult(); 88 SipSubscribe.EventResult eventResult = new SipSubscribe.EventResult();
src/main/java/com/genersoft/iot/vmp/gb28181/event/offline/OfflineEventListener.java
@@ -2,8 +2,13 @@ package com.genersoft.iot.vmp.gb28181.event.offline; @@ -2,8 +2,13 @@ package com.genersoft.iot.vmp.gb28181.event.offline;
2 2
3 import com.genersoft.iot.vmp.conf.UserSetup; 3 import com.genersoft.iot.vmp.conf.UserSetup;
4 import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel; 4 import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel;
  5 +import com.genersoft.iot.vmp.gb28181.bean.SsrcTransaction;
5 import com.genersoft.iot.vmp.gb28181.event.EventPublisher; 6 import com.genersoft.iot.vmp.gb28181.event.EventPublisher;
6 import com.genersoft.iot.vmp.gb28181.event.subscribe.catalog.CatalogEvent; 7 import com.genersoft.iot.vmp.gb28181.event.subscribe.catalog.CatalogEvent;
  8 +import com.genersoft.iot.vmp.gb28181.session.VideoStreamSessionManager;
  9 +import com.genersoft.iot.vmp.media.zlm.ZLMRTPServerFactory;
  10 +import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
  11 +import com.genersoft.iot.vmp.service.IMediaServerService;
7 import org.slf4j.Logger; 12 import org.slf4j.Logger;
8 import org.slf4j.LoggerFactory; 13 import org.slf4j.LoggerFactory;
9 import org.springframework.beans.factory.annotation.Autowired; 14 import org.springframework.beans.factory.annotation.Autowired;
@@ -32,6 +37,9 @@ public class OfflineEventListener implements ApplicationListener<OfflineEvent> { @@ -32,6 +37,9 @@ public class OfflineEventListener implements ApplicationListener<OfflineEvent> {
32 37
33 @Autowired 38 @Autowired
34 private IVideoManagerStorager storager; 39 private IVideoManagerStorager storager;
  40 +
  41 + @Autowired
  42 + private VideoStreamSessionManager streamSession;
35 43
36 @Autowired 44 @Autowired
37 private RedisUtil redis; 45 private RedisUtil redis;
@@ -42,6 +50,14 @@ public class OfflineEventListener implements ApplicationListener<OfflineEvent> { @@ -42,6 +50,14 @@ public class OfflineEventListener implements ApplicationListener<OfflineEvent> {
42 @Autowired 50 @Autowired
43 private EventPublisher eventPublisher; 51 private EventPublisher eventPublisher;
44 52
  53 +
  54 + @Autowired
  55 + private IMediaServerService mediaServerService;
  56 +
  57 +
  58 + @Autowired
  59 + private ZLMRTPServerFactory zlmrtpServerFactory;
  60 +
45 @Override 61 @Override
46 public void onApplicationEvent(OfflineEvent event) { 62 public void onApplicationEvent(OfflineEvent event) {
47 63
@@ -73,5 +89,15 @@ public class OfflineEventListener implements ApplicationListener<OfflineEvent> { @@ -73,5 +89,15 @@ public class OfflineEventListener implements ApplicationListener<OfflineEvent> {
73 89
74 // TODO 离线取消订阅 90 // TODO 离线取消订阅
75 91
  92 + // 离线释放所有ssrc
  93 + List<SsrcTransaction> ssrcTransactions = streamSession.getSsrcTransactionForAll(event.getDeviceId(), null, null, null);
  94 + if (ssrcTransactions.size() > 0) {
  95 + for (SsrcTransaction ssrcTransaction : ssrcTransactions) {
  96 + mediaServerService.releaseSsrc(ssrcTransaction.getMediaServerId(), ssrcTransaction.getSsrc());
  97 + mediaServerService.closeRTPServer(event.getDeviceId(), ssrcTransaction.getChannelId(), ssrcTransaction.getStream());
  98 + streamSession.remove(event.getDeviceId(), ssrcTransaction.getChannelId(), ssrcTransaction.getStream());
  99 + }
  100 + }
  101 +
76 } 102 }
77 } 103 }
src/main/java/com/genersoft/iot/vmp/gb28181/event/platformNotRegister/PlatformNotRegisterEventLister.java
@@ -75,7 +75,7 @@ public class PlatformNotRegisterEventLister implements ApplicationListener&lt;Platf @@ -75,7 +75,7 @@ public class PlatformNotRegisterEventLister implements ApplicationListener&lt;Platf
75 stream.append(","); 75 stream.append(",");
76 } 76 }
77 stream.append(sendRtpItem.getStreamId()); 77 stream.append(sendRtpItem.getStreamId());
78 - redisCatchStorage.deleteSendRTPServer(event.getPlatformGbID(), sendRtpItem.getChannelId()); 78 + redisCatchStorage.deleteSendRTPServer(event.getPlatformGbID(), sendRtpItem.getChannelId(), null, null);
79 MediaServerItem mediaInfo = mediaServerService.getOne(sendRtpItem.getMediaServerId()); 79 MediaServerItem mediaInfo = mediaServerService.getOne(sendRtpItem.getMediaServerId());
80 Map<String, Object> param = new HashMap<>(); 80 Map<String, Object> param = new HashMap<>();
81 param.put("vhost", "__defaultVhost__"); 81 param.put("vhost", "__defaultVhost__");
@@ -84,9 +84,7 @@ public class PlatformNotRegisterEventLister implements ApplicationListener&lt;Platf @@ -84,9 +84,7 @@ public class PlatformNotRegisterEventLister implements ApplicationListener&lt;Platf
84 zlmrtpServerFactory.stopSendRtpStream(mediaInfo, param); 84 zlmrtpServerFactory.stopSendRtpStream(mediaInfo, param);
85 } 85 }
86 86
87 -  
88 } 87 }
89 -  
90 Timer timer = new Timer(); 88 Timer timer = new Timer();
91 SipSubscribe.Event okEvent = (responseEvent)->{ 89 SipSubscribe.Event okEvent = (responseEvent)->{
92 timer.cancel(); 90 timer.cancel();
src/main/java/com/genersoft/iot/vmp/gb28181/event/subscribe/SubscribeListenerForPlatform.java
@@ -4,8 +4,6 @@ import com.genersoft.iot.vmp.common.VideoManagerConstants; @@ -4,8 +4,6 @@ import com.genersoft.iot.vmp.common.VideoManagerConstants;
4 import com.genersoft.iot.vmp.conf.DynamicTask; 4 import com.genersoft.iot.vmp.conf.DynamicTask;
5 import com.genersoft.iot.vmp.conf.RedisKeyExpirationEventMessageListener; 5 import com.genersoft.iot.vmp.conf.RedisKeyExpirationEventMessageListener;
6 import com.genersoft.iot.vmp.conf.UserSetup; 6 import com.genersoft.iot.vmp.conf.UserSetup;
7 -import com.genersoft.iot.vmp.gb28181.event.EventPublisher;  
8 -import org.checkerframework.checker.units.qual.A;  
9 import org.slf4j.Logger; 7 import org.slf4j.Logger;
10 import org.slf4j.LoggerFactory; 8 import org.slf4j.LoggerFactory;
11 import org.springframework.beans.factory.annotation.Autowired; 9 import org.springframework.beans.factory.annotation.Autowired;
@@ -46,7 +44,7 @@ public class SubscribeListenerForPlatform extends RedisKeyExpirationEventMessage @@ -46,7 +44,7 @@ public class SubscribeListenerForPlatform extends RedisKeyExpirationEventMessage
46 String PLATFORM_KEEPLIVEKEY_PREFIX = VideoManagerConstants.SIP_SUBSCRIBE_PREFIX + userSetup.getServerId() + "_"; 44 String PLATFORM_KEEPLIVEKEY_PREFIX = VideoManagerConstants.SIP_SUBSCRIBE_PREFIX + userSetup.getServerId() + "_";
47 if (expiredKey.startsWith(PLATFORM_KEEPLIVEKEY_PREFIX)) { 45 if (expiredKey.startsWith(PLATFORM_KEEPLIVEKEY_PREFIX)) {
48 // 取消定时任务 46 // 取消定时任务
49 - dynamicTask.stopCron(expiredKey); 47 + dynamicTask.stop(expiredKey);
50 } 48 }
51 } 49 }
52 } 50 }
src/main/java/com/genersoft/iot/vmp/gb28181/session/VideoStreamSessionManager.java
@@ -86,6 +86,15 @@ public class VideoStreamSessionManager { @@ -86,6 +86,15 @@ public class VideoStreamSessionManager {
86 return dialog; 86 return dialog;
87 } 87 }
88 88
  89 + public SIPDialog getDialogByCallId(String deviceId, String channelId, String callID){
  90 + SsrcTransaction ssrcTransaction = getSsrcTransaction(deviceId, channelId, callID, null);
  91 + if (ssrcTransaction == null) return null;
  92 + byte[] dialogByteArray = ssrcTransaction.getDialog();
  93 + if (dialogByteArray == null) return null;
  94 + SIPDialog dialog = (SIPDialog)SerializeUtils.deSerialize(dialogByteArray);
  95 + return dialog;
  96 + }
  97 +
89 public SsrcTransaction getSsrcTransaction(String deviceId, String channelId, String callId, String stream){ 98 public SsrcTransaction getSsrcTransaction(String deviceId, String channelId, String callId, String stream){
90 if (StringUtils.isEmpty(callId)) callId ="*"; 99 if (StringUtils.isEmpty(callId)) callId ="*";
91 if (StringUtils.isEmpty(stream)) stream ="*"; 100 if (StringUtils.isEmpty(stream)) stream ="*";
@@ -95,6 +104,21 @@ public class VideoStreamSessionManager { @@ -95,6 +104,21 @@ public class VideoStreamSessionManager {
95 return (SsrcTransaction)redisUtil.get((String) scanResult.get(0)); 104 return (SsrcTransaction)redisUtil.get((String) scanResult.get(0));
96 } 105 }
97 106
  107 + public List<SsrcTransaction> getSsrcTransactionForAll(String deviceId, String channelId, String callId, String stream){
  108 + if (StringUtils.isEmpty(deviceId)) deviceId ="*";
  109 + if (StringUtils.isEmpty(channelId)) channelId ="*";
  110 + if (StringUtils.isEmpty(callId)) callId ="*";
  111 + if (StringUtils.isEmpty(stream)) stream ="*";
  112 + String key = VideoManagerConstants.MEDIA_TRANSACTION_USED_PREFIX + userSetup.getServerId() + "_" + deviceId + "_" + channelId + "_" + callId+ "_" + stream;
  113 + List<Object> scanResult = redisUtil.scan(key);
  114 + if (scanResult.size() == 0) return null;
  115 + List<SsrcTransaction> result = new ArrayList<>();
  116 + for (Object keyObj : scanResult) {
  117 + result.add((SsrcTransaction)redisUtil.get((String) keyObj));
  118 + }
  119 + return result;
  120 + }
  121 +
98 public String getMediaServerId(String deviceId, String channelId, String stream){ 122 public String getMediaServerId(String deviceId, String channelId, String stream){
99 SsrcTransaction ssrcTransaction = getSsrcTransaction(deviceId, channelId, null, stream); 123 SsrcTransaction ssrcTransaction = getSsrcTransaction(deviceId, channelId, null, stream);
100 if (ssrcTransaction == null) return null; 124 if (ssrcTransaction == null) return null;
src/main/java/com/genersoft/iot/vmp/gb28181/task/GPSSubscribeTask.java
@@ -63,7 +63,5 @@ public class GPSSubscribeTask implements Runnable{ @@ -63,7 +63,5 @@ public class GPSSubscribeTask implements Runnable{
63 } 63 }
64 } 64 }
65 } 65 }
66 -  
67 -  
68 } 66 }
69 } 67 }
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/ISIPCommanderForPlatform.java
@@ -96,4 +96,11 @@ public interface ISIPCommanderForPlatform { @@ -96,4 +96,11 @@ public interface ISIPCommanderForPlatform {
96 * @param recordInfo 录像信息 96 * @param recordInfo 录像信息
97 */ 97 */
98 boolean recordInfo(DeviceChannel deviceChannel, ParentPlatform parentPlatform, String fromTag, RecordInfo recordInfo); 98 boolean recordInfo(DeviceChannel deviceChannel, ParentPlatform parentPlatform, String fromTag, RecordInfo recordInfo);
  99 +
  100 + /**
  101 + * 向发起点播的上级回复bye
  102 + * @param platform 平台信息
  103 + * @param callId callId
  104 + */
  105 + void streamByeCmd(ParentPlatform platform, String callId);
99 } 106 }
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java
@@ -2,6 +2,7 @@ package com.genersoft.iot.vmp.gb28181.transmit.cmd.impl; @@ -2,6 +2,7 @@ package com.genersoft.iot.vmp.gb28181.transmit.cmd.impl;
2 2
3 import com.alibaba.fastjson.JSONObject; 3 import com.alibaba.fastjson.JSONObject;
4 import com.genersoft.iot.vmp.common.StreamInfo; 4 import com.genersoft.iot.vmp.common.StreamInfo;
  5 +import com.genersoft.iot.vmp.conf.DynamicTask;
5 import com.genersoft.iot.vmp.conf.SipConfig; 6 import com.genersoft.iot.vmp.conf.SipConfig;
6 import com.genersoft.iot.vmp.conf.UserSetup; 7 import com.genersoft.iot.vmp.conf.UserSetup;
7 import com.genersoft.iot.vmp.gb28181.bean.Device; 8 import com.genersoft.iot.vmp.gb28181.bean.Device;
@@ -85,6 +86,9 @@ public class SIPCommander implements ISIPCommander { @@ -85,6 +86,9 @@ public class SIPCommander implements ISIPCommander {
85 @Autowired 86 @Autowired
86 private IMediaServerService mediaServerService; 87 private IMediaServerService mediaServerService;
87 88
  89 + @Autowired
  90 + private DynamicTask dynamicTask;
  91 +
88 92
89 /** 93 /**
90 * 云台方向放控制,使用配置文件中的默认镜头移动速度 94 * 云台方向放控制,使用配置文件中的默认镜头移动速度
@@ -330,7 +334,8 @@ public class SIPCommander implements ISIPCommander { @@ -330,7 +334,8 @@ public class SIPCommander implements ISIPCommander {
330 * @param errorEvent sip错误订阅 334 * @param errorEvent sip错误订阅
331 */ 335 */
332 @Override 336 @Override
333 - public void playStreamCmd(MediaServerItem mediaServerItem, SSRCInfo ssrcInfo, Device device, String channelId, ZLMHttpHookSubscribe.Event event, SipSubscribe.Event errorEvent) { 337 + public void playStreamCmd(MediaServerItem mediaServerItem, SSRCInfo ssrcInfo, Device device, String channelId,
  338 + ZLMHttpHookSubscribe.Event event, SipSubscribe.Event errorEvent) {
334 String streamId = ssrcInfo.getStream(); 339 String streamId = ssrcInfo.getStream();
335 try { 340 try {
336 if (device == null) return; 341 if (device == null) return;
@@ -342,15 +347,13 @@ public class SIPCommander implements ISIPCommander { @@ -342,15 +347,13 @@ public class SIPCommander implements ISIPCommander {
342 subscribeKey.put("app", "rtp"); 347 subscribeKey.put("app", "rtp");
343 subscribeKey.put("stream", streamId); 348 subscribeKey.put("stream", streamId);
344 subscribeKey.put("regist", true); 349 subscribeKey.put("regist", true);
  350 + subscribeKey.put("schema", "rtmp");
345 subscribeKey.put("mediaServerId", mediaServerItem.getId()); 351 subscribeKey.put("mediaServerId", mediaServerItem.getId());
346 subscribe.addSubscribe(ZLMHttpHookSubscribe.HookType.on_stream_changed, subscribeKey, 352 subscribe.addSubscribe(ZLMHttpHookSubscribe.HookType.on_stream_changed, subscribeKey,
347 (MediaServerItem mediaServerItemInUse, JSONObject json)->{ 353 (MediaServerItem mediaServerItemInUse, JSONObject json)->{
348 - if (userSetup.isWaitTrack() && json.getJSONArray("tracks") == null) return;  
349 if (event != null) { 354 if (event != null) {
350 event.response(mediaServerItemInUse, json); 355 event.response(mediaServerItemInUse, json);
351 } 356 }
352 -  
353 -// subscribe.removeSubscribe(ZLMHttpHookSubscribe.HookType.on_stream_changed, subscribeKey);  
354 }); 357 });
355 // 358 //
356 StringBuffer content = new StringBuffer(200); 359 StringBuffer content = new StringBuffer(200);
@@ -419,7 +422,7 @@ public class SIPCommander implements ISIPCommander { @@ -419,7 +422,7 @@ public class SIPCommander implements ISIPCommander {
419 422
420 transmitRequest(device, request, (e -> { 423 transmitRequest(device, request, (e -> {
421 streamSession.remove(device.getDeviceId(), channelId, ssrcInfo.getStream()); 424 streamSession.remove(device.getDeviceId(), channelId, ssrcInfo.getStream());
422 - mediaServerService.releaseSsrc(mediaServerItem, ssrcInfo.getSsrc()); 425 + mediaServerService.releaseSsrc(mediaServerItem.getId(), ssrcInfo.getSsrc());
423 errorEvent.response(e); 426 errorEvent.response(e);
424 }), e ->{ 427 }), e ->{
425 // 这里为例避免一个通道的点播只有一个callID这个参数使用一个固定值 428 // 这里为例避免一个通道的点播只有一个callID这个参数使用一个固定值
@@ -458,8 +461,6 @@ public class SIPCommander implements ISIPCommander { @@ -458,8 +461,6 @@ public class SIPCommander implements ISIPCommander {
458 logger.debug("录像回放添加订阅,订阅内容:" + subscribeKey.toString()); 461 logger.debug("录像回放添加订阅,订阅内容:" + subscribeKey.toString());
459 subscribe.addSubscribe(ZLMHttpHookSubscribe.HookType.on_stream_changed, subscribeKey, 462 subscribe.addSubscribe(ZLMHttpHookSubscribe.HookType.on_stream_changed, subscribeKey,
460 (MediaServerItem mediaServerItemInUse, JSONObject json)->{ 463 (MediaServerItem mediaServerItemInUse, JSONObject json)->{
461 - System.out.println(344444);  
462 - if (userSetup.isWaitTrack() && json.getJSONArray("tracks") == null) return;  
463 if (event != null) { 464 if (event != null) {
464 event.response(mediaServerItemInUse, json); 465 event.response(mediaServerItemInUse, json);
465 } 466 }
@@ -565,7 +566,6 @@ public class SIPCommander implements ISIPCommander { @@ -565,7 +566,6 @@ public class SIPCommander implements ISIPCommander {
565 logger.debug("录像回放添加订阅,订阅内容:" + subscribeKey.toString()); 566 logger.debug("录像回放添加订阅,订阅内容:" + subscribeKey.toString());
566 subscribe.addSubscribe(ZLMHttpHookSubscribe.HookType.on_stream_changed, subscribeKey, 567 subscribe.addSubscribe(ZLMHttpHookSubscribe.HookType.on_stream_changed, subscribeKey,
567 (MediaServerItem mediaServerItemInUse, JSONObject json)->{ 568 (MediaServerItem mediaServerItemInUse, JSONObject json)->{
568 - if (userSetup.isWaitTrack() && json.getJSONArray("tracks") == null) return;  
569 event.response(mediaServerItemInUse, json); 569 event.response(mediaServerItemInUse, json);
570 subscribe.removeSubscribe(ZLMHttpHookSubscribe.HookType.on_stream_changed, subscribeKey); 570 subscribe.removeSubscribe(ZLMHttpHookSubscribe.HookType.on_stream_changed, subscribeKey);
571 }); 571 });
@@ -662,6 +662,7 @@ public class SIPCommander implements ISIPCommander { @@ -662,6 +662,7 @@ public class SIPCommander implements ISIPCommander {
662 @Override 662 @Override
663 public void streamByeCmd(String deviceId, String channelId, String stream, SipSubscribe.Event okEvent) { 663 public void streamByeCmd(String deviceId, String channelId, String stream, SipSubscribe.Event okEvent) {
664 try { 664 try {
  665 + SsrcTransaction ssrcTransaction = streamSession.getSsrcTransaction(deviceId, channelId, null, stream);
665 ClientTransaction transaction = streamSession.getTransactionByStream(deviceId, channelId, stream); 666 ClientTransaction transaction = streamSession.getTransactionByStream(deviceId, channelId, stream);
666 if (transaction == null) { 667 if (transaction == null) {
667 logger.warn("[ {} -> {}]停止视频流的时候发现事务已丢失", deviceId, channelId); 668 logger.warn("[ {} -> {}]停止视频流的时候发现事务已丢失", deviceId, channelId);
@@ -715,10 +716,9 @@ public class SIPCommander implements ISIPCommander { @@ -715,10 +716,9 @@ public class SIPCommander implements ISIPCommander {
715 716
716 dialog.sendRequest(clientTransaction); 717 dialog.sendRequest(clientTransaction);
717 718
718 - SsrcTransaction ssrcTransaction = streamSession.getSsrcTransaction(deviceId, channelId, callIdHeader.getCallId(), null);  
719 if (ssrcTransaction != null) { 719 if (ssrcTransaction != null) {
720 MediaServerItem mediaServerItem = mediaServerService.getOne(ssrcTransaction.getMediaServerId()); 720 MediaServerItem mediaServerItem = mediaServerService.getOne(ssrcTransaction.getMediaServerId());
721 - mediaServerService.releaseSsrc(mediaServerItem, ssrcTransaction.getSsrc()); 721 + mediaServerService.releaseSsrc(mediaServerItem.getId(), ssrcTransaction.getSsrc());
722 mediaServerService.closeRTPServer(deviceId, channelId, ssrcTransaction.getStream()); 722 mediaServerService.closeRTPServer(deviceId, channelId, ssrcTransaction.getStream());
723 streamSession.remove(deviceId, channelId, ssrcTransaction.getStream()); 723 streamSession.remove(deviceId, channelId, ssrcTransaction.getStream());
724 } 724 }
@@ -1169,8 +1169,6 @@ public class SIPCommander implements ISIPCommander { @@ -1169,8 +1169,6 @@ public class SIPCommander implements ISIPCommander {
1169 */ 1169 */
1170 @Override 1170 @Override
1171 public boolean catalogQuery(Device device, SipSubscribe.Event errorEvent) { 1171 public boolean catalogQuery(Device device, SipSubscribe.Event errorEvent) {
1172 - // 清空通道  
1173 -// storager.cleanChannelsForDevice(device.getDeviceId());  
1174 try { 1172 try {
1175 StringBuffer catalogXml = new StringBuffer(200); 1173 StringBuffer catalogXml = new StringBuffer(200);
1176 catalogXml.append("<?xml version=\"1.0\" encoding=\"GB2312\"?>\r\n"); 1174 catalogXml.append("<?xml version=\"1.0\" encoding=\"GB2312\"?>\r\n");
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommanderFroPlatform.java
@@ -5,8 +5,16 @@ import com.genersoft.iot.vmp.gb28181.event.SipSubscribe; @@ -5,8 +5,16 @@ import com.genersoft.iot.vmp.gb28181.event.SipSubscribe;
5 import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform; 5 import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform;
6 import com.genersoft.iot.vmp.gb28181.transmit.cmd.SIPRequestHeaderPlarformProvider; 6 import com.genersoft.iot.vmp.gb28181.transmit.cmd.SIPRequestHeaderPlarformProvider;
7 import com.genersoft.iot.vmp.gb28181.utils.DateUtil; 7 import com.genersoft.iot.vmp.gb28181.utils.DateUtil;
  8 +import com.genersoft.iot.vmp.media.zlm.ZLMRTPServerFactory;
  9 +import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
  10 +import com.genersoft.iot.vmp.service.IMediaServerService;
8 import com.genersoft.iot.vmp.service.bean.GPSMsgInfo; 11 import com.genersoft.iot.vmp.service.bean.GPSMsgInfo;
9 import com.genersoft.iot.vmp.storager.IRedisCatchStorage; 12 import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
  13 +import com.genersoft.iot.vmp.utils.SerializeUtils;
  14 +import gov.nist.javax.sip.SipProviderImpl;
  15 +import gov.nist.javax.sip.SipStackImpl;
  16 +import gov.nist.javax.sip.message.SIPRequest;
  17 +import gov.nist.javax.sip.stack.SIPDialog;
10 import org.slf4j.Logger; 18 import org.slf4j.Logger;
11 import org.slf4j.LoggerFactory; 19 import org.slf4j.LoggerFactory;
12 import org.springframework.beans.factory.annotation.Autowired; 20 import org.springframework.beans.factory.annotation.Autowired;
@@ -18,10 +26,14 @@ import org.springframework.stereotype.Component; @@ -18,10 +26,14 @@ import org.springframework.stereotype.Component;
18 import org.springframework.util.StringUtils; 26 import org.springframework.util.StringUtils;
19 27
20 import javax.sip.*; 28 import javax.sip.*;
  29 +import javax.sip.address.SipURI;
21 import javax.sip.header.CallIdHeader; 30 import javax.sip.header.CallIdHeader;
  31 +import javax.sip.header.ViaHeader;
22 import javax.sip.header.WWWAuthenticateHeader; 32 import javax.sip.header.WWWAuthenticateHeader;
23 import javax.sip.message.Request; 33 import javax.sip.message.Request;
  34 +import java.lang.reflect.Field;
24 import java.text.ParseException; 35 import java.text.ParseException;
  36 +import java.util.HashSet;
25 import java.util.List; 37 import java.util.List;
26 import java.util.UUID; 38 import java.util.UUID;
27 39
@@ -38,17 +50,23 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform { @@ -38,17 +50,23 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform {
38 private IRedisCatchStorage redisCatchStorage; 50 private IRedisCatchStorage redisCatchStorage;
39 51
40 @Autowired 52 @Autowired
  53 + private IMediaServerService mediaServerService;
  54 +
  55 + @Autowired
41 private SipSubscribe sipSubscribe; 56 private SipSubscribe sipSubscribe;
42 57
  58 + @Autowired
  59 + private ZLMRTPServerFactory zlmrtpServerFactory;
  60 +
43 @Lazy 61 @Lazy
44 @Autowired 62 @Autowired
45 @Qualifier(value="tcpSipProvider") 63 @Qualifier(value="tcpSipProvider")
46 - private SipProvider tcpSipProvider; 64 + private SipProviderImpl tcpSipProvider;
47 65
48 @Lazy 66 @Lazy
49 @Autowired 67 @Autowired
50 @Qualifier(value="udpSipProvider") 68 @Qualifier(value="udpSipProvider")
51 - private SipProvider udpSipProvider; 69 + private SipProviderImpl udpSipProvider;
52 70
53 @Override 71 @Override
54 public boolean register(ParentPlatform parentPlatform, SipSubscribe.Event errorEvent , SipSubscribe.Event okEvent) { 72 public boolean register(ParentPlatform parentPlatform, SipSubscribe.Event errorEvent , SipSubscribe.Event okEvent) {
@@ -57,13 +75,12 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform { @@ -57,13 +75,12 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform {
57 75
58 @Override 76 @Override
59 public boolean unregister(ParentPlatform parentPlatform, SipSubscribe.Event errorEvent , SipSubscribe.Event okEvent) { 77 public boolean unregister(ParentPlatform parentPlatform, SipSubscribe.Event errorEvent , SipSubscribe.Event okEvent) {
60 - parentPlatform.setExpires("0");  
61 ParentPlatformCatch parentPlatformCatch = redisCatchStorage.queryPlatformCatchInfo(parentPlatform.getServerGBId()); 78 ParentPlatformCatch parentPlatformCatch = redisCatchStorage.queryPlatformCatchInfo(parentPlatform.getServerGBId());
62 if (parentPlatformCatch != null) { 79 if (parentPlatformCatch != null) {
63 parentPlatformCatch.setParentPlatform(parentPlatform); 80 parentPlatformCatch.setParentPlatform(parentPlatform);
64 redisCatchStorage.updatePlatformCatchInfo(parentPlatformCatch); 81 redisCatchStorage.updatePlatformCatchInfo(parentPlatformCatch);
65 } 82 }
66 - 83 + parentPlatform.setExpires("0");
67 return register(parentPlatform, null, null, errorEvent, okEvent, false); 84 return register(parentPlatform, null, null, errorEvent, okEvent, false);
68 } 85 }
69 86
@@ -543,4 +560,59 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform { @@ -543,4 +560,59 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform {
543 } 560 }
544 return true; 561 return true;
545 } 562 }
  563 +
  564 + @Override
  565 + public void streamByeCmd(ParentPlatform platform, String callId) {
  566 + SendRtpItem sendRtpItem = redisCatchStorage.querySendRTPServer(platform.getServerGBId(), null, null, callId);
  567 + if (sendRtpItem != null) {
  568 + String mediaServerId = sendRtpItem.getMediaServerId();
  569 + MediaServerItem mediaServerItem = mediaServerService.getOne(mediaServerId);
  570 + if (mediaServerItem != null) {
  571 + mediaServerService.releaseSsrc(mediaServerItem.getId(), sendRtpItem.getSsrc());
  572 + zlmrtpServerFactory.closeRTPServer(mediaServerItem, sendRtpItem.getStreamId());
  573 + }
  574 + byte[] dialogByteArray = sendRtpItem.getDialog();
  575 + if (dialogByteArray != null) {
  576 + SIPDialog dialog = (SIPDialog) SerializeUtils.deSerialize(dialogByteArray);
  577 + SipStack sipStack = udpSipProvider.getSipStack();
  578 + SIPDialog sipDialog = ((SipStackImpl) sipStack).putDialog(dialog);
  579 + if (dialog != sipDialog) {
  580 + dialog = sipDialog;
  581 + } else {
  582 + try {
  583 + dialog.setSipProvider(udpSipProvider);
  584 + Field sipStackField = SIPDialog.class.getDeclaredField("sipStack");
  585 + sipStackField.setAccessible(true);
  586 + sipStackField.set(dialog, sipStack);
  587 + Field eventListenersField = SIPDialog.class.getDeclaredField("eventListeners");
  588 + eventListenersField.setAccessible(true);
  589 + eventListenersField.set(dialog, new HashSet<>());
  590 +
  591 + byte[] transactionByteArray = sendRtpItem.getTransaction();
  592 + ClientTransaction clientTransaction = (ClientTransaction) SerializeUtils.deSerialize(transactionByteArray);
  593 + Request byeRequest = dialog.createRequest(Request.BYE);
  594 + SipURI byeURI = (SipURI) byeRequest.getRequestURI();
  595 + SIPRequest request = (SIPRequest) clientTransaction.getRequest();
  596 + byeURI.setHost(request.getRemoteAddress().getHostName());
  597 + byeURI.setPort(request.getRemotePort());
  598 + if ("TCP".equals(platform.getTransport())) {
  599 + clientTransaction = tcpSipProvider.getNewClientTransaction(byeRequest);
  600 + } else if ("UDP".equals(platform.getTransport())) {
  601 + clientTransaction = udpSipProvider.getNewClientTransaction(byeRequest);
  602 + }
  603 + dialog.sendRequest(clientTransaction);
  604 + } catch (SipException e) {
  605 + e.printStackTrace();
  606 + } catch (ParseException e) {
  607 + e.printStackTrace();
  608 + } catch (NoSuchFieldException e) {
  609 + e.printStackTrace();
  610 + } catch (IllegalAccessException e) {
  611 + e.printStackTrace();
  612 + }
  613 +
  614 + }
  615 + }
  616 + }
  617 + }
546 } 618 }
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/AckRequestProcessor.java
@@ -3,6 +3,7 @@ package com.genersoft.iot.vmp.gb28181.transmit.event.request.impl; @@ -3,6 +3,7 @@ package com.genersoft.iot.vmp.gb28181.transmit.event.request.impl;
3 import com.alibaba.fastjson.JSON; 3 import com.alibaba.fastjson.JSON;
4 import com.alibaba.fastjson.JSONObject; 4 import com.alibaba.fastjson.JSONObject;
5 import com.genersoft.iot.vmp.common.StreamInfo; 5 import com.genersoft.iot.vmp.common.StreamInfo;
  6 +import com.genersoft.iot.vmp.conf.DynamicTask;
6 import com.genersoft.iot.vmp.gb28181.bean.SendRtpItem; 7 import com.genersoft.iot.vmp.gb28181.bean.SendRtpItem;
7 import com.genersoft.iot.vmp.gb28181.transmit.SIPProcessorObserver; 8 import com.genersoft.iot.vmp.gb28181.transmit.SIPProcessorObserver;
8 import com.genersoft.iot.vmp.gb28181.transmit.event.request.ISIPRequestProcessor; 9 import com.genersoft.iot.vmp.gb28181.transmit.event.request.ISIPRequestProcessor;
@@ -22,6 +23,7 @@ import javax.sip.Dialog; @@ -22,6 +23,7 @@ import javax.sip.Dialog;
22 import javax.sip.DialogState; 23 import javax.sip.DialogState;
23 import javax.sip.RequestEvent; 24 import javax.sip.RequestEvent;
24 import javax.sip.address.SipURI; 25 import javax.sip.address.SipURI;
  26 +import javax.sip.header.CallIdHeader;
25 import javax.sip.header.FromHeader; 27 import javax.sip.header.FromHeader;
26 import javax.sip.header.HeaderAddress; 28 import javax.sip.header.HeaderAddress;
27 import javax.sip.header.ToHeader; 29 import javax.sip.header.ToHeader;
@@ -60,6 +62,9 @@ public class AckRequestProcessor extends SIPRequestProcessorParent implements In @@ -60,6 +62,9 @@ public class AckRequestProcessor extends SIPRequestProcessorParent implements In
60 @Autowired 62 @Autowired
61 private ZLMHttpHookSubscribe subscribe; 63 private ZLMHttpHookSubscribe subscribe;
62 64
  65 + @Autowired
  66 + private DynamicTask dynamicTask;
  67 +
63 68
64 /** 69 /**
65 * 处理 ACK请求 70 * 处理 ACK请求
@@ -68,13 +73,16 @@ public class AckRequestProcessor extends SIPRequestProcessorParent implements In @@ -68,13 +73,16 @@ public class AckRequestProcessor extends SIPRequestProcessorParent implements In
68 */ 73 */
69 @Override 74 @Override
70 public void process(RequestEvent evt) { 75 public void process(RequestEvent evt) {
71 - logger.info("ACK请求: {}", ((System.currentTimeMillis())));  
72 Dialog dialog = evt.getDialog(); 76 Dialog dialog = evt.getDialog();
  77 + CallIdHeader callIdHeader = (CallIdHeader)evt.getRequest().getHeader(CallIdHeader.NAME);
73 if (dialog == null) return; 78 if (dialog == null) return;
74 if (dialog.getState()== DialogState.CONFIRMED) { 79 if (dialog.getState()== DialogState.CONFIRMED) {
75 String platformGbId = ((SipURI) ((HeaderAddress) evt.getRequest().getHeader(FromHeader.NAME)).getAddress().getURI()).getUser(); 80 String platformGbId = ((SipURI) ((HeaderAddress) evt.getRequest().getHeader(FromHeader.NAME)).getAddress().getURI()).getUser();
  81 + logger.info("ACK请求: platformGbId->{}", platformGbId);
  82 + // 取消设置的超时任务
  83 + dynamicTask.stop(callIdHeader.getCallId());
76 String channelId = ((SipURI) ((HeaderAddress) evt.getRequest().getHeader(ToHeader.NAME)).getAddress().getURI()).getUser(); 84 String channelId = ((SipURI) ((HeaderAddress) evt.getRequest().getHeader(ToHeader.NAME)).getAddress().getURI()).getUser();
77 - SendRtpItem sendRtpItem = redisCatchStorage.querySendRTPServer(platformGbId, channelId); 85 + SendRtpItem sendRtpItem = redisCatchStorage.querySendRTPServer(platformGbId, channelId, null, callIdHeader.getCallId());
78 String is_Udp = sendRtpItem.isTcp() ? "0" : "1"; 86 String is_Udp = sendRtpItem.isTcp() ? "0" : "1";
79 String deviceId = sendRtpItem.getDeviceId(); 87 String deviceId = sendRtpItem.getDeviceId();
80 StreamInfo streamInfo = null; 88 StreamInfo streamInfo = null;
@@ -83,15 +91,12 @@ public class AckRequestProcessor extends SIPRequestProcessorParent implements In @@ -83,15 +91,12 @@ public class AckRequestProcessor extends SIPRequestProcessorParent implements In
83 }else { 91 }else {
84 streamInfo = redisCatchStorage.queryPlaybackByDevice(deviceId, channelId); 92 streamInfo = redisCatchStorage.queryPlaybackByDevice(deviceId, channelId);
85 } 93 }
86 - System.out.println(JSON.toJSON(streamInfo));  
87 if (streamInfo == null) { 94 if (streamInfo == null) {
88 streamInfo = new StreamInfo(); 95 streamInfo = new StreamInfo();
89 streamInfo.setApp(sendRtpItem.getApp()); 96 streamInfo.setApp(sendRtpItem.getApp());
90 streamInfo.setStream(sendRtpItem.getStreamId()); 97 streamInfo.setStream(sendRtpItem.getStreamId());
91 } 98 }
92 redisCatchStorage.updateSendRTPSever(sendRtpItem); 99 redisCatchStorage.updateSendRTPSever(sendRtpItem);
93 - logger.info(platformGbId);  
94 - logger.info(channelId);  
95 Map<String, Object> param = new HashMap<>(); 100 Map<String, Object> param = new HashMap<>();
96 param.put("vhost","__defaultVhost__"); 101 param.put("vhost","__defaultVhost__");
97 param.put("app",streamInfo.getApp()); 102 param.put("app",streamInfo.getApp());
@@ -100,42 +105,23 @@ public class AckRequestProcessor extends SIPRequestProcessorParent implements In @@ -100,42 +105,23 @@ public class AckRequestProcessor extends SIPRequestProcessorParent implements In
100 param.put("dst_url",sendRtpItem.getIp()); 105 param.put("dst_url",sendRtpItem.getIp());
101 param.put("dst_port", sendRtpItem.getPort()); 106 param.put("dst_port", sendRtpItem.getPort());
102 param.put("is_udp", is_Udp); 107 param.put("is_udp", is_Udp);
103 - // 设备推流查询,成功后才能转推  
104 MediaServerItem mediaInfo = mediaServerService.getOne(sendRtpItem.getMediaServerId()); 108 MediaServerItem mediaInfo = mediaServerService.getOne(sendRtpItem.getMediaServerId());
105 - zlmrtpServerFactory.startSendRtpStream(mediaInfo, param);  
106 -// if (zlmrtpServerFactory.isStreamReady(mediaInfo, streamInfo.getApp(), streamInfo.getStreamId())) {  
107 -// logger.info("已获取设备推流[{}/{}],开始向上级推流[{}:{}]",  
108 -// streamInfo.getApp() ,streamInfo.getStreamId(), sendRtpItem.getIp(), sendRtpItem.getPort());  
109 -// zlmrtpServerFactory.startSendRtpStream(mediaInfo, param);  
110 -// } else {  
111 -// // 对hook进行订阅  
112 -// logger.info("等待设备推流[{}/{}].......",  
113 -// streamInfo.getApp(), streamInfo.getStreamId());  
114 -// Timer timer = new Timer();  
115 -// timer.schedule(new TimerTask() {  
116 -// @Override  
117 -// public void run() {  
118 -// logger.info("设备推流[{}/{}]超时,终止向上级推流",  
119 -// finalStreamInfo.getApp() , finalStreamInfo.getStreamId());  
120 -//  
121 -// }  
122 -// }, 30*1000L);  
123 -// // 添加订阅  
124 -// JSONObject subscribeKey = new JSONObject();  
125 -// subscribeKey.put("app", "rtp");  
126 -// subscribeKey.put("stream", streamInfo.getStreamId());  
127 -// subscribeKey.put("mediaServerId", streamInfo.getMediaServerId());  
128 -// subscribe.addSubscribe(ZLMHttpHookSubscribe.HookType.on_publish, subscribeKey,  
129 -// (MediaServerItem mediaServerItemInUse, JSONObject json) -> {  
130 -// logger.info("已获取设备推流[{}/{}],开始向上级推流[{}:{}]",  
131 -// finalStreamInfo.getApp(), finalStreamInfo.getStreamId(), sendRtpItem.getIp(), sendRtpItem.getPort());  
132 -// timer.cancel();  
133 -// zlmrtpServerFactory.startSendRtpStream(mediaInfo, param);  
134 -// subscribe.removeSubscribe(ZLMHttpHookSubscribe.HookType.on_stream_changed, subscribeKey);  
135 -// });  
136 -// }  
137 -  
138 - 109 + JSONObject jsonObject = zlmrtpServerFactory.startSendRtpStream(mediaInfo, param);
  110 + if (jsonObject.getInteger("code") != 0) {
  111 + logger.info("监听流以等待流上线{}/{}", streamInfo.getApp(), streamInfo.getStream());
  112 + // 监听流上线
  113 + // 添加订阅
  114 + JSONObject subscribeKey = new JSONObject();
  115 + subscribeKey.put("app", "rtp");
  116 + subscribeKey.put("stream", streamInfo.getStream());
  117 + subscribeKey.put("regist", true);
  118 + subscribeKey.put("schema", "rtmp");
  119 + subscribeKey.put("mediaServerId", sendRtpItem.getMediaServerId());
  120 + subscribe.addSubscribe(ZLMHttpHookSubscribe.HookType.on_stream_changed, subscribeKey,
  121 + (MediaServerItem mediaServerItemInUse, JSONObject json)->{
  122 + zlmrtpServerFactory.startSendRtpStream(mediaInfo, param);
  123 + });
  124 + }
139 } 125 }
140 } 126 }
141 } 127 }
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/ByeRequestProcessor.java
@@ -4,6 +4,8 @@ import com.genersoft.iot.vmp.common.StreamInfo; @@ -4,6 +4,8 @@ import com.genersoft.iot.vmp.common.StreamInfo;
4 import com.genersoft.iot.vmp.gb28181.bean.Device; 4 import com.genersoft.iot.vmp.gb28181.bean.Device;
5 import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform; 5 import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform;
6 import com.genersoft.iot.vmp.gb28181.bean.SendRtpItem; 6 import com.genersoft.iot.vmp.gb28181.bean.SendRtpItem;
  7 +import com.genersoft.iot.vmp.gb28181.bean.SsrcTransaction;
  8 +import com.genersoft.iot.vmp.gb28181.session.VideoStreamSessionManager;
7 import com.genersoft.iot.vmp.gb28181.transmit.SIPProcessorObserver; 9 import com.genersoft.iot.vmp.gb28181.transmit.SIPProcessorObserver;
8 import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommander; 10 import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommander;
9 import com.genersoft.iot.vmp.gb28181.transmit.event.request.ISIPRequestProcessor; 11 import com.genersoft.iot.vmp.gb28181.transmit.event.request.ISIPRequestProcessor;
@@ -13,6 +15,8 @@ import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; @@ -13,6 +15,8 @@ import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
13 import com.genersoft.iot.vmp.service.IMediaServerService; 15 import com.genersoft.iot.vmp.service.IMediaServerService;
14 import com.genersoft.iot.vmp.storager.IRedisCatchStorage; 16 import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
15 import com.genersoft.iot.vmp.storager.IVideoManagerStorager; 17 import com.genersoft.iot.vmp.storager.IVideoManagerStorager;
  18 +import com.genersoft.iot.vmp.utils.SerializeUtils;
  19 +import gov.nist.javax.sip.stack.SIPDialog;
16 import org.slf4j.Logger; 20 import org.slf4j.Logger;
17 import org.slf4j.LoggerFactory; 21 import org.slf4j.LoggerFactory;
18 import org.springframework.beans.factory.InitializingBean; 22 import org.springframework.beans.factory.InitializingBean;
@@ -21,6 +25,7 @@ import org.springframework.stereotype.Component; @@ -21,6 +25,7 @@ import org.springframework.stereotype.Component;
21 25
22 import javax.sip.*; 26 import javax.sip.*;
23 import javax.sip.address.SipURI; 27 import javax.sip.address.SipURI;
  28 +import javax.sip.header.CallIdHeader;
24 import javax.sip.header.FromHeader; 29 import javax.sip.header.FromHeader;
25 import javax.sip.header.HeaderAddress; 30 import javax.sip.header.HeaderAddress;
26 import javax.sip.header.ToHeader; 31 import javax.sip.header.ToHeader;
@@ -56,6 +61,9 @@ public class ByeRequestProcessor extends SIPRequestProcessorParent implements In @@ -56,6 +61,9 @@ public class ByeRequestProcessor extends SIPRequestProcessorParent implements In
56 @Autowired 61 @Autowired
57 private SIPProcessorObserver sipProcessorObserver; 62 private SIPProcessorObserver sipProcessorObserver;
58 63
  64 + @Autowired
  65 + private VideoStreamSessionManager streamSession;
  66 +
59 @Override 67 @Override
60 public void afterPropertiesSet() throws Exception { 68 public void afterPropertiesSet() throws Exception {
61 // 添加消息处理的订阅 69 // 添加消息处理的订阅
@@ -71,11 +79,12 @@ public class ByeRequestProcessor extends SIPRequestProcessorParent implements In @@ -71,11 +79,12 @@ public class ByeRequestProcessor extends SIPRequestProcessorParent implements In
71 try { 79 try {
72 responseAck(evt, Response.OK); 80 responseAck(evt, Response.OK);
73 Dialog dialog = evt.getDialog(); 81 Dialog dialog = evt.getDialog();
  82 + CallIdHeader callIdHeader = (CallIdHeader)evt.getRequest().getHeader(CallIdHeader.NAME);
74 if (dialog == null) return; 83 if (dialog == null) return;
75 if (dialog.getState().equals(DialogState.TERMINATED)) { 84 if (dialog.getState().equals(DialogState.TERMINATED)) {
76 String platformGbId = ((SipURI) ((HeaderAddress) evt.getRequest().getHeader(FromHeader.NAME)).getAddress().getURI()).getUser(); 85 String platformGbId = ((SipURI) ((HeaderAddress) evt.getRequest().getHeader(FromHeader.NAME)).getAddress().getURI()).getUser();
77 String channelId = ((SipURI) ((HeaderAddress) evt.getRequest().getHeader(ToHeader.NAME)).getAddress().getURI()).getUser(); 86 String channelId = ((SipURI) ((HeaderAddress) evt.getRequest().getHeader(ToHeader.NAME)).getAddress().getURI()).getUser();
78 - SendRtpItem sendRtpItem = redisCatchStorage.querySendRTPServer(platformGbId, channelId); 87 + SendRtpItem sendRtpItem = redisCatchStorage.querySendRTPServer(platformGbId, channelId, null, callIdHeader.getCallId());
79 logger.info("收到bye, [{}/{}]", platformGbId, channelId); 88 logger.info("收到bye, [{}/{}]", platformGbId, channelId);
80 if (sendRtpItem != null){ 89 if (sendRtpItem != null){
81 String streamId = sendRtpItem.getStreamId(); 90 String streamId = sendRtpItem.getStreamId();
@@ -87,35 +96,44 @@ public class ByeRequestProcessor extends SIPRequestProcessorParent implements In @@ -87,35 +96,44 @@ public class ByeRequestProcessor extends SIPRequestProcessorParent implements In
87 logger.info("停止向上级推流:" + streamId); 96 logger.info("停止向上级推流:" + streamId);
88 MediaServerItem mediaInfo = mediaServerService.getOne(sendRtpItem.getMediaServerId()); 97 MediaServerItem mediaInfo = mediaServerService.getOne(sendRtpItem.getMediaServerId());
89 zlmrtpServerFactory.stopSendRtpStream(mediaInfo, param); 98 zlmrtpServerFactory.stopSendRtpStream(mediaInfo, param);
90 - redisCatchStorage.deleteSendRTPServer(platformGbId, channelId); 99 + redisCatchStorage.deleteSendRTPServer(platformGbId, channelId, callIdHeader.getCallId(), null);
91 int totalReaderCount = zlmrtpServerFactory.totalReaderCount(mediaInfo, sendRtpItem.getApp(), streamId); 100 int totalReaderCount = zlmrtpServerFactory.totalReaderCount(mediaInfo, sendRtpItem.getApp(), streamId);
92 - if (totalReaderCount == 0) { 101 + if (totalReaderCount <= 0) {
93 logger.info(streamId + "无其它观看者,通知设备停止推流"); 102 logger.info(streamId + "无其它观看者,通知设备停止推流");
94 cmder.streamByeCmd(sendRtpItem.getDeviceId(), channelId, streamId); 103 cmder.streamByeCmd(sendRtpItem.getDeviceId(), channelId, streamId);
95 - }else if (totalReaderCount == -1){  
96 - logger.warn(streamId + " 查找其它观看者失败");  
97 } 104 }
98 } 105 }
99 // 可能是设备主动停止 106 // 可能是设备主动停止
100 Device device = storager.queryVideoDeviceByChannelId(platformGbId); 107 Device device = storager.queryVideoDeviceByChannelId(platformGbId);
101 if (device != null) { 108 if (device != null) {
  109 + storager.stopPlay(device.getDeviceId(), channelId);
102 StreamInfo streamInfo = redisCatchStorage.queryPlayByDevice(device.getDeviceId(), channelId); 110 StreamInfo streamInfo = redisCatchStorage.queryPlayByDevice(device.getDeviceId(), channelId);
103 - if (sendRtpItem != null) {  
104 - if (sendRtpItem.isPlay()) {  
105 - if (streamInfo != null) {  
106 - redisCatchStorage.stopPlay(streamInfo);  
107 - }  
108 - }else {  
109 - if (streamInfo != null) {  
110 - redisCatchStorage.stopPlayback(streamInfo); 111 + if (streamInfo != null) {
  112 + redisCatchStorage.stopPlay(streamInfo);
  113 + mediaServerService.closeRTPServer(device.getDeviceId(), channelId, streamInfo.getStream());
  114 + }
  115 + SsrcTransaction ssrcTransactionForPlay = streamSession.getSsrcTransaction(device.getDeviceId(), channelId, "play", null);
  116 + if (ssrcTransactionForPlay != null){
  117 + SIPDialog dialogForPlay = (SIPDialog) SerializeUtils.deSerialize(ssrcTransactionForPlay.getDialog());
  118 + if (dialogForPlay.getCallId().equals(callIdHeader.getCallId())){
  119 + // 释放ssrc
  120 + MediaServerItem mediaServerItem = mediaServerService.getOne(ssrcTransactionForPlay.getMediaServerId());
  121 + if (mediaServerItem != null) {
  122 + mediaServerService.releaseSsrc(mediaServerItem.getId(), ssrcTransactionForPlay.getSsrc());
111 } 123 }
  124 + streamSession.remove(device.getDeviceId(), channelId, ssrcTransactionForPlay.getStream());
112 } 125 }
113 -  
114 - storager.stopPlay(device.getDeviceId(), channelId);  
115 - mediaServerService.closeRTPServer(device.getDeviceId(), channelId, streamInfo.getStream()); 126 + }
  127 + SsrcTransaction ssrcTransactionForPlayBack = streamSession.getSsrcTransaction(device.getDeviceId(), channelId, callIdHeader.getCallId(), null);
  128 + if (ssrcTransactionForPlayBack != null) {
  129 + // 释放ssrc
  130 + MediaServerItem mediaServerItem = mediaServerService.getOne(ssrcTransactionForPlayBack.getMediaServerId());
  131 + if (mediaServerItem != null) {
  132 + mediaServerService.releaseSsrc(mediaServerItem.getId(), ssrcTransactionForPlayBack.getSsrc());
  133 + }
  134 + streamSession.remove(device.getDeviceId(), channelId, ssrcTransactionForPlayBack.getStream());
116 } 135 }
117 } 136 }
118 -  
119 } 137 }
120 } catch (SipException e) { 138 } catch (SipException e) {
121 e.printStackTrace(); 139 e.printStackTrace();
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/InviteRequestProcessor.java
@@ -3,6 +3,7 @@ package com.genersoft.iot.vmp.gb28181.transmit.event.request.impl; @@ -3,6 +3,7 @@ package com.genersoft.iot.vmp.gb28181.transmit.event.request.impl;
3 import com.alibaba.fastjson.JSON; 3 import com.alibaba.fastjson.JSON;
4 import com.alibaba.fastjson.JSONObject; 4 import com.alibaba.fastjson.JSONObject;
5 import com.genersoft.iot.vmp.common.StreamInfo; 5 import com.genersoft.iot.vmp.common.StreamInfo;
  6 +import com.genersoft.iot.vmp.conf.DynamicTask;
6 import com.genersoft.iot.vmp.gb28181.bean.*; 7 import com.genersoft.iot.vmp.gb28181.bean.*;
7 import com.genersoft.iot.vmp.gb28181.event.SipSubscribe; 8 import com.genersoft.iot.vmp.gb28181.event.SipSubscribe;
8 import com.genersoft.iot.vmp.gb28181.transmit.SIPProcessorObserver; 9 import com.genersoft.iot.vmp.gb28181.transmit.SIPProcessorObserver;
@@ -21,6 +22,7 @@ import com.genersoft.iot.vmp.service.IPlayService; @@ -21,6 +22,7 @@ import com.genersoft.iot.vmp.service.IPlayService;
21 import com.genersoft.iot.vmp.service.bean.SSRCInfo; 22 import com.genersoft.iot.vmp.service.bean.SSRCInfo;
22 import com.genersoft.iot.vmp.storager.IRedisCatchStorage; 23 import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
23 import com.genersoft.iot.vmp.storager.IVideoManagerStorager; 24 import com.genersoft.iot.vmp.storager.IVideoManagerStorager;
  25 +import com.genersoft.iot.vmp.utils.SerializeUtils;
24 import com.genersoft.iot.vmp.vmanager.gb28181.play.bean.PlayResult; 26 import com.genersoft.iot.vmp.vmanager.gb28181.play.bean.PlayResult;
25 import gov.nist.javax.sdp.TimeDescriptionImpl; 27 import gov.nist.javax.sdp.TimeDescriptionImpl;
26 import gov.nist.javax.sdp.fields.TimeField; 28 import gov.nist.javax.sdp.fields.TimeField;
@@ -69,6 +71,9 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements @@ -69,6 +71,9 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements
69 private IRedisCatchStorage redisCatchStorage; 71 private IRedisCatchStorage redisCatchStorage;
70 72
71 @Autowired 73 @Autowired
  74 + private DynamicTask dynamicTask;
  75 +
  76 + @Autowired
72 private SIPCommander cmder; 77 private SIPCommander cmder;
73 78
74 @Autowired 79 @Autowired
@@ -257,11 +262,13 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements @@ -257,11 +262,13 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements
257 } 262 }
258 sendRtpItem.setCallId(callIdHeader.getCallId()); 263 sendRtpItem.setCallId(callIdHeader.getCallId());
259 sendRtpItem.setPlay("Play".equals(sessionName)); 264 sendRtpItem.setPlay("Play".equals(sessionName));
  265 + byte[] dialogByteArray = SerializeUtils.serialize(evt.getDialog());
  266 + sendRtpItem.setDialog(dialogByteArray);
  267 + byte[] transactionByteArray = SerializeUtils.serialize(evt.getServerTransaction());
  268 + sendRtpItem.setTransaction(transactionByteArray);
260 // 写入redis, 超时时回复 269 // 写入redis, 超时时回复
261 redisCatchStorage.updateSendRTPSever(sendRtpItem); 270 redisCatchStorage.updateSendRTPSever(sendRtpItem);
262 271
263 - Device finalDevice = device;  
264 - MediaServerItem finalMediaServerItem = mediaServerItem;  
265 Long finalStartTime = startTime; 272 Long finalStartTime = startTime;
266 Long finalStopTime = stopTime; 273 Long finalStopTime = stopTime;
267 ZLMHttpHookSubscribe.Event hookEvent = (mediaServerItemInUSe, responseJSON)->{ 274 ZLMHttpHookSubscribe.Event hookEvent = (mediaServerItemInUSe, responseJSON)->{
@@ -289,7 +296,15 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements @@ -289,7 +296,15 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements
289 content.append("f=\r\n"); 296 content.append("f=\r\n");
290 297
291 try { 298 try {
  299 + // 超时未收到Ack应该回复bye,当前等待时间为10秒
  300 + dynamicTask.startDelay(callIdHeader.getCallId(), ()->{
  301 + logger.info("Ack 等待超时");
  302 + mediaServerService.releaseSsrc(mediaServerItemInUSe.getId(), ssrc);
  303 + // 回复bye
  304 + cmderFroPlatform.streamByeCmd(platform, callIdHeader.getCallId());
  305 + }, 60);
292 responseSdpAck(evt, content.toString(), platform); 306 responseSdpAck(evt, content.toString(), platform);
  307 +
293 } catch (SipException e) { 308 } catch (SipException e) {
294 e.printStackTrace(); 309 e.printStackTrace();
295 } catch (InvalidArgumentException e) { 310 } catch (InvalidArgumentException e) {
@@ -320,6 +335,7 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements @@ -320,6 +335,7 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements
320 if (result.getEvent() != null) { 335 if (result.getEvent() != null) {
321 errorEvent.response(result.getEvent()); 336 errorEvent.response(result.getEvent());
322 } 337 }
  338 + redisCatchStorage.deleteSendRTPServer(platform.getServerGBId(), channelId, callIdHeader.getCallId(), null);
323 try { 339 try {
324 responseAck(evt, Response.REQUEST_TIMEOUT); 340 responseAck(evt, Response.REQUEST_TIMEOUT);
325 } catch (SipException e) { 341 } catch (SipException e) {
@@ -343,7 +359,9 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements @@ -343,7 +359,9 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements
343 sendRtpItem.setStreamId(String.format("%s_%s", device.getDeviceId(), channelId)); 359 sendRtpItem.setStreamId(String.format("%s_%s", device.getDeviceId(), channelId));
344 } 360 }
345 sendRtpItem.setPlay(false); 361 sendRtpItem.setPlay(false);
346 - playService.play(mediaServerItem,device.getDeviceId(), channelId, hookEvent,errorEvent); 362 + playService.play(mediaServerItem,device.getDeviceId(), channelId, hookEvent, errorEvent, ()->{
  363 + redisCatchStorage.deleteSendRTPServer(platform.getServerGBId(), channelId, callIdHeader.getCallId(), null);
  364 + });
347 }else { 365 }else {
348 sendRtpItem.setStreamId(streamInfo.getStream()); 366 sendRtpItem.setStreamId(streamInfo.getStream());
349 hookEvent.response(mediaServerItem, null); 367 hookEvent.response(mediaServerItem, null);
@@ -365,6 +383,11 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements @@ -365,6 +383,11 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements
365 383
366 // 写入redis, 超时时回复 384 // 写入redis, 超时时回复
367 sendRtpItem.setStatus(1); 385 sendRtpItem.setStatus(1);
  386 + sendRtpItem.setCallId(callIdHeader.getCallId());
  387 + byte[] dialogByteArray = SerializeUtils.serialize(evt.getDialog());
  388 + sendRtpItem.setDialog(dialogByteArray);
  389 + byte[] transactionByteArray = SerializeUtils.serialize(evt.getServerTransaction());
  390 + sendRtpItem.setTransaction(transactionByteArray);
368 redisCatchStorage.updateSendRTPSever(sendRtpItem); 391 redisCatchStorage.updateSendRTPSever(sendRtpItem);
369 StringBuffer content = new StringBuffer(200); 392 StringBuffer content = new StringBuffer(200);
370 content.append("v=0\r\n"); 393 content.append("v=0\r\n");
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/RegisterRequestProcessor.java
@@ -158,6 +158,10 @@ public class RegisterRequestProcessor extends SIPRequestProcessorParent implemen @@ -158,6 +158,10 @@ public class RegisterRequestProcessor extends SIPRequestProcessorParent implemen
158 device.setCharset("gb2312"); 158 device.setCharset("gb2312");
159 device.setDeviceId(deviceId); 159 device.setDeviceId(deviceId);
160 device.setFirsRegister(true); 160 device.setFirsRegister(true);
  161 + }else {
  162 + if (device.getOnline() == 0) {
  163 + device.setFirsRegister(true);
  164 + }
161 } 165 }
162 device.setIp(received); 166 device.setIp(received);
163 device.setPort(rPort); 167 device.setPort(rPort);
@@ -187,7 +191,6 @@ public class RegisterRequestProcessor extends SIPRequestProcessorParent implemen @@ -187,7 +191,6 @@ public class RegisterRequestProcessor extends SIPRequestProcessorParent implemen
187 if (serverTransaction.getDialog() != null) serverTransaction.getDialog().delete(); 191 if (serverTransaction.getDialog() != null) serverTransaction.getDialog().delete();
188 // 注册成功 192 // 注册成功
189 // 保存到redis 193 // 保存到redis
190 - // 下发catelog查询目录  
191 if (registerFlag == 1 ) { 194 if (registerFlag == 1 ) {
192 logger.info("[{}] 注册成功! deviceId:" + device.getDeviceId(), requestAddress); 195 logger.info("[{}] 注册成功! deviceId:" + device.getDeviceId(), requestAddress);
193 publisher.onlineEventPublish(device, VideoManagerConstants.EVENT_ONLINE_REGISTER); 196 publisher.onlineEventPublish(device, VideoManagerConstants.EVENT_ONLINE_REGISTER);
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/SubscribeRequestProcessor.java
@@ -27,9 +27,7 @@ import javax.sip.InvalidArgumentException; @@ -27,9 +27,7 @@ import javax.sip.InvalidArgumentException;
27 import javax.sip.RequestEvent; 27 import javax.sip.RequestEvent;
28 import javax.sip.ServerTransaction; 28 import javax.sip.ServerTransaction;
29 import javax.sip.SipException; 29 import javax.sip.SipException;
30 -import javax.sip.header.CallIdHeader;  
31 import javax.sip.header.ExpiresHeader; 30 import javax.sip.header.ExpiresHeader;
32 -import javax.sip.header.Header;  
33 import javax.sip.header.ToHeader; 31 import javax.sip.header.ToHeader;
34 import javax.sip.message.Request; 32 import javax.sip.message.Request;
35 import javax.sip.message.Response; 33 import javax.sip.message.Response;
@@ -139,19 +137,17 @@ public class SubscribeRequestProcessor extends SIPRequestProcessorParent impleme @@ -139,19 +137,17 @@ public class SubscribeRequestProcessor extends SIPRequestProcessorParent impleme
139 137
140 if (subscribeInfo.getExpires() > 0) { 138 if (subscribeInfo.getExpires() > 0) {
141 if (redisCatchStorage.getSubscribe(key) != null) { 139 if (redisCatchStorage.getSubscribe(key) != null) {
142 - dynamicTask.stopCron(key); 140 + dynamicTask.stop(key);
143 } 141 }
144 String interval = XmlUtil.getText(rootElement, "Interval"); // GPS上报时间间隔 142 String interval = XmlUtil.getText(rootElement, "Interval"); // GPS上报时间间隔
145 dynamicTask.startCron(key, new GPSSubscribeTask(redisCatchStorage, sipCommanderForPlatform, storager, platformId, sn, key), Integer.parseInt(interval)); 143 dynamicTask.startCron(key, new GPSSubscribeTask(redisCatchStorage, sipCommanderForPlatform, storager, platformId, sn, key), Integer.parseInt(interval));
146 144
147 redisCatchStorage.updateSubscribe(key, subscribeInfo); 145 redisCatchStorage.updateSubscribe(key, subscribeInfo);
148 }else if (subscribeInfo.getExpires() == 0) { 146 }else if (subscribeInfo.getExpires() == 0) {
149 - dynamicTask.stopCron(key); 147 + dynamicTask.stop(key);
150 redisCatchStorage.delSubscribe(key); 148 redisCatchStorage.delSubscribe(key);
151 } 149 }
152 150
153 -  
154 -  
155 try { 151 try {
156 ParentPlatform parentPlatform = storager.queryParentPlatByServerGBId(platformId); 152 ParentPlatform parentPlatform = storager.queryParentPlatByServerGBId(platformId);
157 Response response = responseXmlAck(evt, resultXml.toString(), parentPlatform); 153 Response response = responseXmlAck(evt, resultXml.toString(), parentPlatform);
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/response/impl/RegisterResponseProcessor.java
@@ -85,19 +85,18 @@ public class RegisterResponseProcessor extends SIPResponseProcessorAbstract { @@ -85,19 +85,18 @@ public class RegisterResponseProcessor extends SIPResponseProcessorAbstract {
85 redisCatchStorage.delPlatformRegisterInfo(callId); 85 redisCatchStorage.delPlatformRegisterInfo(callId);
86 parentPlatform.setStatus("注册".equals(action)); 86 parentPlatform.setStatus("注册".equals(action));
87 // 取回Expires设置,避免注销过程中被置为0 87 // 取回Expires设置,避免注销过程中被置为0
88 - ParentPlatform parentPlatformTmp = storager.queryParentPlatByServerGBId(platformGBId);  
89 - String expires = parentPlatformTmp.getExpires();  
90 - parentPlatform.setExpires(expires);  
91 - parentPlatform.setId(parentPlatformTmp.getId()); 88 + if (!parentPlatformCatch.getParentPlatform().getExpires().equals("0")) {
  89 + ParentPlatform parentPlatformTmp = storager.queryParentPlatByServerGBId(platformGBId);
  90 + String expires = parentPlatformTmp.getExpires();
  91 + parentPlatform.setExpires(expires);
  92 + parentPlatform.setId(parentPlatformTmp.getId());
  93 + redisCatchStorage.updatePlatformRegister(parentPlatform);
  94 + redisCatchStorage.updatePlatformKeepalive(parentPlatform);
  95 + parentPlatformCatch.setParentPlatform(parentPlatform);
  96 + redisCatchStorage.updatePlatformCatchInfo(parentPlatformCatch);
  97 + }
92 storager.updateParentPlatformStatus(platformGBId, "注册".equals(action)); 98 storager.updateParentPlatformStatus(platformGBId, "注册".equals(action));
93 99
94 - redisCatchStorage.updatePlatformRegister(parentPlatform);  
95 -  
96 - redisCatchStorage.updatePlatformKeepalive(parentPlatform);  
97 -  
98 - parentPlatformCatch.setParentPlatform(parentPlatform);  
99 -  
100 - redisCatchStorage.updatePlatformCatchInfo(parentPlatformCatch);  
101 } 100 }
102 } 101 }
103 102
src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java
@@ -504,7 +504,7 @@ public class ZLMHttpHookListener { @@ -504,7 +504,7 @@ public class ZLMHttpHookListener {
504 } 504 }
505 String mediaServerId = json.getString("mediaServerId"); 505 String mediaServerId = json.getString("mediaServerId");
506 MediaServerItem mediaInfo = mediaServerService.getOne(mediaServerId); 506 MediaServerItem mediaInfo = mediaServerService.getOne(mediaServerId);
507 - if (userSetup.isAutoApplyPlay() && mediaInfo != null) { 507 + if (userSetup.isAutoApplyPlay() && mediaInfo != null && mediaInfo.isRtpEnable()) {
508 String app = json.getString("app"); 508 String app = json.getString("app");
509 String streamId = json.getString("stream"); 509 String streamId = json.getString("stream");
510 if ("rtp".equals(app)) { 510 if ("rtp".equals(app)) {
@@ -514,28 +514,16 @@ public class ZLMHttpHookListener { @@ -514,28 +514,16 @@ public class ZLMHttpHookListener {
514 String channelId = s[1]; 514 String channelId = s[1];
515 Device device = redisCatchStorage.getDevice(deviceId); 515 Device device = redisCatchStorage.getDevice(deviceId);
516 if (device != null) { 516 if (device != null) {
517 - UUID uuid = UUID.randomUUID();  
518 - SSRCInfo ssrcInfo;  
519 - String streamId2 = null;  
520 - if (mediaInfo.isRtpEnable()) {  
521 - streamId2 = String.format("%s_%s", device.getDeviceId(), channelId);  
522 - }  
523 - ssrcInfo = mediaServerService.openRTPServer(mediaInfo, streamId2);  
524 - cmder.playStreamCmd(mediaInfo, ssrcInfo, device, channelId, (MediaServerItem mediaServerItemInuse, JSONObject response) -> {  
525 - logger.info("收到订阅消息: " + response.toJSONString());  
526 - playService.onPublishHandlerForPlay(mediaServerItemInuse, response, deviceId, channelId, uuid.toString());  
527 - }, null); 517 + playService.play(mediaInfo,deviceId, channelId, null, null, null);
528 } 518 }
529 -  
530 } 519 }
531 } 520 }
532 -  
533 } 521 }
534 522
535 JSONObject ret = new JSONObject(); 523 JSONObject ret = new JSONObject();
536 ret.put("code", 0); 524 ret.put("code", 0);
537 ret.put("msg", "success"); 525 ret.put("msg", "success");
538 - return new ResponseEntity<String>(ret.toString(),HttpStatus.OK); 526 + return new ResponseEntity<>(ret.toString(),HttpStatus.OK);
539 } 527 }
540 528
541 /** 529 /**
src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRTPServerFactory.java
@@ -205,7 +205,7 @@ public class ZLMRTPServerFactory { @@ -205,7 +205,7 @@ public class ZLMRTPServerFactory {
205 /** 205 /**
206 * 调用zlm RESTful API —— startSendRtp 206 * 调用zlm RESTful API —— startSendRtp
207 */ 207 */
208 - public Boolean startSendRtpStream(MediaServerItem mediaServerItem, Map<String, Object>param) { 208 + public JSONObject startSendRtpStream(MediaServerItem mediaServerItem, Map<String, Object>param) {
209 Boolean result = false; 209 Boolean result = false;
210 JSONObject jsonObject = zlmresTfulUtils.startSendRtp(mediaServerItem, param); 210 JSONObject jsonObject = zlmresTfulUtils.startSendRtp(mediaServerItem, param);
211 if (jsonObject == null) { 211 if (jsonObject == null) {
@@ -216,7 +216,7 @@ public class ZLMRTPServerFactory { @@ -216,7 +216,7 @@ public class ZLMRTPServerFactory {
216 } else { 216 } else {
217 logger.error("RTP推流失败: " + jsonObject.getString("msg")); 217 logger.error("RTP推流失败: " + jsonObject.getString("msg"));
218 } 218 }
219 - return result; 219 + return jsonObject;
220 } 220 }
221 221
222 /** 222 /**
src/main/java/com/genersoft/iot/vmp/media/zlm/event/ZLMStatusEventListener.java
1 package com.genersoft.iot.vmp.media.zlm.event; 1 package com.genersoft.iot.vmp.media.zlm.event;
2 2
3 import com.genersoft.iot.vmp.service.IMediaServerService; 3 import com.genersoft.iot.vmp.service.IMediaServerService;
  4 +import com.genersoft.iot.vmp.service.IPlayService;
4 import com.genersoft.iot.vmp.service.IStreamProxyService; 5 import com.genersoft.iot.vmp.service.IStreamProxyService;
5 import com.genersoft.iot.vmp.service.IStreamPushService; 6 import com.genersoft.iot.vmp.service.IStreamPushService;
6 import org.slf4j.Logger; 7 import org.slf4j.Logger;
@@ -34,6 +35,9 @@ public class ZLMStatusEventListener { @@ -34,6 +35,9 @@ public class ZLMStatusEventListener {
34 @Autowired 35 @Autowired
35 private IMediaServerService mediaServerService; 36 private IMediaServerService mediaServerService;
36 37
  38 + @Autowired
  39 + private IPlayService playService;
  40 +
37 private SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); 41 private SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
38 42
39 @Async 43 @Async
@@ -55,6 +59,6 @@ public class ZLMStatusEventListener { @@ -55,6 +59,6 @@ public class ZLMStatusEventListener {
55 mediaServerService.zlmServerOffline(event.getMediaServerId()); 59 mediaServerService.zlmServerOffline(event.getMediaServerId());
56 streamProxyService.zlmServerOffline(event.getMediaServerId()); 60 streamProxyService.zlmServerOffline(event.getMediaServerId());
57 streamPushService.zlmServerOffline(event.getMediaServerId()); 61 streamPushService.zlmServerOffline(event.getMediaServerId());
58 - // TODO 处理对国标的影响 62 + playService.zlmServerOffline(event.getMediaServerId());
59 } 63 }
60 } 64 }
src/main/java/com/genersoft/iot/vmp/service/IMediaServerService.java
@@ -58,7 +58,7 @@ public interface IMediaServerService { @@ -58,7 +58,7 @@ public interface IMediaServerService {
58 58
59 void removeCount(String mediaServerId); 59 void removeCount(String mediaServerId);
60 60
61 - void releaseSsrc(MediaServerItem mediaServerItem, String ssrc); 61 + void releaseSsrc(String mediaServerItemId, String ssrc);
62 62
63 void clearMediaServerForOnline(); 63 void clearMediaServerForOnline();
64 64
src/main/java/com/genersoft/iot/vmp/service/IPlayService.java
@@ -17,11 +17,13 @@ public interface IPlayService { @@ -17,11 +17,13 @@ public interface IPlayService {
17 17
18 void onPublishHandlerForPlay(MediaServerItem mediaServerItem, JSONObject resonse, String deviceId, String channelId, String uuid); 18 void onPublishHandlerForPlay(MediaServerItem mediaServerItem, JSONObject resonse, String deviceId, String channelId, String uuid);
19 19
20 - PlayResult play(MediaServerItem mediaServerItem, String deviceId, String channelId, ZLMHttpHookSubscribe.Event event, SipSubscribe.Event errorEvent); 20 + PlayResult play(MediaServerItem mediaServerItem, String deviceId, String channelId, ZLMHttpHookSubscribe.Event event, SipSubscribe.Event errorEvent, Runnable timeoutCallback);
21 21
22 MediaServerItem getNewMediaServerItem(Device device); 22 MediaServerItem getNewMediaServerItem(Device device);
23 23
24 void onPublishHandlerForDownload(MediaServerItem mediaServerItem, JSONObject response, String deviceId, String channelId, String toString); 24 void onPublishHandlerForDownload(MediaServerItem mediaServerItem, JSONObject response, String deviceId, String channelId, String toString);
25 25
26 DeferredResult<ResponseEntity<String>> playBack(String deviceId, String channelId, String startTime, String endTime, PlayBackCallback errorCallBack); 26 DeferredResult<ResponseEntity<String>> playBack(String deviceId, String channelId, String startTime, String endTime, PlayBackCallback errorCallBack);
  27 +
  28 + void zlmServerOffline(String mediaServerId);
27 } 29 }
src/main/java/com/genersoft/iot/vmp/service/impl/DeviceServiceImpl.java
@@ -52,11 +52,9 @@ public class DeviceServiceImpl implements IDeviceService { @@ -52,11 +52,9 @@ public class DeviceServiceImpl implements IDeviceService {
52 return false; 52 return false;
53 } 53 }
54 logger.info("移除目录订阅: {}", device.getDeviceId()); 54 logger.info("移除目录订阅: {}", device.getDeviceId());
55 - dynamicTask.stopCron(device.getDeviceId()); 55 + dynamicTask.stop(device.getDeviceId());
56 device.setSubscribeCycleForCatalog(0); 56 device.setSubscribeCycleForCatalog(0);
57 sipCommander.catalogSubscribe(device, null, null); 57 sipCommander.catalogSubscribe(device, null, null);
58 - // 清空cseq计数  
59 -  
60 return true; 58 return true;
61 } 59 }
62 } 60 }
src/main/java/com/genersoft/iot/vmp/service/impl/MediaServerServiceImpl.java
@@ -167,13 +167,14 @@ public class MediaServerServiceImpl implements IMediaServerService { @@ -167,13 +167,14 @@ public class MediaServerServiceImpl implements IMediaServerService {
167 if (mediaServerItem != null) { 167 if (mediaServerItem != null) {
168 String streamId = String.format("%s_%s", deviceId, channelId); 168 String streamId = String.format("%s_%s", deviceId, channelId);
169 zlmrtpServerFactory.closeRTPServer(mediaServerItem, streamId); 169 zlmrtpServerFactory.closeRTPServer(mediaServerItem, streamId);
170 - releaseSsrc(mediaServerItem, ssrc); 170 + releaseSsrc(mediaServerItem.getId(), ssrc);
171 } 171 }
172 streamSession.remove(deviceId, channelId, stream); 172 streamSession.remove(deviceId, channelId, stream);
173 } 173 }
174 174
175 @Override 175 @Override
176 - public void releaseSsrc(MediaServerItem mediaServerItem, String ssrc) { 176 + public void releaseSsrc(String mediaServerItemId, String ssrc) {
  177 + MediaServerItem mediaServerItem = getOne(mediaServerItemId);
177 if (mediaServerItem == null || ssrc == null) { 178 if (mediaServerItem == null || ssrc == null) {
178 return; 179 return;
179 } 180 }
src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java
@@ -5,13 +5,13 @@ import com.alibaba.fastjson.JSONArray; @@ -5,13 +5,13 @@ import com.alibaba.fastjson.JSONArray;
5 import com.alibaba.fastjson.JSONObject; 5 import com.alibaba.fastjson.JSONObject;
6 import com.genersoft.iot.vmp.common.StreamInfo; 6 import com.genersoft.iot.vmp.common.StreamInfo;
7 import com.genersoft.iot.vmp.conf.UserSetup; 7 import com.genersoft.iot.vmp.conf.UserSetup;
8 -import com.genersoft.iot.vmp.gb28181.bean.Device;  
9 -import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel; 8 +import com.genersoft.iot.vmp.gb28181.bean.*;
10 import com.genersoft.iot.vmp.gb28181.event.SipSubscribe; 9 import com.genersoft.iot.vmp.gb28181.event.SipSubscribe;
11 import com.genersoft.iot.vmp.gb28181.session.VideoStreamSessionManager; 10 import com.genersoft.iot.vmp.gb28181.session.VideoStreamSessionManager;
12 import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder; 11 import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder;
13 import com.genersoft.iot.vmp.gb28181.transmit.callback.RequestMessage; 12 import com.genersoft.iot.vmp.gb28181.transmit.callback.RequestMessage;
14 import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander; 13 import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander;
  14 +import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommanderFroPlatform;
15 import com.genersoft.iot.vmp.media.zlm.ZLMHttpHookSubscribe; 15 import com.genersoft.iot.vmp.media.zlm.ZLMHttpHookSubscribe;
16 import com.genersoft.iot.vmp.media.zlm.ZLMRESTfulUtils; 16 import com.genersoft.iot.vmp.media.zlm.ZLMRESTfulUtils;
17 import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; 17 import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
@@ -37,8 +37,7 @@ import org.springframework.util.ResourceUtils; @@ -37,8 +37,7 @@ import org.springframework.util.ResourceUtils;
37 import org.springframework.web.context.request.async.DeferredResult; 37 import org.springframework.web.context.request.async.DeferredResult;
38 38
39 import java.io.FileNotFoundException; 39 import java.io.FileNotFoundException;
40 -import java.util.Objects;  
41 -import java.util.UUID; 40 +import java.util.*;
42 41
43 @SuppressWarnings(value = {"rawtypes", "unchecked"}) 42 @SuppressWarnings(value = {"rawtypes", "unchecked"})
44 @Service 43 @Service
@@ -53,6 +52,9 @@ public class PlayServiceImpl implements IPlayService { @@ -53,6 +52,9 @@ public class PlayServiceImpl implements IPlayService {
53 private SIPCommander cmder; 52 private SIPCommander cmder;
54 53
55 @Autowired 54 @Autowired
  55 + private SIPCommanderFroPlatform sipCommanderFroPlatform;
  56 +
  57 + @Autowired
56 private IRedisCatchStorage redisCatchStorage; 58 private IRedisCatchStorage redisCatchStorage;
57 59
58 @Autowired 60 @Autowired
@@ -78,7 +80,9 @@ public class PlayServiceImpl implements IPlayService { @@ -78,7 +80,9 @@ public class PlayServiceImpl implements IPlayService {
78 80
79 81
80 @Override 82 @Override
81 - public PlayResult play(MediaServerItem mediaServerItem, String deviceId, String channelId, ZLMHttpHookSubscribe.Event hookEvent, SipSubscribe.Event errorEvent) { 83 + public PlayResult play(MediaServerItem mediaServerItem, String deviceId, String channelId,
  84 + ZLMHttpHookSubscribe.Event hookEvent, SipSubscribe.Event errorEvent,
  85 + Runnable timeoutCallback) {
82 PlayResult playResult = new PlayResult(); 86 PlayResult playResult = new PlayResult();
83 RequestMessage msg = new RequestMessage(); 87 RequestMessage msg = new RequestMessage();
84 String key = DeferredResultHolder.CALLBACK_CMD_PLAY + deviceId + channelId; 88 String key = DeferredResultHolder.CALLBACK_CMD_PLAY + deviceId + channelId;
@@ -101,29 +105,10 @@ public class PlayServiceImpl implements IPlayService { @@ -101,29 +105,10 @@ public class PlayServiceImpl implements IPlayService {
101 Device device = redisCatchStorage.getDevice(deviceId); 105 Device device = redisCatchStorage.getDevice(deviceId);
102 StreamInfo streamInfo = redisCatchStorage.queryPlayByDevice(deviceId, channelId); 106 StreamInfo streamInfo = redisCatchStorage.queryPlayByDevice(deviceId, channelId);
103 playResult.setDevice(device); 107 playResult.setDevice(device);
104 - // 超时处理  
105 - result.onTimeout(()->{  
106 - logger.warn(String.format("设备点播超时,deviceId:%s ,channelId:%s", deviceId, channelId));  
107 - WVPResult wvpResult = new WVPResult();  
108 - wvpResult.setCode(-1);  
109 - SIPDialog dialog = streamSession.getDialogByStream(deviceId, channelId, streamInfo.getStream());  
110 - if (dialog != null) {  
111 - wvpResult.setMsg("收流超时,请稍候重试");  
112 - }else {  
113 - wvpResult.setMsg("点播超时,请稍候重试");  
114 - }  
115 108
116 - msg.setData(wvpResult);  
117 - // 点播超时回复BYE  
118 - cmder.streamByeCmd(device.getDeviceId(), channelId, streamInfo.getStream());  
119 - // 释放rtpserver  
120 - mediaServerService.closeRTPServer(playResult.getDevice().getDeviceId(), channelId, streamInfo.getStream());  
121 - // 回复之前所有的点播请求  
122 - resultHolder.invokeAllResult(msg);  
123 - // TODO 释放ssrc  
124 - });  
125 result.onCompletion(()->{ 109 result.onCompletion(()->{
126 // 点播结束时调用截图接口 110 // 点播结束时调用截图接口
  111 + // TODO 应该在上流时调用更好,结束也可能是错误结束
127 try { 112 try {
128 String classPath = ResourceUtils.getURL("classpath:").getPath(); 113 String classPath = ResourceUtils.getURL("classpath:").getPath();
129 // 兼容打包为jar的class路径 114 // 兼容打包为jar的class路径
@@ -161,31 +146,60 @@ public class PlayServiceImpl implements IPlayService { @@ -161,31 +146,60 @@ public class PlayServiceImpl implements IPlayService {
161 if (mediaServerItem.isRtpEnable()) { 146 if (mediaServerItem.isRtpEnable()) {
162 streamId = String.format("%s_%s", device.getDeviceId(), channelId); 147 streamId = String.format("%s_%s", device.getDeviceId(), channelId);
163 } 148 }
164 -  
165 SSRCInfo ssrcInfo = mediaServerService.openRTPServer(mediaServerItem, streamId); 149 SSRCInfo ssrcInfo = mediaServerService.openRTPServer(mediaServerItem, streamId);
  150 + // 超时处理
  151 + Timer timer = new Timer();
  152 + timer.schedule(new TimerTask() {
  153 + @Override
  154 + public void run() {
  155 + logger.warn(String.format("设备点播超时,deviceId:%s ,channelId:%s", deviceId, channelId));
  156 + if (timeoutCallback != null) {
  157 + timeoutCallback.run();
  158 + }
  159 + WVPResult wvpResult = new WVPResult();
  160 + wvpResult.setCode(-1);
  161 + SIPDialog dialog = streamSession.getDialogByStream(deviceId, channelId, ssrcInfo.getStream());
  162 + if (dialog != null) {
  163 + wvpResult.setMsg("收流超时,请稍候重试");
  164 + // 点播超时回复BYE 同时释放ssrc以及此次点播的资源
  165 + cmder.streamByeCmd(device.getDeviceId(), channelId, ssrcInfo.getStream());
  166 + }else {
  167 + wvpResult.setMsg("点播超时,请稍候重试");
  168 + mediaServerService.releaseSsrc(mediaServerItem.getId(), ssrcInfo.getSsrc());
  169 + mediaServerService.closeRTPServer(deviceId, channelId, ssrcInfo.getStream());
  170 + streamSession.remove(deviceId, channelId, ssrcInfo.getStream());
  171 + }
  172 +
  173 + msg.setData(wvpResult);
  174 +
  175 + // 回复之前所有的点播请求
  176 + resultHolder.invokeAllResult(msg);
  177 + }
  178 + }, userSetup.getPlayTimeout());
166 // 发送点播消息 179 // 发送点播消息
167 cmder.playStreamCmd(mediaServerItem, ssrcInfo, device, channelId, (MediaServerItem mediaServerItemInUse, JSONObject response) -> { 180 cmder.playStreamCmd(mediaServerItem, ssrcInfo, device, channelId, (MediaServerItem mediaServerItemInUse, JSONObject response) -> {
168 logger.info("收到订阅消息: " + response.toJSONString()); 181 logger.info("收到订阅消息: " + response.toJSONString());
  182 + timer.cancel();
169 onPublishHandlerForPlay(mediaServerItemInUse, response, deviceId, channelId, uuid); 183 onPublishHandlerForPlay(mediaServerItemInUse, response, deviceId, channelId, uuid);
170 if (hookEvent != null) { 184 if (hookEvent != null) {
171 hookEvent.response(mediaServerItem, response); 185 hookEvent.response(mediaServerItem, response);
172 } 186 }
173 }, (event) -> { 187 }, (event) -> {
  188 + timer.cancel();
174 WVPResult wvpResult = new WVPResult(); 189 WVPResult wvpResult = new WVPResult();
175 wvpResult.setCode(-1); 190 wvpResult.setCode(-1);
176 // 点播返回sip错误 191 // 点播返回sip错误
177 mediaServerService.closeRTPServer(playResult.getDevice().getDeviceId(), channelId, ssrcInfo.getStream()); 192 mediaServerService.closeRTPServer(playResult.getDevice().getDeviceId(), channelId, ssrcInfo.getStream());
178 // 释放ssrc 193 // 释放ssrc
179 - mediaServerService.releaseSsrc(mediaServerItem, ssrcInfo.getSsrc()); 194 + mediaServerService.releaseSsrc(mediaServerItem.getId(), ssrcInfo.getSsrc());
180 streamSession.remove(deviceId, channelId, ssrcInfo.getStream()); 195 streamSession.remove(deviceId, channelId, ssrcInfo.getStream());
  196 +
181 wvpResult.setMsg(String.format("点播失败, 错误码: %s, %s", event.statusCode, event.msg)); 197 wvpResult.setMsg(String.format("点播失败, 错误码: %s, %s", event.statusCode, event.msg));
182 msg.setData(wvpResult); 198 msg.setData(wvpResult);
183 resultHolder.invokeAllResult(msg); 199 resultHolder.invokeAllResult(msg);
184 if (errorEvent != null) { 200 if (errorEvent != null) {
185 errorEvent.response(event); 201 errorEvent.response(event);
186 } 202 }
187 -  
188 -  
189 }); 203 });
190 } else { 204 } else {
191 String streamId = streamInfo.getStream(); 205 String streamId = streamInfo.getStream();
@@ -222,13 +236,41 @@ public class PlayServiceImpl implements IPlayService { @@ -222,13 +236,41 @@ public class PlayServiceImpl implements IPlayService {
222 streamId2 = String.format("%s_%s", device.getDeviceId(), channelId); 236 streamId2 = String.format("%s_%s", device.getDeviceId(), channelId);
223 } 237 }
224 SSRCInfo ssrcInfo = mediaServerService.openRTPServer(mediaServerItem, streamId2); 238 SSRCInfo ssrcInfo = mediaServerService.openRTPServer(mediaServerItem, streamId2);
  239 + // 超时处理
  240 + Timer timer = new Timer();
  241 + timer.schedule(new TimerTask() {
  242 + @Override
  243 + public void run() {
  244 + logger.warn(String.format("设备点播超时,deviceId:%s ,channelId:%s", deviceId, channelId));
  245 + if (timeoutCallback != null) {
  246 + timeoutCallback.run();
  247 + }
  248 + WVPResult wvpResult = new WVPResult();
  249 + wvpResult.setCode(-1);
  250 + SIPDialog dialog = streamSession.getDialogByStream(deviceId, channelId, ssrcInfo.getStream());
  251 + if (dialog != null) {
  252 + wvpResult.setMsg("收流超时,请稍候重试");
  253 + // 点播超时回复BYE 同时释放ssrc以及此次点播的资源
  254 + cmder.streamByeCmd(device.getDeviceId(), channelId, ssrcInfo.getStream());
  255 + }else {
  256 + wvpResult.setMsg("点播超时,请稍候重试");
  257 + mediaServerService.releaseSsrc(mediaServerItem.getId(), ssrcInfo.getSsrc());
  258 + mediaServerService.closeRTPServer(deviceId, channelId, ssrcInfo.getStream());
  259 + streamSession.remove(deviceId, channelId, ssrcInfo.getStream());
  260 + }
  261 +
  262 + msg.setData(wvpResult);
  263 + // 回复之前所有的点播请求
  264 + resultHolder.invokeAllResult(msg);
  265 + }
  266 + }, userSetup.getPlayTimeout());
225 cmder.playStreamCmd(mediaServerItem, ssrcInfo, device, channelId, (MediaServerItem mediaServerItemInuse, JSONObject response) -> { 267 cmder.playStreamCmd(mediaServerItem, ssrcInfo, device, channelId, (MediaServerItem mediaServerItemInuse, JSONObject response) -> {
226 logger.info("收到订阅消息: " + response.toJSONString()); 268 logger.info("收到订阅消息: " + response.toJSONString());
227 onPublishHandlerForPlay(mediaServerItemInuse, response, deviceId, channelId, uuid); 269 onPublishHandlerForPlay(mediaServerItemInuse, response, deviceId, channelId, uuid);
228 }, (event) -> { 270 }, (event) -> {
229 mediaServerService.closeRTPServer(playResult.getDevice().getDeviceId(), channelId, ssrcInfo.getStream()); 271 mediaServerService.closeRTPServer(playResult.getDevice().getDeviceId(), channelId, ssrcInfo.getStream());
230 // 释放ssrc 272 // 释放ssrc
231 - mediaServerService.releaseSsrc(mediaServerItem, ssrcInfo.getSsrc()); 273 + mediaServerService.releaseSsrc(mediaServerItem.getId(), ssrcInfo.getSsrc());
232 streamSession.remove(deviceId, channelId, ssrcInfo.getStream()); 274 streamSession.remove(deviceId, channelId, ssrcInfo.getStream());
233 WVPResult wvpResult = new WVPResult(); 275 WVPResult wvpResult = new WVPResult();
234 wvpResult.setCode(-1); 276 wvpResult.setCode(-1);
@@ -306,14 +348,33 @@ public class PlayServiceImpl implements IPlayService { @@ -306,14 +348,33 @@ public class PlayServiceImpl implements IPlayService {
306 msg.setId(uuid); 348 msg.setId(uuid);
307 msg.setKey(key); 349 msg.setKey(key);
308 PlayBackResult<RequestMessage> playBackResult = new PlayBackResult<>(); 350 PlayBackResult<RequestMessage> playBackResult = new PlayBackResult<>();
309 - result.onTimeout(()->{  
310 - msg.setData("回放超时");  
311 - playBackResult.setCode(-1);  
312 - playBackResult.setData(msg);  
313 - callback.call(playBackResult);  
314 - }); 351 +
  352 + Timer timer = new Timer();
  353 + timer.schedule(new TimerTask() {
  354 + @Override
  355 + public void run() {
  356 + logger.warn(String.format("设备回放超时,deviceId:%s ,channelId:%s", deviceId, channelId));
  357 + playBackResult.setCode(-1);
  358 + playBackResult.setData(msg);
  359 + callback.call(playBackResult);
  360 + SIPDialog dialog = streamSession.getDialogByStream(deviceId, channelId, ssrcInfo.getStream());
  361 + // 点播超时回复BYE 同时释放ssrc以及此次点播的资源
  362 + if (dialog != null) {
  363 + // 点播超时回复BYE 同时释放ssrc以及此次点播的资源
  364 + cmder.streamByeCmd(device.getDeviceId(), channelId, ssrcInfo.getStream());
  365 + }else {
  366 + mediaServerService.releaseSsrc(newMediaServerItem.getId(), ssrcInfo.getSsrc());
  367 + mediaServerService.closeRTPServer(deviceId, channelId, ssrcInfo.getStream());
  368 + streamSession.remove(deviceId, channelId, ssrcInfo.getStream());
  369 + }
  370 + cmder.streamByeCmd(device.getDeviceId(), channelId, ssrcInfo.getStream());
  371 + // 回复之前所有的点播请求
  372 + callback.call(playBackResult);
  373 + }
  374 + }, userSetup.getPlayTimeout());
315 cmder.playbackStreamCmd(newMediaServerItem, ssrcInfo, device, channelId, startTime, endTime, (MediaServerItem mediaServerItem, JSONObject response) -> { 375 cmder.playbackStreamCmd(newMediaServerItem, ssrcInfo, device, channelId, startTime, endTime, (MediaServerItem mediaServerItem, JSONObject response) -> {
316 logger.info("收到订阅消息: " + response.toJSONString()); 376 logger.info("收到订阅消息: " + response.toJSONString());
  377 + timer.cancel();
317 StreamInfo streamInfo = onPublishHandler(mediaServerItem, response, deviceId, channelId); 378 StreamInfo streamInfo = onPublishHandler(mediaServerItem, response, deviceId, channelId);
318 if (streamInfo == null) { 379 if (streamInfo == null) {
319 logger.warn("设备回放API调用失败!"); 380 logger.warn("设备回放API调用失败!");
@@ -331,6 +392,7 @@ public class PlayServiceImpl implements IPlayService { @@ -331,6 +392,7 @@ public class PlayServiceImpl implements IPlayService {
331 playBackResult.setResponse(response); 392 playBackResult.setResponse(response);
332 callback.call(playBackResult); 393 callback.call(playBackResult);
333 }, event -> { 394 }, event -> {
  395 + timer.cancel();
334 msg.setData(String.format("回放失败, 错误码: %s, %s", event.statusCode, event.msg)); 396 msg.setData(String.format("回放失败, 错误码: %s, %s", event.statusCode, event.msg));
335 playBackResult.setCode(-1); 397 playBackResult.setCode(-1);
336 playBackResult.setData(msg); 398 playBackResult.setData(msg);
@@ -370,4 +432,26 @@ public class PlayServiceImpl implements IPlayService { @@ -370,4 +432,26 @@ public class PlayServiceImpl implements IPlayService {
370 return streamInfo; 432 return streamInfo;
371 } 433 }
372 434
  435 + @Override
  436 + public void zlmServerOffline(String mediaServerId) {
  437 + // 处理正在向上推流的上级平台
  438 + List<SendRtpItem> sendRtpItems = redisCatchStorage.querySendRTPServer(null);
  439 + if (sendRtpItems.size() > 0) {
  440 + for (SendRtpItem sendRtpItem : sendRtpItems) {
  441 + if (sendRtpItem.getMediaServerId().equals(mediaServerId)) {
  442 + ParentPlatform platform = storager.queryParentPlatByServerGBId(sendRtpItem.getPlatformId());
  443 + sipCommanderFroPlatform.streamByeCmd(platform, sendRtpItem.getCallId());
  444 + }
  445 + }
  446 + }
  447 + // 处理正在观看的国标设备
  448 + List<SsrcTransaction> allSsrc = streamSession.getAllSsrc();
  449 + if (allSsrc.size() > 0) {
  450 + for (SsrcTransaction ssrcTransaction : allSsrc) {
  451 + if(ssrcTransaction.getMediaServerId().equals(mediaServerId)) {
  452 + cmder.streamByeCmd(ssrcTransaction.getDeviceId(), ssrcTransaction.getChannelId(), ssrcTransaction.getStream());
  453 + }
  454 + }
  455 + }
  456 + }
373 } 457 }
src/main/java/com/genersoft/iot/vmp/storager/IRedisCatchStorage.java
@@ -89,7 +89,7 @@ public interface IRedisCatchStorage { @@ -89,7 +89,7 @@ public interface IRedisCatchStorage {
89 * @param channelId 89 * @param channelId
90 * @return sendRtpItem 90 * @return sendRtpItem
91 */ 91 */
92 - SendRtpItem querySendRTPServer(String platformGbId, String channelId); 92 + SendRtpItem querySendRTPServer(String platformGbId, String channelId, String streamId, String callId);
93 93
94 List<SendRtpItem> querySendRTPServer(String platformGbId); 94 List<SendRtpItem> querySendRTPServer(String platformGbId);
95 95
@@ -98,7 +98,7 @@ public interface IRedisCatchStorage { @@ -98,7 +98,7 @@ public interface IRedisCatchStorage {
98 * @param platformGbId 98 * @param platformGbId
99 * @param channelId 99 * @param channelId
100 */ 100 */
101 - void deleteSendRTPServer(String platformGbId, String channelId); 101 + void deleteSendRTPServer(String platformGbId, String channelId, String callId, String streamId);
102 102
103 /** 103 /**
104 * 查询某个通道是否存在上级点播(RTP推送) 104 * 查询某个通道是否存在上级点播(RTP推送)
src/main/java/com/genersoft/iot/vmp/storager/dao/DeviceChannelMapper.java
@@ -135,6 +135,32 @@ public interface DeviceChannelMapper { @@ -135,6 +135,32 @@ public interface DeviceChannelMapper {
135 "'${item.ipAddress}', ${item.port}, '${item.password}', ${item.PTZType}, ${item.status}, " + 135 "'${item.ipAddress}', ${item.port}, '${item.password}', ${item.PTZType}, ${item.status}, " +
136 "'${item.streamId}', ${item.longitude}, ${item.latitude},'${item.createTime}', '${item.updateTime}')" + 136 "'${item.streamId}', ${item.longitude}, ${item.latitude},'${item.createTime}', '${item.updateTime}')" +
137 "</foreach> " + 137 "</foreach> " +
  138 + "ON DUPLICATE KEY UPDATE " +
  139 + "updateTime=VALUES(updateTime), " +
  140 + "name=VALUES(name), " +
  141 + "manufacture=VALUES(manufacture), " +
  142 + "model=VALUES(model), " +
  143 + "owner=VALUES(owner), " +
  144 + "civilCode=VALUES(civilCode), " +
  145 + "block=VALUES(block), " +
  146 + "subCount=VALUES(subCount), " +
  147 + "address=VALUES(address), " +
  148 + "parental=VALUES(parental), " +
  149 + "parentId=VALUES(parentId), " +
  150 + "safetyWay=VALUES(safetyWay), " +
  151 + "registerWay=VALUES(registerWay), " +
  152 + "certNum=VALUES(certNum), " +
  153 + "certifiable=VALUES(certifiable), " +
  154 + "errCode=VALUES(errCode), " +
  155 + "secrecy=VALUES(secrecy), " +
  156 + "ipAddress=VALUES(ipAddress), " +
  157 + "port=VALUES(port), " +
  158 + "password=VALUES(password), " +
  159 + "PTZType=VALUES(PTZType), " +
  160 + "status=VALUES(status), " +
  161 + "streamId=VALUES(streamId), " +
  162 + "longitude=VALUES(longitude), " +
  163 + "latitude=VALUES(latitude)" +
138 "</script>") 164 "</script>")
139 int batchAdd(List<DeviceChannel> addChannels); 165 int batchAdd(List<DeviceChannel> addChannels);
140 166
@@ -211,4 +237,15 @@ public interface DeviceChannelMapper { @@ -211,4 +237,15 @@ public interface DeviceChannelMapper {
211 " from device_channel\n" + 237 " from device_channel\n" +
212 " where deviceId = #{deviceId}") 238 " where deviceId = #{deviceId}")
213 List<DeviceChannelTree> tree(String deviceId); 239 List<DeviceChannelTree> tree(String deviceId);
  240 +
  241 + @Delete(value = {" <script>" +
  242 + "DELETE " +
  243 + "from " +
  244 + "device_channel " +
  245 + "WHERE " +
  246 + "deviceId = #{deviceId} " +
  247 + " AND channelId NOT IN " +
  248 + "<foreach collection='channels' item='item' open='(' separator=',' close=')' > #{item.channelId}</foreach>" +
  249 + " </script>"})
  250 + int cleanChannelsNotInList(String deviceId, List<DeviceChannel> channels);
214 } 251 }
src/main/java/com/genersoft/iot/vmp/storager/impl/RedisCatchStorageImpl.java
@@ -18,6 +18,7 @@ import com.genersoft.iot.vmp.utils.redis.RedisUtil; @@ -18,6 +18,7 @@ import com.genersoft.iot.vmp.utils.redis.RedisUtil;
18 import org.slf4j.Logger; 18 import org.slf4j.Logger;
19 import org.slf4j.LoggerFactory; 19 import org.slf4j.LoggerFactory;
20 import org.springframework.beans.factory.annotation.Autowired; 20 import org.springframework.beans.factory.annotation.Autowired;
  21 +import org.springframework.security.core.parameters.P;
21 import org.springframework.stereotype.Component; 22 import org.springframework.stereotype.Component;
22 import org.springframework.util.StringUtils; 23 import org.springframework.util.StringUtils;
23 24
@@ -276,19 +277,32 @@ public class RedisCatchStorageImpl implements IRedisCatchStorage { @@ -276,19 +277,32 @@ public class RedisCatchStorageImpl implements IRedisCatchStorage {
276 277
277 @Override 278 @Override
278 public void updateSendRTPSever(SendRtpItem sendRtpItem) { 279 public void updateSendRTPSever(SendRtpItem sendRtpItem) {
279 - String key = VideoManagerConstants.PLATFORM_SEND_RTP_INFO_PREFIX + userSetup.getServerId() + "_" + sendRtpItem.getPlatformId() + "_" + sendRtpItem.getChannelId(); 280 + String key = VideoManagerConstants.PLATFORM_SEND_RTP_INFO_PREFIX + userSetup.getServerId() + "_"
  281 + + sendRtpItem.getPlatformId() + "_" + sendRtpItem.getChannelId() + "_"
  282 + + sendRtpItem.getStreamId() + "_" + sendRtpItem.getCallId();
280 redis.set(key, sendRtpItem); 283 redis.set(key, sendRtpItem);
281 } 284 }
282 285
283 @Override 286 @Override
284 - public SendRtpItem querySendRTPServer(String platformGbId, String channelId) {  
285 - String key = VideoManagerConstants.PLATFORM_SEND_RTP_INFO_PREFIX + userSetup.getServerId() + "_" + platformGbId + "_" + channelId;  
286 - return (SendRtpItem)redis.get(key); 287 + public SendRtpItem querySendRTPServer(String platformGbId, String channelId, String streamId, String callId) {
  288 + if (platformGbId == null) platformGbId = "*";
  289 + if (channelId == null) channelId = "*";
  290 + if (streamId == null) streamId = "*";
  291 + if (callId == null) callId = "*";
  292 + String key = VideoManagerConstants.PLATFORM_SEND_RTP_INFO_PREFIX + userSetup.getServerId() + "_" + platformGbId
  293 + + "_" + channelId + "_" + streamId + "_" + callId;
  294 + List<Object> scan = redis.scan(key);
  295 + if (scan.size() > 0) {
  296 + return (SendRtpItem)redis.get((String)scan.get(0));
  297 + }else {
  298 + return null;
  299 + }
287 } 300 }
288 301
289 @Override 302 @Override
290 public List<SendRtpItem> querySendRTPServer(String platformGbId) { 303 public List<SendRtpItem> querySendRTPServer(String platformGbId) {
291 - String key = VideoManagerConstants.PLATFORM_SEND_RTP_INFO_PREFIX + userSetup.getServerId() + "_" + platformGbId + "_*"; 304 + if (platformGbId == null) platformGbId = "*";
  305 + String key = VideoManagerConstants.PLATFORM_SEND_RTP_INFO_PREFIX + userSetup.getServerId() + "_" + platformGbId + "_*" + "_*" + "_*";
292 List<Object> queryResult = redis.scan(key); 306 List<Object> queryResult = redis.scan(key);
293 List<SendRtpItem> result= new ArrayList<>(); 307 List<SendRtpItem> result= new ArrayList<>();
294 308
@@ -306,18 +320,28 @@ public class RedisCatchStorageImpl implements IRedisCatchStorage { @@ -306,18 +320,28 @@ public class RedisCatchStorageImpl implements IRedisCatchStorage {
306 * @param channelId 320 * @param channelId
307 */ 321 */
308 @Override 322 @Override
309 - public void deleteSendRTPServer(String platformGbId, String channelId) {  
310 - String key = VideoManagerConstants.PLATFORM_SEND_RTP_INFO_PREFIX + userSetup.getServerId() + "_" + platformGbId + "_" + channelId;  
311 - redis.del(key); 323 + public void deleteSendRTPServer(String platformGbId, String channelId, String callId, String streamId) {
  324 + if (streamId == null) streamId = "*";
  325 + if (callId == null) callId = "*";
  326 + String key = VideoManagerConstants.PLATFORM_SEND_RTP_INFO_PREFIX + userSetup.getServerId() + "_" + platformGbId
  327 + + "_" + channelId + "_" + streamId + "_" + callId;
  328 + List<Object> scan = redis.scan(key);
  329 + if (scan.size() > 0) {
  330 + for (Object keyStr : scan) {
  331 + redis.del((String)keyStr);
  332 + }
  333 + }
312 } 334 }
313 335
  336 +
  337 +
314 /** 338 /**
315 * 查询某个通道是否存在上级点播(RTP推送) 339 * 查询某个通道是否存在上级点播(RTP推送)
316 * @param channelId 340 * @param channelId
317 */ 341 */
318 @Override 342 @Override
319 public boolean isChannelSendingRTP(String channelId) { 343 public boolean isChannelSendingRTP(String channelId) {
320 - String key = VideoManagerConstants.PLATFORM_SEND_RTP_INFO_PREFIX + userSetup.getServerId() + "_" + "*_" + channelId; 344 + String key = VideoManagerConstants.PLATFORM_SEND_RTP_INFO_PREFIX + userSetup.getServerId() + "_" + "*_" + channelId + "*_" + "*_";
321 List<Object> RtpStreams = redis.scan(key); 345 List<Object> RtpStreams = redis.scan(key);
322 if (RtpStreams.size() > 0) { 346 if (RtpStreams.size() > 0) {
323 return true; 347 return true;
src/main/java/com/genersoft/iot/vmp/storager/impl/VideoManagerStoragerImpl.java
@@ -284,7 +284,8 @@ public class VideoManagerStoragerImpl implements IVideoManagerStorager { @@ -284,7 +284,8 @@ public class VideoManagerStoragerImpl implements IVideoManagerStorager {
284 logger.debug("[目录查询]收到的数据存在重复: {}" , stringBuilder); 284 logger.debug("[目录查询]收到的数据存在重复: {}" , stringBuilder);
285 } 285 }
286 try { 286 try {
287 - int cleanChannelsResult = deviceChannelMapper.cleanChannelsByDeviceId(deviceId); 287 +// int cleanChannelsResult = deviceChannelMapper.cleanChannelsByDeviceId(deviceId);
  288 + int cleanChannelsResult = deviceChannelMapper.cleanChannelsNotInList(deviceId, channels);
288 int limitCount = 300; 289 int limitCount = 300;
289 boolean result = cleanChannelsResult < 0; 290 boolean result = cleanChannelsResult < 0;
290 if (!result && channels.size() > 0) { 291 if (!result && channels.size() > 0) {
src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/device/DeviceQuery.java
1 package com.genersoft.iot.vmp.vmanager.gb28181.device; 1 package com.genersoft.iot.vmp.vmanager.gb28181.device;
2 2
3 import com.alibaba.fastjson.JSONObject; 3 import com.alibaba.fastjson.JSONObject;
  4 +import com.genersoft.iot.vmp.conf.DynamicTask;
4 import com.genersoft.iot.vmp.gb28181.bean.Device; 5 import com.genersoft.iot.vmp.gb28181.bean.Device;
5 import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel; 6 import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel;
6 import com.genersoft.iot.vmp.gb28181.event.DeviceOffLineDetector; 7 import com.genersoft.iot.vmp.gb28181.event.DeviceOffLineDetector;
@@ -13,7 +14,6 @@ import com.genersoft.iot.vmp.storager.IVideoManagerStorager; @@ -13,7 +14,6 @@ import com.genersoft.iot.vmp.storager.IVideoManagerStorager;
13 import com.genersoft.iot.vmp.vmanager.bean.DeviceChannelTree; 14 import com.genersoft.iot.vmp.vmanager.bean.DeviceChannelTree;
14 import com.genersoft.iot.vmp.vmanager.bean.WVPResult; 15 import com.genersoft.iot.vmp.vmanager.bean.WVPResult;
15 import com.github.pagehelper.PageInfo; 16 import com.github.pagehelper.PageInfo;
16 -import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;  
17 import io.swagger.annotations.Api; 17 import io.swagger.annotations.Api;
18 import io.swagger.annotations.ApiImplicitParam; 18 import io.swagger.annotations.ApiImplicitParam;
19 import io.swagger.annotations.ApiImplicitParams; 19 import io.swagger.annotations.ApiImplicitParams;
@@ -57,6 +57,9 @@ public class DeviceQuery { @@ -57,6 +57,9 @@ public class DeviceQuery {
57 @Autowired 57 @Autowired
58 private IDeviceService deviceService; 58 private IDeviceService deviceService;
59 59
  60 + @Autowired
  61 + private DynamicTask dynamicTask;
  62 +
60 /** 63 /**
61 * 使用ID查询国标设备 64 * 使用ID查询国标设备
62 * @param deviceId 国标ID 65 * @param deviceId 国标ID
@@ -209,6 +212,8 @@ public class DeviceQuery { @@ -209,6 +212,8 @@ public class DeviceQuery {
209 boolean isSuccess = storager.delete(deviceId); 212 boolean isSuccess = storager.delete(deviceId);
210 if (isSuccess) { 213 if (isSuccess) {
211 redisCatchStorage.clearCatchByDeviceId(deviceId); 214 redisCatchStorage.clearCatchByDeviceId(deviceId);
  215 + // 停止此设备的订阅更新
  216 + dynamicTask.stop(deviceId);
212 JSONObject json = new JSONObject(); 217 JSONObject json = new JSONObject();
213 json.put("deviceId", deviceId); 218 json.put("deviceId", deviceId);
214 return new ResponseEntity<>(json.toString(),HttpStatus.OK); 219 return new ResponseEntity<>(json.toString(),HttpStatus.OK);
src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/platform/PlatformController.java
@@ -2,8 +2,9 @@ package com.genersoft.iot.vmp.vmanager.gb28181.platform; @@ -2,8 +2,9 @@ package com.genersoft.iot.vmp.vmanager.gb28181.platform;
2 2
3 import com.alibaba.fastjson.JSON; 3 import com.alibaba.fastjson.JSON;
4 import com.alibaba.fastjson.JSONObject; 4 import com.alibaba.fastjson.JSONObject;
5 -import com.genersoft.iot.vmp.gb28181.bean.CatalogData;  
6 -import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel; 5 +import com.genersoft.iot.vmp.common.VideoManagerConstants;
  6 +import com.genersoft.iot.vmp.conf.DynamicTask;
  7 +import com.genersoft.iot.vmp.conf.UserSetup;
7 import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform; 8 import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform;
8 import com.genersoft.iot.vmp.gb28181.bean.PlatformCatalog; 9 import com.genersoft.iot.vmp.gb28181.bean.PlatformCatalog;
9 import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform; 10 import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform;
@@ -40,6 +41,9 @@ public class PlatformController { @@ -40,6 +41,9 @@ public class PlatformController {
40 private final static Logger logger = LoggerFactory.getLogger(PlatformController.class); 41 private final static Logger logger = LoggerFactory.getLogger(PlatformController.class);
41 42
42 @Autowired 43 @Autowired
  44 + private UserSetup userSetup;
  45 +
  46 + @Autowired
43 private IVideoManagerStorager storager; 47 private IVideoManagerStorager storager;
44 48
45 @Autowired 49 @Autowired
@@ -48,11 +52,15 @@ public class PlatformController { @@ -48,11 +52,15 @@ public class PlatformController {
48 @Autowired 52 @Autowired
49 private ISIPCommanderForPlatform commanderForPlatform; 53 private ISIPCommanderForPlatform commanderForPlatform;
50 54
  55 + @Autowired
  56 + private SipConfig sipConfig;
  57 +
51 @Autowired 58 @Autowired
52 - private SipConfig sipConfig; 59 + private DynamicTask dynamicTask;
53 60
54 /** 61 /**
55 * 获取国标服务的配置 62 * 获取国标服务的配置
  63 + *
56 * @return 64 * @return
57 */ 65 */
58 @ApiOperation("获取国标服务的配置") 66 @ApiOperation("获取国标服务的配置")
@@ -65,8 +73,10 @@ public class PlatformController { @@ -65,8 +73,10 @@ public class PlatformController {
65 result.put("password", sipConfig.getPassword()); 73 result.put("password", sipConfig.getPassword());
66 return new ResponseEntity<>(result, HttpStatus.OK); 74 return new ResponseEntity<>(result, HttpStatus.OK);
67 } 75 }
  76 +
68 /** 77 /**
69 * 获取级联服务器信息 78 * 获取级联服务器信息
  79 + *
70 * @return 80 * @return
71 */ 81 */
72 @ApiOperation("获取国标服务的配置") 82 @ApiOperation("获取国标服务的配置")
@@ -78,7 +88,7 @@ public class PlatformController { @@ -78,7 +88,7 @@ public class PlatformController {
78 wvpResult.setCode(0); 88 wvpResult.setCode(0);
79 wvpResult.setMsg("success"); 89 wvpResult.setMsg("success");
80 wvpResult.setData(parentPlatform); 90 wvpResult.setData(parentPlatform);
81 - }else { 91 + } else {
82 wvpResult.setCode(-1); 92 wvpResult.setCode(-1);
83 wvpResult.setMsg("未查询到此平台"); 93 wvpResult.setMsg("未查询到此平台");
84 } 94 }
@@ -87,7 +97,8 @@ public class PlatformController { @@ -87,7 +97,8 @@ public class PlatformController {
87 97
88 /** 98 /**
89 * 分页查询级联平台 99 * 分页查询级联平台
90 - * @param page 当前页 100 + *
  101 + * @param page 当前页
91 * @param count 每页条数 102 * @param count 每页条数
92 * @return 103 * @return
93 */ 104 */
@@ -97,7 +108,7 @@ public class PlatformController { @@ -97,7 +108,7 @@ public class PlatformController {
97 @ApiImplicitParam(name = "page", value = "当前页", dataTypeClass = Integer.class), 108 @ApiImplicitParam(name = "page", value = "当前页", dataTypeClass = Integer.class),
98 @ApiImplicitParam(name = "count", value = "每页条数", dataTypeClass = Integer.class), 109 @ApiImplicitParam(name = "count", value = "每页条数", dataTypeClass = Integer.class),
99 }) 110 })
100 - public PageInfo<ParentPlatform> platforms(@PathVariable int page, @PathVariable int count){ 111 + public PageInfo<ParentPlatform> platforms(@PathVariable int page, @PathVariable int count) {
101 112
102 // if (logger.isDebugEnabled()) { 113 // if (logger.isDebugEnabled()) {
103 // logger.debug("查询所有上级设备API调用"); 114 // logger.debug("查询所有上级设备API调用");
@@ -107,6 +118,7 @@ public class PlatformController { @@ -107,6 +118,7 @@ public class PlatformController {
107 118
108 /** 119 /**
109 * 添加上级平台信息 120 * 添加上级平台信息
  121 + *
110 * @param parentPlatform 122 * @param parentPlatform
111 * @return 123 * @return
112 */ 124 */
@@ -116,28 +128,28 @@ public class PlatformController { @@ -116,28 +128,28 @@ public class PlatformController {
116 }) 128 })
117 @PostMapping("/add") 129 @PostMapping("/add")
118 @ResponseBody 130 @ResponseBody
119 - public ResponseEntity<WVPResult<String>> addPlatform(@RequestBody ParentPlatform parentPlatform){ 131 + public ResponseEntity<WVPResult<String>> addPlatform(@RequestBody ParentPlatform parentPlatform) {
120 132
121 if (logger.isDebugEnabled()) { 133 if (logger.isDebugEnabled()) {
122 logger.debug("保存上级平台信息API调用"); 134 logger.debug("保存上级平台信息API调用");
123 } 135 }
124 WVPResult<String> wvpResult = new WVPResult<>(); 136 WVPResult<String> wvpResult = new WVPResult<>();
125 if (StringUtils.isEmpty(parentPlatform.getName()) 137 if (StringUtils.isEmpty(parentPlatform.getName())
126 - ||StringUtils.isEmpty(parentPlatform.getServerGBId())  
127 - ||StringUtils.isEmpty(parentPlatform.getServerGBDomain())  
128 - ||StringUtils.isEmpty(parentPlatform.getServerIP())  
129 - ||StringUtils.isEmpty(parentPlatform.getServerPort())  
130 - ||StringUtils.isEmpty(parentPlatform.getDeviceGBId())  
131 - ||StringUtils.isEmpty(parentPlatform.getExpires())  
132 - ||StringUtils.isEmpty(parentPlatform.getKeepTimeout())  
133 - ||StringUtils.isEmpty(parentPlatform.getTransport())  
134 - ||StringUtils.isEmpty(parentPlatform.getCharacterSet())  
135 - ){ 138 + || StringUtils.isEmpty(parentPlatform.getServerGBId())
  139 + || StringUtils.isEmpty(parentPlatform.getServerGBDomain())
  140 + || StringUtils.isEmpty(parentPlatform.getServerIP())
  141 + || StringUtils.isEmpty(parentPlatform.getServerPort())
  142 + || StringUtils.isEmpty(parentPlatform.getDeviceGBId())
  143 + || StringUtils.isEmpty(parentPlatform.getExpires())
  144 + || StringUtils.isEmpty(parentPlatform.getKeepTimeout())
  145 + || StringUtils.isEmpty(parentPlatform.getTransport())
  146 + || StringUtils.isEmpty(parentPlatform.getCharacterSet())
  147 + ) {
136 wvpResult.setCode(-1); 148 wvpResult.setCode(-1);
137 wvpResult.setMsg("missing parameters"); 149 wvpResult.setMsg("missing parameters");
138 return new ResponseEntity<>(wvpResult, HttpStatus.BAD_REQUEST); 150 return new ResponseEntity<>(wvpResult, HttpStatus.BAD_REQUEST);
139 } 151 }
140 - if (parentPlatform.getServerPort()< 0 || parentPlatform.getServerPort() > 65535){ 152 + if (parentPlatform.getServerPort() < 0 || parentPlatform.getServerPort() > 65535) {
141 wvpResult.setCode(-1); 153 wvpResult.setCode(-1);
142 wvpResult.setMsg("error severPort"); 154 wvpResult.setMsg("error severPort");
143 return new ResponseEntity<>(wvpResult, HttpStatus.BAD_REQUEST); 155 return new ResponseEntity<>(wvpResult, HttpStatus.BAD_REQUEST);
@@ -146,7 +158,7 @@ public class PlatformController { @@ -146,7 +158,7 @@ public class PlatformController {
146 ParentPlatform parentPlatformOld = storager.queryParentPlatByServerGBId(parentPlatform.getServerGBId()); 158 ParentPlatform parentPlatformOld = storager.queryParentPlatByServerGBId(parentPlatform.getServerGBId());
147 if (parentPlatformOld != null) { 159 if (parentPlatformOld != null) {
148 wvpResult.setCode(-1); 160 wvpResult.setCode(-1);
149 - wvpResult.setMsg("平台 "+parentPlatform.getServerGBId()+" 已存在"); 161 + wvpResult.setMsg("平台 " + parentPlatform.getServerGBId() + " 已存在");
150 return new ResponseEntity<>(wvpResult, HttpStatus.OK); 162 return new ResponseEntity<>(wvpResult, HttpStatus.OK);
151 } 163 }
152 boolean updateResult = storager.updateParentPlatform(parentPlatform); 164 boolean updateResult = storager.updateParentPlatform(parentPlatform);
@@ -154,17 +166,17 @@ public class PlatformController { @@ -154,17 +166,17 @@ public class PlatformController {
154 if (updateResult) { 166 if (updateResult) {
155 // 保存时启用就发送注册 167 // 保存时启用就发送注册
156 if (parentPlatform.isEnable()) { 168 if (parentPlatform.isEnable()) {
157 - if (parentPlatformOld.isStatus()) { 169 + if (parentPlatformOld != null && parentPlatformOld.isStatus()) {
158 commanderForPlatform.unregister(parentPlatformOld, null, eventResult -> { 170 commanderForPlatform.unregister(parentPlatformOld, null, eventResult -> {
159 // 只要保存就发送注册 171 // 只要保存就发送注册
160 commanderForPlatform.register(parentPlatform, null, null); 172 commanderForPlatform.register(parentPlatform, null, null);
161 }); 173 });
162 - }else { 174 + } else {
163 // 只要保存就发送注册 175 // 只要保存就发送注册
164 commanderForPlatform.register(parentPlatform, null, null); 176 commanderForPlatform.register(parentPlatform, null, null);
165 } 177 }
166 178
167 - } else if (parentPlatformOld != null && parentPlatformOld.isEnable() && !parentPlatform.isEnable()){ // 关闭启用时注销 179 + } else if (parentPlatformOld != null && parentPlatformOld.isEnable() && !parentPlatform.isEnable()) { // 关闭启用时注销
168 commanderForPlatform.unregister(parentPlatform, null, null); 180 commanderForPlatform.unregister(parentPlatform, null, null);
169 } 181 }
170 wvpResult.setCode(0); 182 wvpResult.setCode(0);
@@ -179,6 +191,7 @@ public class PlatformController { @@ -179,6 +191,7 @@ public class PlatformController {
179 191
180 /** 192 /**
181 * 保存上级平台信息 193 * 保存上级平台信息
  194 + *
182 * @param parentPlatform 195 * @param parentPlatform
183 * @return 196 * @return
184 */ 197 */
@@ -188,23 +201,23 @@ public class PlatformController { @@ -188,23 +201,23 @@ public class PlatformController {
188 }) 201 })
189 @PostMapping("/save") 202 @PostMapping("/save")
190 @ResponseBody 203 @ResponseBody
191 - public ResponseEntity<WVPResult<String>> savePlatform(@RequestBody ParentPlatform parentPlatform){ 204 + public ResponseEntity<WVPResult<String>> savePlatform(@RequestBody ParentPlatform parentPlatform) {
192 205
193 if (logger.isDebugEnabled()) { 206 if (logger.isDebugEnabled()) {
194 logger.debug("保存上级平台信息API调用"); 207 logger.debug("保存上级平台信息API调用");
195 } 208 }
196 WVPResult<String> wvpResult = new WVPResult<>(); 209 WVPResult<String> wvpResult = new WVPResult<>();
197 if (StringUtils.isEmpty(parentPlatform.getName()) 210 if (StringUtils.isEmpty(parentPlatform.getName())
198 - ||StringUtils.isEmpty(parentPlatform.getServerGBId())  
199 - ||StringUtils.isEmpty(parentPlatform.getServerGBDomain())  
200 - ||StringUtils.isEmpty(parentPlatform.getServerIP())  
201 - ||StringUtils.isEmpty(parentPlatform.getServerPort())  
202 - ||StringUtils.isEmpty(parentPlatform.getDeviceGBId())  
203 - ||StringUtils.isEmpty(parentPlatform.getExpires())  
204 - ||StringUtils.isEmpty(parentPlatform.getKeepTimeout())  
205 - ||StringUtils.isEmpty(parentPlatform.getTransport())  
206 - ||StringUtils.isEmpty(parentPlatform.getCharacterSet())  
207 - ){ 211 + || StringUtils.isEmpty(parentPlatform.getServerGBId())
  212 + || StringUtils.isEmpty(parentPlatform.getServerGBDomain())
  213 + || StringUtils.isEmpty(parentPlatform.getServerIP())
  214 + || StringUtils.isEmpty(parentPlatform.getServerPort())
  215 + || StringUtils.isEmpty(parentPlatform.getDeviceGBId())
  216 + || StringUtils.isEmpty(parentPlatform.getExpires())
  217 + || StringUtils.isEmpty(parentPlatform.getKeepTimeout())
  218 + || StringUtils.isEmpty(parentPlatform.getTransport())
  219 + || StringUtils.isEmpty(parentPlatform.getCharacterSet())
  220 + ) {
208 wvpResult.setCode(-1); 221 wvpResult.setCode(-1);
209 wvpResult.setMsg("missing parameters"); 222 wvpResult.setMsg("missing parameters");
210 return new ResponseEntity<>(wvpResult, HttpStatus.BAD_REQUEST); 223 return new ResponseEntity<>(wvpResult, HttpStatus.BAD_REQUEST);
@@ -216,7 +229,7 @@ public class PlatformController { @@ -216,7 +229,7 @@ public class PlatformController {
216 if (updateResult) { 229 if (updateResult) {
217 // 保存时启用就发送注册 230 // 保存时启用就发送注册
218 if (parentPlatform.isEnable()) { 231 if (parentPlatform.isEnable()) {
219 - if (parentPlatformOld.isStatus()) { 232 + if (parentPlatformOld != null && parentPlatformOld.isStatus()) {
220 commanderForPlatform.unregister(parentPlatformOld, null, null); 233 commanderForPlatform.unregister(parentPlatformOld, null, null);
221 try { 234 try {
222 Thread.sleep(500); 235 Thread.sleep(500);
@@ -225,11 +238,11 @@ public class PlatformController { @@ -225,11 +238,11 @@ public class PlatformController {
225 } 238 }
226 // 只要保存就发送注册 239 // 只要保存就发送注册
227 commanderForPlatform.register(parentPlatform, null, null); 240 commanderForPlatform.register(parentPlatform, null, null);
228 - }else { 241 + } else {
229 // 只要保存就发送注册 242 // 只要保存就发送注册
230 commanderForPlatform.register(parentPlatform, null, null); 243 commanderForPlatform.register(parentPlatform, null, null);
231 } 244 }
232 - } else if (parentPlatformOld != null && parentPlatformOld.isEnable() && !parentPlatform.isEnable()){ // 关闭启用时注销 245 + } else if (parentPlatformOld != null && parentPlatformOld.isEnable() && !parentPlatform.isEnable()) { // 关闭启用时注销
233 commanderForPlatform.unregister(parentPlatformOld, null, null); 246 commanderForPlatform.unregister(parentPlatformOld, null, null);
234 } 247 }
235 wvpResult.setCode(0); 248 wvpResult.setCode(0);
@@ -244,7 +257,8 @@ public class PlatformController { @@ -244,7 +257,8 @@ public class PlatformController {
244 257
245 /** 258 /**
246 * 删除上级平台 259 * 删除上级平台
247 - * @param serverGBId 上级平台国标ID 260 + *
  261 + * @param serverGBId 上级平台国标ID
248 * @return 262 * @return
249 */ 263 */
250 @ApiOperation("删除上级平台") 264 @ApiOperation("删除上级平台")
@@ -253,13 +267,13 @@ public class PlatformController { @@ -253,13 +267,13 @@ public class PlatformController {
253 }) 267 })
254 @DeleteMapping("/delete/{serverGBId}") 268 @DeleteMapping("/delete/{serverGBId}")
255 @ResponseBody 269 @ResponseBody
256 - public ResponseEntity<String> deletePlatform(@PathVariable String serverGBId){ 270 + public ResponseEntity<String> deletePlatform(@PathVariable String serverGBId) {
257 271
258 if (logger.isDebugEnabled()) { 272 if (logger.isDebugEnabled()) {
259 logger.debug("删除上级平台API调用"); 273 logger.debug("删除上级平台API调用");
260 } 274 }
261 if (StringUtils.isEmpty(serverGBId) 275 if (StringUtils.isEmpty(serverGBId)
262 - ){ 276 + ) {
263 return new ResponseEntity<>("missing parameters", HttpStatus.BAD_REQUEST); 277 return new ResponseEntity<>("missing parameters", HttpStatus.BAD_REQUEST);
264 } 278 }
265 ParentPlatform parentPlatform = storager.queryParentPlatByServerGBId(serverGBId); 279 ParentPlatform parentPlatform = storager.queryParentPlatByServerGBId(serverGBId);
@@ -280,17 +294,19 @@ public class PlatformController { @@ -280,17 +294,19 @@ public class PlatformController {
280 boolean deleteResult = storager.deleteParentPlatform(parentPlatform); 294 boolean deleteResult = storager.deleteParentPlatform(parentPlatform);
281 storager.delCatalogByPlatformId(parentPlatform.getServerGBId()); 295 storager.delCatalogByPlatformId(parentPlatform.getServerGBId());
282 storager.delRelationByPlatformId(parentPlatform.getServerGBId()); 296 storager.delRelationByPlatformId(parentPlatform.getServerGBId());
283 -  
284 - 297 + // 停止发送位置订阅定时任务
  298 + String key = VideoManagerConstants.SIP_SUBSCRIBE_PREFIX + userSetup.getServerId() + "_MobilePosition_" + parentPlatform.getServerGBId();
  299 + dynamicTask.stop(key);
285 if (deleteResult) { 300 if (deleteResult) {
286 return new ResponseEntity<>("success", HttpStatus.OK); 301 return new ResponseEntity<>("success", HttpStatus.OK);
287 - }else { 302 + } else {
288 return new ResponseEntity<>("fail", HttpStatus.OK); 303 return new ResponseEntity<>("fail", HttpStatus.OK);
289 } 304 }
290 } 305 }
291 306
292 /** 307 /**
293 * 查询上级平台是否存在 308 * 查询上级平台是否存在
  309 + *
294 * @param serverGBId 上级平台国标ID 310 * @param serverGBId 上级平台国标ID
295 * @return 311 * @return
296 */ 312 */
@@ -300,7 +316,7 @@ public class PlatformController { @@ -300,7 +316,7 @@ public class PlatformController {
300 }) 316 })
301 @GetMapping("/exit/{serverGBId}") 317 @GetMapping("/exit/{serverGBId}")
302 @ResponseBody 318 @ResponseBody
303 - public ResponseEntity<String> exitPlatform(@PathVariable String serverGBId){ 319 + public ResponseEntity<String> exitPlatform(@PathVariable String serverGBId) {
304 320
305 // if (logger.isDebugEnabled()) { 321 // if (logger.isDebugEnabled()) {
306 // logger.debug("查询上级平台是否存在API调用:" + serverGBId); 322 // logger.debug("查询上级平台是否存在API调用:" + serverGBId);
@@ -311,12 +327,13 @@ public class PlatformController { @@ -311,12 +327,13 @@ public class PlatformController {
311 327
312 /** 328 /**
313 * 分页查询级联平台的所有所有通道 329 * 分页查询级联平台的所有所有通道
314 - * @param page 当前页  
315 - * @param count 每页条数  
316 - * @param platformId 上级平台ID  
317 - * @param query 查询内容  
318 - * @param online 是否在线  
319 - * @param choosed 是否已选中 330 + *
  331 + * @param page 当前页
  332 + * @param count 每页条数
  333 + * @param platformId 上级平台ID
  334 + * @param query 查询内容
  335 + * @param online 是否在线
  336 + * @param choosed 是否已选中
320 * @param channelType 通道类型 337 * @param channelType 通道类型
321 * @return 338 * @return
322 */ 339 */
@@ -333,22 +350,22 @@ public class PlatformController { @@ -333,22 +350,22 @@ public class PlatformController {
333 @GetMapping("/channel_list") 350 @GetMapping("/channel_list")
334 @ResponseBody 351 @ResponseBody
335 public PageInfo<ChannelReduce> channelList(int page, int count, 352 public PageInfo<ChannelReduce> channelList(int page, int count,
336 - @RequestParam(required = false) String platformId,  
337 - @RequestParam(required = false) String catalogId,  
338 - @RequestParam(required = false) String query,  
339 - @RequestParam(required = false) Boolean online,  
340 - @RequestParam(required = false) Boolean channelType){ 353 + @RequestParam(required = false) String platformId,
  354 + @RequestParam(required = false) String catalogId,
  355 + @RequestParam(required = false) String query,
  356 + @RequestParam(required = false) Boolean online,
  357 + @RequestParam(required = false) Boolean channelType) {
341 358
342 // if (logger.isDebugEnabled()) { 359 // if (logger.isDebugEnabled()) {
343 // logger.debug("查询所有所有通道API调用"); 360 // logger.debug("查询所有所有通道API调用");
344 // } 361 // }
345 - if(StringUtils.isEmpty(platformId)) { 362 + if (StringUtils.isEmpty(platformId)) {
346 platformId = null; 363 platformId = null;
347 } 364 }
348 - if(StringUtils.isEmpty(query)) { 365 + if (StringUtils.isEmpty(query)) {
349 query = null; 366 query = null;
350 } 367 }
351 - if(StringUtils.isEmpty(platformId) || StringUtils.isEmpty(catalogId)) { 368 + if (StringUtils.isEmpty(platformId) || StringUtils.isEmpty(catalogId)) {
352 catalogId = null; 369 catalogId = null;
353 } 370 }
354 PageInfo<ChannelReduce> channelReduces = storager.queryAllChannelList(page, count, query, online, channelType, platformId, catalogId); 371 PageInfo<ChannelReduce> channelReduces = storager.queryAllChannelList(page, count, query, online, channelType, platformId, catalogId);
@@ -358,6 +375,7 @@ public class PlatformController { @@ -358,6 +375,7 @@ public class PlatformController {
358 375
359 /** 376 /**
360 * 向上级平台添加国标通道 377 * 向上级平台添加国标通道
  378 + *
361 * @param param 通道关联参数 379 * @param param 通道关联参数
362 * @return 380 * @return
363 */ 381 */
@@ -367,7 +385,7 @@ public class PlatformController { @@ -367,7 +385,7 @@ public class PlatformController {
367 }) 385 })
368 @PostMapping("/update_channel_for_gb") 386 @PostMapping("/update_channel_for_gb")
369 @ResponseBody 387 @ResponseBody
370 - public ResponseEntity<String> updateChannelForGB(@RequestBody UpdateChannelParam param){ 388 + public ResponseEntity<String> updateChannelForGB(@RequestBody UpdateChannelParam param) {
371 389
372 if (logger.isDebugEnabled()) { 390 if (logger.isDebugEnabled()) {
373 logger.debug("给上级平台添加国标通道API调用"); 391 logger.debug("给上级平台添加国标通道API调用");
@@ -379,6 +397,7 @@ public class PlatformController { @@ -379,6 +397,7 @@ public class PlatformController {
379 397
380 /** 398 /**
381 * 从上级平台移除国标通道 399 * 从上级平台移除国标通道
  400 + *
382 * @param param 通道关联参数 401 * @param param 通道关联参数
383 * @return 402 * @return
384 */ 403 */
@@ -388,7 +407,7 @@ public class PlatformController { @@ -388,7 +407,7 @@ public class PlatformController {
388 }) 407 })
389 @DeleteMapping("/del_channel_for_gb") 408 @DeleteMapping("/del_channel_for_gb")
390 @ResponseBody 409 @ResponseBody
391 - public ResponseEntity<String> delChannelForGB(@RequestBody UpdateChannelParam param){ 410 + public ResponseEntity<String> delChannelForGB(@RequestBody UpdateChannelParam param) {
392 411
393 if (logger.isDebugEnabled()) { 412 if (logger.isDebugEnabled()) {
394 logger.debug("给上级平台删除国标通道API调用"); 413 logger.debug("给上级平台删除国标通道API调用");
@@ -400,8 +419,9 @@ public class PlatformController { @@ -400,8 +419,9 @@ public class PlatformController {
400 419
401 /** 420 /**
402 * 获取目录 421 * 获取目录
  422 + *
403 * @param platformId 平台ID 423 * @param platformId 平台ID
404 - * @param parentId 目录父ID 424 + * @param parentId 目录父ID
405 * @return 425 * @return
406 */ 426 */
407 @ApiOperation("获取目录") 427 @ApiOperation("获取目录")
@@ -411,7 +431,7 @@ public class PlatformController { @@ -411,7 +431,7 @@ public class PlatformController {
411 }) 431 })
412 @GetMapping("/catalog") 432 @GetMapping("/catalog")
413 @ResponseBody 433 @ResponseBody
414 - public ResponseEntity<WVPResult<List<PlatformCatalog>>> getCatalogByPlatform(String platformId, String parentId){ 434 + public ResponseEntity<WVPResult<List<PlatformCatalog>>> getCatalogByPlatform(String platformId, String parentId) {
415 435
416 if (logger.isDebugEnabled()) { 436 if (logger.isDebugEnabled()) {
417 logger.debug("查询目录,platformId: {}, parentId: {}", platformId, parentId); 437 logger.debug("查询目录,platformId: {}, parentId: {}", platformId, parentId);
@@ -432,6 +452,7 @@ public class PlatformController { @@ -432,6 +452,7 @@ public class PlatformController {
432 452
433 /** 453 /**
434 * 添加目录 454 * 添加目录
  455 + *
435 * @param platformCatalog 目录 456 * @param platformCatalog 目录
436 * @return 457 * @return
437 */ 458 */
@@ -441,7 +462,7 @@ public class PlatformController { @@ -441,7 +462,7 @@ public class PlatformController {
441 }) 462 })
442 @PostMapping("/catalog/add") 463 @PostMapping("/catalog/add")
443 @ResponseBody 464 @ResponseBody
444 - public ResponseEntity<WVPResult<List<PlatformCatalog>>> addCatalog(@RequestBody PlatformCatalog platformCatalog){ 465 + public ResponseEntity<WVPResult<List<PlatformCatalog>>> addCatalog(@RequestBody PlatformCatalog platformCatalog) {
445 466
446 if (logger.isDebugEnabled()) { 467 if (logger.isDebugEnabled()) {
447 logger.debug("添加目录,{}", JSON.toJSONString(platformCatalog)); 468 logger.debug("添加目录,{}", JSON.toJSONString(platformCatalog));
@@ -452,7 +473,7 @@ public class PlatformController { @@ -452,7 +473,7 @@ public class PlatformController {
452 473
453 if (platformCatalogInStore != null) { 474 if (platformCatalogInStore != null) {
454 result.setCode(-1); 475 result.setCode(-1);
455 - result.setMsg( platformCatalog.getId() + " already exists"); 476 + result.setMsg(platformCatalog.getId() + " already exists");
456 return new ResponseEntity<>(result, HttpStatus.OK); 477 return new ResponseEntity<>(result, HttpStatus.OK);
457 } 478 }
458 int addResult = storager.addCatalog(platformCatalog); 479 int addResult = storager.addCatalog(platformCatalog);
@@ -460,7 +481,7 @@ public class PlatformController { @@ -460,7 +481,7 @@ public class PlatformController {
460 result.setCode(0); 481 result.setCode(0);
461 result.setMsg("success"); 482 result.setMsg("success");
462 return new ResponseEntity<>(result, HttpStatus.OK); 483 return new ResponseEntity<>(result, HttpStatus.OK);
463 - }else { 484 + } else {
464 result.setCode(-500); 485 result.setCode(-500);
465 result.setMsg("save error"); 486 result.setMsg("save error");
466 return new ResponseEntity<>(result, HttpStatus.OK); 487 return new ResponseEntity<>(result, HttpStatus.OK);
@@ -469,6 +490,7 @@ public class PlatformController { @@ -469,6 +490,7 @@ public class PlatformController {
469 490
470 /** 491 /**
471 * 编辑目录 492 * 编辑目录
  493 + *
472 * @param platformCatalog 目录 494 * @param platformCatalog 目录
473 * @return 495 * @return
474 */ 496 */
@@ -478,7 +500,7 @@ public class PlatformController { @@ -478,7 +500,7 @@ public class PlatformController {
478 }) 500 })
479 @PostMapping("/catalog/edit") 501 @PostMapping("/catalog/edit")
480 @ResponseBody 502 @ResponseBody
481 - public ResponseEntity<WVPResult<List<PlatformCatalog>>> editCatalog(@RequestBody PlatformCatalog platformCatalog){ 503 + public ResponseEntity<WVPResult<List<PlatformCatalog>>> editCatalog(@RequestBody PlatformCatalog platformCatalog) {
482 504
483 if (logger.isDebugEnabled()) { 505 if (logger.isDebugEnabled()) {
484 logger.debug("编辑目录,{}", JSON.toJSONString(platformCatalog)); 506 logger.debug("编辑目录,{}", JSON.toJSONString(platformCatalog));
@@ -488,14 +510,14 @@ public class PlatformController { @@ -488,14 +510,14 @@ public class PlatformController {
488 result.setCode(0); 510 result.setCode(0);
489 511
490 if (platformCatalogInStore == null) { 512 if (platformCatalogInStore == null) {
491 - result.setMsg( platformCatalog.getId() + " not exists"); 513 + result.setMsg(platformCatalog.getId() + " not exists");
492 return new ResponseEntity<>(result, HttpStatus.OK); 514 return new ResponseEntity<>(result, HttpStatus.OK);
493 } 515 }
494 int addResult = storager.updateCatalog(platformCatalog); 516 int addResult = storager.updateCatalog(platformCatalog);
495 if (addResult > 0) { 517 if (addResult > 0) {
496 result.setMsg("success"); 518 result.setMsg("success");
497 return new ResponseEntity<>(result, HttpStatus.OK); 519 return new ResponseEntity<>(result, HttpStatus.OK);
498 - }else { 520 + } else {
499 result.setMsg("save error"); 521 result.setMsg("save error");
500 return new ResponseEntity<>(result, HttpStatus.OK); 522 return new ResponseEntity<>(result, HttpStatus.OK);
501 } 523 }
@@ -503,6 +525,7 @@ public class PlatformController { @@ -503,6 +525,7 @@ public class PlatformController {
503 525
504 /** 526 /**
505 * 删除目录 527 * 删除目录
  528 + *
506 * @param id 目录Id 529 * @param id 目录Id
507 * @return 530 * @return
508 */ 531 */
@@ -512,7 +535,7 @@ public class PlatformController { @@ -512,7 +535,7 @@ public class PlatformController {
512 }) 535 })
513 @DeleteMapping("/catalog/del") 536 @DeleteMapping("/catalog/del")
514 @ResponseBody 537 @ResponseBody
515 - public ResponseEntity<WVPResult<String>> delCatalog(String id, String platformId){ 538 + public ResponseEntity<WVPResult<String>> delCatalog(String id, String platformId) {
516 539
517 if (logger.isDebugEnabled()) { 540 if (logger.isDebugEnabled()) {
518 logger.debug("删除目录,{}", id); 541 logger.debug("删除目录,{}", id);
@@ -540,7 +563,7 @@ public class PlatformController { @@ -540,7 +563,7 @@ public class PlatformController {
540 if (delResult > 0) { 563 if (delResult > 0) {
541 result.setMsg("success"); 564 result.setMsg("success");
542 return new ResponseEntity<>(result, HttpStatus.OK); 565 return new ResponseEntity<>(result, HttpStatus.OK);
543 - }else { 566 + } else {
544 result.setMsg("save error"); 567 result.setMsg("save error");
545 return new ResponseEntity<>(result, HttpStatus.OK); 568 return new ResponseEntity<>(result, HttpStatus.OK);
546 } 569 }
@@ -548,6 +571,7 @@ public class PlatformController { @@ -548,6 +571,7 @@ public class PlatformController {
548 571
549 /** 572 /**
550 * 删除关联 573 * 删除关联
  574 + *
551 * @param platformCatalog 关联的信息 575 * @param platformCatalog 关联的信息
552 * @return 576 * @return
553 */ 577 */
@@ -557,7 +581,7 @@ public class PlatformController { @@ -557,7 +581,7 @@ public class PlatformController {
557 }) 581 })
558 @DeleteMapping("/catalog/relation/del") 582 @DeleteMapping("/catalog/relation/del")
559 @ResponseBody 583 @ResponseBody
560 - public ResponseEntity<WVPResult<List<PlatformCatalog>>> delRelation(@RequestBody PlatformCatalog platformCatalog){ 584 + public ResponseEntity<WVPResult<List<PlatformCatalog>>> delRelation(@RequestBody PlatformCatalog platformCatalog) {
561 585
562 if (logger.isDebugEnabled()) { 586 if (logger.isDebugEnabled()) {
563 logger.debug("删除关联,{}", JSON.toJSONString(platformCatalog)); 587 logger.debug("删除关联,{}", JSON.toJSONString(platformCatalog));
@@ -569,7 +593,7 @@ public class PlatformController { @@ -569,7 +593,7 @@ public class PlatformController {
569 if (delResult > 0) { 593 if (delResult > 0) {
570 result.setMsg("success"); 594 result.setMsg("success");
571 return new ResponseEntity<>(result, HttpStatus.OK); 595 return new ResponseEntity<>(result, HttpStatus.OK);
572 - }else { 596 + } else {
573 result.setMsg("save error"); 597 result.setMsg("save error");
574 return new ResponseEntity<>(result, HttpStatus.OK); 598 return new ResponseEntity<>(result, HttpStatus.OK);
575 } 599 }
@@ -578,8 +602,9 @@ public class PlatformController { @@ -578,8 +602,9 @@ public class PlatformController {
578 602
579 /** 603 /**
580 * 修改默认目录 604 * 修改默认目录
  605 + *
581 * @param platformId 平台Id 606 * @param platformId 平台Id
582 - * @param catalogId 目录Id 607 + * @param catalogId 目录Id
583 * @return 608 * @return
584 */ 609 */
585 @ApiOperation("修改默认目录") 610 @ApiOperation("修改默认目录")
@@ -589,7 +614,7 @@ public class PlatformController { @@ -589,7 +614,7 @@ public class PlatformController {
589 }) 614 })
590 @PostMapping("/catalog/default/update") 615 @PostMapping("/catalog/default/update")
591 @ResponseBody 616 @ResponseBody
592 - public ResponseEntity<WVPResult<String>> setDefaultCatalog(String platformId, String catalogId){ 617 + public ResponseEntity<WVPResult<String>> setDefaultCatalog(String platformId, String catalogId) {
593 618
594 if (logger.isDebugEnabled()) { 619 if (logger.isDebugEnabled()) {
595 logger.debug("修改默认目录,{},{}", platformId, catalogId); 620 logger.debug("修改默认目录,{},{}", platformId, catalogId);
@@ -601,7 +626,7 @@ public class PlatformController { @@ -601,7 +626,7 @@ public class PlatformController {
601 if (updateResult > 0) { 626 if (updateResult > 0) {
602 result.setMsg("success"); 627 result.setMsg("success");
603 return new ResponseEntity<>(result, HttpStatus.OK); 628 return new ResponseEntity<>(result, HttpStatus.OK);
604 - }else { 629 + } else {
605 result.setMsg("save error"); 630 result.setMsg("save error");
606 return new ResponseEntity<>(result, HttpStatus.OK); 631 return new ResponseEntity<>(result, HttpStatus.OK);
607 } 632 }
src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/play/PlayController.java
@@ -88,7 +88,7 @@ public class PlayController { @@ -88,7 +88,7 @@ public class PlayController {
88 // 获取可用的zlm 88 // 获取可用的zlm
89 Device device = storager.queryVideoDevice(deviceId); 89 Device device = storager.queryVideoDevice(deviceId);
90 MediaServerItem newMediaServerItem = playService.getNewMediaServerItem(device); 90 MediaServerItem newMediaServerItem = playService.getNewMediaServerItem(device);
91 - PlayResult playResult = playService.play(newMediaServerItem, deviceId, channelId, null, null); 91 + PlayResult playResult = playService.play(newMediaServerItem, deviceId, channelId, null, null, null);
92 92
93 return playResult.getResult(); 93 return playResult.getResult();
94 } 94 }
src/main/java/com/genersoft/iot/vmp/web/gb28181/ApiStreamController.java
@@ -150,7 +150,7 @@ public class ApiStreamController { @@ -150,7 +150,7 @@ public class ApiStreamController {
150 JSONObject result = new JSONObject(); 150 JSONObject result = new JSONObject();
151 result.put("error", "channel[ " + code + " ] " + eventResult.msg); 151 result.put("error", "channel[ " + code + " ] " + eventResult.msg);
152 resultDeferredResult.setResult(result); 152 resultDeferredResult.setResult(result);
153 - }); 153 + }, null);
154 return resultDeferredResult; 154 return resultDeferredResult;
155 } 155 }
156 156
src/main/resources/all-application.yml
@@ -170,8 +170,6 @@ user-settings: @@ -170,8 +170,6 @@ user-settings:
170 save-position-history: false 170 save-position-history: false
171 # 点播等待超时时间,单位:毫秒 171 # 点播等待超时时间,单位:毫秒
172 play-timeout: 3000 172 play-timeout: 3000
173 - # 等待音视频编码信息再返回, true: 可以根据编码选择合适的播放器,false: 可以更快点播  
174 - wait-track: false  
175 # 是否开启接口鉴权 173 # 是否开启接口鉴权
176 interface-authentication: true 174 interface-authentication: true
177 # 自动配置redis 可以过期事件 175 # 自动配置redis 可以过期事件
src/main/resources/application-dev.yml
@@ -13,7 +13,7 @@ spring: @@ -13,7 +13,7 @@ spring:
13 # [可选] 数据库 DB 13 # [可选] 数据库 DB
14 database: 6 14 database: 6
15 # [可选] 访问密码,若你的redis服务器没有设置密码,就不需要用密码去连接 15 # [可选] 访问密码,若你的redis服务器没有设置密码,就不需要用密码去连接
16 - password: 16 + password: face2020
17 # [可选] 超时时间 17 # [可选] 超时时间
18 timeout: 10000 18 timeout: 10000
19 # [可选] jdbc数据库配置, 项目使用sqlite作为数据库,一般不需要配置 19 # [可选] jdbc数据库配置, 项目使用sqlite作为数据库,一般不需要配置
@@ -23,7 +23,7 @@ spring: @@ -23,7 +23,7 @@ spring:
23 driver-class-name: com.mysql.cj.jdbc.Driver 23 driver-class-name: com.mysql.cj.jdbc.Driver
24 url: jdbc:mysql://127.0.0.1:3306/wvp?useUnicode=true&characterEncoding=UTF8&rewriteBatchedStatements=true&serverTimezone=PRC&useSSL=false 24 url: jdbc:mysql://127.0.0.1:3306/wvp?useUnicode=true&characterEncoding=UTF8&rewriteBatchedStatements=true&serverTimezone=PRC&useSSL=false
25 username: root 25 username: root
26 - password: root123 26 + password: 123456
27 druid: 27 druid:
28 initialSize: 10 # 连接池初始化连接数 28 initialSize: 10 # 连接池初始化连接数
29 maxActive: 200 # 连接池最大连接数 29 maxActive: 200 # 连接池最大连接数
@@ -50,7 +50,7 @@ server: @@ -50,7 +50,7 @@ server:
50 # 作为28181服务器的配置 50 # 作为28181服务器的配置
51 sip: 51 sip:
52 # [必须修改] 本机的IP 52 # [必须修改] 本机的IP
53 - ip: 192.168.118.70 53 + ip: 192.168.41.16
54 # [可选] 28181服务监听的端口 54 # [可选] 28181服务监听的端口
55 port: 5060 55 port: 5060
56 # 根据国标6.1.2中规定,domain宜采用ID统一编码的前十位编码。国标附录D中定义前8位为中心编码(由省级、市级、区级、基层编号组成,参照GB/T 2260-2007) 56 # 根据国标6.1.2中规定,domain宜采用ID统一编码的前十位编码。国标附录D中定义前8位为中心编码(由省级、市级、区级、基层编号组成,参照GB/T 2260-2007)
@@ -67,9 +67,9 @@ sip: @@ -67,9 +67,9 @@ sip:
67 media: 67 media:
68 id: FQ3TF8yT83wh5Wvz 68 id: FQ3TF8yT83wh5Wvz
69 # [必须修改] zlm服务器的内网IP 69 # [必须修改] zlm服务器的内网IP
70 - ip: 192.168.118.70 70 + ip: 192.168.41.16
71 # [必须修改] zlm服务器的http.port 71 # [必须修改] zlm服务器的http.port
72 - http-port: 80 72 + http-port: 8091
73 # [可选] zlm服务器的hook.admin_params=secret 73 # [可选] zlm服务器的hook.admin_params=secret
74 secret: 035c73f7-bb6b-4889-a715-d9eb2d1925cc 74 secret: 035c73f7-bb6b-4889-a715-d9eb2d1925cc
75 # 启用多端口模式, 多端口模式使用端口区分每路流,兼容性更好。 单端口使用流的ssrc区分, 点播超时建议使用多端口测试 75 # 启用多端口模式, 多端口模式使用端口区分每路流,兼容性更好。 单端口使用流的ssrc区分, 点播超时建议使用多端口测试