Commit bf7ab3fe2ba246208d729901c33a9402209ee26a

Authored by songww
1 parent ab45f1a1

优化代码结构,提供NVR录像检索接口

src/main/java/com/genersoft/iot/vmp/conf/RedisConfig.java
@@ -12,20 +12,19 @@ import com.alibaba.fastjson.parser.ParserConfig; @@ -12,20 +12,19 @@ import com.alibaba.fastjson.parser.ParserConfig;
12 import com.genersoft.iot.vmp.utils.redis.FastJsonRedisSerializer; 12 import com.genersoft.iot.vmp.utils.redis.FastJsonRedisSerializer;
13 13
14 /** 14 /**
15 - * @Description:Redis中间件配置类 15 + * @Description:Redis中间件配置类,使用spring-data-redis集成,自动从application.yml中加载redis配置
16 * @author: songww 16 * @author: songww
17 * @date: 2019年5月30日 上午10:58:25 17 * @date: 2019年5月30日 上午10:58:25
18 * 18 *
19 */ 19 */
20 @Configuration 20 @Configuration
21 -// @EnableCaching  
22 public class RedisConfig extends CachingConfigurerSupport { 21 public class RedisConfig extends CachingConfigurerSupport {
23 22
24 @Bean("redisTemplate") 23 @Bean("redisTemplate")
25 public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) { 24 public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
26 RedisTemplate<Object, Object> template = new RedisTemplate<>(); 25 RedisTemplate<Object, Object> template = new RedisTemplate<>();
27 template.setConnectionFactory(redisConnectionFactory); 26 template.setConnectionFactory(redisConnectionFactory);
28 - ParserConfig.getGlobalInstance().setAutoTypeSupport(true); 27 + // 使用fastjson进行序列化处理,提高解析效率
29 FastJsonRedisSerializer<Object> serializer = new FastJsonRedisSerializer<Object>(Object.class); 28 FastJsonRedisSerializer<Object> serializer = new FastJsonRedisSerializer<Object>(Object.class);
30 // value值的序列化采用fastJsonRedisSerializer 29 // value值的序列化采用fastJsonRedisSerializer
31 template.setValueSerializer(serializer); 30 template.setValueSerializer(serializer);
@@ -33,8 +32,9 @@ public class RedisConfig extends CachingConfigurerSupport { @@ -33,8 +32,9 @@ public class RedisConfig extends CachingConfigurerSupport {
33 // key的序列化采用StringRedisSerializer 32 // key的序列化采用StringRedisSerializer
34 template.setKeySerializer(new StringRedisSerializer()); 33 template.setKeySerializer(new StringRedisSerializer());
35 template.setHashKeySerializer(new StringRedisSerializer()); 34 template.setHashKeySerializer(new StringRedisSerializer());
36 -  
37 template.setConnectionFactory(redisConnectionFactory); 35 template.setConnectionFactory(redisConnectionFactory);
  36 + // 使用fastjson时需设置此项,否则会报异常not support type
  37 + ParserConfig.getGlobalInstance().setAutoTypeSupport(true);
38 return template; 38 return template;
39 } 39 }
40 40
@@ -53,27 +53,5 @@ public class RedisConfig extends CachingConfigurerSupport { @@ -53,27 +53,5 @@ public class RedisConfig extends CachingConfigurerSupport {
53 container.setConnectionFactory(connectionFactory); 53 container.setConnectionFactory(connectionFactory);
54 return container; 54 return container;
55 } 55 }
56 -// @Bean  
57 -// RedisMessageListenerContainer container(RedisConnectionFactory connectionFactory,  
58 -// MessageListenerAdapter listenerAdapter) {  
59 -//  
60 -// RedisMessageListenerContainer container = new RedisMessageListenerContainer();  
61 -// container.setConnectionFactory(connectionFactory);  
62 -// // 订阅了一个叫通道  
63 -// container.addMessageListener(listenerAdapter, new PatternTopic(VideoManagerConstants.KEEPLIVEKEY_PREFIX+"*"));  
64 -// // 这个container 可以添加多个 messageListener  
65 -// return container;  
66 -// }  
67 -  
68 -// /**  
69 -// * 消息监听器适配器,绑定消息处理器,利用反射技术调用消息处理器的业务方法  
70 -// * @param receiver  
71 -// * @return  
72 -// */  
73 -// @Bean  
74 -// MessageListenerAdapter listenerAdapter(MessageReceiver receiver) {  
75 -// //这个地方 是给messageListenerAdapter 传入一个消息接受的处理器,利用反射的方法调用“receiveMessage”  
76 -// //也有好几个重载方法,这边默认调用处理器的方法 叫handleMessage 可以自己到源码里面看  
77 -// return new MessageListenerAdapter(receiver, "receiveMessage");  
78 -// } 56 +
79 } 57 }
src/main/java/com/genersoft/iot/vmp/conf/SipConfig.java
@@ -16,7 +16,6 @@ public class SipConfig { @@ -16,7 +16,6 @@ public class SipConfig {
16 String sipPassword; 16 String sipPassword;
17 @Value("${media.ip}") 17 @Value("${media.ip}")
18 String mediaIp; 18 String mediaIp;
19 -  
20 @Value("${media.port}") 19 @Value("${media.port}")
21 Integer mediaPort; 20 Integer mediaPort;
22 21
src/main/java/com/genersoft/iot/vmp/gb28181/SipLayer.java
@@ -2,6 +2,7 @@ package com.genersoft.iot.vmp.gb28181; @@ -2,6 +2,7 @@ package com.genersoft.iot.vmp.gb28181;
2 2
3 import java.util.Properties; 3 import java.util.Properties;
4 4
  5 +import javax.annotation.PostConstruct;
5 import javax.sip.DialogTerminatedEvent; 6 import javax.sip.DialogTerminatedEvent;
6 import javax.sip.IOExceptionEvent; 7 import javax.sip.IOExceptionEvent;
7 import javax.sip.ListeningPoint; 8 import javax.sip.ListeningPoint;
@@ -26,7 +27,6 @@ import javax.sip.message.Response; @@ -26,7 +27,6 @@ import javax.sip.message.Response;
26 import org.slf4j.Logger; 27 import org.slf4j.Logger;
27 import org.slf4j.LoggerFactory; 28 import org.slf4j.LoggerFactory;
28 import org.springframework.beans.factory.annotation.Autowired; 29 import org.springframework.beans.factory.annotation.Autowired;
29 -import org.springframework.context.annotation.Bean;  
30 import org.springframework.stereotype.Component; 30 import org.springframework.stereotype.Component;
31 31
32 import com.genersoft.iot.vmp.conf.SipConfig; 32 import com.genersoft.iot.vmp.conf.SipConfig;
@@ -37,70 +37,78 @@ import com.genersoft.iot.vmp.gb28181.transmit.response.ISIPResponseProcessor; @@ -37,70 +37,78 @@ import com.genersoft.iot.vmp.gb28181.transmit.response.ISIPResponseProcessor;
37 import gov.nist.javax.sip.SipStackImpl; 37 import gov.nist.javax.sip.SipStackImpl;
38 38
39 @Component 39 @Component
40 -public class SipLayer implements SipListener{  
41 - 40 +public class SipLayer implements SipListener, Runnable {
  41 +
42 private final static Logger logger = LoggerFactory.getLogger(SipLayer.class); 42 private final static Logger logger = LoggerFactory.getLogger(SipLayer.class);
43 - 43 +
44 @Autowired 44 @Autowired
45 private SipConfig config; 45 private SipConfig config;
46 - 46 +
47 private SipProvider tcpSipProvider; 47 private SipProvider tcpSipProvider;
48 - 48 +
49 private SipProvider udpSipProvider; 49 private SipProvider udpSipProvider;
50 - 50 +
51 @Autowired 51 @Autowired
52 private SIPProcessorFactory processorFactory; 52 private SIPProcessorFactory processorFactory;
53 - 53 +
54 private SipStack sipStack; 54 private SipStack sipStack;
55 - 55 +
56 private AddressFactory addressFactory; 56 private AddressFactory addressFactory;
57 private HeaderFactory headerFactory; 57 private HeaderFactory headerFactory;
58 private MessageFactory messageFactory; 58 private MessageFactory messageFactory;
59 59
60 - @Bean  
61 - private boolean initSipServer() throws Exception { 60 + @PostConstruct
  61 + private void initSipServer() {
  62 + Thread thread=new Thread(this);
  63 + thread.setDaemon(true);
  64 + thread.setName("sip server thread start");
  65 + thread.start();
  66 + }
  67 +
  68 + @Override
  69 + public void run() {
62 SipFactory sipFactory = SipFactory.getInstance(); 70 SipFactory sipFactory = SipFactory.getInstance();
63 sipFactory.setPathName("gov.nist"); 71 sipFactory.setPathName("gov.nist");
64 - headerFactory = sipFactory.createHeaderFactory();  
65 - addressFactory = sipFactory.createAddressFactory();  
66 - messageFactory = sipFactory.createMessageFactory();  
67 -  
68 - Properties properties = new Properties();  
69 - properties.setProperty("javax.sip.STACK_NAME", "GB28181_SIP");  
70 - properties.setProperty("javax.sip.IP_ADDRESS", config.getSipIp());  
71 - /**  
72 - * sip_server_log.log 和 sip_debug_log.log public static final int TRACE_NONE =  
73 - * 0; public static final int TRACE_MESSAGES = 16; public static final int  
74 - * TRACE_EXCEPTION = 17; public static final int TRACE_DEBUG = 32;  
75 - */  
76 - properties.setProperty("gov.nist.javax.sip.TRACE_LEVEL", "16");  
77 - properties.setProperty("gov.nist.javax.sip.SERVER_LOG", "sip_server_log");  
78 - properties.setProperty("gov.nist.javax.sip.DEBUG_LOG", "sip_debug_log");  
79 - sipStack = (SipStackImpl) sipFactory.createSipStack(properties);  
80 -  
81 try { 72 try {
  73 + headerFactory = sipFactory.createHeaderFactory();
  74 +
  75 + addressFactory = sipFactory.createAddressFactory();
  76 + messageFactory = sipFactory.createMessageFactory();
  77 +
  78 + Properties properties = new Properties();
  79 + properties.setProperty("javax.sip.STACK_NAME", "GB28181_SIP");
  80 + properties.setProperty("javax.sip.IP_ADDRESS", config.getSipIp());
  81 + properties.setProperty("gov.nist.javax.sip.LOG_MESSAGE_CONTENT", "false");
  82 + /**
  83 + * sip_server_log.log 和 sip_debug_log.log public static final int TRACE_NONE =
  84 + * 0; public static final int TRACE_MESSAGES = 16; public static final int
  85 + * TRACE_EXCEPTION = 17; public static final int TRACE_DEBUG = 32;
  86 + */
  87 + properties.setProperty("gov.nist.javax.sip.TRACE_LEVEL", "0");
  88 + properties.setProperty("gov.nist.javax.sip.SERVER_LOG", "sip_server_log");
  89 + properties.setProperty("gov.nist.javax.sip.DEBUG_LOG", "sip_debug_log");
  90 + sipStack = (SipStackImpl) sipFactory.createSipStack(properties);
  91 +
82 startTcpListener(); 92 startTcpListener();
83 startUdpListener(); 93 startUdpListener();
84 } catch (Exception e) { 94 } catch (Exception e) {
85 - logger.error("Sip Server 启动失败! port {"+config.getSipPort()+"}"); 95 + logger.error("Sip Server 启动失败! port {" + config.getSipPort() + "}");
86 e.printStackTrace(); 96 e.printStackTrace();
87 - throw e;  
88 } 97 }
89 - logger.info("Sip Server 启动成功 port {"+config.getSipPort()+"}");  
90 - return true; 98 + logger.info("Sip Server 启动成功 port {" + config.getSipPort() + "}");
91 } 99 }
92 - 100 +
93 private void startTcpListener() throws Exception { 101 private void startTcpListener() throws Exception {
94 ListeningPoint tcpListeningPoint = sipStack.createListeningPoint(config.getSipIp(), config.getSipPort(), "TCP"); 102 ListeningPoint tcpListeningPoint = sipStack.createListeningPoint(config.getSipIp(), config.getSipPort(), "TCP");
95 tcpSipProvider = sipStack.createSipProvider(tcpListeningPoint); 103 tcpSipProvider = sipStack.createSipProvider(tcpListeningPoint);
96 tcpSipProvider.addSipListener(this); 104 tcpSipProvider.addSipListener(this);
97 - }  
98 -  
99 - private void startUdpListener() throws Exception { 105 + }
  106 +
  107 + private void startUdpListener() throws Exception {
100 ListeningPoint udpListeningPoint = sipStack.createListeningPoint(config.getSipIp(), config.getSipPort(), "UDP"); 108 ListeningPoint udpListeningPoint = sipStack.createListeningPoint(config.getSipIp(), config.getSipPort(), "UDP");
101 udpSipProvider = sipStack.createSipProvider(udpListeningPoint); 109 udpSipProvider = sipStack.createSipProvider(udpListeningPoint);
102 udpSipProvider.addSipListener(this); 110 udpSipProvider.addSipListener(this);
103 - } 111 + }
104 112
105 /** 113 /**
106 * SIP服务端接收消息的方法 Content 里面是GBK编码 This method is called by the SIP stack when a 114 * SIP服务端接收消息的方法 Content 里面是GBK编码 This method is called by the SIP stack when a
@@ -118,60 +126,80 @@ public class SipLayer implements SipListener{ @@ -118,60 +126,80 @@ public class SipLayer implements SipListener{
118 int status = response.getStatusCode(); 126 int status = response.getStatusCode();
119 if ((status >= 200) && (status < 300)) { // Success! 127 if ((status >= 200) && (status < 300)) { // Success!
120 ISIPResponseProcessor processor = processorFactory.createResponseProcessor(evt); 128 ISIPResponseProcessor processor = processorFactory.createResponseProcessor(evt);
121 - processor.process(evt,this,config); 129 + processor.process(evt, this, config);
122 } else { 130 } else {
123 - logger.warn("接收到失败的response响应!status:"+status+",message:"+response.getContent().toString()); 131 + logger.warn("接收到失败的response响应!status:" + status + ",message:" + response.getContent().toString());
124 } 132 }
125 - //trying不会回复  
126 - if(status == Response.TRYING){ 133 + // trying不会回复
  134 + if (status == Response.TRYING) {
127 135
128 } 136 }
129 } 137 }
130 138
131 - /**  
132 - * <p>Title: processTimeout</p>  
133 - * <p>Description: </p>  
134 - * @param timeoutEvent  
135 - */ 139 + /**
  140 + * <p>
  141 + * Title: processTimeout
  142 + * </p>
  143 + * <p>
  144 + * Description:
  145 + * </p>
  146 + *
  147 + * @param timeoutEvent
  148 + */
136 @Override 149 @Override
137 public void processTimeout(TimeoutEvent timeoutEvent) { 150 public void processTimeout(TimeoutEvent timeoutEvent) {
138 // TODO Auto-generated method stub 151 // TODO Auto-generated method stub
139 - 152 +
140 } 153 }
141 154
142 - /**  
143 - * <p>Title: processIOException</p>  
144 - * <p>Description: </p>  
145 - * @param exceptionEvent  
146 - */ 155 + /**
  156 + * <p>
  157 + * Title: processIOException
  158 + * </p>
  159 + * <p>
  160 + * Description:
  161 + * </p>
  162 + *
  163 + * @param exceptionEvent
  164 + */
147 @Override 165 @Override
148 public void processIOException(IOExceptionEvent exceptionEvent) { 166 public void processIOException(IOExceptionEvent exceptionEvent) {
149 // TODO Auto-generated method stub 167 // TODO Auto-generated method stub
150 - 168 +
151 } 169 }
152 170
153 - /**  
154 - * <p>Title: processTransactionTerminated</p>  
155 - * <p>Description: </p>  
156 - * @param transactionTerminatedEvent  
157 - */ 171 + /**
  172 + * <p>
  173 + * Title: processTransactionTerminated
  174 + * </p>
  175 + * <p>
  176 + * Description:
  177 + * </p>
  178 + *
  179 + * @param transactionTerminatedEvent
  180 + */
158 @Override 181 @Override
159 public void processTransactionTerminated(TransactionTerminatedEvent transactionTerminatedEvent) { 182 public void processTransactionTerminated(TransactionTerminatedEvent transactionTerminatedEvent) {
160 // TODO Auto-generated method stub 183 // TODO Auto-generated method stub
161 - 184 +
162 } 185 }
163 186
164 - /**  
165 - * <p>Title: processDialogTerminated</p>  
166 - * <p>Description: </p>  
167 - * @param dialogTerminatedEvent  
168 - */ 187 + /**
  188 + * <p>
  189 + * Title: processDialogTerminated
  190 + * </p>
  191 + * <p>
  192 + * Description:
  193 + * </p>
  194 + *
  195 + * @param dialogTerminatedEvent
  196 + */
169 @Override 197 @Override
170 public void processDialogTerminated(DialogTerminatedEvent dialogTerminatedEvent) { 198 public void processDialogTerminated(DialogTerminatedEvent dialogTerminatedEvent) {
171 // TODO Auto-generated method stub 199 // TODO Auto-generated method stub
172 - 200 +
173 } 201 }
174 - 202 +
175 private ServerTransaction getServerTransaction(RequestEvent evt) { 203 private ServerTransaction getServerTransaction(RequestEvent evt) {
176 Request request = evt.getRequest(); 204 Request request = evt.getRequest();
177 ServerTransaction serverTransaction = evt.getServerTransaction(); 205 ServerTransaction serverTransaction = evt.getServerTransaction();
@@ -185,11 +213,11 @@ public class SipLayer implements SipListener{ @@ -185,11 +213,11 @@ public class SipLayer implements SipListener{
185 213
186 if (serverTransaction == null) { 214 if (serverTransaction == null) {
187 try { 215 try {
188 - if (isTcp) {  
189 - serverTransaction = tcpSipProvider.getNewServerTransaction(request);  
190 - } else {  
191 - serverTransaction = udpSipProvider.getNewServerTransaction(request);  
192 - } 216 + if (isTcp) {
  217 + serverTransaction = tcpSipProvider.getNewServerTransaction(request);
  218 + } else {
  219 + serverTransaction = udpSipProvider.getNewServerTransaction(request);
  220 + }
193 } catch (TransactionAlreadyExistsException e) { 221 } catch (TransactionAlreadyExistsException e) {
194 e.printStackTrace(); 222 e.printStackTrace();
195 } catch (TransactionUnavailableException e) { 223 } catch (TransactionUnavailableException e) {
@@ -199,7 +227,6 @@ public class SipLayer implements SipListener{ @@ -199,7 +227,6 @@ public class SipLayer implements SipListener{
199 return serverTransaction; 227 return serverTransaction;
200 } 228 }
201 229
202 -  
203 public AddressFactory getAddressFactory() { 230 public AddressFactory getAddressFactory() {
204 return addressFactory; 231 return addressFactory;
205 } 232 }
@@ -219,5 +246,5 @@ public class SipLayer implements SipListener{ @@ -219,5 +246,5 @@ public class SipLayer implements SipListener{
219 public SipProvider getUdpSipProvider() { 246 public SipProvider getUdpSipProvider() {
220 return udpSipProvider; 247 return udpSipProvider;
221 } 248 }
222 - 249 +
223 } 250 }
src/main/java/com/genersoft/iot/vmp/gb28181/auth/RegisterLogicHandler.java 0 → 100644
  1 +package com.genersoft.iot.vmp.gb28181.auth;
  2 +
  3 +import org.springframework.beans.factory.annotation.Autowired;
  4 +import org.springframework.stereotype.Component;
  5 +
  6 +import com.genersoft.iot.vmp.gb28181.bean.Device;
  7 +import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander;
  8 +
  9 +/**
  10 + * @Description:注册逻辑处理,当设备注册后触发逻辑。
  11 + * @author: songww
  12 + * @date: 2020年5月8日 下午9:41:46
  13 + */
  14 +@Component
  15 +public class RegisterLogicHandler {
  16 +
  17 + @Autowired
  18 + private SIPCommander cmder;
  19 +
  20 + public void onRegister(Device device) {
  21 + // TODO 后续处理,只有第一次注册时调用查询设备信息,如需更新调用更新API接口
  22 + cmder.deviceInfoQuery(device);
  23 +
  24 + cmder.catalogQuery(device);
  25 + }
  26 +}
src/main/java/com/genersoft/iot/vmp/gb28181/bean/RecordInfo.java 0 → 100644
  1 +package com.genersoft.iot.vmp.gb28181.bean;
  2 +
  3 +import java.util.List;
  4 +
  5 +/**
  6 + * @Description:设备录像信息bean
  7 + * @author: songww
  8 + * @date: 2020年5月8日 下午2:05:56
  9 + */
  10 +public class RecordInfo {
  11 +
  12 + private String deviceId;
  13 +
  14 + private String name;
  15 +
  16 + private int sumNum;
  17 +
  18 + private List<RecordItem> recordList;
  19 +
  20 + public String getDeviceId() {
  21 + return deviceId;
  22 + }
  23 +
  24 + public void setDeviceId(String deviceId) {
  25 + this.deviceId = deviceId;
  26 + }
  27 +
  28 + public String getName() {
  29 + return name;
  30 + }
  31 +
  32 + public void setName(String name) {
  33 + this.name = name;
  34 + }
  35 +
  36 + public int getSumNum() {
  37 + return sumNum;
  38 + }
  39 +
  40 + public void setSumNum(int sumNum) {
  41 + this.sumNum = sumNum;
  42 + }
  43 +
  44 + public List<RecordItem> getRecordList() {
  45 + return recordList;
  46 + }
  47 +
  48 + public void setRecordList(List<RecordItem> recordList) {
  49 + this.recordList = recordList;
  50 + }
  51 +}
src/main/java/com/genersoft/iot/vmp/gb28181/bean/RecordItem.java 0 → 100644
  1 +package com.genersoft.iot.vmp.gb28181.bean;
  2 +
  3 +/**
  4 + * @Description:设备录像bean
  5 + * @author: songww
  6 + * @date: 2020年5月8日 下午2:06:54
  7 + */
  8 +public class RecordItem {
  9 +
  10 + private String deviceId;
  11 +
  12 + private String name;
  13 +
  14 + private String filePath;
  15 +
  16 + private String address;
  17 +
  18 + private String startTime;
  19 +
  20 + private String endTime;
  21 +
  22 + private int secrecy;
  23 +
  24 + private String type;
  25 +
  26 + private String recordId;
  27 +
  28 + public String getDeviceId() {
  29 + return deviceId;
  30 + }
  31 +
  32 + public void setDeviceId(String deviceId) {
  33 + this.deviceId = deviceId;
  34 + }
  35 +
  36 + public String getName() {
  37 + return name;
  38 + }
  39 +
  40 + public void setName(String name) {
  41 + this.name = name;
  42 + }
  43 +
  44 + public String getFilePath() {
  45 + return filePath;
  46 + }
  47 +
  48 + public void setFilePath(String filePath) {
  49 + this.filePath = filePath;
  50 + }
  51 +
  52 + public String getAddress() {
  53 + return address;
  54 + }
  55 +
  56 + public void setAddress(String address) {
  57 + this.address = address;
  58 + }
  59 +
  60 + public String getStartTime() {
  61 + return startTime;
  62 + }
  63 +
  64 + public void setStartTime(String startTime) {
  65 + this.startTime = startTime;
  66 + }
  67 +
  68 + public int getSecrecy() {
  69 + return secrecy;
  70 + }
  71 +
  72 + public void setSecrecy(int secrecy) {
  73 + this.secrecy = secrecy;
  74 + }
  75 +
  76 + public String getType() {
  77 + return type;
  78 + }
  79 +
  80 + public void setType(String type) {
  81 + this.type = type;
  82 + }
  83 +
  84 + public String getRecordId() {
  85 + return recordId;
  86 + }
  87 +
  88 + public void setRecordId(String recordId) {
  89 + this.recordId = recordId;
  90 + }
  91 +
  92 + public String getEndTime() {
  93 + return endTime;
  94 + }
  95 +
  96 + public void setEndTime(String endTime) {
  97 + this.endTime = endTime;
  98 + }
  99 +}
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/callback/DeferredResultHolder.java 0 → 100644
  1 +package com.genersoft.iot.vmp.gb28181.transmit.callback;
  2 +
  3 +import java.util.HashMap;
  4 +import java.util.Map;
  5 +
  6 +import org.springframework.http.HttpStatus;
  7 +import org.springframework.http.ResponseEntity;
  8 +import org.springframework.stereotype.Component;
  9 +import org.springframework.web.context.request.async.DeferredResult;
  10 +
  11 +/**
  12 + * @Description:TODO(这里用一句话描述这个类的作用)
  13 + * @author: songww
  14 + * @date: 2020年5月8日 下午7:59:05
  15 + */
  16 +@Component
  17 +public class DeferredResultHolder {
  18 +
  19 + public static final String CALLBACK_CMD_DEVICEINFO = "CALLBACK_DEVICEINFO";
  20 +
  21 + public static final String CALLBACK_CMD_CATALOG = "CALLBACK_CATALOG";
  22 +
  23 + public static final String CALLBACK_CMD_RECORDINFO = "CALLBACK_RECORDINFO";
  24 +
  25 + private Map<String, DeferredResult> map = new HashMap<String, DeferredResult>();
  26 +
  27 + public void put(String key, DeferredResult result) {
  28 + map.put(key, result);
  29 + }
  30 +
  31 + public DeferredResult get(String key) {
  32 + return map.get(key);
  33 + }
  34 +
  35 + public void invokeResult(RequestMessage msg) {
  36 + DeferredResult result = map.get(msg.getId());
  37 + if (result == null) {
  38 + return;
  39 + }
  40 + result.setResult(new ResponseEntity<>(msg.getData(),HttpStatus.OK));
  41 + }
  42 +}
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/callback/RequestMessage.java 0 → 100644
  1 +package com.genersoft.iot.vmp.gb28181.transmit.callback;
  2 +
  3 +/**
  4 + * @Description:TODO(这里用一句话描述这个类的作用)
  5 + * @author: songww
  6 + * @date: 2020年5月8日 下午1:09:18
  7 + */
  8 +public class RequestMessage {
  9 +
  10 + private String id;
  11 +
  12 + private String deviceId;
  13 +
  14 + private String type;
  15 +
  16 + private Object data;
  17 +
  18 + public String getId() {
  19 + return id;
  20 + }
  21 +
  22 + public void setId(String id) {
  23 + this.id = id;
  24 + }
  25 +
  26 + public String getDeviceId() {
  27 + return deviceId;
  28 + }
  29 +
  30 + public void setDeviceId(String deviceId) {
  31 + this.deviceId = deviceId;
  32 + this.id = type + deviceId;
  33 + }
  34 +
  35 + public String getType() {
  36 + return type;
  37 + }
  38 +
  39 + public void setType(String type) {
  40 + this.type = type;
  41 + this.id = type + deviceId;
  42 + }
  43 +
  44 + public Object getData() {
  45 + return data;
  46 + }
  47 +
  48 + public void setData(Object data) {
  49 + this.data = data;
  50 + }
  51 +}
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/ISIPCommander.java
@@ -12,48 +12,48 @@ public interface ISIPCommander { @@ -12,48 +12,48 @@ public interface ISIPCommander {
12 /** 12 /**
13 * 云台方向放控制,使用配置文件中的默认镜头移动速度 13 * 云台方向放控制,使用配置文件中的默认镜头移动速度
14 * 14 *
15 - * @param deviceId 控制设备 15 + * @param device 控制设备
16 * @param channelId 预览通道 16 * @param channelId 预览通道
17 * @param leftRight 镜头左移右移 0:停止 1:左移 2:右移 17 * @param leftRight 镜头左移右移 0:停止 1:左移 2:右移
18 * @param upDown 镜头上移下移 0:停止 1:上移 2:下移 18 * @param upDown 镜头上移下移 0:停止 1:上移 2:下移
19 * @param moveSpeed 镜头移动速度 19 * @param moveSpeed 镜头移动速度
20 */ 20 */
21 - public boolean ptzdirectCmd(String deviceId,String channelId,int leftRight, int upDown); 21 + public boolean ptzdirectCmd(Device device,String channelId,int leftRight, int upDown);
22 22
23 /** 23 /**
24 * 云台方向放控制 24 * 云台方向放控制
25 * 25 *
26 - * @param deviceId 控制设备 26 + * @param device 控制设备
27 * @param channelId 预览通道 27 * @param channelId 预览通道
28 * @param leftRight 镜头左移右移 0:停止 1:左移 2:右移 28 * @param leftRight 镜头左移右移 0:停止 1:左移 2:右移
29 * @param upDown 镜头上移下移 0:停止 1:上移 2:下移 29 * @param upDown 镜头上移下移 0:停止 1:上移 2:下移
30 * @param moveSpeed 镜头移动速度 30 * @param moveSpeed 镜头移动速度
31 */ 31 */
32 - public boolean ptzdirectCmd(String deviceId,String channelId,int leftRight, int upDown, int moveSpeed); 32 + public boolean ptzdirectCmd(Device device,String channelId,int leftRight, int upDown, int moveSpeed);
33 33
34 /** 34 /**
35 * 云台缩放控制,使用配置文件中的默认镜头缩放速度 35 * 云台缩放控制,使用配置文件中的默认镜头缩放速度
36 * 36 *
37 - * @param deviceId 控制设备 37 + * @param device 控制设备
38 * @param channelId 预览通道 38 * @param channelId 预览通道
39 * @param inOut 镜头放大缩小 0:停止 1:缩小 2:放大 39 * @param inOut 镜头放大缩小 0:停止 1:缩小 2:放大
40 */ 40 */
41 - public boolean ptzZoomCmd(String deviceId,String channelId,int inOut); 41 + public boolean ptzZoomCmd(Device device,String channelId,int inOut);
42 42
43 /** 43 /**
44 * 云台缩放控制 44 * 云台缩放控制
45 * 45 *
46 - * @param deviceId 控制设备 46 + * @param device 控制设备
47 * @param channelId 预览通道 47 * @param channelId 预览通道
48 * @param inOut 镜头放大缩小 0:停止 1:缩小 2:放大 48 * @param inOut 镜头放大缩小 0:停止 1:缩小 2:放大
49 * @param zoomSpeed 镜头缩放速度 49 * @param zoomSpeed 镜头缩放速度
50 */ 50 */
51 - public boolean ptzZoomCmd(String deviceId,String channelId,int inOut, int moveSpeed); 51 + public boolean ptzZoomCmd(Device device,String channelId,int inOut, int moveSpeed);
52 52
53 /** 53 /**
54 * 云台控制,支持方向与缩放控制 54 * 云台控制,支持方向与缩放控制
55 * 55 *
56 - * @param deviceId 控制设备 56 + * @param device 控制设备
57 * @param channelId 预览通道 57 * @param channelId 预览通道
58 * @param leftRight 镜头左移右移 0:停止 1:左移 2:右移 58 * @param leftRight 镜头左移右移 0:停止 1:左移 2:右移
59 * @param upDown 镜头上移下移 0:停止 1:上移 2:下移 59 * @param upDown 镜头上移下移 0:停止 1:上移 2:下移
@@ -61,67 +61,67 @@ public interface ISIPCommander { @@ -61,67 +61,67 @@ public interface ISIPCommander {
61 * @param moveSpeed 镜头移动速度 61 * @param moveSpeed 镜头移动速度
62 * @param zoomSpeed 镜头缩放速度 62 * @param zoomSpeed 镜头缩放速度
63 */ 63 */
64 - public boolean ptzCmd(String deviceId,String channelId,int leftRight, int upDown, int inOut, int moveSpeed, int zoomSpeed); 64 + public boolean ptzCmd(Device device,String channelId,int leftRight, int upDown, int inOut, int moveSpeed, int zoomSpeed);
65 65
66 /** 66 /**
67 * 请求预览视频流 67 * 请求预览视频流
68 * 68 *
69 - * @param deviceId 视频设备 69 + * @param device 视频设备
70 * @param channelId 预览通道 70 * @param channelId 预览通道
71 */ 71 */
72 - public String playStreamCmd(String deviceId,String channelId); 72 + public String playStreamCmd(Device device,String channelId);
73 73
74 /** 74 /**
75 * 语音广播 75 * 语音广播
76 * 76 *
77 - * @param deviceId 视频设备 77 + * @param device 视频设备
78 * @param channelId 预览通道 78 * @param channelId 预览通道
79 */ 79 */
80 - public String audioBroadcastCmd(String deviceId,String channelId); 80 + public boolean audioBroadcastCmd(Device device,String channelId);
81 81
82 /** 82 /**
83 * 音视频录像控制 83 * 音视频录像控制
84 * 84 *
85 - * @param deviceId 视频设备 85 + * @param device 视频设备
86 * @param channelId 预览通道 86 * @param channelId 预览通道
87 */ 87 */
88 - public String recordCmd(String deviceId,String channelId); 88 + public boolean recordCmd(Device device,String channelId);
89 89
90 /** 90 /**
91 * 报警布防/撤防命令 91 * 报警布防/撤防命令
92 * 92 *
93 - * @param deviceId 视频设备 93 + * @param device 视频设备
94 */ 94 */
95 - public String guardCmd(String deviceId); 95 + public boolean guardCmd(Device device);
96 96
97 /** 97 /**
98 * 报警复位命令 98 * 报警复位命令
99 * 99 *
100 - * @param deviceId 视频设备 100 + * @param device 视频设备
101 */ 101 */
102 - public String alarmCmd(String deviceId); 102 + public boolean alarmCmd(Device device);
103 103
104 /** 104 /**
105 * 强制关键帧命令,设备收到此命令应立刻发送一个IDR帧 105 * 强制关键帧命令,设备收到此命令应立刻发送一个IDR帧
106 * 106 *
107 - * @param deviceId 视频设备 107 + * @param device 视频设备
108 * @param channelId 预览通道 108 * @param channelId 预览通道
109 */ 109 */
110 - public String iFameCmd(String deviceId,String channelId); 110 + public boolean iFameCmd(Device device,String channelId);
111 111
112 /** 112 /**
113 * 看守位控制命令 113 * 看守位控制命令
114 * 114 *
115 - * @param deviceId 视频设备 115 + * @param device 视频设备
116 */ 116 */
117 - public String homePositionCmd(String deviceId); 117 + public boolean homePositionCmd(Device device);
118 118
119 /** 119 /**
120 * 设备配置命令 120 * 设备配置命令
121 * 121 *
122 - * @param deviceId 视频设备 122 + * @param device 视频设备
123 */ 123 */
124 - public String deviceConfigCmd(String deviceId); 124 + public boolean deviceConfigCmd(Device device);
125 125
126 126
127 /** 127 /**
@@ -150,8 +150,10 @@ public interface ISIPCommander { @@ -150,8 +150,10 @@ public interface ISIPCommander {
150 * 查询录像信息 150 * 查询录像信息
151 * 151 *
152 * @param device 视频设备 152 * @param device 视频设备
  153 + * @param startTime 开始时间,格式要求:yyyy-MM-dd HH:mm:ss
  154 + * @param endTime 结束时间,格式要求:yyyy-MM-dd HH:mm:ss
153 */ 155 */
154 - public boolean recordInfoQuery(Device device); 156 + public boolean recordInfoQuery(Device device, String startTime, String endTime);
155 157
156 /** 158 /**
157 * 查询报警信息 159 * 查询报警信息
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java
@@ -8,6 +8,7 @@ import javax.sip.SipException; @@ -8,6 +8,7 @@ import javax.sip.SipException;
8 import javax.sip.message.Request; 8 import javax.sip.message.Request;
9 9
10 import org.springframework.beans.factory.annotation.Autowired; 10 import org.springframework.beans.factory.annotation.Autowired;
  11 +import org.springframework.context.ApplicationEventPublisher;
11 import org.springframework.stereotype.Component; 12 import org.springframework.stereotype.Component;
12 13
13 import com.genersoft.iot.vmp.conf.SipConfig; 14 import com.genersoft.iot.vmp.conf.SipConfig;
@@ -15,7 +16,7 @@ import com.genersoft.iot.vmp.gb28181.SipLayer; @@ -15,7 +16,7 @@ import com.genersoft.iot.vmp.gb28181.SipLayer;
15 import com.genersoft.iot.vmp.gb28181.bean.Device; 16 import com.genersoft.iot.vmp.gb28181.bean.Device;
16 import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommander; 17 import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommander;
17 import com.genersoft.iot.vmp.gb28181.transmit.cmd.SIPRequestHeaderProvider; 18 import com.genersoft.iot.vmp.gb28181.transmit.cmd.SIPRequestHeaderProvider;
18 -import com.genersoft.iot.vmp.storager.IVideoManagerStorager; 19 +import com.genersoft.iot.vmp.gb28181.utils.DateUtil;
19 20
20 /** 21 /**
21 * @Description:设备能力接口,用于定义设备的控制、查询能力 22 * @Description:设备能力接口,用于定义设备的控制、查询能力
@@ -34,66 +35,63 @@ public class SIPCommander implements ISIPCommander { @@ -34,66 +35,63 @@ public class SIPCommander implements ISIPCommander {
34 @Autowired 35 @Autowired
35 private SipLayer sipLayer; 36 private SipLayer sipLayer;
36 37
37 - @Autowired  
38 - private IVideoManagerStorager storager;  
39 -  
40 /** 38 /**
41 * 云台方向放控制,使用配置文件中的默认镜头移动速度 39 * 云台方向放控制,使用配置文件中的默认镜头移动速度
42 * 40 *
43 - * @param deviceId 控制设备 41 + * @param device 控制设备
44 * @param channelId 预览通道 42 * @param channelId 预览通道
45 * @param leftRight 镜头左移右移 0:停止 1:左移 2:右移 43 * @param leftRight 镜头左移右移 0:停止 1:左移 2:右移
46 * @param upDown 镜头上移下移 0:停止 1:上移 2:下移 44 * @param upDown 镜头上移下移 0:停止 1:上移 2:下移
47 * @param moveSpeed 镜头移动速度 45 * @param moveSpeed 镜头移动速度
48 */ 46 */
49 @Override 47 @Override
50 - public boolean ptzdirectCmd(String deviceId, String channelId, int leftRight, int upDown) {  
51 - return ptzCmd(deviceId, channelId, leftRight, upDown, 0, config.getSpeed(), 0); 48 + public boolean ptzdirectCmd(Device device, String channelId, int leftRight, int upDown) {
  49 + return ptzCmd(device, channelId, leftRight, upDown, 0, config.getSpeed(), 0);
52 } 50 }
53 51
54 /** 52 /**
55 * 云台方向放控制 53 * 云台方向放控制
56 * 54 *
57 - * @param deviceId 控制设备 55 + * @param device 控制设备
58 * @param channelId 预览通道 56 * @param channelId 预览通道
59 * @param leftRight 镜头左移右移 0:停止 1:左移 2:右移 57 * @param leftRight 镜头左移右移 0:停止 1:左移 2:右移
60 * @param upDown 镜头上移下移 0:停止 1:上移 2:下移 58 * @param upDown 镜头上移下移 0:停止 1:上移 2:下移
61 * @param moveSpeed 镜头移动速度 59 * @param moveSpeed 镜头移动速度
62 */ 60 */
63 @Override 61 @Override
64 - public boolean ptzdirectCmd(String deviceId, String channelId, int leftRight, int upDown, int moveSpeed) {  
65 - return ptzCmd(deviceId, channelId, leftRight, upDown, 0, moveSpeed, 0); 62 + public boolean ptzdirectCmd(Device device, String channelId, int leftRight, int upDown, int moveSpeed) {
  63 + return ptzCmd(device, channelId, leftRight, upDown, 0, moveSpeed, 0);
66 } 64 }
67 65
68 /** 66 /**
69 * 云台缩放控制,使用配置文件中的默认镜头缩放速度 67 * 云台缩放控制,使用配置文件中的默认镜头缩放速度
70 * 68 *
71 - * @param deviceId 控制设备 69 + * @param device 控制设备
72 * @param channelId 预览通道 70 * @param channelId 预览通道
73 * @param inOut 镜头放大缩小 0:停止 1:缩小 2:放大 71 * @param inOut 镜头放大缩小 0:停止 1:缩小 2:放大
74 */ 72 */
75 @Override 73 @Override
76 - public boolean ptzZoomCmd(String deviceId, String channelId, int inOut) {  
77 - return ptzCmd(deviceId, channelId, 0, 0, inOut, 0, config.getSpeed()); 74 + public boolean ptzZoomCmd(Device device, String channelId, int inOut) {
  75 + return ptzCmd(device, channelId, 0, 0, inOut, 0, config.getSpeed());
78 } 76 }
79 77
80 /** 78 /**
81 * 云台缩放控制 79 * 云台缩放控制
82 * 80 *
83 - * @param deviceId 控制设备 81 + * @param device 控制设备
84 * @param channelId 预览通道 82 * @param channelId 预览通道
85 * @param inOut 镜头放大缩小 0:停止 1:缩小 2:放大 83 * @param inOut 镜头放大缩小 0:停止 1:缩小 2:放大
86 * @param zoomSpeed 镜头缩放速度 84 * @param zoomSpeed 镜头缩放速度
87 */ 85 */
88 @Override 86 @Override
89 - public boolean ptzZoomCmd(String deviceId, String channelId, int inOut, int zoomSpeed) {  
90 - return ptzCmd(deviceId, channelId, 0, 0, inOut, 0, zoomSpeed); 87 + public boolean ptzZoomCmd(Device device, String channelId, int inOut, int zoomSpeed) {
  88 + return ptzCmd(device, channelId, 0, 0, inOut, 0, zoomSpeed);
91 } 89 }
92 90
93 /** 91 /**
94 * 云台控制,支持方向与缩放控制 92 * 云台控制,支持方向与缩放控制
95 * 93 *
96 - * @param deviceId 控制设备 94 + * @param device 控制设备
97 * @param channelId 预览通道 95 * @param channelId 预览通道
98 * @param leftRight 镜头左移右移 0:停止 1:左移 2:右移 96 * @param leftRight 镜头左移右移 0:停止 1:左移 2:右移
99 * @param upDown 镜头上移下移 0:停止 1:上移 2:下移 97 * @param upDown 镜头上移下移 0:停止 1:上移 2:下移
@@ -102,10 +100,9 @@ public class SIPCommander implements ISIPCommander { @@ -102,10 +100,9 @@ public class SIPCommander implements ISIPCommander {
102 * @param zoomSpeed 镜头缩放速度 100 * @param zoomSpeed 镜头缩放速度
103 */ 101 */
104 @Override 102 @Override
105 - public boolean ptzCmd(String deviceId, String channelId, int leftRight, int upDown, int inOut, int moveSpeed, 103 + public boolean ptzCmd(Device device, String channelId, int leftRight, int upDown, int inOut, int moveSpeed,
106 int zoomSpeed) { 104 int zoomSpeed) {
107 try { 105 try {
108 - Device device = storager.queryVideoDevice(deviceId);  
109 StringBuffer ptzXml = new StringBuffer(200); 106 StringBuffer ptzXml = new StringBuffer(200);
110 ptzXml.append("<?xml version=\"1.0\" ?>"); 107 ptzXml.append("<?xml version=\"1.0\" ?>");
111 ptzXml.append("<Control>"); 108 ptzXml.append("<Control>");
@@ -119,7 +116,7 @@ public class SIPCommander implements ISIPCommander { @@ -119,7 +116,7 @@ public class SIPCommander implements ISIPCommander {
119 116
120 Request request = headerProvider.createMessageRequest(device, ptzXml.toString(), "ViaPtzBranch", "FromPtzTag", "ToPtzTag"); 117 Request request = headerProvider.createMessageRequest(device, ptzXml.toString(), "ViaPtzBranch", "FromPtzTag", "ToPtzTag");
121 118
122 - transmitRequest(device.getTransport(), request); 119 + transmitRequest(device, request);
123 120
124 return true; 121 return true;
125 } catch (SipException | ParseException | InvalidArgumentException e) { 122 } catch (SipException | ParseException | InvalidArgumentException e) {
@@ -131,15 +128,13 @@ public class SIPCommander implements ISIPCommander { @@ -131,15 +128,13 @@ public class SIPCommander implements ISIPCommander {
131 /** 128 /**
132 * 请求预览视频流 129 * 请求预览视频流
133 * 130 *
134 - * @param deviceId 视频设备 131 + * @param device 视频设备
135 * @param channelId 预览通道 132 * @param channelId 预览通道
136 */ 133 */
137 @Override 134 @Override
138 - public String playStreamCmd(String deviceId, String channelId) { 135 + public String playStreamCmd(Device device, String channelId) {
139 try { 136 try {
140 137
141 - Device device = storager.queryVideoDevice(deviceId);  
142 -  
143 //生成ssrc标识数据流 10位数字 138 //生成ssrc标识数据流 10位数字
144 String ssrc = ""; 139 String ssrc = "";
145 Random random = new Random(); 140 Random random = new Random();
@@ -170,7 +165,7 @@ public class SIPCommander implements ISIPCommander { @@ -170,7 +165,7 @@ public class SIPCommander implements ISIPCommander {
170 165
171 Request request = headerProvider.createInviteRequest(device, content.toString(), null, "live", null); 166 Request request = headerProvider.createInviteRequest(device, content.toString(), null, "live", null);
172 167
173 - transmitRequest(device.getTransport(), request); 168 + transmitRequest(device, request);
174 return ssrc; 169 return ssrc;
175 } catch ( SipException | ParseException | InvalidArgumentException e) { 170 } catch ( SipException | ParseException | InvalidArgumentException e) {
176 e.printStackTrace(); 171 e.printStackTrace();
@@ -181,81 +176,81 @@ public class SIPCommander implements ISIPCommander { @@ -181,81 +176,81 @@ public class SIPCommander implements ISIPCommander {
181 /** 176 /**
182 * 语音广播 177 * 语音广播
183 * 178 *
184 - * @param deviceId 视频设备 179 + * @param device 视频设备
185 * @param channelId 预览通道 180 * @param channelId 预览通道
186 */ 181 */
187 @Override 182 @Override
188 - public String audioBroadcastCmd(String deviceId, String channelId) { 183 + public boolean audioBroadcastCmd(Device device, String channelId) {
189 // TODO Auto-generated method stub 184 // TODO Auto-generated method stub
190 - return null; 185 + return false;
191 } 186 }
192 187
193 /** 188 /**
194 * 音视频录像控制 189 * 音视频录像控制
195 * 190 *
196 - * @param deviceId 视频设备 191 + * @param device 视频设备
197 * @param channelId 预览通道 192 * @param channelId 预览通道
198 */ 193 */
199 @Override 194 @Override
200 - public String recordCmd(String deviceId, String channelId) { 195 + public boolean recordCmd(Device device, String channelId) {
201 // TODO Auto-generated method stub 196 // TODO Auto-generated method stub
202 - return null; 197 + return false;
203 } 198 }
204 199
205 /** 200 /**
206 * 报警布防/撤防命令 201 * 报警布防/撤防命令
207 * 202 *
208 - * @param deviceId 视频设备 203 + * @param device 视频设备
209 */ 204 */
210 @Override 205 @Override
211 - public String guardCmd(String deviceId) { 206 + public boolean guardCmd(Device device) {
212 // TODO Auto-generated method stub 207 // TODO Auto-generated method stub
213 - return null; 208 + return false;
214 } 209 }
215 210
216 /** 211 /**
217 * 报警复位命令 212 * 报警复位命令
218 * 213 *
219 - * @param deviceId 视频设备 214 + * @param device 视频设备
220 */ 215 */
221 @Override 216 @Override
222 - public String alarmCmd(String deviceId) { 217 + public boolean alarmCmd(Device device) {
223 // TODO Auto-generated method stub 218 // TODO Auto-generated method stub
224 - return null; 219 + return false;
225 } 220 }
226 221
227 /** 222 /**
228 * 强制关键帧命令,设备收到此命令应立刻发送一个IDR帧 223 * 强制关键帧命令,设备收到此命令应立刻发送一个IDR帧
229 * 224 *
230 - * @param deviceId 视频设备 225 + * @param device 视频设备
231 * @param channelId 预览通道 226 * @param channelId 预览通道
232 */ 227 */
233 @Override 228 @Override
234 - public String iFameCmd(String deviceId, String channelId) { 229 + public boolean iFameCmd(Device device, String channelId) {
235 // TODO Auto-generated method stub 230 // TODO Auto-generated method stub
236 - return null; 231 + return false;
237 } 232 }
238 233
239 /** 234 /**
240 * 看守位控制命令 235 * 看守位控制命令
241 * 236 *
242 - * @param deviceId 视频设备 237 + * @param device 视频设备
243 */ 238 */
244 @Override 239 @Override
245 - public String homePositionCmd(String deviceId) { 240 + public boolean homePositionCmd(Device device) {
246 // TODO Auto-generated method stub 241 // TODO Auto-generated method stub
247 - return null; 242 + return false;
248 } 243 }
249 244
250 /** 245 /**
251 * 设备配置命令 246 * 设备配置命令
252 * 247 *
253 - * @param deviceId 视频设备 248 + * @param device 视频设备
254 */ 249 */
255 @Override 250 @Override
256 - public String deviceConfigCmd(String deviceId) { 251 + public boolean deviceConfigCmd(Device device) {
257 // TODO Auto-generated method stub 252 // TODO Auto-generated method stub
258 - return null; 253 + return false;
259 } 254 }
260 255
261 /** 256 /**
@@ -286,8 +281,8 @@ public class SIPCommander implements ISIPCommander { @@ -286,8 +281,8 @@ public class SIPCommander implements ISIPCommander {
286 catalogXml.append("</Query>"); 281 catalogXml.append("</Query>");
287 282
288 Request request = headerProvider.createMessageRequest(device, catalogXml.toString(), "ViaDeviceInfoBranch", "FromDeviceInfoTag", "ToDeviceInfoTag"); 283 Request request = headerProvider.createMessageRequest(device, catalogXml.toString(), "ViaDeviceInfoBranch", "FromDeviceInfoTag", "ToDeviceInfoTag");
  284 + transmitRequest(device, request);
289 285
290 - transmitRequest(device.getTransport(), request);  
291 } catch (SipException | ParseException | InvalidArgumentException e) { 286 } catch (SipException | ParseException | InvalidArgumentException e) {
292 e.printStackTrace(); 287 e.printStackTrace();
293 return false; 288 return false;
@@ -312,9 +307,7 @@ public class SIPCommander implements ISIPCommander { @@ -312,9 +307,7 @@ public class SIPCommander implements ISIPCommander {
312 catalogXml.append("</Query>"); 307 catalogXml.append("</Query>");
313 308
314 Request request = headerProvider.createMessageRequest(device, catalogXml.toString(), "ViaCatalogBranch", "FromCatalogTag", "ToCatalogTag"); 309 Request request = headerProvider.createMessageRequest(device, catalogXml.toString(), "ViaCatalogBranch", "FromCatalogTag", "ToCatalogTag");
315 -  
316 - transmitRequest(device.getTransport(), request);  
317 - 310 + transmitRequest(device, request);
318 } catch (SipException | ParseException | InvalidArgumentException e) { 311 } catch (SipException | ParseException | InvalidArgumentException e) {
319 e.printStackTrace(); 312 e.printStackTrace();
320 return false; 313 return false;
@@ -326,11 +319,32 @@ public class SIPCommander implements ISIPCommander { @@ -326,11 +319,32 @@ public class SIPCommander implements ISIPCommander {
326 * 查询录像信息 319 * 查询录像信息
327 * 320 *
328 * @param device 视频设备 321 * @param device 视频设备
  322 + * @param startTime 开始时间,格式要求:yyyy-MM-dd HH:mm:ss
  323 + * @param endTime 结束时间,格式要求:yyyy-MM-dd HH:mm:ss
329 */ 324 */
330 @Override 325 @Override
331 - public boolean recordInfoQuery(Device device) {  
332 - // TODO Auto-generated method stub  
333 - return false; 326 + public boolean recordInfoQuery(Device device, String startTime, String endTime) {
  327 +
  328 + try {
  329 + StringBuffer catalogXml = new StringBuffer(200);
  330 + catalogXml.append("<?xml version=\"1.0\" encoding=\"GB2312\"?>");
  331 + catalogXml.append("<Query>");
  332 + catalogXml.append("<CmdType>RecordInfo</CmdType>");
  333 + catalogXml.append("<SN>" + (int)((Math.random()*9+1)*100000) + "</SN>");
  334 + catalogXml.append("<DeviceID>" + device.getDeviceId() + "</DeviceID>");
  335 + catalogXml.append("<StartTime>" + DateUtil.yyyy_MM_dd_HH_mm_ssToISO8601(startTime) + "</StartTime>");
  336 + catalogXml.append("<EndTime>" + DateUtil.yyyy_MM_dd_HH_mm_ssToISO8601(endTime) + "</EndTime>");
  337 + // 大华NVR要求必须增加一个值为all的文本元素节点Type
  338 + catalogXml.append("<Type>all</Type>");
  339 + catalogXml.append("</Query>");
  340 +
  341 + Request request = headerProvider.createMessageRequest(device, catalogXml.toString(), "ViaRecordInfoBranch", "FromRecordInfoTag", "ToRecordInfoTag");
  342 + transmitRequest(device, request);
  343 + } catch (SipException | ParseException | InvalidArgumentException e) {
  344 + e.printStackTrace();
  345 + return false;
  346 + }
  347 + return true;
334 } 348 }
335 349
336 /** 350 /**
@@ -377,10 +391,10 @@ public class SIPCommander implements ISIPCommander { @@ -377,10 +391,10 @@ public class SIPCommander implements ISIPCommander {
377 return false; 391 return false;
378 } 392 }
379 393
380 - private void transmitRequest(String transport, Request request) throws SipException {  
381 - if(transport.equals("TCP")) { 394 + private void transmitRequest(Device device, Request request) throws SipException {
  395 + if(device.getTransport().equals("TCP")) {
382 sipLayer.getTcpSipProvider().sendRequest(request); 396 sipLayer.getTcpSipProvider().sendRequest(request);
383 - } else if(transport.equals("UDP")) { 397 + } else if(device.getTransport().equals("UDP")) {
384 sipLayer.getUdpSipProvider().sendRequest(request); 398 sipLayer.getUdpSipProvider().sendRequest(request);
385 } 399 }
386 } 400 }
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/MessageRequestProcessor.java
@@ -2,8 +2,10 @@ package com.genersoft.iot.vmp.gb28181.transmit.request.impl; @@ -2,8 +2,10 @@ package com.genersoft.iot.vmp.gb28181.transmit.request.impl;
2 2
3 import java.io.ByteArrayInputStream; 3 import java.io.ByteArrayInputStream;
4 import java.text.ParseException; 4 import java.text.ParseException;
  5 +import java.util.ArrayList;
5 import java.util.HashMap; 6 import java.util.HashMap;
6 import java.util.Iterator; 7 import java.util.Iterator;
  8 +import java.util.List;
7 import java.util.Map; 9 import java.util.Map;
8 10
9 import javax.sip.InvalidArgumentException; 11 import javax.sip.InvalidArgumentException;
@@ -24,9 +26,14 @@ import com.genersoft.iot.vmp.common.VideoManagerConstants; @@ -24,9 +26,14 @@ import com.genersoft.iot.vmp.common.VideoManagerConstants;
24 import com.genersoft.iot.vmp.gb28181.SipLayer; 26 import com.genersoft.iot.vmp.gb28181.SipLayer;
25 import com.genersoft.iot.vmp.gb28181.bean.Device; 27 import com.genersoft.iot.vmp.gb28181.bean.Device;
26 import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel; 28 import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel;
  29 +import com.genersoft.iot.vmp.gb28181.bean.RecordInfo;
  30 +import com.genersoft.iot.vmp.gb28181.bean.RecordItem;
27 import com.genersoft.iot.vmp.gb28181.event.EventPublisher; 31 import com.genersoft.iot.vmp.gb28181.event.EventPublisher;
  32 +import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder;
  33 +import com.genersoft.iot.vmp.gb28181.transmit.callback.RequestMessage;
28 import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander; 34 import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander;
29 import com.genersoft.iot.vmp.gb28181.transmit.request.ISIPRequestProcessor; 35 import com.genersoft.iot.vmp.gb28181.transmit.request.ISIPRequestProcessor;
  36 +import com.genersoft.iot.vmp.gb28181.utils.DateUtil;
30 import com.genersoft.iot.vmp.gb28181.utils.XmlUtil; 37 import com.genersoft.iot.vmp.gb28181.utils.XmlUtil;
31 import com.genersoft.iot.vmp.storager.IVideoManagerStorager; 38 import com.genersoft.iot.vmp.storager.IVideoManagerStorager;
32 39
@@ -51,6 +58,9 @@ public class MessageRequestProcessor implements ISIPRequestProcessor { @@ -51,6 +58,9 @@ public class MessageRequestProcessor implements ISIPRequestProcessor {
51 @Autowired 58 @Autowired
52 private EventPublisher publisher; 59 private EventPublisher publisher;
53 60
  61 + @Autowired
  62 + private DeferredResultHolder deferredResultHolder;
  63 +
54 /** 64 /**
55 * 处理MESSAGE请求 65 * 处理MESSAGE请求
56 * 66 *
@@ -74,21 +84,49 @@ public class MessageRequestProcessor implements ISIPRequestProcessor { @@ -74,21 +84,49 @@ public class MessageRequestProcessor implements ISIPRequestProcessor {
74 processMessageDeviceInfo(evt); 84 processMessageDeviceInfo(evt);
75 } else if (new String(request.getRawContent()).contains("<CmdType>Alarm</CmdType>")) { 85 } else if (new String(request.getRawContent()).contains("<CmdType>Alarm</CmdType>")) {
76 processMessageAlarm(evt); 86 processMessageAlarm(evt);
  87 + } else if (new String(request.getRawContent()).contains("<CmdType>recordInfo</CmdType>")) {
  88 + processMessageRecordInfo(evt);
77 } 89 }
78 90
79 } 91 }
80 92
  93 + /**
  94 + * 收到deviceInfo设备信息请求 处理
  95 + * @param evt
  96 + */
  97 + private void processMessageDeviceInfo(RequestEvent evt) {
  98 + try {
  99 + Element rootElement = getRootElement(evt);
  100 + Element deviceIdElement = rootElement.element("DeviceID");
  101 + String deviceId = deviceIdElement.getText().toString();
  102 +
  103 + Device device = storager.queryVideoDevice(deviceId);
  104 + if (device == null) {
  105 + return;
  106 + }
  107 + device.setName(XmlUtil.getText(rootElement,"DeviceName"));
  108 + device.setManufacturer(XmlUtil.getText(rootElement,"Manufacturer"));
  109 + device.setModel(XmlUtil.getText(rootElement,"Model"));
  110 + device.setFirmware(XmlUtil.getText(rootElement,"Firmware"));
  111 + storager.update(device);
  112 +
  113 + RequestMessage msg = new RequestMessage();
  114 + msg.setDeviceId(deviceId);
  115 + msg.setType(DeferredResultHolder.CALLBACK_CMD_DEVICEINFO);
  116 + msg.setData(device);
  117 + deferredResultHolder.invokeResult(msg);
  118 + } catch (DocumentException e) {
  119 + e.printStackTrace();
  120 + }
  121 + }
  122 +
81 /*** 123 /***
82 * 收到catalog设备目录列表请求 处理 124 * 收到catalog设备目录列表请求 处理
83 * @param evt 125 * @param evt
84 */ 126 */
85 private void processMessageCatalogList(RequestEvent evt) { 127 private void processMessageCatalogList(RequestEvent evt) {
86 try { 128 try {
87 - Request request = evt.getRequest();  
88 - SAXReader reader = new SAXReader();  
89 - reader.setEncoding("GB2312");  
90 - Document xml = reader.read(new ByteArrayInputStream(request.getRawContent()));  
91 - Element rootElement = xml.getRootElement(); 129 + Element rootElement = getRootElement(evt);
92 Element deviceIdElement = rootElement.element("DeviceID"); 130 Element deviceIdElement = rootElement.element("DeviceID");
93 String deviceId = deviceIdElement.getText().toString(); 131 String deviceId = deviceIdElement.getText().toString();
94 Element deviceListElement = rootElement.element("DeviceList"); 132 Element deviceListElement = rootElement.element("DeviceList");
@@ -152,6 +190,11 @@ public class MessageRequestProcessor implements ISIPRequestProcessor { @@ -152,6 +190,11 @@ public class MessageRequestProcessor implements ISIPRequestProcessor {
152 } 190 }
153 // 更新 191 // 更新
154 storager.update(device); 192 storager.update(device);
  193 + RequestMessage msg = new RequestMessage();
  194 + msg.setDeviceId(deviceId);
  195 + msg.setType(DeferredResultHolder.CALLBACK_CMD_CATALOG);
  196 + msg.setData(device);
  197 + deferredResultHolder.invokeResult(msg);
155 } 198 }
156 } catch (DocumentException e) { 199 } catch (DocumentException e) {
157 e.printStackTrace(); 200 e.printStackTrace();
@@ -159,16 +202,12 @@ public class MessageRequestProcessor implements ISIPRequestProcessor { @@ -159,16 +202,12 @@ public class MessageRequestProcessor implements ISIPRequestProcessor {
159 } 202 }
160 203
161 /*** 204 /***
162 - * 收到deviceInfo设备信息请求 处理 205 + * 收到alarm设备报警信息 处理
163 * @param evt 206 * @param evt
164 */ 207 */
165 - private void processMessageDeviceInfo(RequestEvent evt) { 208 + private void processMessageAlarm(RequestEvent evt) {
166 try { 209 try {
167 - Request request = evt.getRequest();  
168 - SAXReader reader = new SAXReader();  
169 - // reader.setEncoding("GB2312");  
170 - Document xml = reader.read(new ByteArrayInputStream(request.getRawContent()));  
171 - Element rootElement = xml.getRootElement(); 210 + Element rootElement = getRootElement(evt);
172 Element deviceIdElement = rootElement.element("DeviceID"); 211 Element deviceIdElement = rootElement.element("DeviceID");
173 String deviceId = deviceIdElement.getText().toString(); 212 String deviceId = deviceIdElement.getText().toString();
174 213
@@ -188,52 +227,83 @@ public class MessageRequestProcessor implements ISIPRequestProcessor { @@ -188,52 +227,83 @@ public class MessageRequestProcessor implements ISIPRequestProcessor {
188 } 227 }
189 228
190 /*** 229 /***
191 - * 收到alarm设备报警信息 处理 230 + * 收到keepalive请求 处理
192 * @param evt 231 * @param evt
193 */ 232 */
194 - private void processMessageAlarm(RequestEvent evt) { 233 + private void processMessageKeepAlive(RequestEvent evt){
195 try { 234 try {
196 Request request = evt.getRequest(); 235 Request request = evt.getRequest();
197 - SAXReader reader = new SAXReader();  
198 - // reader.setEncoding("GB2312");  
199 - Document xml = reader.read(new ByteArrayInputStream(request.getRawContent()));  
200 - Element rootElement = xml.getRootElement(); 236 + Response response = layer.getMessageFactory().createResponse(Response.OK,request);
  237 + Element rootElement = getRootElement(evt);
201 Element deviceIdElement = rootElement.element("DeviceID"); 238 Element deviceIdElement = rootElement.element("DeviceID");
202 - String deviceId = deviceIdElement.getText().toString();  
203 -  
204 - Device device = storager.queryVideoDevice(deviceId);  
205 - if (device == null) {  
206 - return;  
207 - }  
208 - device.setName(XmlUtil.getText(rootElement,"DeviceName"));  
209 - device.setManufacturer(XmlUtil.getText(rootElement,"Manufacturer"));  
210 - device.setModel(XmlUtil.getText(rootElement,"Model"));  
211 - device.setFirmware(XmlUtil.getText(rootElement,"Firmware"));  
212 - storager.update(device);  
213 - cmder.catalogQuery(device);  
214 - } catch (DocumentException e) { 239 + transaction.sendResponse(response);
  240 + publisher.onlineEventPublish(deviceIdElement.getText(), VideoManagerConstants.EVENT_ONLINE_KEEPLIVE);
  241 + } catch (ParseException | SipException | InvalidArgumentException | DocumentException e) {
215 e.printStackTrace(); 242 e.printStackTrace();
216 } 243 }
217 } 244 }
218 245
219 /*** 246 /***
220 - * 收到keepalive请求 处理 247 + * 收到catalog设备目录列表请求 处理
221 * @param evt 248 * @param evt
222 */ 249 */
223 - private void processMessageKeepAlive(RequestEvent evt){ 250 + private void processMessageRecordInfo(RequestEvent evt) {
224 try { 251 try {
225 - Request request = evt.getRequest();  
226 - Response response = layer.getMessageFactory().createResponse(Response.OK,request);  
227 - SAXReader reader = new SAXReader();  
228 - Document xml = reader.read(new ByteArrayInputStream(request.getRawContent()));  
229 - // reader.setEncoding("GB2312");  
230 - Element rootElement = xml.getRootElement(); 252 + RecordInfo recordInfo = new RecordInfo();
  253 + Element rootElement = getRootElement(evt);
231 Element deviceIdElement = rootElement.element("DeviceID"); 254 Element deviceIdElement = rootElement.element("DeviceID");
232 - transaction.sendResponse(response);  
233 - publisher.onlineEventPublish(deviceIdElement.getText(), VideoManagerConstants.EVENT_ONLINE_KEEPLIVE);  
234 - } catch (ParseException | SipException | InvalidArgumentException | DocumentException e) { 255 + String deviceId = deviceIdElement.getText().toString();
  256 + recordInfo.setDeviceId(deviceId);
  257 + recordInfo.setName(XmlUtil.getText(rootElement,"Name"));
  258 + recordInfo.setSumNum(Integer.parseInt(XmlUtil.getText(rootElement,"SumNum")));
  259 + Element recordListElement = rootElement.element("RecordList");
  260 + if (recordListElement == null) {
  261 + return;
  262 + }
  263 +
  264 + Iterator<Element> recordListIterator = recordListElement.elementIterator();
  265 + if (recordListIterator != null) {
  266 +
  267 + List<RecordItem> recordList = new ArrayList<RecordItem>();
  268 + RecordItem record = new RecordItem();
  269 + // 遍历DeviceList
  270 + while (recordListIterator.hasNext()) {
  271 + Element itemRecord = recordListIterator.next();
  272 + Element recordElement = itemRecord.element("DeviceID");
  273 + if (recordElement == null) {
  274 + continue;
  275 + }
  276 + record.setDeviceId(XmlUtil.getText(itemRecord,"DeviceID"));
  277 + record.setName(XmlUtil.getText(itemRecord,"Name"));
  278 + record.setFilePath(XmlUtil.getText(itemRecord,"FilePath"));
  279 + record.setAddress(XmlUtil.getText(itemRecord,"Address"));
  280 + record.setStartTime(DateUtil.ISO8601Toyyyy_MM_dd_HH_mm_ss(XmlUtil.getText(itemRecord,"StartTime")));
  281 + record.setEndTime(DateUtil.ISO8601Toyyyy_MM_dd_HH_mm_ss(XmlUtil.getText(itemRecord,"EndTime")));
  282 + record.setSecrecy(itemRecord.element("Secrecy") == null? 0:Integer.parseInt(XmlUtil.getText(itemRecord,"Secrecy")));
  283 + record.setType(XmlUtil.getText(itemRecord,"Type"));
  284 + record.setRecordId(XmlUtil.getText(itemRecord,"RecordID"));
  285 + recordList.add(record);
  286 + }
  287 + recordInfo.setRecordList(recordList);
  288 + }
  289 +
  290 +
  291 + RequestMessage msg = new RequestMessage();
  292 + msg.setDeviceId(deviceId);
  293 + msg.setType(DeferredResultHolder.CALLBACK_CMD_RECORDINFO);
  294 + msg.setData(recordInfo);
  295 + deferredResultHolder.invokeResult(msg);
  296 + } catch (DocumentException e) {
235 e.printStackTrace(); 297 e.printStackTrace();
236 } 298 }
237 } 299 }
  300 +
  301 + private Element getRootElement(RequestEvent evt) throws DocumentException {
  302 + Request request = evt.getRequest();
  303 + SAXReader reader = new SAXReader();
  304 + reader.setEncoding("GB2312");
  305 + Document xml = reader.read(new ByteArrayInputStream(request.getRawContent()));
  306 + return xml.getRootElement();
  307 + }
238 308
239 } 309 }
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/RegisterRequestProcessor.java
@@ -25,10 +25,10 @@ import com.genersoft.iot.vmp.common.VideoManagerConstants; @@ -25,10 +25,10 @@ import com.genersoft.iot.vmp.common.VideoManagerConstants;
25 import com.genersoft.iot.vmp.conf.SipConfig; 25 import com.genersoft.iot.vmp.conf.SipConfig;
26 import com.genersoft.iot.vmp.gb28181.SipLayer; 26 import com.genersoft.iot.vmp.gb28181.SipLayer;
27 import com.genersoft.iot.vmp.gb28181.auth.DigestServerAuthenticationHelper; 27 import com.genersoft.iot.vmp.gb28181.auth.DigestServerAuthenticationHelper;
  28 +import com.genersoft.iot.vmp.gb28181.auth.RegisterLogicHandler;
28 import com.genersoft.iot.vmp.gb28181.bean.Device; 29 import com.genersoft.iot.vmp.gb28181.bean.Device;
29 import com.genersoft.iot.vmp.gb28181.bean.Host; 30 import com.genersoft.iot.vmp.gb28181.bean.Host;
30 import com.genersoft.iot.vmp.gb28181.event.EventPublisher; 31 import com.genersoft.iot.vmp.gb28181.event.EventPublisher;
31 -import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander;  
32 import com.genersoft.iot.vmp.gb28181.transmit.request.ISIPRequestProcessor; 32 import com.genersoft.iot.vmp.gb28181.transmit.request.ISIPRequestProcessor;
33 import com.genersoft.iot.vmp.storager.IVideoManagerStorager; 33 import com.genersoft.iot.vmp.storager.IVideoManagerStorager;
34 34
@@ -48,7 +48,7 @@ public class RegisterRequestProcessor implements ISIPRequestProcessor { @@ -48,7 +48,7 @@ public class RegisterRequestProcessor implements ISIPRequestProcessor {
48 private SipConfig config; 48 private SipConfig config;
49 49
50 @Autowired 50 @Autowired
51 - private SIPCommander cmder; 51 + private RegisterLogicHandler handler;
52 52
53 @Autowired 53 @Autowired
54 private IVideoManagerStorager storager; 54 private IVideoManagerStorager storager;
@@ -149,7 +149,7 @@ public class RegisterRequestProcessor implements ISIPRequestProcessor { @@ -149,7 +149,7 @@ public class RegisterRequestProcessor implements ISIPRequestProcessor {
149 System.out.println("注册成功! deviceId:" + device.getDeviceId()); 149 System.out.println("注册成功! deviceId:" + device.getDeviceId());
150 storager.update(device); 150 storager.update(device);
151 publisher.onlineEventPublish(device.getDeviceId(), VideoManagerConstants.EVENT_ONLINE_REGISTER); 151 publisher.onlineEventPublish(device.getDeviceId(), VideoManagerConstants.EVENT_ONLINE_REGISTER);
152 - cmder.deviceInfoQuery(device); 152 + handler.onRegister(device);
153 } else if (registerFlag == 2) { 153 } else if (registerFlag == 2) {
154 System.out.println("注销成功! deviceId:" + device.getDeviceId()); 154 System.out.println("注销成功! deviceId:" + device.getDeviceId());
155 publisher.outlineEventPublish(device.getDeviceId(), VideoManagerConstants.EVENT_OUTLINE_UNREGISTER); 155 publisher.outlineEventPublish(device.getDeviceId(), VideoManagerConstants.EVENT_OUTLINE_UNREGISTER);
src/main/java/com/genersoft/iot/vmp/gb28181/utils/DateUtil.java 0 → 100644
  1 +package com.genersoft.iot.vmp.gb28181.utils;
  2 +
  3 +import java.text.ParseException;
  4 +import java.text.SimpleDateFormat;
  5 +import java.util.Locale;
  6 +
  7 +/**
  8 + * @Description:时间工具类,主要处理ISO 8601格式转换
  9 + * @author: songww
  10 + * @date: 2020年5月8日 下午3:24:42
  11 + */
  12 +public class DateUtil {
  13 +
  14 + private static final String yyyy_MM_dd_T_HH_mm_ss_SSSXXX = "yyyy-MM-dd'T'HH:mm:ss.SSSXXX";
  15 + private static final String yyyy_MM_dd_HH_mm_ss = "yyyy-MM-dd HH:mm:ss";
  16 +
  17 + public static String yyyy_MM_dd_HH_mm_ssToISO8601(String formatTime) {
  18 +
  19 + SimpleDateFormat oldsdf = new SimpleDateFormat(yyyy_MM_dd_HH_mm_ss, Locale.getDefault());
  20 + SimpleDateFormat newsdf = new SimpleDateFormat(yyyy_MM_dd_T_HH_mm_ss_SSSXXX, Locale.getDefault());
  21 + try {
  22 + return newsdf.format(oldsdf.parse(formatTime));
  23 + } catch (ParseException e) {
  24 + e.printStackTrace();
  25 + }
  26 + return "";
  27 + }
  28 +
  29 + public static String ISO8601Toyyyy_MM_dd_HH_mm_ss(String formatTime) {
  30 +
  31 + SimpleDateFormat oldsdf = new SimpleDateFormat(yyyy_MM_dd_T_HH_mm_ss_SSSXXX, Locale.getDefault());
  32 + SimpleDateFormat newsdf = new SimpleDateFormat(yyyy_MM_dd_HH_mm_ss, Locale.getDefault());
  33 + try {
  34 + return newsdf.format(oldsdf.parse(formatTime));
  35 + } catch (ParseException e) {
  36 + e.printStackTrace();
  37 + }
  38 + return "";
  39 + }
  40 +}
src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java 0 → 100644
  1 +package com.genersoft.iot.vmp.media.zlm;
  2 +
  3 +import org.slf4j.Logger;
  4 +import org.slf4j.LoggerFactory;
  5 +import org.springframework.http.ResponseEntity;
  6 +import org.springframework.web.bind.annotation.PostMapping;
  7 +import org.springframework.web.bind.annotation.RequestMapping;
  8 +import org.springframework.web.bind.annotation.RestController;
  9 +
  10 +/**
  11 + * @Description:针对 ZLMediaServer的hook事件监听
  12 + * @author: songww
  13 + * @date: 2020年5月8日 上午10:46:48
  14 + */
  15 +@RestController
  16 +@RequestMapping("/hook/zlm")
  17 +public class ZLMHttpHookListener {
  18 +
  19 + private final static Logger logger = LoggerFactory.getLogger(ZLMHttpHookListener.class);
  20 +
  21 + /**
  22 + * 流量统计事件,播放器或推流器断开时并且耗用流量超过特定阈值时会触发此事件,阈值通过配置文件general.flowThreshold配置;此事件对回复不敏感。
  23 + *
  24 + */
  25 + @PostMapping("/on_flow_report")
  26 + public ResponseEntity onFlowReport(){
  27 + // TODO Auto-generated method stub
  28 +
  29 + return null;
  30 + }
  31 +
  32 + /**
  33 + * 访问http文件服务器上hls之外的文件时触发。
  34 + *
  35 + */
  36 + @PostMapping("/on_http_access")
  37 + public ResponseEntity onHttpAccess(){
  38 + // TODO Auto-generated method stub
  39 +
  40 + return null;
  41 + }
  42 +
  43 + /**
  44 + * 播放器鉴权事件,rtsp/rtmp/http-flv/ws-flv/hls的播放都将触发此鉴权事件。
  45 + *
  46 + */
  47 + @PostMapping("/on_play")
  48 + public ResponseEntity onPlay(){
  49 + // TODO Auto-generated method stub
  50 +
  51 + return null;
  52 + }
  53 +
  54 + /**
  55 + * rtsp/rtmp/rtp推流鉴权事件。
  56 + *
  57 + */
  58 + @PostMapping("/on_publish")
  59 + public ResponseEntity onPublish(){
  60 + // TODO Auto-generated method stub
  61 +
  62 + return null;
  63 + }
  64 +
  65 + /**
  66 + * 录制mp4完成后通知事件;此事件对回复不敏感。
  67 + *
  68 + */
  69 + @PostMapping("/on_record_mp4")
  70 + public ResponseEntity onRecordMp4(){
  71 + // TODO Auto-generated method stub
  72 +
  73 + return null;
  74 + }
  75 +
  76 + /**
  77 + * 该rtsp流是否开启rtsp专用方式的鉴权事件,开启后才会触发on_rtsp_auth事件。需要指出的是rtsp也支持url参数鉴权,它支持两种方式鉴权。
  78 + *
  79 + */
  80 + @PostMapping("/on_rtsp_auth")
  81 + public ResponseEntity onRtspAuth(){
  82 + // TODO Auto-generated method stub
  83 +
  84 + return null;
  85 + }
  86 +
  87 + /**
  88 + * rtsp专用的鉴权事件,先触发on_rtsp_realm事件然后才会触发on_rtsp_auth事件。
  89 + *
  90 + */
  91 + @PostMapping("/on_rtsp_realm")
  92 + public ResponseEntity onRtspRealm(){
  93 + // TODO Auto-generated method stub
  94 +
  95 + return null;
  96 + }
  97 +
  98 + /**
  99 + * shell登录鉴权,ZLMediaKit提供简单的telnet调试方式,使用telnet 127.0.0.1 9000能进入MediaServer进程的shell界面。
  100 + *
  101 + */
  102 + @PostMapping("/on_shell_login")
  103 + public ResponseEntity onShellLogin(){
  104 + // TODO Auto-generated method stub
  105 +
  106 + return null;
  107 + }
  108 +
  109 + /**
  110 + * rtsp/rtmp流注册或注销时触发此事件;此事件对回复不敏感。
  111 + *
  112 + */
  113 + @PostMapping("/on_stream_changed")
  114 + public ResponseEntity onStreamChanged(){
  115 + // TODO Auto-generated method stub
  116 +
  117 + return null;
  118 + }
  119 +
  120 + /**
  121 + * 流无人观看时事件,用户可以通过此事件选择是否关闭无人看的流。
  122 + *
  123 + */
  124 + @PostMapping("/on_stream_none_reader")
  125 + public ResponseEntity onStreamNoneReader(){
  126 + // TODO Auto-generated method stub
  127 +
  128 + return null;
  129 + }
  130 +
  131 + /**
  132 + * 流未找到事件,用户可以在此事件触发时,立即去拉流,这样可以实现按需拉流;此事件对回复不敏感。
  133 + *
  134 + */
  135 + @PostMapping("/on_stream_not_found")
  136 + public ResponseEntity onStreamNotFound(){
  137 + // TODO Auto-generated method stub
  138 +
  139 + return null;
  140 + }
  141 +
  142 + /**
  143 + * 服务器启动事件,可以用于监听服务器崩溃重启;此事件对回复不敏感。
  144 + *
  145 + */
  146 + @PostMapping("/on_server_started")
  147 + public ResponseEntity onServerStarted(){
  148 + // TODO Auto-generated method stub
  149 +
  150 + return null;
  151 + }
  152 +}
src/main/java/com/genersoft/iot/vmp/vmanager/device/DeviceController.java
1 package com.genersoft.iot.vmp.vmanager.device; 1 package com.genersoft.iot.vmp.vmanager.device;
2 2
3 -import java.util.ArrayList;  
4 import java.util.List; 3 import java.util.List;
  4 +import java.util.concurrent.ExecutorService;
  5 +import java.util.concurrent.Executors;
5 6
6 import org.slf4j.Logger; 7 import org.slf4j.Logger;
7 import org.slf4j.LoggerFactory; 8 import org.slf4j.LoggerFactory;
@@ -10,10 +11,14 @@ import org.springframework.http.HttpStatus; @@ -10,10 +11,14 @@ import org.springframework.http.HttpStatus;
10 import org.springframework.http.ResponseEntity; 11 import org.springframework.http.ResponseEntity;
11 import org.springframework.web.bind.annotation.GetMapping; 12 import org.springframework.web.bind.annotation.GetMapping;
12 import org.springframework.web.bind.annotation.PathVariable; 13 import org.springframework.web.bind.annotation.PathVariable;
  14 +import org.springframework.web.bind.annotation.PostMapping;
13 import org.springframework.web.bind.annotation.RequestMapping; 15 import org.springframework.web.bind.annotation.RequestMapping;
14 import org.springframework.web.bind.annotation.RestController; 16 import org.springframework.web.bind.annotation.RestController;
  17 +import org.springframework.web.context.request.async.DeferredResult;
15 18
16 import com.genersoft.iot.vmp.gb28181.bean.Device; 19 import com.genersoft.iot.vmp.gb28181.bean.Device;
  20 +import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder;
  21 +import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander;
17 import com.genersoft.iot.vmp.storager.IVideoManagerStorager; 22 import com.genersoft.iot.vmp.storager.IVideoManagerStorager;
18 23
19 @RestController 24 @RestController
@@ -25,16 +30,21 @@ public class DeviceController { @@ -25,16 +30,21 @@ public class DeviceController {
25 @Autowired 30 @Autowired
26 private IVideoManagerStorager storager; 31 private IVideoManagerStorager storager;
27 32
  33 + @Autowired
  34 + private SIPCommander cmder;
  35 +
  36 + @Autowired
  37 + private DeferredResultHolder resultHolder;
  38 +
28 @GetMapping("/devices/{deviceId}") 39 @GetMapping("/devices/{deviceId}")
29 - public ResponseEntity<List<Device>> devices(@PathVariable String deviceId){ 40 + public ResponseEntity<Device> devices(@PathVariable String deviceId){
30 41
31 if (logger.isDebugEnabled()) { 42 if (logger.isDebugEnabled()) {
32 logger.debug("查询视频设备API调用,deviceId:" + deviceId); 43 logger.debug("查询视频设备API调用,deviceId:" + deviceId);
33 } 44 }
34 45
35 - List<Device> deviceList = new ArrayList<>();  
36 - deviceList.add(storager.queryVideoDevice(deviceId));  
37 - return new ResponseEntity<>(deviceList,HttpStatus.OK); 46 + Device device = storager.queryVideoDevice(deviceId);
  47 + return new ResponseEntity<>(device,HttpStatus.OK);
38 } 48 }
39 49
40 @GetMapping("/devices") 50 @GetMapping("/devices")
@@ -47,4 +57,18 @@ public class DeviceController { @@ -47,4 +57,18 @@ public class DeviceController {
47 List<Device> deviceList = storager.queryVideoDeviceList(null); 57 List<Device> deviceList = storager.queryVideoDeviceList(null);
48 return new ResponseEntity<>(deviceList,HttpStatus.OK); 58 return new ResponseEntity<>(deviceList,HttpStatus.OK);
49 } 59 }
  60 +
  61 + @PostMapping("/devices/{deviceId}/sync")
  62 + public DeferredResult<ResponseEntity<Device>> devicesSync(@PathVariable String deviceId){
  63 +
  64 + if (logger.isDebugEnabled()) {
  65 + logger.debug("设备信息同步API调用,deviceId:" + deviceId);
  66 + }
  67 +
  68 + Device device = storager.queryVideoDevice(deviceId);
  69 + cmder.catalogQuery(device);
  70 + DeferredResult<ResponseEntity<Device>> result = new DeferredResult<ResponseEntity<Device>>();
  71 + resultHolder.put(DeferredResultHolder.CALLBACK_CMD_CATALOG+deviceId, result);
  72 + return result;
  73 + }
50 } 74 }
src/main/java/com/genersoft/iot/vmp/vmanager/play/PlayController.java
@@ -10,7 +10,9 @@ import org.springframework.web.bind.annotation.PathVariable; @@ -10,7 +10,9 @@ import org.springframework.web.bind.annotation.PathVariable;
10 import org.springframework.web.bind.annotation.RequestMapping; 10 import org.springframework.web.bind.annotation.RequestMapping;
11 import org.springframework.web.bind.annotation.RestController; 11 import org.springframework.web.bind.annotation.RestController;
12 12
  13 +import com.genersoft.iot.vmp.gb28181.bean.Device;
13 import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander; 14 import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander;
  15 +import com.genersoft.iot.vmp.storager.IVideoManagerStorager;
14 16
15 @RestController 17 @RestController
16 @RequestMapping("/api") 18 @RequestMapping("/api")
@@ -21,10 +23,14 @@ public class PlayController { @@ -21,10 +23,14 @@ public class PlayController {
21 @Autowired 23 @Autowired
22 private SIPCommander cmder; 24 private SIPCommander cmder;
23 25
  26 + @Autowired
  27 + private IVideoManagerStorager storager;
  28 +
24 @GetMapping("/play/{deviceId}_{channelId}") 29 @GetMapping("/play/{deviceId}_{channelId}")
25 public ResponseEntity<String> play(@PathVariable String deviceId,@PathVariable String channelId){ 30 public ResponseEntity<String> play(@PathVariable String deviceId,@PathVariable String channelId){
26 31
27 - String ssrc = cmder.playStreamCmd(deviceId, channelId); 32 + Device device = storager.queryVideoDevice(deviceId);
  33 + String ssrc = cmder.playStreamCmd(device, channelId);
28 34
29 if (logger.isDebugEnabled()) { 35 if (logger.isDebugEnabled()) {
30 logger.debug(String.format("设备预览 API调用,deviceId:%s ,channelId:%s",deviceId, channelId)); 36 logger.debug(String.format("设备预览 API调用,deviceId:%s ,channelId:%s",deviceId, channelId));
src/main/java/com/genersoft/iot/vmp/vmanager/ptz/PtzController.java
@@ -10,7 +10,9 @@ import org.springframework.web.bind.annotation.PathVariable; @@ -10,7 +10,9 @@ import org.springframework.web.bind.annotation.PathVariable;
10 import org.springframework.web.bind.annotation.RequestMapping; 10 import org.springframework.web.bind.annotation.RequestMapping;
11 import org.springframework.web.bind.annotation.RestController; 11 import org.springframework.web.bind.annotation.RestController;
12 12
  13 +import com.genersoft.iot.vmp.gb28181.bean.Device;
13 import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander; 14 import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander;
  15 +import com.genersoft.iot.vmp.storager.IVideoManagerStorager;
14 16
15 @RestController 17 @RestController
16 @RequestMapping("/api") 18 @RequestMapping("/api")
@@ -20,6 +22,9 @@ public class PtzController { @@ -20,6 +22,9 @@ public class PtzController {
20 22
21 @Autowired 23 @Autowired
22 private SIPCommander cmder; 24 private SIPCommander cmder;
  25 +
  26 + @Autowired
  27 + private IVideoManagerStorager storager;
23 28
24 /*** 29 /***
25 * http://localhost:8080/api/ptz/34020000001320000002_34020000001320000008?leftRight=1&upDown=0&inOut=0&moveSpeed=50&zoomSpeed=0 30 * http://localhost:8080/api/ptz/34020000001320000002_34020000001320000008?leftRight=1&upDown=0&inOut=0&moveSpeed=50&zoomSpeed=0
@@ -38,8 +43,9 @@ public class PtzController { @@ -38,8 +43,9 @@ public class PtzController {
38 if (logger.isDebugEnabled()) { 43 if (logger.isDebugEnabled()) {
39 logger.debug(String.format("设备云台控制 API调用,deviceId:%s ,channelId:%s ,leftRight:%d ,upDown:%d ,inOut:%d ,moveSpeed:%d ,zoomSpeed:%d",deviceId, channelId, leftRight, upDown, inOut, moveSpeed, zoomSpeed)); 44 logger.debug(String.format("设备云台控制 API调用,deviceId:%s ,channelId:%s ,leftRight:%d ,upDown:%d ,inOut:%d ,moveSpeed:%d ,zoomSpeed:%d",deviceId, channelId, leftRight, upDown, inOut, moveSpeed, zoomSpeed));
40 } 45 }
  46 + Device device = storager.queryVideoDevice(deviceId);
41 47
42 - cmder.ptzCmd(deviceId, channelId, leftRight, upDown, inOut, moveSpeed, zoomSpeed); 48 + cmder.ptzCmd(device, channelId, leftRight, upDown, inOut, moveSpeed, zoomSpeed);
43 return new ResponseEntity<String>("success",HttpStatus.OK); 49 return new ResponseEntity<String>("success",HttpStatus.OK);
44 } 50 }
45 } 51 }
src/main/java/com/genersoft/iot/vmp/vmanager/record/RecordController.java 0 → 100644
  1 +package com.genersoft.iot.vmp.vmanager.record;
  2 +
  3 +import org.slf4j.Logger;
  4 +import org.slf4j.LoggerFactory;
  5 +import org.springframework.beans.factory.annotation.Autowired;
  6 +import org.springframework.http.ResponseEntity;
  7 +import org.springframework.web.bind.annotation.GetMapping;
  8 +import org.springframework.web.bind.annotation.PathVariable;
  9 +import org.springframework.web.bind.annotation.RequestMapping;
  10 +import org.springframework.web.bind.annotation.RestController;
  11 +import org.springframework.web.context.request.async.DeferredResult;
  12 +
  13 +import com.genersoft.iot.vmp.gb28181.bean.Device;
  14 +import com.genersoft.iot.vmp.gb28181.bean.RecordInfo;
  15 +import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder;
  16 +import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander;
  17 +import com.genersoft.iot.vmp.storager.IVideoManagerStorager;
  18 +
  19 +@RestController
  20 +@RequestMapping("/api")
  21 +public class RecordController {
  22 +
  23 + private final static Logger logger = LoggerFactory.getLogger(RecordController.class);
  24 +
  25 + @Autowired
  26 + private SIPCommander cmder;
  27 +
  28 + @Autowired
  29 + private IVideoManagerStorager storager;
  30 +
  31 + @Autowired
  32 + private DeferredResultHolder resultHolder;
  33 +
  34 + @GetMapping("/recordinfo/{deviceId}")
  35 + public DeferredResult<ResponseEntity<RecordInfo>> recordinfo(@PathVariable String deviceId, String startTime, String endTime){
  36 +
  37 + if (logger.isDebugEnabled()) {
  38 + logger.debug(String.format("录像信息 API调用,deviceId:%s ,startTime:%s, startTime:%s",deviceId, startTime, endTime));
  39 + }
  40 +
  41 + Device device = storager.queryVideoDevice(deviceId);
  42 + cmder.recordInfoQuery(device, startTime, endTime);
  43 + DeferredResult<ResponseEntity<RecordInfo>> result = new DeferredResult<ResponseEntity<RecordInfo>>();
  44 + resultHolder.put(DeferredResultHolder.CALLBACK_CMD_CATALOG+deviceId, result);
  45 + return result;
  46 + }
  47 +}