Commit 3c48ef8f4305630663cdc0df0880d3559652edf4

Authored by mk1990
2 parents fe576c58 46c77302

Merge branch 'wvp-28181-2.0' of https://github.com/mk1990/wvp-GB28181-pro into wvp-28181-2.0

src/main/java/com/genersoft/iot/vmp/conf/MediaConfig.java
@@ -6,6 +6,10 @@ import org.springframework.beans.factory.annotation.Value; @@ -6,6 +6,10 @@ import org.springframework.beans.factory.annotation.Value;
6 import org.springframework.context.annotation.Configuration; 6 import org.springframework.context.annotation.Configuration;
7 import org.springframework.util.StringUtils; 7 import org.springframework.util.StringUtils;
8 8
  9 +import java.net.InetAddress;
  10 +import java.net.UnknownHostException;
  11 +import java.util.regex.Pattern;
  12 +
9 13
10 @Configuration("mediaConfig") 14 @Configuration("mediaConfig")
11 public class MediaConfig{ 15 public class MediaConfig{
@@ -161,7 +165,18 @@ public class MediaConfig{ @@ -161,7 +165,18 @@ public class MediaConfig{
161 if (StringUtils.isEmpty(sdpIp)){ 165 if (StringUtils.isEmpty(sdpIp)){
162 return ip; 166 return ip;
163 }else { 167 }else {
164 - return sdpIp; 168 + if (isValidIPAddress(sdpIp)) {
  169 + return sdpIp;
  170 + }else {
  171 + // 按照域名解析
  172 + String hostAddress = null;
  173 + try {
  174 + hostAddress = InetAddress.getByName(sdpIp).getHostAddress();
  175 + } catch (UnknownHostException e) {
  176 + throw new RuntimeException(e);
  177 + }
  178 + return hostAddress;
  179 + }
165 } 180 }
166 } 181 }
167 182
@@ -211,4 +226,11 @@ public class MediaConfig{ @@ -211,4 +226,11 @@ public class MediaConfig{
211 return mediaServerItem; 226 return mediaServerItem;
212 } 227 }
213 228
  229 + private boolean isValidIPAddress(String ipAddress) {
  230 + if ((ipAddress != null) && (!ipAddress.isEmpty())) {
  231 + return Pattern.matches("^([1-9]|[1-9]\\d|1\\d{2}|2[0-4]\\d|25[0-5])(\\.(\\d|[1-9]\\d|1\\d{2}|2[0-4]\\d|25[0-5])){3}$", ipAddress);
  232 + }
  233 + return false;
  234 + }
  235 +
214 } 236 }
src/main/java/com/genersoft/iot/vmp/conf/security/LoginSuccessHandler.java
@@ -11,6 +11,9 @@ import javax.servlet.http.HttpServletRequest; @@ -11,6 +11,9 @@ import javax.servlet.http.HttpServletRequest;
11 import javax.servlet.http.HttpServletResponse; 11 import javax.servlet.http.HttpServletResponse;
12 import java.io.IOException; 12 import java.io.IOException;
13 13
  14 +/**
  15 + * @author lin
  16 + */
