s3暂时编写回放逻辑

dongguan-huaweiyun
LAPTOP-S9HJSOEB\昊天 2 years ago
parent b206c32c48
commit 0f290d98f7

@ -37,6 +37,18 @@ public class ConfigProperties {
private ScanCodeMode scanCodeMode;
private ServerOpenInfo serverOpenInfo;
private S3Config s3Config;
@Data
public static class S3Config {
private String accessKey = "minio";
private String secretKey = "minio123";
// 桶所在的区域对应网关URL的域名地址
private String host = "192.168.1.52:9000";
private String bucketName = "camera";
private String urlCache = "D://camera/";
}
@Data

@ -0,0 +1,25 @@
package com.leaper.web.config;
import com.leaper.web.task.S3Utils;
import org.springframework.cache.CacheManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.annotation.Resource;
// ftp配置
@Configuration
public class S3Config {
@Resource
ConfigProperties properties;
@Bean
public S3Utils s3Utils() {
S3Utils s3Utils = new S3Utils();
s3Utils.init(properties.getS3Config().getAccessKey(), properties.getS3Config().getSecretKey(), properties.getS3Config().getHost());
return s3Utils;
}
}

@ -0,0 +1,103 @@
package com.leaper.web.controller;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.additional.query.impl.QueryChainWrapper;
import com.github.pagehelper.PageInfo;
import com.leaper.filter.pojo.LicenseHandler;
import com.leaper.web.config.ConfigProperties;
import com.leaper.web.entity.Camera;
import com.leaper.web.entity.CameraRecordDuoji;
import com.leaper.web.entity.Record;
import com.leaper.web.lib.CameraControlModule;
import com.leaper.web.lib.hik.HikCameraControlModuleImpl;
import com.leaper.web.mapper.CameraRecordDuojiMapper;
import com.leaper.web.pojo.street.StreetSearch;
import com.leaper.web.task.S3Utils;
import com.zhehekeji.core.pojo.Result;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import java.io.File;
import java.time.Duration;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.stream.Collectors;
@Api(value = "cameraRecord", tags = "球机回放管理")
@RestController
@RequestMapping("/cameraRecord")
@Slf4j
public class CameraRecord {
@Resource
CameraRecordDuojiMapper cameraRecordDuojiMapper;
@Resource
ConfigProperties configProperties;
@Resource
S3Utils s3Utils;
@PostMapping("/record")
@ApiOperation(value = "回放列表 ")
@LicenseHandler
public Result<Record> record(@RequestBody Record record) {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-M-dd");
LocalDate today = LocalDate.parse(record.getDate(), formatter);
LocalDateTime startOfDay = LocalDateTime.of(today, LocalTime.MIN);
LocalDateTime endOfDay = LocalDateTime.of(today, LocalTime.MAX);
List<CameraRecordDuoji> cameraRecordDuoji = cameraRecordDuojiMapper.selectList(new QueryWrapper<CameraRecordDuoji>()
.eq("camera_Id", record.getCameraId())
.ge("start_Time", startOfDay)
.le("end_Time", endOfDay)
.orderByAsc("start_Time"));
record.setStartTimeLong(0L);
record.setEndTimeLong(24L * 60 * 60);
List<Record> urls = cameraRecordDuoji.stream()
.map(cameraRecordDuoji1 -> {
Record r = new Record();
r.setUrl( "/"+configProperties.getS3Config().getBucketName() +"/"+cameraRecordDuoji1.getPath() +".mp4");
r.setStartTimeLong(toSecondsSinceMidnight(cameraRecordDuoji1.getStartTime()));
r.setEndTimeLong(toSecondsSinceMidnight(cameraRecordDuoji1.getEndTime()));
return r;
})
.collect(Collectors.toList());
record.setUrls(urls);
return new Result<>(record);
}
@PostMapping("/convetor")
@ApiOperation(value = "视频转换 ")
@LicenseHandler
public Result<Boolean> convetor(@RequestBody Record record) {
String url = record.getUrl().replace(".mp4","").replace("/"+configProperties.getS3Config().getBucketName() ,"").substring(1);
// 文件或目录的路径
String filePath =configProperties.getS3Config().getUrlCache() +url+".mp4";
// 创建一个File对象
File file = new File(filePath);
if(file.exists()){
return new Result<>(true);
}else {
s3Utils.downloadFile(configProperties.getS3Config().getBucketName(), url, configProperties.getS3Config().getUrlCache() + url);
HikCameraControlModuleImpl.convetor(configProperties.getS3Config().getUrlCache() + url, filePath);
return new Result<>(true);
}
}
private static long toSecondsSinceMidnight(LocalDateTime dateTime) {
LocalDateTime midnight = dateTime.toLocalDate().atStartOfDay();
Duration duration = Duration.between(midnight, dateTime);
return duration.getSeconds();
}
}

@ -0,0 +1,25 @@
package com.leaper.web.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import java.time.LocalDateTime;
@Data
@TableName("camera_record_duoji")
public class CameraRecordDuoji {
@TableId(type = IdType.AUTO)
private Integer id;
private Integer cameraId;
private Integer type;
@JsonFormat(pattern="yyyy-MM-dd HH:mm:ss")
private LocalDateTime startTime;
@JsonFormat(pattern="yyyy-MM-dd HH:mm:ss")
private LocalDateTime endTime;
private String path;
}

@ -0,0 +1,17 @@
package com.leaper.web.entity;
import lombok.Data;
import java.util.List;
@Data
public class Record {
private String date;
private Integer cameraId;
private Long startTimeLong;
private Long endTimeLong;
private String url;
private List<Record> urls;
}

@ -111,6 +111,7 @@ public interface CameraControlModule {
void downloadMp4(Integer cameraId, String path, LocalDateTime start, LocalDateTime end, ConfigProperties.SavePath savePath);
void downloadMp4(Integer cameraId, String path, LocalDateTime start, LocalDateTime end, ConfigProperties.SavePath savePath,Integer channel);
boolean downloadMp4Stream(Integer cameraId, String path, LocalDateTime start, LocalDateTime end,Integer channel);
/**
*
*

@ -303,6 +303,50 @@ public class HikCameraControlModuleImpl implements CameraControlModule {
}
}
public boolean downloadMp4Stream(Integer cameraId, String path, LocalDateTime start, LocalDateTime end,Integer channel) {
PathUtil.checkDirc(path);
HCNetSDK.NET_DVR_TIME startTime = new HCNetSDK.NET_DVR_TIME();
startTime.setTime(start.getYear(), start.getMonthValue(), start.getDayOfMonth(), start.getHour(), start.getMinute(), start.getSecond());
HCNetSDK.NET_DVR_TIME endTime = new HCNetSDK.NET_DVR_TIME();
endTime.setTime(end.getYear(), end.getMonthValue(), end.getDayOfMonth(), end.getHour(), end.getMinute(), end.getSecond());
log.info("start download mp4 path:{} ,cameraId:{},start_time{}end_time:{}",path,cameraId,startTime.toStringTime(),endTime.toStringTime());
int lUserID = CameraConnMap.getConnId(cameraId).intValue();
int result = HikLoginModuleImpl.hcNetsdk.NET_DVR_GetFileByTime(lUserID, channel, startTime, endTime, path);
if (result == -1) {
log.error("downloadMp4 error code:{},cameraId:{},path:{}", HikLoginModuleImpl.hcNetsdk.NET_DVR_GetLastError(),cameraId,path);
return false;
} else {
HikLoginModuleImpl.hcNetsdk.NET_DVR_PlayBackControl(result, HikLoginModuleImpl.hcNetsdk.NET_DVR_PLAYSTART,0,null);
int tmp = -1;
IntByReference pos = new IntByReference(0);
while (result >= 0) {
boolean backFlag = HikLoginModuleImpl.hcNetsdk.NET_DVR_PlayBackControl(result, HikLoginModuleImpl.hcNetsdk.NET_DVR_PLAYGETPOS, 0, pos);
if (!backFlag) {//防止单个线程死循环
return false;
}
int produce = pos.getValue();
if ((produce % 10) == 0 && tmp != produce) {//输出进度
tmp = produce;
}
if (produce == 100) {//下载成功
HikLoginModuleImpl.hcNetsdk.NET_DVR_StopGetFile(result);
return true;
}
if (produce > 100) {//下载失败
HikLoginModuleImpl.hcNetsdk.NET_DVR_StopGetFile(result);
result = -1;
return false;
}
}
return true;
}
}
class DownloadTask extends java.util.TimerTask {
private Integer handler;
private Timer downloadtimer;
@ -377,6 +421,7 @@ public class HikCameraControlModuleImpl implements CameraControlModule {
while ((line = br.readLine()) != null) {
}
}catch (Exception e){
}finally {
try {
if (br != null) {

@ -16,7 +16,7 @@ public class HikExceptionCallBack implements HCNetSDK.FExceptionCallBack {
if(cameraId != null){
log.error("hik disconnect,cameraId:{}", cameraId);
CameraConnMap.disConn(cameraId);
//CameraConnMap.disConn(cameraId);
}
}else if(dwType == 32791){

@ -305,7 +305,9 @@ public class JoywareCameraControlModuleImpl implements CameraControlModule {
log.error("download mp4 error:{},startTime:{} ,endTime:{},cameraId:{}",ToolKits.getErrorCodePrint(),start,end,cameraId);
}
}
public boolean downloadMp4Stream(Integer cameraId, String path, LocalDateTime start, LocalDateTime end, Integer channel){
return false;
}
public void downloadMp4(Integer cameraId, String path, LocalDateTime start, LocalDateTime end, ConfigProperties.SavePath savePath,Integer channel) {

@ -0,0 +1,8 @@
package com.leaper.web.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.leaper.web.entity.CameraRecord;
import com.leaper.web.entity.CameraRecordDuoji;
public interface CameraRecordDuojiMapper extends BaseMapper<CameraRecordDuoji> {
}

@ -132,12 +132,12 @@ public class CameraService {
if (ok) {
camera.setStatus("连接正常");
} else {
CameraConnMap.disConn(camera.getId());
//CameraConnMap.disConn(camera.getId());
camera.setStatus("未连接");
cameraLogin(camera);
}
}).collect(Collectors.toList());
return new PageInfo<>(cameras);
return new PageInfo<>(collect);
}
public class StatusThread extends Thread {
@ -166,11 +166,11 @@ public class CameraService {
if (ok) {
camera.setStatus("连接正常");
} else {
CameraConnMap.disConn(camera.getId());
//CameraConnMap.disConn(camera.getId());
camera.setStatus("未连接");
}
} catch (Exception e) {
CameraConnMap.disConn(camera.getId());
//CameraConnMap.disConn(camera.getId());
camera.setStatus("未连接");
} finally {
latch.countDown();

@ -4,20 +4,16 @@ import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.jcraft.jsch.ChannelSftp;
import com.jcraft.jsch.SftpATTRS;
import com.leaper.web.config.ConfigProperties;
import com.leaper.web.entity.Camera;
import com.leaper.web.entity.LightSource;
import com.leaper.web.entity.OrderLive;
import com.leaper.web.entity.PicData;
import com.leaper.web.entity.*;
import com.leaper.web.lib.CameraConnMap;
import com.leaper.web.lib.CameraControlModule;
import com.leaper.web.lib.hik.HikLoginModuleImpl;
import com.leaper.web.lib.joyware.JoywareLoginModuleImpl;
import com.leaper.web.mapper.CameraMapper;
import com.leaper.web.mapper.LightSourceMapper;
import com.leaper.web.mapper.OrderLiveMapper;
import com.leaper.web.mapper.PicDataMapper;
import com.leaper.web.mapper.*;
import com.leaper.web.service.damLightSource.JYDAMEquip;
import com.leaper.web.service.damLightSource.JYDamHelper;
import com.leaper.web.service.hikLightSource.HikControlSocket;
import com.leaper.web.task.S3Utils;
import lombok.extern.slf4j.Slf4j;
import net.schmizz.sshj.sftp.SFTPClient;
import org.springframework.scheduling.annotation.EnableScheduling;
@ -32,10 +28,9 @@ import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.attribute.BasicFileAttributes;
import java.time.*;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.time.format.DateTimeFormatter;
import java.time.temporal.TemporalAdjusters;
import java.util.*;
import java.util.concurrent.CountDownLatch;
@Component
@ -100,6 +95,87 @@ public class CronTab {
}
}
/**
*
*
* @param directory
*/
@Scheduled(cron = "15 0 0 * * ?")
public void clearDirectoryRecursively() {
File directory = new File(configProperties.getS3Config().getUrlCache());
if (directory.exists() && directory.isDirectory()) {
File[] files = directory.listFiles();
if (files != null) {
for (File file : files) {
if (file.isDirectory()) {
// 递归调用此方法来清除子目录
clearDirectoryRecursively(file);
}
// 删除文件或空目录
file.delete();
}
}
}
}
public static void clearDirectoryRecursively(File directory) {
if (directory.exists() && directory.isDirectory()) {
File[] files = directory.listFiles();
if (files != null) {
for (File file : files) {
if (file.isDirectory()) {
// 递归调用此方法来清除子目录
clearDirectoryRecursively(file);
}
// 删除文件或空目录
file.delete();
}
}
}
}
@Resource
S3Utils s3Utils;
@Resource
CameraRecordDuojiMapper cameraRecordDuojiMapper;
@Resource
CameraControlModule cameraControlModule;
/**
*
*/
@Scheduled(cron = "5 0/1 * * * ? ")
//@Scheduled(cron = "0 0/1 * * * *")
public void s3DownloadFile() {
List<Camera> cameras = cameraMapper.selectList(new QueryWrapper<>());
LocalDate currentDate = LocalDate.now(); // 获取当前日期
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd"); // 设置日期格式
LocalDateTime now = LocalDateTime.now();
//结束时间
LocalDateTime currentMinuteStart = now.minusMinutes(2).withSecond(0).withNano(0);
//开始时间
LocalDateTime previousMinuteStart = now.minusMinutes(3).withSecond(0).withNano(0);
String formattedDate = currentDate.format(formatter);
for (Camera camera : cameras){
String url = formattedDate + "/" +UUID.randomUUID();
boolean ok =cameraControlModule.downloadMp4Stream(camera.getId(), "D:\\" + url, previousMinuteStart, currentMinuteStart, camera.getChannel());
if(ok) {
File file = new File("D:\\" + url);
s3Utils.uploadFile(configProperties.getS3Config().getBucketName(), url, file);
CameraRecordDuoji cameraRecordDuoji = new CameraRecordDuoji();
cameraRecordDuoji.setCameraId(camera.getId());
cameraRecordDuoji.setPath(configProperties.getS3Config().getBucketName()+ "/" +url);
cameraRecordDuoji.setStartTime(previousMinuteStart);
cameraRecordDuoji.setEndTime(currentMinuteStart);
cameraRecordDuoji.setPath(url);
cameraRecordDuojiMapper.insert(cameraRecordDuoji);
file.delete();
}
}
}
@Scheduled(cron = "0 * * * * ?")
public void cameraConn() {
log.info("球机连接判断");
@ -144,12 +220,12 @@ public class CronTab {
if (ok) {
camera.setStatus("连接正常");
} else {
CameraConnMap.disConn(camera.getId());
//CameraConnMap.disConn(camera.getId());
camera.setStatus("未连接");
//cameraService.cameraLogin(camera);
}
} catch (Exception e) {
CameraConnMap.disConn(camera.getId());
//CameraConnMap.disConn(camera.getId());
camera.setStatus("未连接");
} finally {
latch.countDown();

@ -19,6 +19,7 @@ import com.amazonaws.services.s3.model.S3ObjectInputStream;
import com.amazonaws.services.s3.transfer.internal.TransferManagerUtils;
import com.amazonaws.util.IOUtils;
import com.amazonaws.util.json.Jackson;
import org.springframework.stereotype.Service;
import java.io.File;
import java.io.IOException;

@ -1,4 +0,0 @@
package com.leaper.web.task;
public class T {
}

@ -109,3 +109,10 @@ deleteFileDays: 365
mybatis-plus:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
s3Config:
accessKey: "minio"
secretKey: "minio123"
host: "192.168.1.52:9000"
bucketName: "camera"
urlCache: "D://camera/"
Loading…
Cancel
Save