src/main/java/com/genersoft/iot/vmp/conf/MediaConfig.java
@@ -6,6 +6,10 @@ import org.springframework.context.annotation.Configuration; import org.springframework.util.StringUtils; import java.net.InetAddress; import java.net.UnknownHostException; import java.util.regex.Pattern; @Configuration("mediaConfig") public class MediaConfig{ @@ -161,7 +165,18 @@ if (StringUtils.isEmpty(sdpIp)){ return ip; }else { return sdpIp; if (isValidIPAddress(sdpIp)) { return sdpIp; }else { // 按照域名解析 String hostAddress = null; try { hostAddress = InetAddress.getByName(sdpIp).getHostAddress(); } catch (UnknownHostException e) { throw new RuntimeException(e); } return hostAddress; } } } @@ -211,4 +226,11 @@ return mediaServerItem; } private boolean isValidIPAddress(String ipAddress) { if ((ipAddress != null) && (!ipAddress.isEmpty())) { 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); } return false; } } src/main/java/com/genersoft/iot/vmp/conf/security/LoginSuccessHandler.java
@@ -11,6 +11,9 @@ import javax.servlet.http.HttpServletResponse; import java.io.IOException; /** * @author lin */ @Component public class LoginSuccessHandler implements AuthenticationSuccessHandler { src/main/java/com/genersoft/iot/vmp/conf/security/WebSecurityConfig.java
@@ -20,6 +20,7 @@ /** * 配置Spring Security * @author lin */ @Configuration @EnableWebSecurity @@ -132,15 +133,19 @@ .anyRequest().authenticated() // 异常处理(权限拒绝、登录失效等) .and().exceptionHandling() .authenticationEntryPoint(anonymousAuthenticationEntryPoint)//匿名用户访问无权限资源时的异常处理 //匿名用户访问无权限资源时的异常处理 .authenticationEntryPoint(anonymousAuthenticationEntryPoint) // .accessDeniedHandler(accessDeniedHandler)//登录用户没有权限访问资源 // 登入 .and().formLogin().permitAll()//允许所有用户 .successHandler(loginSuccessHandler)//登录成功处理逻辑 .failureHandler(loginFailureHandler)//登录失败处理逻辑 // 登入 允许所有用户 .and().formLogin().permitAll() //登录成功处理逻辑 .successHandler(loginSuccessHandler) //登录失败处理逻辑 .failureHandler(loginFailureHandler) // 登出 .and().logout().logoutUrl("/api/user/logout").permitAll()//允许所有用户 .logoutSuccessHandler(logoutHandler)//登出成功处理逻辑 .and().logout().logoutUrl("/api/user/logout").permitAll() //登出成功处理逻辑 .logoutSuccessHandler(logoutHandler) .deleteCookies("JSESSIONID") // 会话管理 // .and().sessionManagement().invalidSessionStrategy(invalidSessionHandler) // 超时处理 src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/RegisterRequestProcessor.java
@@ -1,17 +1,13 @@ package com.genersoft.iot.vmp.gb28181.transmit.event.request.impl; import com.genersoft.iot.vmp.common.VideoManagerConstants; import com.genersoft.iot.vmp.conf.SipConfig; import com.genersoft.iot.vmp.gb28181.auth.DigestServerAuthenticationHelper; import com.genersoft.iot.vmp.gb28181.bean.Device; import com.genersoft.iot.vmp.gb28181.bean.WvpSipDate; import com.genersoft.iot.vmp.gb28181.event.EventPublisher; import com.genersoft.iot.vmp.gb28181.transmit.SIPProcessorObserver; import com.genersoft.iot.vmp.gb28181.transmit.event.request.ISIPRequestProcessor; import com.genersoft.iot.vmp.gb28181.transmit.event.request.SIPRequestProcessorParent; import com.genersoft.iot.vmp.gb28181.auth.DigestServerAuthenticationHelper; import com.genersoft.iot.vmp.service.IDeviceService; import com.genersoft.iot.vmp.storager.IRedisCatchStorage; import com.genersoft.iot.vmp.storager.IVideoManagerStorage; import com.genersoft.iot.vmp.utils.DateUtil; import gov.nist.javax.sip.RequestEventExt; import gov.nist.javax.sip.address.AddressImpl; @@ -51,15 +47,6 @@ private SipConfig sipConfig; @Autowired private IRedisCatchStorage redisCatchStorage; @Autowired private IVideoManagerStorage storager; @Autowired private EventPublisher publisher; @Autowired private SIPProcessorObserver sipProcessorObserver; @Autowired @@ -86,7 +73,7 @@ ExpiresHeader expiresHeader = (ExpiresHeader) request.getHeader(Expires.NAME); Response response = null; boolean passwordCorrect = false; // 注册标志 0:未携带授权头或者密码错误 1:注册成功 2:注销成功 // 注册标志 boolean registerFlag = false; FromHeader fromHeader = (FromHeader) request.getHeader(FromHeader.NAME); AddressImpl address = (AddressImpl) fromHeader.getAddress(); @@ -105,7 +92,6 @@ // 校验密码是否正确 passwordCorrect = StringUtils.isEmpty(sipConfig.getPassword()) || new DigestServerAuthenticationHelper().doAuthenticatePlainTextPassword(request, sipConfig.getPassword()); // 未携带授权头或者密码错误 回复401 if (!passwordCorrect) { // 注册失败 src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/KeepaliveNotifyMessageHandler.java
@@ -64,16 +64,14 @@ device.setHostAddress(received.concat(":").concat(String.valueOf(rPort))); } device.setKeepaliveTime(DateUtil.getNow()); // 回复200 OK responseAck(evt, Response.OK); if (device.getOnline() == 1) { // 回复200 OK responseAck(evt, Response.OK); deviceService.updateDevice(device); }else { // 对于已经离线的设备判断他的注册是否已经过期 if (!deviceService.expire(device)){ deviceService.online(device); // 回复200 OK responseAck(evt, Response.OK); } } } catch (SipException e) { src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/response/cmd/RecordInfoResponseMessageHandler.java
@@ -70,15 +70,20 @@ rootElement = getRootElement(evt, device.getCharset()); String sn = getText(rootElement, "SN"); RecordInfo recordInfo = new RecordInfo(); recordInfo.setDeviceId(device.getDeviceId()); recordInfo.setSn(sn); recordInfo.setName(getText(rootElement, "Name")); String sumNumStr = getText(rootElement, "SumNum"); int sumNum = 0; if (!StringUtils.isEmpty(sumNumStr)) { sumNum = Integer.parseInt(sumNumStr); } recordInfo.setSumNum(sumNum); Element recordListElement = rootElement.element("RecordList"); if (recordListElement == null || sumNum == 0) { logger.info("无录像数据"); eventPublisher.recordEndEventPush(recordInfo); recordDataCatch.put(device.getDeviceId(), sn, sumNum, new ArrayList<>()); releaseRequest(device.getDeviceId(), sn); } else { @@ -112,6 +117,9 @@ record.setRecorderId(getText(itemRecord, "RecorderID")); recordList.add(record); } recordInfo.setRecordList(recordList); // 发送消息,如果是上级查询此录像,则会通过这里通知给上级 eventPublisher.recordEndEventPush(recordInfo); int count = recordDataCatch.put(device.getDeviceId(), sn, sumNum, recordList); logger.info("[国标录像], {}->{}: {}/{}", device.getDeviceId(), sn, count, sumNum); } src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java
@@ -19,17 +19,16 @@ import com.genersoft.iot.vmp.media.zlm.ZLMRESTfulUtils; import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; import com.genersoft.iot.vmp.service.IMediaServerService; import com.genersoft.iot.vmp.service.IMediaService; import com.genersoft.iot.vmp.service.IPlayService; import com.genersoft.iot.vmp.service.bean.InviteTimeOutCallback; import com.genersoft.iot.vmp.service.bean.PlayBackCallback; import com.genersoft.iot.vmp.service.bean.PlayBackResult; import com.genersoft.iot.vmp.service.bean.SSRCInfo; import com.genersoft.iot.vmp.storager.IRedisCatchStorage; import com.genersoft.iot.vmp.storager.IVideoManagerStorage; import com.genersoft.iot.vmp.utils.redis.RedisUtil; import com.genersoft.iot.vmp.vmanager.bean.WVPResult; import com.genersoft.iot.vmp.vmanager.gb28181.play.bean.PlayResult; import com.genersoft.iot.vmp.service.IMediaService; import com.genersoft.iot.vmp.service.IPlayService; import gov.nist.javax.sip.stack.SIPDialog; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -43,6 +42,7 @@ import javax.sip.ResponseEvent; import java.io.FileNotFoundException; import java.math.BigDecimal; import java.math.RoundingMode; import java.util.*; @SuppressWarnings(value = {"rawtypes", "unchecked"}) @@ -62,9 +62,6 @@ @Autowired private IRedisCatchStorage redisCatchStorage; @Autowired private RedisUtil redis; @Autowired private DeferredResultHolder resultHolder; @@ -591,7 +588,7 @@ BigDecimal currentCount = new BigDecimal(duration/1000); BigDecimal totalCount = new BigDecimal(end-start); BigDecimal divide = currentCount.divide(totalCount,2, BigDecimal.ROUND_HALF_UP); BigDecimal divide = currentCount.divide(totalCount,2, RoundingMode.HALF_UP); double process = divide.doubleValue(); streamInfo.setProgress(process); } web_src/package.json
@@ -52,7 +52,7 @@ "postcss-url": "^7.2.1", "rimraf": "^2.6.0", "semver": "^5.3.0", "shelljs": "^0.7.6", "shelljs": "^0.8.5", "uglifyjs-webpack-plugin": "^1.1.1", "url-loader": "^0.5.8", "vue-loader": "^13.3.0", web_src/src/components/dialog/devicePlayer.vue
@@ -605,12 +605,12 @@ url: '/api/playback/start/' + this.deviceId + '/' + this.channelId + '?startTime=' + row.startTime + '&endTime=' + row.endTime }).then(function (res) { var streamInfo = res.data; that.app = streamInfo.app; that.streamId = streamInfo.stream; that.mediaServerId = streamInfo.mediaServerId; that.ssrc = streamInfo.ssrc; that.videoUrl = that.getUrlByStreamInfo(streamInfo); that.streamInfo = res.data; that.app = that.streamInfo.app; that.streamId = that.streamInfo.stream; that.mediaServerId = that.streamInfo.mediaServerId; that.ssrc = that.streamInfo.ssrc; that.videoUrl = that.getUrlByStreamInfo(); that.recordPlay = true; }); }