14 @Component 17 @Component
15 public class LoginSuccessHandler implements AuthenticationSuccessHandler { 18 public class LoginSuccessHandler implements AuthenticationSuccessHandler {
16 19
src/main/java/com/genersoft/iot/vmp/conf/security/WebSecurityConfig.java
@@ -20,6 +20,7 @@ import java.util.List; @@ -20,6 +20,7 @@ import java.util.List;
20 20
21 /** 21 /**
22 * 配置Spring Security 22 * 配置Spring Security
  23 + * @author lin
23 */ 24 */
24 @Configuration 25 @Configuration
25 @EnableWebSecurity 26 @EnableWebSecurity
@@ -132,15 +133,19 @@ public class WebSecurityConfig extends WebSecurityConfigurerAdapter { @@ -132,15 +133,19 @@ public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
132 .anyRequest().authenticated() 133 .anyRequest().authenticated()
133 // 异常处理(权限拒绝、登录失效等) 134 // 异常处理(权限拒绝、登录失效等)
134 .and().exceptionHandling() 135 .and().exceptionHandling()
135 - .authenticationEntryPoint(anonymousAuthenticationEntryPoint)//匿名用户访问无权限资源时的异常处理 136 + //匿名用户访问无权限资源时的异常处理
  137 + .authenticationEntryPoint(anonymousAuthenticationEntryPoint)
136 // .accessDeniedHandler(accessDeniedHandler)//登录用户没有权限访问资源 138 // .accessDeniedHandler(accessDeniedHandler)//登录用户没有权限访问资源
137 - // 登入  
138 - .and().formLogin().permitAll()//允许所有用户  
139 - .successHandler(loginSuccessHandler)//登录成功处理逻辑  
140 - .failureHandler(loginFailureHandler)//登录失败处理逻辑 139 + // 登入 允许所有用户
  140 + .and().formLogin().permitAll()
  141 + //登录成功处理逻辑
  142 + .successHandler(loginSuccessHandler)
  143 + //登录失败处理逻辑
  144 + .failureHandler(loginFailureHandler)
141 // 登出 145 // 登出
142 - .and().logout().logoutUrl("/api/user/logout").permitAll()//允许所有用户  
143 - .logoutSuccessHandler(logoutHandler)//登出成功处理逻辑 146 + .and().logout().logoutUrl("/api/user/logout").permitAll()
  147 + //登出成功处理逻辑
  148 + .logoutSuccessHandler(logoutHandler)
144 .deleteCookies("JSESSIONID") 149 .deleteCookies("JSESSIONID")
145 // 会话管理 150 // 会话管理
146 // .and().sessionManagement().invalidSessionStrategy(invalidSessionHandler) // 超时处理 151 // .and().sessionManagement().invalidSessionStrategy(invalidSessionHandler) // 超时处理
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/RegisterRequestProcessor.java
1 package com.genersoft.iot.vmp.gb28181.transmit.event.request.impl; 1 package com.genersoft.iot.vmp.gb28181.transmit.event.request.impl;
2 2
3 -import com.genersoft.iot.vmp.common.VideoManagerConstants;  
4 import com.genersoft.iot.vmp.conf.SipConfig; 3 import com.genersoft.iot.vmp.conf.SipConfig;
5 -import com.genersoft.iot.vmp.gb28181.auth.DigestServerAuthenticationHelper;  
6 import com.genersoft.iot.vmp.gb28181.bean.Device; 4 import com.genersoft.iot.vmp.gb28181.bean.Device;
7 import com.genersoft.iot.vmp.gb28181.bean.WvpSipDate; 5 import com.genersoft.iot.vmp.gb28181.bean.WvpSipDate;
8 -import com.genersoft.iot.vmp.gb28181.event.EventPublisher;  
9 import com.genersoft.iot.vmp.gb28181.transmit.SIPProcessorObserver; 6 import com.genersoft.iot.vmp.gb28181.transmit.SIPProcessorObserver;
10 import com.genersoft.iot.vmp.gb28181.transmit.event.request.ISIPRequestProcessor; 7 import com.genersoft.iot.vmp.gb28181.transmit.event.request.ISIPRequestProcessor;
11 import com.genersoft.iot.vmp.gb28181.transmit.event.request.SIPRequestProcessorParent; 8 import com.genersoft.iot.vmp.gb28181.transmit.event.request.SIPRequestProcessorParent;
  9 +import com.genersoft.iot.vmp.gb28181.auth.DigestServerAuthenticationHelper;
12 import com.genersoft.iot.vmp.service.IDeviceService; 10 import com.genersoft.iot.vmp.service.IDeviceService;
13 -import com.genersoft.iot.vmp.storager.IRedisCatchStorage;  
14 -import com.genersoft.iot.vmp.storager.IVideoManagerStorage;  
15 import com.genersoft.iot.vmp.utils.DateUtil; 11 import com.genersoft.iot.vmp.utils.DateUtil;
16 import gov.nist.javax.sip.RequestEventExt; 12 import gov.nist.javax.sip.RequestEventExt;
17 import gov.nist.javax.sip.address.AddressImpl; 13 import gov.nist.javax.sip.address.AddressImpl;
@@ -51,15 +47,6 @@ public class RegisterRequestProcessor extends SIPRequestProcessorParent implemen @@ -51,15 +47,6 @@ public class RegisterRequestProcessor extends SIPRequestProcessorParent implemen
51 private SipConfig sipConfig; 47 private SipConfig sipConfig;
52 48
53 @Autowired 49 @Autowired
54 - private IRedisCatchStorage redisCatchStorage;  
55 -  
56 - @Autowired  
57 - private IVideoManagerStorage storager;  
58 -  
59 - @Autowired  
60 - private EventPublisher publisher;  
61 -  
62 - @Autowired  
63 private SIPProcessorObserver sipProcessorObserver; 50 private SIPProcessorObserver sipProcessorObserver;
64 51
65 @Autowired 52 @Autowired
@@ -86,7 +73,7 @@ public class RegisterRequestProcessor extends SIPRequestProcessorParent implemen @@ -86,7 +73,7 @@ public class RegisterRequestProcessor extends SIPRequestProcessorParent implemen
86 ExpiresHeader expiresHeader = (ExpiresHeader) request.getHeader(Expires.NAME); 73 ExpiresHeader expiresHeader = (ExpiresHeader) request.getHeader(Expires.NAME);
87 Response response = null; 74 Response response = null;
88 boolean passwordCorrect = false; 75 boolean passwordCorrect = false;
89 - // 注册标志 0:未携带授权头或者密码错误 1:注册成功 2:注销成功 76 + // 注册标志
90 boolean registerFlag = false; 77 boolean registerFlag = false;
91 FromHeader fromHeader = (FromHeader) request.getHeader(FromHeader.NAME); 78 FromHeader fromHeader = (FromHeader) request.getHeader(FromHeader.NAME);
92 AddressImpl address = (AddressImpl) fromHeader.getAddress(); 79 AddressImpl address = (AddressImpl) fromHeader.getAddress();
@@ -105,7 +92,6 @@ public class RegisterRequestProcessor extends SIPRequestProcessorParent implemen @@ -105,7 +92,6 @@ public class RegisterRequestProcessor extends SIPRequestProcessorParent implemen
105 // 校验密码是否正确 92 // 校验密码是否正确
106 passwordCorrect = StringUtils.isEmpty(sipConfig.getPassword()) || 93 passwordCorrect = StringUtils.isEmpty(sipConfig.getPassword()) ||
107 new DigestServerAuthenticationHelper().doAuthenticatePlainTextPassword(request, sipConfig.getPassword()); 94 new DigestServerAuthenticationHelper().doAuthenticatePlainTextPassword(request, sipConfig.getPassword());
108 - // 未携带授权头或者密码错误 回复401  
109 95
110 if (!passwordCorrect) { 96 if (!passwordCorrect) {
111 // 注册失败 97 // 注册失败
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/KeepaliveNotifyMessageHandler.java
@@ -64,16 +64,14 @@ public class KeepaliveNotifyMessageHandler extends SIPRequestProcessorParent imp @@ -64,16 +64,14 @@ public class KeepaliveNotifyMessageHandler extends SIPRequestProcessorParent imp
64 device.setHostAddress(received.concat(":").concat(String.valueOf(rPort))); 64 device.setHostAddress(received.concat(":").concat(String.valueOf(rPort)));
65 } 65 }
66 device.setKeepaliveTime(DateUtil.getNow()); 66 device.setKeepaliveTime(DateUtil.getNow());
  67 + // 回复200 OK
  68 + responseAck(evt, Response.OK);
67 if (device.getOnline() == 1) { 69 if (device.getOnline() == 1) {
68 - // 回复200 OK  
69 - responseAck(evt, Response.OK);  
70 deviceService.updateDevice(device); 70 deviceService.updateDevice(device);
71 }else { 71 }else {
72 // 对于已经离线的设备判断他的注册是否已经过期 72 // 对于已经离线的设备判断他的注册是否已经过期
73 if (!deviceService.expire(device)){ 73 if (!deviceService.expire(device)){
74 deviceService.online(device); 74 deviceService.online(device);
75 - // 回复200 OK  
76 - responseAck(evt, Response.OK);  
77 } 75 }
78 } 76 }
79 } catch (SipException e) { 77 } catch (SipException e) {
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/response/cmd/RecordInfoResponseMessageHandler.java
@@ -70,15 +70,20 @@ public class RecordInfoResponseMessageHandler extends SIPRequestProcessorParent @@ -70,15 +70,20 @@ public class RecordInfoResponseMessageHandler extends SIPRequestProcessorParent
70 70
71 rootElement = getRootElement(evt, device.getCharset()); 71 rootElement = getRootElement(evt, device.getCharset());
72 String sn = getText(rootElement, "SN"); 72 String sn = getText(rootElement, "SN");
73 - 73 + RecordInfo recordInfo = new RecordInfo();
  74 + recordInfo.setDeviceId(device.getDeviceId());
  75 + recordInfo.setSn(sn);
  76 + recordInfo.setName(getText(rootElement, "Name"));
74 String sumNumStr = getText(rootElement, "SumNum"); 77 String sumNumStr = getText(rootElement, "SumNum");
75 int sumNum = 0; 78 int sumNum = 0;
76 if (!StringUtils.isEmpty(sumNumStr)) { 79 if (!StringUtils.isEmpty(sumNumStr)) {
77 sumNum = Integer.parseInt(sumNumStr); 80 sumNum = Integer.parseInt(sumNumStr);
78 } 81 }
  82 + recordInfo.setSumNum(sumNum);
79 Element recordListElement = rootElement.element("RecordList"); 83 Element recordListElement = rootElement.element("RecordList");
80 if (recordListElement == null || sumNum == 0) { 84 if (recordListElement == null || sumNum == 0) {
81 logger.info("无录像数据"); 85 logger.info("无录像数据");
  86 + eventPublisher.recordEndEventPush(recordInfo);
82 recordDataCatch.put(device.getDeviceId(), sn, sumNum, new ArrayList<>()); 87 recordDataCatch.put(device.getDeviceId(), sn, sumNum, new ArrayList<>());
83 releaseRequest(device.getDeviceId(), sn); 88 releaseRequest(device.getDeviceId(), sn);
84 } else { 89 } else {
@@ -112,6 +117,9 @@ public class RecordInfoResponseMessageHandler extends SIPRequestProcessorParent @@ -112,6 +117,9 @@ public class RecordInfoResponseMessageHandler extends SIPRequestProcessorParent
112 record.setRecorderId(getText(itemRecord, "RecorderID")); 117 record.setRecorderId(getText(itemRecord, "RecorderID"));
113 recordList.add(record); 118 recordList.add(record);
114 } 119 }
  120 + recordInfo.setRecordList(recordList);
  121 + // 发送消息,如果是上级查询此录像,则会通过这里通知给上级
  122 + eventPublisher.recordEndEventPush(recordInfo);
115 int count = recordDataCatch.put(device.getDeviceId(), sn, sumNum, recordList); 123 int count = recordDataCatch.put(device.getDeviceId(), sn, sumNum, recordList);
116 logger.info("[国标录像], {}->{}: {}/{}", device.getDeviceId(), sn, count, sumNum); 124 logger.info("[国标录像], {}->{}: {}/{}", device.getDeviceId(), sn, count, sumNum);
117 } 125 }
src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java
@@ -19,17 +19,16 @@ import com.genersoft.iot.vmp.media.zlm.ZLMHttpHookSubscribe; @@ -19,17 +19,16 @@ import com.genersoft.iot.vmp.media.zlm.ZLMHttpHookSubscribe;
19 import com.genersoft.iot.vmp.media.zlm.ZLMRESTfulUtils; 19 import com.genersoft.iot.vmp.media.zlm.ZLMRESTfulUtils;
20 import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; 20 import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
21 import com.genersoft.iot.vmp.service.IMediaServerService; 21 import com.genersoft.iot.vmp.service.IMediaServerService;
  22 +import com.genersoft.iot.vmp.service.IMediaService;
  23 +import com.genersoft.iot.vmp.service.IPlayService;
22 import com.genersoft.iot.vmp.service.bean.InviteTimeOutCallback; 24 import com.genersoft.iot.vmp.service.bean.InviteTimeOutCallback;
23 import com.genersoft.iot.vmp.service.bean.PlayBackCallback; 25 import com.genersoft.iot.vmp.service.bean.PlayBackCallback;
24 import com.genersoft.iot.vmp.service.bean.PlayBackResult; 26 import com.genersoft.iot.vmp.service.bean.PlayBackResult;
25 import com.genersoft.iot.vmp.service.bean.SSRCInfo; 27 import com.genersoft.iot.vmp.service.bean.SSRCInfo;
26 import com.genersoft.iot.vmp.storager.IRedisCatchStorage; 28 import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
27 import com.genersoft.iot.vmp.storager.IVideoManagerStorage; 29 import com.genersoft.iot.vmp.storager.IVideoManagerStorage;
28 -import com.genersoft.iot.vmp.utils.redis.RedisUtil;  
29 import com.genersoft.iot.vmp.vmanager.bean.WVPResult; 30 import com.genersoft.iot.vmp.vmanager.bean.WVPResult;
30 import com.genersoft.iot.vmp.vmanager.gb28181.play.bean.PlayResult; 31 import com.genersoft.iot.vmp.vmanager.gb28181.play.bean.PlayResult;
31 -import com.genersoft.iot.vmp.service.IMediaService;  
32 -import com.genersoft.iot.vmp.service.IPlayService;  
33 import gov.nist.javax.sip.stack.SIPDialog; 32 import gov.nist.javax.sip.stack.SIPDialog;
34 import org.slf4j.Logger; 33 import org.slf4j.Logger;
35 import org.slf4j.LoggerFactory; 34 import org.slf4j.LoggerFactory;
@@ -43,6 +42,7 @@ import org.springframework.web.context.request.async.DeferredResult; @@ -43,6 +42,7 @@ import org.springframework.web.context.request.async.DeferredResult;
43 import javax.sip.ResponseEvent; 42 import javax.sip.ResponseEvent;
44 import java.io.FileNotFoundException; 43 import java.io.FileNotFoundException;
45 import java.math.BigDecimal; 44 import java.math.BigDecimal;
  45 +import java.math.RoundingMode;
46 import java.util.*; 46 import java.util.*;
47 47
48 @SuppressWarnings(value = {"rawtypes", "unchecked"}) 48 @SuppressWarnings(value = {"rawtypes", "unchecked"})
@@ -64,9 +64,6 @@ public class PlayServiceImpl implements IPlayService { @@ -64,9 +64,6 @@ public class PlayServiceImpl implements IPlayService {
64 private IRedisCatchStorage redisCatchStorage; 64 private IRedisCatchStorage redisCatchStorage;
65 65
66 @Autowired 66 @Autowired
67 - private RedisUtil redis;  
68 -  
69 - @Autowired  
70 private DeferredResultHolder resultHolder; 67 private DeferredResultHolder resultHolder;
71 68
72 @Autowired 69 @Autowired
@@ -591,7 +588,7 @@ public class PlayServiceImpl implements IPlayService { @@ -591,7 +588,7 @@ public class PlayServiceImpl implements IPlayService {
591 588
592 BigDecimal currentCount = new BigDecimal(duration/1000); 589 BigDecimal currentCount = new BigDecimal(duration/1000);
593 BigDecimal totalCount = new BigDecimal(end-start); 590 BigDecimal totalCount = new BigDecimal(end-start);
594 - BigDecimal divide = currentCount.divide(totalCount,2, BigDecimal.ROUND_HALF_UP); 591 + BigDecimal divide = currentCount.divide(totalCount,2, RoundingMode.HALF_UP);
595 double process = divide.doubleValue(); 592 double process = divide.doubleValue();
596 streamInfo.setProgress(process); 593 streamInfo.setProgress(process);
597 } 594 }
web_src/package.json
@@ -52,7 +52,7 @@ @@ -52,7 +52,7 @@
52 "postcss-url": "^7.2.1", 52 "postcss-url": "^7.2.1",
53 "rimraf": "^2.6.0", 53 "rimraf": "^2.6.0",
54 "semver": "^5.3.0", 54 "semver": "^5.3.0",
55 - "shelljs": "^0.7.6", 55 + "shelljs": "^0.8.5",
56 "uglifyjs-webpack-plugin": "^1.1.1", 56 "uglifyjs-webpack-plugin": "^1.1.1",
57 "url-loader": "^0.5.8", 57 "url-loader": "^0.5.8",
58 "vue-loader": "^13.3.0", 58 "vue-loader": "^13.3.0",
web_src/src/components/dialog/devicePlayer.vue
@@ -605,12 +605,12 @@ export default { @@ -605,12 +605,12 @@ export default {
605 url: '/api/playback/start/' + this.deviceId + '/' + this.channelId + '?startTime=' + row.startTime + '&endTime=' + 605 url: '/api/playback/start/' + this.deviceId + '/' + this.channelId + '?startTime=' + row.startTime + '&endTime=' +
606 row.endTime 606 row.endTime
607 }).then(function (res) { 607 }).then(function (res) {
608 - var streamInfo = res.data;  
609 - that.app = streamInfo.app;  
610 - that.streamId = streamInfo.stream;  
611 - that.mediaServerId = streamInfo.mediaServerId;  
612 - that.ssrc = streamInfo.ssrc;  
613 - that.videoUrl = that.getUrlByStreamInfo(streamInfo); 608 + that.streamInfo = res.data;
  609 + that.app = that.streamInfo.app;
  610 + that.streamId = that.streamInfo.stream;
  611 + that.mediaServerId = that.streamInfo.mediaServerId;
  612 + that.ssrc = that.streamInfo.ssrc;
  613 + that.videoUrl = that.getUrlByStreamInfo();
614 that.recordPlay = true; 614 that.recordPlay = true;
615 }); 615 });
616 } 616 }