You've already forked FrameTour-BE
获取人脸对应视频流程,自动删除源视频流程,自动创建任务渲染流程,自动删除人脸数据逻辑
This commit is contained in:
45
src/main/java/com/ycwl/basic/device/DeviceFactory.java
Normal file
45
src/main/java/com/ycwl/basic/device/DeviceFactory.java
Normal file
@ -0,0 +1,45 @@
|
||||
package com.ycwl.basic.device;
|
||||
|
||||
import com.ycwl.basic.device.checker.IDeviceStatusChecker;
|
||||
import com.ycwl.basic.device.checker.impl.AliOssDeviceChecker;
|
||||
import com.ycwl.basic.device.checker.impl.AlwaysOnDeviceChecker;
|
||||
import com.ycwl.basic.device.enums.DeviceStoreTypeEnum;
|
||||
import com.ycwl.basic.device.operator.IDeviceStorageOperator;
|
||||
import com.ycwl.basic.device.operator.impl.AliOssStorageOperator;
|
||||
import com.ycwl.basic.device.operator.impl.LocalStorageOperator;
|
||||
import com.ycwl.basic.model.pc.device.entity.DeviceConfigEntity;
|
||||
import com.ycwl.basic.model.pc.device.entity.DeviceEntity;
|
||||
|
||||
public class DeviceFactory {
|
||||
public static IDeviceStorageOperator getDeviceStorageOperator(DeviceEntity device, DeviceConfigEntity config) {
|
||||
IDeviceStorageOperator operator = null;
|
||||
if (config.getStoreType() == DeviceStoreTypeEnum.ALI_OSS.getType()) {
|
||||
operator = new AliOssStorageOperator(config.getStoreConfigJson());
|
||||
} else if (config.getStoreType() == DeviceStoreTypeEnum.LOCAL.getType()) {
|
||||
operator = new LocalStorageOperator(config.getStoreConfigJson());
|
||||
}
|
||||
if (operator == null) {
|
||||
return null;
|
||||
}
|
||||
operator.setDevice(device);
|
||||
operator.setDeviceConfig(config);
|
||||
return operator;
|
||||
}
|
||||
|
||||
public static IDeviceStatusChecker getDeviceStatusChecker(DeviceEntity device, DeviceConfigEntity config) {
|
||||
IDeviceStatusChecker checker = null;
|
||||
if (config.getOnlineCheck() <= 0) {
|
||||
checker = new AlwaysOnDeviceChecker();
|
||||
} else {
|
||||
if (config.getStoreType() == DeviceStoreTypeEnum.ALI_OSS.getType()) {
|
||||
checker = new AliOssDeviceChecker(config.getStoreConfigJson());
|
||||
}
|
||||
}
|
||||
if (checker == null) {
|
||||
return null;
|
||||
}
|
||||
checker.setDevice(device);
|
||||
checker.setDeviceConfig(config);
|
||||
return checker;
|
||||
}
|
||||
}
|
9
src/main/java/com/ycwl/basic/device/IDeviceCommon.java
Normal file
9
src/main/java/com/ycwl/basic/device/IDeviceCommon.java
Normal file
@ -0,0 +1,9 @@
|
||||
package com.ycwl.basic.device;
|
||||
|
||||
import com.ycwl.basic.model.pc.device.entity.DeviceConfigEntity;
|
||||
import com.ycwl.basic.model.pc.device.entity.DeviceEntity;
|
||||
|
||||
public interface IDeviceCommon {
|
||||
void setDevice(DeviceEntity device);
|
||||
void setDeviceConfig(DeviceConfigEntity config);
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
package com.ycwl.basic.device.checker;
|
||||
|
||||
import com.ycwl.basic.device.IDeviceCommon;
|
||||
|
||||
public interface IDeviceStatusChecker extends IDeviceCommon {
|
||||
boolean checkDeviceStatus();
|
||||
}
|
@ -0,0 +1,23 @@
|
||||
package com.ycwl.basic.device.checker.helper;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.ycwl.basic.model.pc.device.entity.DeviceConfigEntity;
|
||||
import com.ycwl.basic.model.pc.device.entity.DeviceEntity;
|
||||
import lombok.Setter;
|
||||
|
||||
public abstract class CommonDeviceChecker<C> {
|
||||
protected C config;
|
||||
@Setter
|
||||
protected DeviceEntity device;
|
||||
@Setter
|
||||
protected DeviceConfigEntity deviceConfig;
|
||||
|
||||
public CommonDeviceChecker(String configJson) {
|
||||
config = JSON.parseObject(configJson, getConfigClass());
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private Class<C> getConfigClass() {
|
||||
return (Class<C>) ((java.lang.reflect.ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
|
||||
}
|
||||
}
|
@ -0,0 +1,88 @@
|
||||
package com.ycwl.basic.device.checker.impl;
|
||||
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import com.aliyun.oss.OSS;
|
||||
import com.aliyun.oss.OSSClientBuilder;
|
||||
import com.aliyun.oss.OSSException;
|
||||
import com.aliyun.oss.model.ListObjectsV2Request;
|
||||
import com.aliyun.oss.model.ListObjectsV2Result;
|
||||
import com.aliyun.oss.model.OSSObjectSummary;
|
||||
import com.ycwl.basic.device.checker.IDeviceStatusChecker;
|
||||
import com.ycwl.basic.device.checker.helper.CommonDeviceChecker;
|
||||
import com.ycwl.basic.device.entity.alioss.DeviceAliOssConfig;
|
||||
import com.ycwl.basic.device.entity.common.FileObject;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Slf4j
|
||||
public class AliOssDeviceChecker extends CommonDeviceChecker<DeviceAliOssConfig> implements IDeviceStatusChecker {
|
||||
public AliOssDeviceChecker(String configJson) {
|
||||
super(configJson);
|
||||
}
|
||||
|
||||
private OSS getClient() {
|
||||
return new OSSClientBuilder().build(config.getEndpoint(), config.getAccessKeyId(), config.getAccessKeySecret());
|
||||
}
|
||||
|
||||
private List<FileObject> getOssFileListByPrefix(String prefix) {
|
||||
OSS ossClient = getClient();
|
||||
ListObjectsV2Request listObjectsV2Request = new ListObjectsV2Request(config.getBucketName());
|
||||
listObjectsV2Request.setPrefix(config.getPrefix() + prefix);
|
||||
boolean isTruncated = true;
|
||||
String continuationToken = null;
|
||||
List<OSSObjectSummary> objectList = new ArrayList<>();
|
||||
try {
|
||||
while (isTruncated) {
|
||||
if (continuationToken != null) {
|
||||
listObjectsV2Request.setContinuationToken(continuationToken);
|
||||
}
|
||||
|
||||
// 列举文件。
|
||||
ListObjectsV2Result result = ossClient.listObjectsV2(listObjectsV2Request);
|
||||
|
||||
objectList.addAll(result.getObjectSummaries());
|
||||
|
||||
isTruncated = result.isTruncated();
|
||||
continuationToken = result.getNextContinuationToken();
|
||||
}
|
||||
return objectList.stream().filter(item -> item.getKey().endsWith(".ts")).map(item -> {
|
||||
FileObject object = new FileObject();
|
||||
object.setPath(item.getKey());
|
||||
object.setNeedDownload(true);
|
||||
String[] splitDir = item.getKey().split("/");
|
||||
String splitDate = splitDir[splitDir.length - 2];
|
||||
String splitName = splitDir[splitDir.length - 1];
|
||||
String[] splitExt = splitName.split("\\.", 2);
|
||||
String[] splitDt = splitExt[0].split("_", 2);
|
||||
String createTime = splitDt[0];
|
||||
String endTime = splitDt[1];
|
||||
object.setName(splitName);
|
||||
object.setEndTime(DateUtil.parse(splitDate+endTime, "yyyyMMddHHmmss"));
|
||||
object.setCreateTime(DateUtil.parse(splitDate+createTime, "yyyyMMddHHmmss"));
|
||||
return object;
|
||||
}).collect(Collectors.toList());
|
||||
} catch (OSSException e) {
|
||||
log.error("获取OSS文件列表失败", e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@Override
|
||||
public boolean checkDeviceStatus() {
|
||||
Date now = new Date();
|
||||
if (deviceConfig.getOnlineMaxInterval() == null) {
|
||||
// 没有合适配置
|
||||
return true;
|
||||
}
|
||||
Date startTime = DateUtil.offsetMinute(now, -deviceConfig.getOnlineMaxInterval());
|
||||
List<FileObject> fileList = getOssFileListByPrefix(DateUtil.format(startTime, "yyyyMMdd/HHmm"));
|
||||
if (fileList != null) {
|
||||
return !fileList.isEmpty();
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,20 @@
|
||||
package com.ycwl.basic.device.checker.impl;
|
||||
|
||||
import com.ycwl.basic.device.checker.IDeviceStatusChecker;
|
||||
import com.ycwl.basic.device.checker.helper.CommonDeviceChecker;
|
||||
import com.ycwl.basic.model.pc.device.entity.DeviceConfigEntity;
|
||||
import com.ycwl.basic.model.pc.device.entity.DeviceEntity;
|
||||
import lombok.Setter;
|
||||
|
||||
@SuppressWarnings("LombokSetterMayBeUsed")
|
||||
public class AlwaysOnDeviceChecker implements IDeviceStatusChecker {
|
||||
@Setter
|
||||
private DeviceEntity device;
|
||||
@Setter
|
||||
private DeviceConfigEntity deviceConfig;
|
||||
|
||||
@Override
|
||||
public boolean checkDeviceStatus() {
|
||||
return true;
|
||||
}
|
||||
}
|
@ -0,0 +1,14 @@
|
||||
package com.ycwl.basic.device.entity.alioss;
|
||||
|
||||
import lombok.Data;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
@Data
|
||||
public class DeviceAliOssConfig {
|
||||
private String accessKeyId;
|
||||
private String accessKeySecret;
|
||||
private String bucketName;
|
||||
private String endpoint;
|
||||
private String region;
|
||||
private String prefix;
|
||||
}
|
@ -0,0 +1,15 @@
|
||||
package com.ycwl.basic.device.entity.common;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
@Data
|
||||
public class FileObject {
|
||||
private String path;
|
||||
private String name;
|
||||
private String url;
|
||||
private boolean needDownload = false;
|
||||
private Date createTime;
|
||||
private Date endTime;
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
package com.ycwl.basic.device.entity.local;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class DeviceLocalConfig {
|
||||
}
|
@ -0,0 +1,23 @@
|
||||
package com.ycwl.basic.device.enums;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum DeviceStoreTypeEnum {
|
||||
ALI_OSS(1, "阿里云OSS"),
|
||||
LOCAL(2, "本地文件");
|
||||
|
||||
private final int type;
|
||||
private final String remark;
|
||||
|
||||
public static DeviceStoreTypeEnum getByType(int type) {
|
||||
for (DeviceStoreTypeEnum e : values()) {
|
||||
if (e.type == type) {
|
||||
return e;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
@ -0,0 +1,26 @@
|
||||
package com.ycwl.basic.device.operator;
|
||||
|
||||
import com.ycwl.basic.device.IDeviceCommon;
|
||||
import com.ycwl.basic.device.entity.common.FileObject;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
public interface IDeviceStorageOperator extends IDeviceCommon {
|
||||
/**
|
||||
* 获取指定时间范围内的文件列表
|
||||
*
|
||||
* @param startDate 开始时间
|
||||
* @param endDate 结束时间
|
||||
* @return
|
||||
*/
|
||||
List<FileObject> getFileListByDtRange(Date startDate, Date endDate);
|
||||
|
||||
/**
|
||||
* 删除指定日期之前的文件,不包含指定的日期当天
|
||||
*
|
||||
* @param date 指定日期,不包含指定日期当天
|
||||
* @return
|
||||
*/
|
||||
boolean removeFilesBeforeDate(Date date);
|
||||
}
|
@ -0,0 +1,24 @@
|
||||
package com.ycwl.basic.device.operator.helper;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.ycwl.basic.model.pc.device.entity.DeviceConfigEntity;
|
||||
import com.ycwl.basic.model.pc.device.entity.DeviceEntity;
|
||||
import lombok.Setter;
|
||||
|
||||
public abstract class CommonPieceGetter<C> {
|
||||
protected C config;
|
||||
@Setter
|
||||
private DeviceEntity device;
|
||||
@Setter
|
||||
private DeviceConfigEntity deviceConfig;
|
||||
|
||||
public CommonPieceGetter(String configJson) {
|
||||
config = JSON.parseObject(configJson, getConfigClass());
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private Class<C> getConfigClass() {
|
||||
return (Class<C>) ((java.lang.reflect.ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,151 @@
|
||||
package com.ycwl.basic.device.operator.impl;
|
||||
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import com.aliyun.oss.HttpMethod;
|
||||
import com.aliyun.oss.OSS;
|
||||
import com.aliyun.oss.OSSClientBuilder;
|
||||
import com.aliyun.oss.OSSException;
|
||||
import com.aliyun.oss.model.DeleteObjectsRequest;
|
||||
import com.aliyun.oss.model.ListObjectsV2Request;
|
||||
import com.aliyun.oss.model.ListObjectsV2Result;
|
||||
import com.aliyun.oss.model.OSSObjectSummary;
|
||||
import com.ycwl.basic.device.entity.alioss.DeviceAliOssConfig;
|
||||
import com.ycwl.basic.device.entity.common.FileObject;
|
||||
import com.ycwl.basic.device.operator.IDeviceStorageOperator;
|
||||
import com.ycwl.basic.device.operator.helper.CommonPieceGetter;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import java.net.URL;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
import java.util.Comparator;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Slf4j
|
||||
public class AliOssStorageOperator extends CommonPieceGetter<DeviceAliOssConfig> implements IDeviceStorageOperator {
|
||||
public AliOssStorageOperator(String configJson) {
|
||||
super(configJson);
|
||||
}
|
||||
|
||||
private OSS getClient() {
|
||||
return new OSSClientBuilder().build(config.getEndpoint(), config.getAccessKeyId(), config.getAccessKeySecret());
|
||||
}
|
||||
|
||||
private List<OSSObjectSummary> getOssObjectListByPrefix(String prefix) {
|
||||
OSS ossClient = getClient();
|
||||
ListObjectsV2Request listObjectsV2Request = new ListObjectsV2Request(config.getBucketName());
|
||||
listObjectsV2Request.setPrefix(config.getPrefix() + prefix);
|
||||
boolean isTruncated = true;
|
||||
String continuationToken = null;
|
||||
List<OSSObjectSummary> objectList = new ArrayList<>();
|
||||
try {
|
||||
while (isTruncated) {
|
||||
if (continuationToken != null) {
|
||||
listObjectsV2Request.setContinuationToken(continuationToken);
|
||||
}
|
||||
|
||||
// 列举文件。
|
||||
ListObjectsV2Result result = ossClient.listObjectsV2(listObjectsV2Request);
|
||||
|
||||
objectList.addAll(result.getObjectSummaries());
|
||||
|
||||
isTruncated = result.isTruncated();
|
||||
continuationToken = result.getNextContinuationToken();
|
||||
}
|
||||
return objectList;
|
||||
} catch (OSSException e) {
|
||||
log.error("获取OSS文件列表失败", e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private List<FileObject> getOssFileListByPrefix(String prefix) {
|
||||
OSS ossClient = getClient();
|
||||
List<OSSObjectSummary> objectList = getOssObjectListByPrefix(prefix);
|
||||
if (objectList == null) {
|
||||
return null;
|
||||
}
|
||||
return objectList.stream().filter(item -> item.getKey().endsWith(".ts")).map(item -> {
|
||||
FileObject object = new FileObject();
|
||||
object.setPath(item.getKey());
|
||||
URL url = ossClient.generatePresignedUrl(item.getBucketName(), item.getKey(), DateUtil.offsetHour(new Date(), 8), HttpMethod.GET);
|
||||
object.setUrl(url.toString());
|
||||
object.setNeedDownload(true);
|
||||
String[] splitDir = item.getKey().split("/");
|
||||
String splitDate = splitDir[splitDir.length - 2];
|
||||
String splitName = splitDir[splitDir.length - 1];
|
||||
String[] splitExt = splitName.split("\\.", 2);
|
||||
String[] splitDt = splitExt[0].split("_", 2);
|
||||
String createTime = splitDt[0];
|
||||
String endTime = splitDt[1];
|
||||
object.setName(splitName);
|
||||
object.setEndTime(DateUtil.parse(splitDate+endTime, "yyyyMMddHHmmss"));
|
||||
object.setCreateTime(DateUtil.parse(splitDate+createTime, "yyyyMMddHHmmss"));
|
||||
return object;
|
||||
}).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
private boolean removeFilesByPrefix(String prefix) {
|
||||
OSS ossClient = getClient();
|
||||
List<OSSObjectSummary> objectList = getOssObjectListByPrefix(prefix);
|
||||
if (objectList == null) {
|
||||
return false;
|
||||
}
|
||||
DeleteObjectsRequest request = new DeleteObjectsRequest(config.getBucketName());
|
||||
request.setKeys(objectList.stream().map(OSSObjectSummary::getKey).collect(Collectors.toList()));
|
||||
try {
|
||||
ossClient.deleteObjects(request);
|
||||
return true;
|
||||
} catch (OSSException e) {
|
||||
return false;
|
||||
} finally {
|
||||
ossClient.shutdown();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<FileObject> getFileListByDtRange(Date startDate, Date endDate) {
|
||||
if (startDate == null || endDate == null) {
|
||||
return null;
|
||||
}
|
||||
List<FileObject> fileList = new ArrayList<>();
|
||||
if (startDate.after(endDate)) {
|
||||
return fileList;
|
||||
}
|
||||
Calendar calendar = Calendar.getInstance();
|
||||
calendar.setTime(startDate);
|
||||
calendar.set(Calendar.SECOND, 0);
|
||||
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd/HHmm");
|
||||
while (calendar.getTime().before(endDate)) {
|
||||
String prefix = dateFormat.format(calendar.getTime());
|
||||
List<FileObject> fileListByPrefix = getOssFileListByPrefix(prefix);
|
||||
if (fileListByPrefix == null) {
|
||||
return null;
|
||||
}
|
||||
fileList.addAll(fileListByPrefix);
|
||||
calendar.add(Calendar.MINUTE, 1);
|
||||
}
|
||||
calendar.clear();
|
||||
return fileList.stream()
|
||||
.sorted(Comparator.comparing(FileObject::getCreateTime))
|
||||
.filter(item -> item.getCreateTime().after(startDate))
|
||||
.filter(item -> item.getCreateTime().before(endDate))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removeFilesBeforeDate(Date date) {
|
||||
Calendar calendar = Calendar.getInstance();
|
||||
calendar.setTime(date);
|
||||
calendar.set(Calendar.SECOND, 0);
|
||||
calendar.set(Calendar.MINUTE, 0);
|
||||
calendar.set(Calendar.HOUR_OF_DAY, 0);
|
||||
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd/");
|
||||
calendar.add(Calendar.DAY_OF_MONTH, -1);
|
||||
String prefix = dateFormat.format(calendar.getTime());
|
||||
return removeFilesByPrefix(prefix);
|
||||
}
|
||||
}
|
@ -0,0 +1,26 @@
|
||||
package com.ycwl.basic.device.operator.impl;
|
||||
|
||||
import com.ycwl.basic.device.entity.common.FileObject;
|
||||
import com.ycwl.basic.device.entity.local.DeviceLocalConfig;
|
||||
import com.ycwl.basic.device.operator.IDeviceStorageOperator;
|
||||
import com.ycwl.basic.device.operator.helper.CommonPieceGetter;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
public class LocalStorageOperator extends CommonPieceGetter<DeviceLocalConfig> implements IDeviceStorageOperator {
|
||||
public LocalStorageOperator(String configJson) {
|
||||
super(configJson);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<FileObject> getFileListByDtRange(Date startDate, Date endDate) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removeFilesBeforeDate(Date date) {
|
||||
return false;
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user