Commit 175720320244a7d576e576b65e1995f53d9f843e

Authored by 648540858
1 parent ec749de7

支持海康摄像头国标录像查看播放

src/main/java/com/genersoft/iot/vmp/gb28181/SipLayer.java
... ... @@ -81,11 +81,11 @@ public class SipLayer{
81 81 tcpSipProvider.setDialogErrorsAutomaticallyHandled();
82 82 tcpSipProvider.addSipListener(sipProcessorObserver);
83 83 // tcpSipProvider.setAutomaticDialogSupportEnabled(false);
84   - logger.info("Sip Server TCP 启动成功 port {" + sipConfig.getMonitorIp() + ":" + sipConfig.getPort() + "}");
  84 + logger.info("[Sip Server] TCP 启动成功 {}:{}", sipConfig.getMonitorIp(), sipConfig.getPort());
85 85 } catch (TransportNotSupportedException e) {
86 86 e.printStackTrace();
87 87 } catch (InvalidArgumentException e) {
88   - logger.error("无法使用 [ {}:{} ]作为SIP[ TCP ]服务,可排查: 1. sip.monitor-ip 是否为本机网卡IP; 2. sip.port 是否已被占用"
  88 + logger.error("[Sip Server] 无法使用 [ {}:{} ]作为SIP[ TCP ]服务,可排查: 1. sip.monitor-ip 是否为本机网卡IP; 2. sip.port 是否已被占用"
89 89 , sipConfig.getMonitorIp(), sipConfig.getPort());
90 90 } catch (TooManyListenersException e) {
91 91 e.printStackTrace();
... ... @@ -108,14 +108,14 @@ public class SipLayer{
108 108 } catch (TransportNotSupportedException e) {
109 109 e.printStackTrace();
110 110 } catch (InvalidArgumentException e) {
111   - logger.error("无法使用 [ {}:{} ]作为SIP[ UDP ]服务,可排查: 1. sip.monitor-ip 是否为本机网卡IP; 2. sip.port 是否已被占用"
  111 + logger.error("[Sip Server] 无法使用 [ {}:{} ]作为SIP[ UDP ]服务,可排查: 1. sip.monitor-ip 是否为本机网卡IP; 2. sip.port 是否已被占用"
112 112 , sipConfig.getMonitorIp(), sipConfig.getPort());
113 113 } catch (TooManyListenersException e) {
114 114 e.printStackTrace();
115 115 } catch (ObjectInUseException e) {
116 116 e.printStackTrace();
117 117 }
118   - logger.info("Sip Server UDP 启动成功 port [" + sipConfig.getMonitorIp() + ":" + sipConfig.getPort() + "]");
  118 + logger.info("[Sip Server] UDP 启动成功 {}:{}", sipConfig.getMonitorIp(), sipConfig.getPort());
119 119 return udpSipProvider;
120 120 }
121 121  
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/bean/RecordInfo.java
1 1 package com.genersoft.iot.vmp.gb28181.bean;
2 2  
3   -
4   -//import gov.nist.javax.sip.header.SIPDate;
5   -
  3 +import java.util.Date;
6 4 import java.util.List;
7 5  
8 6 /**
... ... @@ -21,6 +19,8 @@ public class RecordInfo {
21 19 private String name;
22 20  
23 21 private int sumNum;
  22 +
  23 + private Date lastTime;
24 24  
25 25 private List<RecordItem> recordList;
26 26  
... ... @@ -71,4 +71,12 @@ public class RecordInfo {
71 71 public void setSn(String sn) {
72 72 this.sn = sn;
73 73 }
  74 +
  75 + public Date getLastTime() {
  76 + return lastTime;
  77 + }
  78 +
  79 + public void setLastTime(Date lastTime) {
  80 + this.lastTime = lastTime;
  81 + }
74 82 }
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/session/RecordDataCatch.java 0 → 100644
  1 +package com.genersoft.iot.vmp.gb28181.session;
  2 +
  3 +import com.genersoft.iot.vmp.gb28181.bean.*;
  4 +import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder;
  5 +import com.genersoft.iot.vmp.gb28181.transmit.callback.RequestMessage;
  6 +import com.genersoft.iot.vmp.storager.IVideoManagerStorage;
  7 +import com.genersoft.iot.vmp.utils.DateUtil;
  8 +import com.genersoft.iot.vmp.vmanager.bean.WVPResult;
  9 +import org.springframework.beans.factory.annotation.Autowired;
  10 +import org.springframework.scheduling.annotation.Scheduled;
  11 +import org.springframework.stereotype.Component;
  12 +
  13 +import java.text.SimpleDateFormat;
  14 +import java.util.*;
  15 +import java.util.concurrent.ConcurrentHashMap;
  16 +
  17 +/**
  18 + * @author lin
  19 + */
  20 +@Component
  21 +public class RecordDataCatch {
  22 +
  23 + public static Map<String, RecordInfo> data = new ConcurrentHashMap<>();
  24 +
  25 + @Autowired
  26 + private DeferredResultHolder deferredResultHolder;
  27 +
  28 +
  29 + public int put(String deviceId, String sn, int sumNum, List<RecordItem> recordItems) {
  30 + String key = deviceId + sn;
  31 + RecordInfo recordInfo = data.get(key);
  32 + if (recordInfo == null) {
  33 + recordInfo = new RecordInfo();
  34 + recordInfo.setDeviceId(deviceId);
  35 + recordInfo.setSn(sn.trim());
  36 + recordInfo.setSumNum(sumNum);
  37 + recordInfo.setRecordList(Collections.synchronizedList(new ArrayList<>()));
  38 + recordInfo.setLastTime(new Date(System.currentTimeMillis()));
  39 + recordInfo.getRecordList().addAll(recordItems);
  40 + data.put(key, recordInfo);
  41 + }else {
  42 + // 同一个设备的通道同步请求只考虑一个,其他的直接忽略
  43 + if (!Objects.equals(sn.trim(), recordInfo.getSn())) {
  44 + return 0;
  45 + }
  46 + recordInfo.getRecordList().addAll(recordItems);
  47 + recordInfo.setLastTime(new Date(System.currentTimeMillis()));
  48 + }
  49 + return recordInfo.getRecordList().size();
  50 + }
  51 +
  52 + @Scheduled(fixedRate = 5 * 1000) //每5秒执行一次, 发现数据5秒未更新则移除数据并认为数据接收超时
  53 + private void timerTask(){
  54 + Set<String> keys = data.keySet();
  55 + Calendar calendarBefore5S = Calendar.getInstance();
  56 + calendarBefore5S.setTime(new Date());
  57 + calendarBefore5S.set(Calendar.SECOND, calendarBefore5S.get(Calendar.SECOND) - 5);
  58 +
  59 + for (String key : keys) {
  60 + RecordInfo recordInfo = data.get(key);
  61 + // 超过五秒收不到消息任务超时, 只更新这一部分数据
  62 + if ( recordInfo.getLastTime().before(calendarBefore5S.getTime())) {
  63 + // 处理录像数据, 返回给前端
  64 + String msgKey = DeferredResultHolder.CALLBACK_CMD_RECORDINFO + recordInfo.getDeviceId() + recordInfo.getSn();
  65 +
  66 + WVPResult<RecordInfo> wvpResult = new WVPResult<>();
  67 + wvpResult.setCode(0);
  68 + wvpResult.setMsg("success");
  69 + // 对数据进行排序
  70 + Collections.sort(recordInfo.getRecordList());
  71 + wvpResult.setData(recordInfo);
  72 +
  73 + RequestMessage msg = new RequestMessage();
  74 + msg.setKey(msgKey);
  75 + msg.setData(wvpResult);
  76 + deferredResultHolder.invokeAllResult(msg);
  77 + data.remove(key);
  78 + }
  79 + }
  80 + }
  81 +
  82 + public boolean isComplete(String deviceId, String sn) {
  83 + RecordInfo recordInfo = data.get(deviceId + sn);
  84 + return recordInfo != null && recordInfo.getRecordList().size() == recordInfo.getSumNum();
  85 + }
  86 +
  87 + public RecordInfo getRecordInfo(String deviceId, String sn) {
  88 + return data.get(deviceId + sn);
  89 + }
  90 +
  91 + public void remove(String deviceId, String sn) {
  92 + data.remove(deviceId + sn);
  93 + }
  94 +}
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/callback/CheckForAllRecordsThread.java deleted 100644 → 0
1   -package com.genersoft.iot.vmp.gb28181.transmit.callback;
2   -
3   -import com.genersoft.iot.vmp.gb28181.bean.RecordInfo;
4   -import com.genersoft.iot.vmp.gb28181.bean.RecordItem;
5   -import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.response.cmd.RecordInfoResponseMessageHandler;
6   -import com.genersoft.iot.vmp.utils.redis.RedisUtil;
7   -import org.slf4j.Logger;
8   -
9   -import java.util.ArrayList;
10   -import java.util.Comparator;
11   -import java.util.List;
12   -import java.util.concurrent.TimeUnit;
13   -
14   -@SuppressWarnings("unchecked")
15   -public class CheckForAllRecordsThread extends Thread {
16   -
17   - private String key;
18   -
19   - private RecordInfo recordInfo;
20   -
21   - private RedisUtil redis;
22   -
23   - private Logger logger;
24   -
25   - private DeferredResultHolder deferredResultHolder;
26   -
27   - public CheckForAllRecordsThread(String key, RecordInfo recordInfo) {
28   - this.key = key;
29   - this.recordInfo = recordInfo;
30   - }
31   -
32   - @Override
33   - public void run() {
34   -
35   - String cacheKey = this.key;
36   -
37   - for (long stop = System.nanoTime() + TimeUnit.SECONDS.toNanos(10); stop > System.nanoTime();) {
38   - List<Object> cacheKeys = redis.scan(cacheKey + "_*");
39   - List<RecordItem> totalRecordList = new ArrayList<RecordItem>();
40   - for (int i = 0; i < cacheKeys.size(); i++) {
41   - totalRecordList.addAll((List<RecordItem>) redis.get(cacheKeys.get(i).toString()));
42   - }
43   - if (totalRecordList.size() < this.recordInfo.getSumNum()) {
44   - logger.info("已获取" + totalRecordList.size() + "项录像数据,共" + this.recordInfo.getSumNum() + "项");
45   - } else {
46   - logger.info("录像数据已全部获取,共 {} 项", this.recordInfo.getSumNum());
47   - this.recordInfo.setRecordList(totalRecordList);
48   - for (int i = 0; i < cacheKeys.size(); i++) {
49   - redis.del(cacheKeys.get(i).toString());
50   - }
51   - break;
52   - }
53   - }
54   - // 自然顺序排序, 元素进行升序排列
55   - this.recordInfo.getRecordList().sort(Comparator.naturalOrder());
56   - RequestMessage msg = new RequestMessage();
57   - msg.setKey(DeferredResultHolder.CALLBACK_CMD_RECORDINFO + recordInfo.getDeviceId() + recordInfo.getSn());
58   - msg.setData(recordInfo);
59   - deferredResultHolder.invokeAllResult(msg);
60   - logger.info("处理完成,返回结果");
61   - RecordInfoResponseMessageHandler.threadNameList.remove(cacheKey);
62   - }
63   -
64   - public void setRedis(RedisUtil redis) {
65   - this.redis = redis;
66   - }
67   -
68   - public void setDeferredResultHolder(DeferredResultHolder deferredResultHolder) {
69   - this.deferredResultHolder = deferredResultHolder;
70   - }
71   -
72   - public void setLogger(Logger logger) {
73   - this.logger = logger;
74   - }
75   -
76   -}
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java
... ... @@ -370,7 +370,7 @@ public class SIPCommander implements ISIPCommander {
370 370 //
371 371 StringBuffer content = new StringBuffer(200);
372 372 content.append("v=0\r\n");
373   - content.append("o="+ sipConfig.getId()+" 0 0 IN IP4 "+ mediaServerItem.getSdpIp() +"\r\n");
  373 + content.append("o="+ channelId+" 0 0 IN IP4 "+ mediaServerItem.getSdpIp() +"\r\n");
374 374 content.append("s=Play\r\n");
375 375 content.append("c=IN IP4 "+ mediaServerItem.getSdpIp() +"\r\n");
376 376 content.append("t=0 0\r\n");
... ... @@ -389,8 +389,7 @@ public class SIPCommander implements ISIPCommander {
389 389 content.append("a=rtpmap:126 H264/90000\r\n");
390 390 content.append("a=rtpmap:125 H264S/90000\r\n");
391 391 content.append("a=fmtp:125 profile-level-id=42e01e\r\n");
392   - content.append("a=rtpmap:99 MP4V-ES/90000\r\n");
393   - content.append("a=fmtp:99 profile-level-id=3\r\n");
  392 + content.append("a=rtpmap:99 H265/90000\r\n");
394 393 content.append("a=rtpmap:98 H264/90000\r\n");
395 394 content.append("a=rtpmap:97 MPEG4/90000\r\n");
396 395 if("TCP-PASSIVE".equals(streamMode)){ // tcp被动模式
... ... @@ -402,16 +401,17 @@ public class SIPCommander implements ISIPCommander {
402 401 }
403 402 }else {
404 403 if("TCP-PASSIVE".equals(streamMode)) {
405   - content.append("m=video "+ ssrcInfo.getPort() +" TCP/RTP/AVP 96 98 97\r\n");
  404 + content.append("m=video "+ ssrcInfo.getPort() +" TCP/RTP/AVP 96 97 98 99\r\n");
406 405 }else if ("TCP-ACTIVE".equals(streamMode)) {
407   - content.append("m=video "+ ssrcInfo.getPort() +" TCP/RTP/AVP 96 98 97\r\n");
  406 + content.append("m=video "+ ssrcInfo.getPort() +" TCP/RTP/AVP 96 97 98 99\r\n");
408 407 }else if("UDP".equals(streamMode)) {
409   - content.append("m=video "+ ssrcInfo.getPort() +" RTP/AVP 96 98 97\r\n");
  408 + content.append("m=video "+ ssrcInfo.getPort() +" RTP/AVP 96 97 98 99\r\n");
410 409 }
411 410 content.append("a=recvonly\r\n");
412 411 content.append("a=rtpmap:96 PS/90000\r\n");
413 412 content.append("a=rtpmap:98 H264/90000\r\n");
414 413 content.append("a=rtpmap:97 MPEG4/90000\r\n");
  414 + content.append("a=rtpmap:99 H265/90000\r\n");
415 415 if ("TCP-PASSIVE".equals(streamMode)) { // tcp被动模式
416 416 content.append("a=setup:passive\r\n");
417 417 content.append("a=connection:new\r\n");
... ... @@ -467,7 +467,7 @@ public class SIPCommander implements ISIPCommander {
467 467  
468 468 StringBuffer content = new StringBuffer(200);
469 469 content.append("v=0\r\n");
470   - content.append("o="+sipConfig.getId()+" 0 0 IN IP4 " + mediaServerItem.getSdpIp() + "\r\n");
  470 + content.append("o="+channelId+" 0 0 IN IP4 " + mediaServerItem.getSdpIp() + "\r\n");
471 471 content.append("s=Playback\r\n");
472 472 content.append("u="+channelId+":0\r\n");
473 473 content.append("c=IN IP4 "+mediaServerItem.getSdpIp()+"\r\n");
... ... @@ -490,8 +490,7 @@ public class SIPCommander implements ISIPCommander {
490 490 content.append("a=rtpmap:126 H264/90000\r\n");
491 491 content.append("a=rtpmap:125 H264S/90000\r\n");
492 492 content.append("a=fmtp:125 profile-level-id=42e01e\r\n");
493   - content.append("a=rtpmap:99 MP4V-ES/90000\r\n");
494   - content.append("a=fmtp:99 profile-level-id=3\r\n");
  493 + content.append("a=rtpmap:99 H265/90000\r\n");
495 494 content.append("a=rtpmap:98 H264/90000\r\n");
496 495 content.append("a=rtpmap:97 MPEG4/90000\r\n");
497 496 if("TCP-PASSIVE".equals(streamMode)){ // tcp被动模式
... ... @@ -503,16 +502,17 @@ public class SIPCommander implements ISIPCommander {
503 502 }
504 503 }else {
505 504 if("TCP-PASSIVE".equals(streamMode)) {
506   - content.append("m=video "+ ssrcInfo.getPort() +" TCP/RTP/AVP 96 98 97\r\n");
  505 + content.append("m=video "+ ssrcInfo.getPort() +" TCP/RTP/AVP 96 97 98 99\r\n");
507 506 }else if ("TCP-ACTIVE".equals(streamMode)) {
508   - content.append("m=video "+ ssrcInfo.getPort() +" TCP/RTP/AVP 96 98 97\r\n");
  507 + content.append("m=video "+ ssrcInfo.getPort() +" TCP/RTP/AVP 96 97 98 99\r\n");
509 508 }else if("UDP".equals(streamMode)) {
510   - content.append("m=video "+ ssrcInfo.getPort() +" RTP/AVP 96 98 97\r\n");
  509 + content.append("m=video "+ ssrcInfo.getPort() +" RTP/AVP 96 97 98 99\r\n");
511 510 }
512 511 content.append("a=recvonly\r\n");
513 512 content.append("a=rtpmap:96 PS/90000\r\n");
514   - content.append("a=rtpmap:98 H264/90000\r\n");
515 513 content.append("a=rtpmap:97 MPEG4/90000\r\n");
  514 + content.append("a=rtpmap:98 H264/90000\r\n");
  515 + content.append("a=rtpmap:99 H265/90000\r\n");
516 516 if("TCP-PASSIVE".equals(streamMode)){ // tcp被动模式
517 517 content.append("a=setup:passive\r\n");
518 518 content.append("a=connection:new\r\n");
... ... @@ -577,7 +577,7 @@ public class SIPCommander implements ISIPCommander {
577 577  
578 578 StringBuffer content = new StringBuffer(200);
579 579 content.append("v=0\r\n");
580   - content.append("o="+sipConfig.getId()+" 0 0 IN IP4 " + mediaServerItem.getSdpIp() + "\r\n");
  580 + content.append("o="+channelId+" 0 0 IN IP4 " + mediaServerItem.getSdpIp() + "\r\n");
581 581 content.append("s=Download\r\n");
582 582 content.append("u="+channelId+":0\r\n");
583 583 content.append("c=IN IP4 "+mediaServerItem.getSdpIp()+"\r\n");
... ... @@ -613,16 +613,17 @@ public class SIPCommander implements ISIPCommander {
613 613 }
614 614 }else {
615 615 if("TCP-PASSIVE".equals(streamMode)) {
616   - content.append("m=video "+ ssrcInfo.getPort() +" TCP/RTP/AVP 96 98 97\r\n");
  616 + content.append("m=video "+ ssrcInfo.getPort() +" TCP/RTP/AVP 96 97 98 99\r\n");
617 617 }else if ("TCP-ACTIVE".equals(streamMode)) {
618   - content.append("m=video "+ ssrcInfo.getPort() +" TCP/RTP/AVP 96 98 97\r\n");
  618 + content.append("m=video "+ ssrcInfo.getPort() +" TCP/RTP/AVP 96 97 98 99\r\n");
619 619 }else if("UDP".equals(streamMode)) {
620   - content.append("m=video "+ ssrcInfo.getPort() +" RTP/AVP 96 98 97\r\n");
  620 + content.append("m=video "+ ssrcInfo.getPort() +" RTP/AVP 96 97 98 99\r\n");
621 621 }
622 622 content.append("a=recvonly\r\n");
623 623 content.append("a=rtpmap:96 PS/90000\r\n");
624   - content.append("a=rtpmap:98 H264/90000\r\n");
625 624 content.append("a=rtpmap:97 MPEG4/90000\r\n");
  625 + content.append("a=rtpmap:98 H264/90000\r\n");
  626 + content.append("a=rtpmap:99 H265/90000\r\n");
626 627 if("TCP-PASSIVE".equals(streamMode)){ // tcp被动模式
627 628 content.append("a=setup:passive\r\n");
628 629 content.append("a=connection:new\r\n");
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/InviteRequestProcessor.java
... ... @@ -331,7 +331,7 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements
331 331 sendRtpItem.setApp("rtp");
332 332 if ("Playback".equals(sessionName)) {
333 333 sendRtpItem.setPlayType(InviteStreamType.PLAYBACK);
334   - SSRCInfo ssrcInfo = mediaServerService.openRTPServer(mediaServerItem, null, true);
  334 + SSRCInfo ssrcInfo = mediaServerService.openRTPServer(mediaServerItem, null, true, true);
335 335 sendRtpItem.setStreamId(ssrcInfo.getStream());
336 336 // 写入redis, 超时时回复
337 337 redisCatchStorage.updateSendRTPSever(sendRtpItem);
... ... @@ -372,7 +372,7 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements
372 372 if (mediaServerItem.isRtpEnable()) {
373 373 streamId = String.format("%s_%s", device.getDeviceId(), channelId);
374 374 }
375   - SSRCInfo ssrcInfo = mediaServerService.openRTPServer(mediaServerItem, streamId, true);
  375 + SSRCInfo ssrcInfo = mediaServerService.openRTPServer(mediaServerItem, streamId, true, false);
376 376 sendRtpItem.setStreamId(ssrcInfo.getStream());
377 377 // 写入redis, 超时时回复
378 378 redisCatchStorage.updateSendRTPSever(sendRtpItem);
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/RegisterRequestProcessor.java
... ... @@ -81,7 +81,7 @@ public class RegisterRequestProcessor extends SIPRequestProcessorParent implemen
81 81 try {
82 82 RequestEventExt evtExt = (RequestEventExt) evt;
83 83 String requestAddress = evtExt.getRemoteIpAddress() + ":" + evtExt.getRemotePort();
84   - logger.info("[{}] 收到注册请求,开始处理", requestAddress);
  84 + logger.info("[注册请求] 开始处理: {}", requestAddress);
85 85 Request request = evt.getRequest();
86 86 ExpiresHeader expiresHeader = (ExpiresHeader) request.getHeader(Expires.NAME);
87 87 Response response = null;
... ... @@ -95,7 +95,7 @@ public class RegisterRequestProcessor extends SIPRequestProcessorParent implemen
95 95  
96 96 AuthorizationHeader authHead = (AuthorizationHeader) request.getHeader(AuthorizationHeader.NAME);
97 97 if (authHead == null) {
98   - logger.info("[{}] 未携带授权头 回复401", requestAddress);
  98 + logger.info("[注册请求] 未携带授权头 回复401: {}", requestAddress);
99 99 response = getMessageFactory().createResponse(Response.UNAUTHORIZED, request);
100 100 new DigestServerAuthenticationHelper().generateChallenge(getHeaderFactory(), response, sipConfig.getDomain());
101 101 sendResponse(evt, response);
... ... @@ -111,7 +111,7 @@ public class RegisterRequestProcessor extends SIPRequestProcessorParent implemen
111 111 // 注册失败
112 112 response = getMessageFactory().createResponse(Response.FORBIDDEN, request);
113 113 response.setReasonPhrase("wrong password");
114   - logger.info("[{}] 密码/SIP服务器ID错误, 回复403", requestAddress);
  114 + logger.info("[注册请求] 密码/SIP服务器ID错误, 回复403: {}", requestAddress);
115 115 sendResponse(evt, response);
116 116 return;
117 117 }
... ... @@ -176,11 +176,11 @@ public class RegisterRequestProcessor extends SIPRequestProcessorParent implemen
176 176 // 注册成功
177 177 // 保存到redis
178 178 if (registerFlag) {
179   - logger.info("[{}] 注册成功! deviceId:" + deviceId, requestAddress);
  179 + logger.info("[注册成功] deviceId: {}->{}", deviceId, requestAddress);
180 180 device.setRegisterTime(DateUtil.getNow());
181 181 deviceService.online(device);
182 182 } else {
183   - logger.info("[{}] 注销成功! deviceId:" + deviceId, requestAddress);
  183 + logger.info("[注销成功] deviceId: {}->{}" ,deviceId, requestAddress);
184 184 deviceService.offline(deviceId);
185 185 }
186 186 } catch (SipException | InvalidArgumentException | NoSuchAlgorithmException | ParseException e) {
... ... @@ -192,7 +192,7 @@ public class RegisterRequestProcessor extends SIPRequestProcessorParent implemen
192 192 private void sendResponse(RequestEvent evt, Response response) throws InvalidArgumentException, SipException {
193 193 ServerTransaction serverTransaction = getServerTransaction(evt);
194 194 if (serverTransaction == null) {
195   - logger.warn("回复失败:{}", response);
  195 + logger.warn("[回复失败]:{}", response);
196 196 return;
197 197 }
198 198 serverTransaction.sendResponse(response);
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/response/cmd/RecordInfoResponseMessageHandler.java
... ... @@ -5,14 +5,14 @@ import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform;
5 5 import com.genersoft.iot.vmp.gb28181.bean.RecordInfo;
6 6 import com.genersoft.iot.vmp.gb28181.bean.RecordItem;
7 7 import com.genersoft.iot.vmp.gb28181.event.EventPublisher;
8   -import com.genersoft.iot.vmp.gb28181.transmit.callback.CheckForAllRecordsThread;
  8 +import com.genersoft.iot.vmp.gb28181.session.RecordDataCatch;
9 9 import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder;
10 10 import com.genersoft.iot.vmp.gb28181.transmit.callback.RequestMessage;
11 11 import com.genersoft.iot.vmp.gb28181.transmit.event.request.SIPRequestProcessorParent;
12 12 import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.IMessageHandler;
13 13 import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.response.ResponseMessageHandler;
14 14 import com.genersoft.iot.vmp.utils.DateUtil;
15   -import com.genersoft.iot.vmp.utils.redis.RedisUtil;
  15 +import com.genersoft.iot.vmp.vmanager.bean.WVPResult;
16 16 import org.dom4j.DocumentException;
17 17 import org.dom4j.Element;
18 18 import org.slf4j.Logger;
... ... @@ -20,19 +20,20 @@ import org.slf4j.LoggerFactory;
20 20 import org.springframework.beans.factory.InitializingBean;
21 21 import org.springframework.beans.factory.annotation.Autowired;
22 22 import org.springframework.stereotype.Component;
  23 +import org.springframework.util.StringUtils;
23 24  
24 25 import javax.sip.InvalidArgumentException;
25 26 import javax.sip.RequestEvent;
26 27 import javax.sip.SipException;
27 28 import javax.sip.message.Response;
28 29 import java.text.ParseException;
29   -import java.util.ArrayList;
30   -import java.util.Iterator;
31   -import java.util.List;
32   -import java.util.UUID;
  30 +import java.util.*;
33 31  
34 32 import static com.genersoft.iot.vmp.gb28181.utils.XmlUtil.getText;
35 33  
  34 +/**
  35 + * @author lin
  36 + */
36 37 @Component
37 38 public class RecordInfoResponseMessageHandler extends SIPRequestProcessorParent implements InitializingBean, IMessageHandler {
38 39  
... ... @@ -45,11 +46,13 @@ public class RecordInfoResponseMessageHandler extends SIPRequestProcessorParent
45 46 private ResponseMessageHandler responseMessageHandler;
46 47  
47 48 @Autowired
48   - private RedisUtil redis;
  49 + private RecordDataCatch recordDataCatch;
49 50  
50 51 @Autowired
51 52 private DeferredResultHolder deferredResultHolder;
52 53  
  54 +
  55 +
53 56 @Autowired
54 57 private EventPublisher eventPublisher;
55 58  
... ... @@ -66,32 +69,22 @@ public class RecordInfoResponseMessageHandler extends SIPRequestProcessorParent
66 69 responseAck(evt, Response.OK);
67 70  
68 71 rootElement = getRootElement(evt, device.getCharset());
69   - String uuid = UUID.randomUUID().toString().replace("-", "");
70   - RecordInfo recordInfo = new RecordInfo();
71 72 String sn = getText(rootElement, "SN");
72   - String key = DeferredResultHolder.CALLBACK_CMD_RECORDINFO + device.getDeviceId() + sn;
73   - recordInfo.setDeviceId(device.getDeviceId());
74   - recordInfo.setSn(sn);
75   - recordInfo.setName(getText(rootElement, "Name"));
76   - if (getText(rootElement, "SumNum") == null || getText(rootElement, "SumNum") == "") {
77   - recordInfo.setSumNum(0);
78   - } else {
79   - recordInfo.setSumNum(Integer.parseInt(getText(rootElement, "SumNum")));
  73 +
  74 + String sumNumStr = getText(rootElement, "SumNum");
  75 + int sumNum = 0;
  76 + if (!StringUtils.isEmpty(sumNumStr)) {
  77 + sumNum = Integer.parseInt(sumNumStr);
80 78 }
81 79 Element recordListElement = rootElement.element("RecordList");
82   - if (recordListElement == null || recordInfo.getSumNum() == 0) {
  80 + if (recordListElement == null || sumNum == 0) {
83 81 logger.info("无录像数据");
84   - eventPublisher.recordEndEventPush(recordInfo);
85   - RequestMessage msg = new RequestMessage();
86   - msg.setKey(key);
87   - msg.setData(recordInfo);
88   - deferredResultHolder.invokeAllResult(msg);
  82 + recordDataCatch.put(device.getDeviceId(), sn, sumNum, new ArrayList<>());
  83 + releaseRequest(device.getDeviceId(), sn);
89 84 } else {
90 85 Iterator<Element> recordListIterator = recordListElement.elementIterator();
91   - List<RecordItem> recordList = new ArrayList<RecordItem>();
92 86 if (recordListIterator != null) {
93   - RecordItem record = new RecordItem();
94   - logger.info("处理录像列表数据...");
  87 + List<RecordItem> recordList = new ArrayList<>();
95 88 // 遍历DeviceList
96 89 while (recordListIterator.hasNext()) {
97 90 Element itemRecord = recordListIterator.next();
... ... @@ -100,43 +93,31 @@ public class RecordInfoResponseMessageHandler extends SIPRequestProcessorParent
100 93 logger.info("记录为空,下一个...");
101 94 continue;
102 95 }
103   - record = new RecordItem();
  96 + RecordItem record = new RecordItem();
104 97 record.setDeviceId(getText(itemRecord, "DeviceID"));
105 98 record.setName(getText(itemRecord, "Name"));
106 99 record.setFilePath(getText(itemRecord, "FilePath"));
107 100 record.setFileSize(getText(itemRecord, "FileSize"));
108 101 record.setAddress(getText(itemRecord, "Address"));
109   - record.setStartTime(
110   - DateUtil.ISO8601Toyyyy_MM_dd_HH_mm_ss(getText(itemRecord, "StartTime")));
111   - record.setEndTime(
112   - DateUtil.ISO8601Toyyyy_MM_dd_HH_mm_ss(getText(itemRecord, "EndTime")));
  102 +
  103 + String startTimeStr = getText(itemRecord, "StartTime");
  104 + record.setStartTime(DateUtil.ISO8601Toyyyy_MM_dd_HH_mm_ss(startTimeStr));
  105 +
  106 + String endTimeStr = getText(itemRecord, "EndTime");
  107 + record.setEndTime(DateUtil.ISO8601Toyyyy_MM_dd_HH_mm_ss(endTimeStr));
  108 +
113 109 record.setSecrecy(itemRecord.element("Secrecy") == null ? 0
114 110 : Integer.parseInt(getText(itemRecord, "Secrecy")));
115 111 record.setType(getText(itemRecord, "Type"));
116 112 record.setRecorderId(getText(itemRecord, "RecorderID"));
117 113 recordList.add(record);
118 114 }
119   - recordInfo.setRecordList(recordList);
  115 + int count = recordDataCatch.put(device.getDeviceId(), sn, sumNum, recordList);
  116 + logger.info("[国标录像], {}->{}: {}/{}", device.getDeviceId(), sn, count, sumNum);
120 117 }
121   - eventPublisher.recordEndEventPush(recordInfo);
122   - // 改用单独线程统计已获取录像文件数量,避免多包并行分别统计不完整的问题
123   - String cacheKey = CACHE_RECORDINFO_KEY + device.getDeviceId() + sn;
124   - redis.set(cacheKey + "_" + uuid, recordList, 90);
125   - if (!threadNameList.contains(cacheKey)) {
126   - threadNameList.add(cacheKey);
127   - CheckForAllRecordsThread chk = new CheckForAllRecordsThread(cacheKey, recordInfo);
128   - chk.setName(cacheKey);
129   - chk.setDeferredResultHolder(deferredResultHolder);
130   - chk.setRedis(redis);
131   - chk.setLogger(logger);
132   - chk.start();
133   - if (logger.isDebugEnabled()) {
134   - logger.debug("Start Thread " + cacheKey + ".");
135   - }
136   - } else {
137   - if (logger.isDebugEnabled()) {
138   - logger.debug("Thread " + cacheKey + " already started.");
139   - }
  118 +
  119 + if (recordDataCatch.isComplete(device.getDeviceId(), sn)){
  120 + releaseRequest(device.getDeviceId(), sn);
140 121 }
141 122 }
142 123 } catch (SipException e) {
... ... @@ -154,4 +135,20 @@ public class RecordInfoResponseMessageHandler extends SIPRequestProcessorParent
154 135 public void handForPlatform(RequestEvent evt, ParentPlatform parentPlatform, Element element) {
155 136  
156 137 }
  138 +
  139 + public void releaseRequest(String deviceId, String sn){
  140 + String key = DeferredResultHolder.CALLBACK_CMD_RECORDINFO + deviceId + sn;
  141 + WVPResult<RecordInfo> wvpResult = new WVPResult<>();
  142 + wvpResult.setCode(0);
  143 + wvpResult.setMsg("success");
  144 + // 对数据进行排序
  145 + Collections.sort(recordDataCatch.getRecordInfo(deviceId, sn).getRecordList());
  146 + wvpResult.setData(recordDataCatch.getRecordInfo(deviceId, sn));
  147 +
  148 + RequestMessage msg = new RequestMessage();
  149 + msg.setKey(key);
  150 + msg.setData(wvpResult);
  151 + deferredResultHolder.invokeAllResult(msg);
  152 + recordDataCatch.remove(deviceId, sn);
  153 + }
157 154 }
... ...
src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRunner.java
... ... @@ -89,7 +89,7 @@ public class ZLMRunner implements CommandLineRunner {
89 89 });
90 90  
91 91 // 获取zlm信息
92   - logger.info("[zlm接入]等待默认zlm中...");
  92 + logger.info("[zlm] 等待默认zlm中...");
93 93  
94 94 // 获取所有的zlm, 并开启主动连接
95 95 List<MediaServerItem> all = mediaServerService.getAllFromDatabase();
... ...
src/main/java/com/genersoft/iot/vmp/media/zlm/event/ZLMStatusEventListener.java
... ... @@ -39,8 +39,7 @@ public class ZLMStatusEventListener {
39 39 @Async
40 40 @EventListener
41 41 public void onApplicationEvent(ZLMOnlineEvent event) {
42   -
43   - logger.info("【ZLM上线】ID:" + event.getMediaServerId());
  42 + logger.info("[ZLM] 上线 ID:" + event.getMediaServerId());
44 43 streamPushService.zlmServerOnline(event.getMediaServerId());
45 44 streamProxyService.zlmServerOnline(event.getMediaServerId());
46 45  
... ... @@ -50,7 +49,7 @@ public class ZLMStatusEventListener {
50 49 @EventListener
51 50 public void onApplicationEvent(ZLMOfflineEvent event) {
52 51  
53   - logger.info("ZLM离线事件触发,ID:" + event.getMediaServerId());
  52 + logger.info("[ZLM] 离线,ID:" + event.getMediaServerId());
54 53 // 处理ZLM离线
55 54 mediaServerService.zlmServerOffline(event.getMediaServerId());
56 55 streamProxyService.zlmServerOffline(event.getMediaServerId());
... ...
src/main/java/com/genersoft/iot/vmp/service/IMediaServerService.java
... ... @@ -44,7 +44,7 @@ public interface IMediaServerService {
44 44  
45 45 void updateVmServer(List<MediaServerItem> mediaServerItemList);
46 46  
47   - SSRCInfo openRTPServer(MediaServerItem mediaServerItem, String streamId, boolean ssrcCheck);
  47 + SSRCInfo openRTPServer(MediaServerItem mediaServerItem, String streamId, boolean ssrcCheck, boolean isPlayback);
48 48  
49 49 SSRCInfo openRTPServer(MediaServerItem mediaServerItem, String streamId, String ssrc, boolean ssrcCheck, boolean isPlayback);
50 50  
... ...
src/main/java/com/genersoft/iot/vmp/service/impl/DeviceServiceImpl.java
... ... @@ -66,7 +66,7 @@ public class DeviceServiceImpl implements IDeviceService {
66 66  
67 67 @Override
68 68 public void online(Device device) {
69   - logger.info("[设备上线],deviceId:" + device.getDeviceId());
  69 + logger.info("[设备上线] deviceId:{}->{}:{}", device.getDeviceId(), device.getIp(), device.getPort());
70 70 Device deviceInRedis = redisCatchStorage.getDevice(device.getDeviceId());
71 71 Device deviceInDb = deviceMapper.getDeviceByDeviceId(device.getDeviceId());
72 72  
... ...
src/main/java/com/genersoft/iot/vmp/service/impl/MediaServerServiceImpl.java
... ... @@ -95,7 +95,7 @@ public class MediaServerServiceImpl implements IMediaServerService {
95 95 */
96 96 @Override
97 97 public void updateVmServer(List<MediaServerItem> mediaServerItemList) {
98   - logger.info("[缓存初始化] Media Server ");
  98 + logger.info("[zlm] 缓存初始化 ");
99 99 for (MediaServerItem mediaServerItem : mediaServerItemList) {
100 100 if (StringUtils.isEmpty(mediaServerItem.getId())) {
101 101 continue;
... ... @@ -116,8 +116,8 @@ public class MediaServerServiceImpl implements IMediaServerService {
116 116 }
117 117  
118 118 @Override
119   - public SSRCInfo openRTPServer(MediaServerItem mediaServerItem, String streamId, boolean ssrcCheck) {
120   - return openRTPServer(mediaServerItem, streamId, null, ssrcCheck,false);
  119 + public SSRCInfo openRTPServer(MediaServerItem mediaServerItem, String streamId, boolean ssrcCheck, boolean isPlayback) {
  120 + return openRTPServer(mediaServerItem, streamId, null, ssrcCheck,isPlayback);
121 121 }
122 122  
123 123 @Override
... ... @@ -352,7 +352,7 @@ public class MediaServerServiceImpl implements IMediaServerService {
352 352 */
353 353 @Override
354 354 public void zlmServerOnline(ZLMServerConfig zlmServerConfig) {
355   - logger.info("[ ZLM:{} ]-[ {}:{} ]正在连接",
  355 + logger.info("[ZLM] 正在连接 : {} -> {}:{}",
356 356 zlmServerConfig.getGeneralMediaServerId(), zlmServerConfig.getIp(), zlmServerConfig.getHttpPort());
357 357  
358 358 MediaServerItem serverItem = mediaServerMapper.queryOne(zlmServerConfig.getGeneralMediaServerId());
... ... @@ -405,7 +405,7 @@ public class MediaServerServiceImpl implements IMediaServerService {
405 405 setZLMConfig(serverItem, "0".equals(zlmServerConfig.getHookEnable()));
406 406 }
407 407 publisher.zlmOnlineEventPublish(serverItem.getId());
408   - logger.info("[ ZLM:{} ]-[ {}:{} ]连接成功",
  408 + logger.info("[ZLM] 连接成功 {} - {}:{} ",
409 409 zlmServerConfig.getGeneralMediaServerId(), zlmServerConfig.getIp(), zlmServerConfig.getHttpPort());
410 410 }
411 411  
... ... @@ -483,7 +483,7 @@ public class MediaServerServiceImpl implements IMediaServerService {
483 483 */
484 484 @Override
485 485 public void setZLMConfig(MediaServerItem mediaServerItem, boolean restart) {
486   - logger.info("[ ZLM:{} ]-[ {}:{} ]正在设置zlm",
  486 + logger.info("[ZLM] 正在设置 :{} -> {}:{}",
487 487 mediaServerItem.getId(), mediaServerItem.getIp(), mediaServerItem.getHttpPort());
488 488 String protocol = sslEnabled ? "https" : "http";
489 489 String hookPrex = String.format("%s://%s:%s/index/hook", protocol, mediaServerItem.getHookIp(), serverPort);
... ... @@ -527,17 +527,17 @@ public class MediaServerServiceImpl implements IMediaServerService {
527 527  
528 528 if (responseJSON != null && responseJSON.getInteger("code") == 0) {
529 529 if (restart) {
530   - logger.info("[ ZLM:{} ]-[ {}:{} ]设置zlm成功, 开始重启以保证配置生效",
  530 + logger.info("[ZLM] 设置成功,开始重启以保证配置生效 {} -> {}:{}",
531 531 mediaServerItem.getId(), mediaServerItem.getIp(), mediaServerItem.getHttpPort());
532 532 zlmresTfulUtils.restartServer(mediaServerItem);
533 533 }else {
534   - logger.info("[ ZLM:{} ]-[ {}:{} ]设置zlm成功",
  534 + logger.info("[ZLM] 设置成功 {} -> {}:{}",
535 535 mediaServerItem.getId(), mediaServerItem.getIp(), mediaServerItem.getHttpPort());
536 536 }
537 537  
538 538  
539 539 }else {
540   - logger.info("[ ZLM:{} ]-[ {}:{} ]设置zlm失败",
  540 + logger.info("[ZLM] 设置zlm失败 {} -> {}:{}",
541 541 mediaServerItem.getId(), mediaServerItem.getIp(), mediaServerItem.getHttpPort());
542 542 }
543 543  
... ...
src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java
... ... @@ -193,7 +193,7 @@ public class PlayServiceImpl implements IPlayService {
193 193 if (mediaServerItem.isRtpEnable()) {
194 194 streamId = String.format("%s_%s", device.getDeviceId(), channelId);
195 195 }
196   - SSRCInfo ssrcInfo = mediaServerService.openRTPServer(mediaServerItem, streamId, device.isSsrcCheck());
  196 + SSRCInfo ssrcInfo = mediaServerService.openRTPServer(mediaServerItem, streamId, device.isSsrcCheck(), false);
197 197 play(mediaServerItem, ssrcInfo, device, channelId, (mediaServerItemInUse, response)->{
198 198 if (hookEvent != null) {
199 199 hookEvent.response(mediaServerItem, response);
... ... @@ -237,7 +237,7 @@ public class PlayServiceImpl implements IPlayService {
237 237 streamId = String.format("%s_%s", device.getDeviceId(), channelId);
238 238 }
239 239 if (ssrcInfo == null) {
240   - ssrcInfo = mediaServerService.openRTPServer(mediaServerItem, streamId, device.isSsrcCheck());
  240 + ssrcInfo = mediaServerService.openRTPServer(mediaServerItem, streamId, device.isSsrcCheck(), false);
241 241 }
242 242  
243 243 // 超时处理
... ... @@ -360,7 +360,7 @@ public class PlayServiceImpl implements IPlayService {
360 360 return null;
361 361 }
362 362 MediaServerItem newMediaServerItem = getNewMediaServerItem(device);
363   - SSRCInfo ssrcInfo = mediaServerService.openRTPServer(newMediaServerItem, null, true);
  363 + SSRCInfo ssrcInfo = mediaServerService.openRTPServer(newMediaServerItem, null, true, true);
364 364  
365 365 return playBack(newMediaServerItem, ssrcInfo, deviceId, channelId, startTime, endTime, inviteStreamCallback, callback);
366 366 }
... ... @@ -447,7 +447,7 @@ public class PlayServiceImpl implements IPlayService {
447 447 return null;
448 448 }
449 449 MediaServerItem newMediaServerItem = getNewMediaServerItem(device);
450   - SSRCInfo ssrcInfo = mediaServerService.openRTPServer(newMediaServerItem, null, true);
  450 + SSRCInfo ssrcInfo = mediaServerService.openRTPServer(newMediaServerItem, null, true, true);
451 451  
452 452 return download(newMediaServerItem, ssrcInfo, deviceId, channelId, startTime, endTime, downloadSpeed,infoCallBack, hookCallBack);
453 453 }
... ...
src/main/java/com/genersoft/iot/vmp/utils/DateUtil.java
1 1 package com.genersoft.iot.vmp.utils;
2 2  
3   -import java.text.ParseException;
  3 +
4 4 import java.text.SimpleDateFormat;
5   -import java.util.Date;
  5 +import java.time.Instant;
  6 +import java.time.LocalDate;
  7 +import java.time.LocalDateTime;
  8 +import java.time.ZoneId;
  9 +import java.time.format.DateTimeFormatter;
  10 +import java.time.format.DateTimeParseException;
  11 +import java.time.temporal.TemporalAccessor;
  12 +
6 13 import java.util.Locale;
7 14  
8 15 /**
... ... @@ -12,46 +19,40 @@ import java.util.Locale;
12 19 public class DateUtil {
13 20  
14 21 private static final String yyyy_MM_dd_T_HH_mm_ss_SSSXXX = "yyyy-MM-dd'T'HH:mm:ss";
15   - private static final String yyyy_MM_dd_HH_mm_ss = "yyyy-MM-dd HH:mm:ss";
  22 + public static final String yyyy_MM_dd_HH_mm_ss = "yyyy-MM-dd HH:mm:ss";
16 23  
17 24 public static final SimpleDateFormat formatISO8601 = new SimpleDateFormat(yyyy_MM_dd_T_HH_mm_ss_SSSXXX, Locale.getDefault());
18 25 public static final SimpleDateFormat format = new SimpleDateFormat(yyyy_MM_dd_HH_mm_ss, Locale.getDefault());
19 26  
20   - public static String yyyy_MM_dd_HH_mm_ssToISO8601(String formatTime) {
  27 + public static final DateTimeFormatter formatterISO8601 = DateTimeFormatter.ofPattern(yyyy_MM_dd_T_HH_mm_ss_SSSXXX, Locale.getDefault()).withZone(ZoneId.systemDefault());
  28 + public static final DateTimeFormatter formatter = DateTimeFormatter.ofPattern(yyyy_MM_dd_HH_mm_ss, Locale.getDefault()).withZone(ZoneId.systemDefault());
21 29  
22   - try {
23   - return formatISO8601.format(format.parse(formatTime));
24   - } catch (ParseException e) {
25   - e.printStackTrace();
26   - }
27   - return "";
  30 + public static String yyyy_MM_dd_HH_mm_ssToISO8601(String formatTime) {
  31 + return formatterISO8601.format(formatter.parse(formatTime));
28 32 }
29 33  
30 34 public static String ISO8601Toyyyy_MM_dd_HH_mm_ss(String formatTime) {
  35 + return formatter.format(formatterISO8601.parse(formatTime));
31 36  
32   - try {
33   - return format.format(formatISO8601.parse(formatTime));
34   - } catch (ParseException e) {
35   - e.printStackTrace();
36   - }
37   - return "";
38 37 }
39 38  
40 39 public static long yyyy_MM_dd_HH_mm_ssToTimestamp(String formatTime) {
41   - //设置要读取的时间字符串格式
42   - Date date;
43   - try {
44   - date = format.parse(formatTime);
45   - Long timestamp=date.getTime()/1000;
46   - //转换为Date类
47   - return timestamp;
48   - } catch (ParseException e) {
49   - e.printStackTrace();
50   - }
51   - return 0;
  40 + TemporalAccessor temporalAccessor = formatter.parse(formatTime);
  41 + Instant instant = Instant.from(temporalAccessor);
  42 + return instant.getEpochSecond();
52 43 }
53 44  
54 45 public static String getNow() {
55   - return format.format(System.currentTimeMillis());
  46 + LocalDateTime nowDateTime = LocalDateTime.now();
  47 + return formatter.format(nowDateTime);
  48 + }
  49 +
  50 + public static boolean verification(String timeStr, DateTimeFormatter dateTimeFormatter) {
  51 + try {
  52 + LocalDate.parse(timeStr, dateTimeFormatter);
  53 + return true;
  54 + }catch (DateTimeParseException exception) {
  55 + return false;
  56 + }
56 57 }
57 58 }
... ...
src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/record/GBRecordController.java
... ... @@ -5,6 +5,8 @@ import com.genersoft.iot.vmp.common.StreamInfo;
5 5 import com.genersoft.iot.vmp.gb28181.transmit.callback.RequestMessage;
6 6 import com.genersoft.iot.vmp.service.IMediaServerService;
7 7 import com.genersoft.iot.vmp.service.IPlayService;
  8 +import com.genersoft.iot.vmp.utils.DateUtil;
  9 +import com.genersoft.iot.vmp.vmanager.bean.WVPResult;
8 10 import io.swagger.annotations.Api;
9 11 import io.swagger.annotations.ApiImplicitParam;
10 12 import io.swagger.annotations.ApiImplicitParams;
... ... @@ -27,6 +29,7 @@ import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder;
27 29 import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander;
28 30 import com.genersoft.iot.vmp.storager.IVideoManagerStorage;
29 31  
  32 +import java.time.LocalDate;
30 33 import java.util.UUID;
31 34  
32 35 @Api(tags = "国标录像")
... ... @@ -60,15 +63,32 @@ public class GBRecordController {
60 63 @ApiImplicitParam(name = "endTime", value = "结束时间", dataTypeClass = String.class),
61 64 })
62 65 @GetMapping("/query/{deviceId}/{channelId}")
63   - public DeferredResult<ResponseEntity<RecordInfo>> recordinfo(@PathVariable String deviceId,@PathVariable String channelId, String startTime, String endTime){
  66 + public DeferredResult<ResponseEntity<WVPResult<RecordInfo>>> recordinfo(@PathVariable String deviceId, @PathVariable String channelId, String startTime, String endTime){
64 67  
65 68 if (logger.isDebugEnabled()) {
66 69 logger.debug(String.format("录像信息查询 API调用,deviceId:%s ,startTime:%s, endTime:%s",deviceId, startTime, endTime));
67 70 }
  71 + DeferredResult<ResponseEntity<WVPResult<RecordInfo>>> result = new DeferredResult<>();
  72 + if (!DateUtil.verification(startTime, DateUtil.formatter)){
  73 + WVPResult<RecordInfo> wvpResult = new WVPResult<>();
  74 + wvpResult.setCode(-1);
  75 + wvpResult.setMsg("startTime error, format is " + DateUtil.yyyy_MM_dd_HH_mm_ss);
  76 +
  77 + ResponseEntity<WVPResult<RecordInfo>> resultResponseEntity = new ResponseEntity<>(wvpResult, HttpStatus.OK);
  78 + result.setResult(resultResponseEntity);
  79 + return result;
  80 + }
  81 + if (!DateUtil.verification(endTime, DateUtil.formatter)){
  82 + WVPResult<RecordInfo> wvpResult = new WVPResult<>();
  83 + wvpResult.setCode(-1);
  84 + wvpResult.setMsg("endTime error, format is " + DateUtil.yyyy_MM_dd_HH_mm_ss);
  85 + ResponseEntity<WVPResult<RecordInfo>> resultResponseEntity = new ResponseEntity<>(wvpResult, HttpStatus.OK);
  86 + result.setResult(resultResponseEntity);
  87 + return result;
  88 + }
68 89  
69 90 Device device = storager.queryVideoDevice(deviceId);
70 91 // 指定超时时间 1分钟30秒
71   - DeferredResult<ResponseEntity<RecordInfo>> result = new DeferredResult<>(90*1000L);
72 92 String uuid = UUID.randomUUID().toString();
73 93 int sn = (int)((Math.random()*9+1)*100000);
74 94 String key = DeferredResultHolder.CALLBACK_CMD_RECORDINFO + deviceId + sn;
... ... @@ -76,7 +96,10 @@ public class GBRecordController {
76 96 msg.setId(uuid);
77 97 msg.setKey(key);
78 98 cmder.recordInfoQuery(device, channelId, startTime, endTime, sn, null, null, null, (eventResult -> {
79   - msg.setData("查询录像失败, status: " + eventResult.statusCode + ", message: " + eventResult.msg );
  99 + WVPResult<RecordInfo> wvpResult = new WVPResult<>();
  100 + wvpResult.setCode(-1);
  101 + wvpResult.setMsg("查询录像失败, status: " + eventResult.statusCode + ", message: " + eventResult.msg);
  102 + msg.setData(wvpResult);
80 103 resultHolder.invokeResult(msg);
81 104 }));
82 105  
... ... @@ -84,6 +107,10 @@ public class GBRecordController {
84 107 resultHolder.put(key, uuid, result);
85 108 result.onTimeout(()->{
86 109 msg.setData("timeout");
  110 + WVPResult<RecordInfo> wvpResult = new WVPResult<>();
  111 + wvpResult.setCode(-1);
  112 + wvpResult.setMsg("timeout");
  113 + msg.setData(wvpResult);
87 114 resultHolder.invokeResult(msg);
88 115 });
89 116 return result;
... ...
web_src/src/components/channelList.vue
... ... @@ -244,7 +244,7 @@ export default {
244 244 });
245 245 },
246 246 queryRecords: function (itemData) {
247   - var format = moment().format("YYYY-M-D");
  247 + var format = moment().format("yyyy-MM-DD");
248 248 let deviceId = this.deviceId;
249 249 let channelId = itemData.channelId;
250 250 this.$refs.devicePlayer.openDialog("record", deviceId, channelId, {date: format})
... ...
web_src/src/components/dialog/devicePlayer.vue
... ... @@ -453,9 +453,19 @@ export default {
453 453 method: 'get',
454 454 url: '/api/gb_record/query/' + this.deviceId + '/' + this.channelId + '?startTime=' + startTime + '&endTime=' + endTime
455 455 }).then(function (res) {
456   - // 处理时间信息
457   - that.videoHistory.searchHistoryResult = res.data.recordList;
458   - that.recordsLoading = false;
  456 + console.log(res)
  457 + if(res.data.code === 0) {
  458 + // 处理时间信息
  459 + that.videoHistory.searchHistoryResult = res.data.data.recordList;
  460 + that.recordsLoading = false;
  461 + }else {
  462 + this.$message({
  463 + showClose: true,
  464 + message: res.data.msg,
  465 + type: "error",
  466 + });
  467 + }
  468 +
459 469 }).catch(function (e) {
460 470 console.log(e.message);
461 471 // that.videoHistory.searchHistoryResult = falsificationData.recordData;
... ...