获取人脸对应视频流程,自动删除源视频流程,自动创建任务渲染流程,自动删除人脸数据逻辑

This commit is contained in:
2024-12-11 15:38:18 +08:00
parent ba4c339660
commit 8c81a994c8
47 changed files with 1318 additions and 222 deletions

View 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;
}
}

View 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);
}

View File

@ -0,0 +1,7 @@
package com.ycwl.basic.device.checker;
import com.ycwl.basic.device.IDeviceCommon;
public interface IDeviceStatusChecker extends IDeviceCommon {
boolean checkDeviceStatus();
}

View File

@ -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];
}
}

View File

@ -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;
}
}
}

View File

@ -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;
}
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -0,0 +1,7 @@
package com.ycwl.basic.device.entity.local;
import lombok.Data;
@Data
public class DeviceLocalConfig {
}

View File

@ -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;
}
}

View File

@ -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);
}

View File

@ -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];
}
}

View File

@ -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);
}
}

View File

@ -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;
}
}