This commit is contained in:
2025-01-13 10:26:18 +08:00
parent 9c1d979bd8
commit 02548a3028
33 changed files with 399 additions and 222 deletions

View File

@ -42,12 +42,8 @@ public class DynamicTaskGenerator {
@Autowired
private TaskFaceService faceService;
@Autowired
private FaceSampleMapper faceSampleMapper;
@Autowired
private TaskService taskService;
@Autowired
private DeviceMapper deviceMapper;
@Autowired
private TemplateBiz templateBiz;
@Scheduled(cron = "0 0 * * * ?")

View File

@ -4,7 +4,8 @@ import com.ycwl.basic.biz.OrderBiz;
import com.ycwl.basic.device.DeviceFactory;
import com.ycwl.basic.device.entity.common.FileObject;
import com.ycwl.basic.device.operator.IDeviceStorageOperator;
import com.ycwl.basic.device.repository.DeviceRepository;
import com.ycwl.basic.model.pc.faceSample.entity.FaceSampleEntity;
import com.ycwl.basic.repository.DeviceRepository;
import com.ycwl.basic.mapper.DeviceMapper;
import com.ycwl.basic.mapper.FaceSampleMapper;
import com.ycwl.basic.mapper.SourceMapper;
@ -14,6 +15,7 @@ import com.ycwl.basic.model.pc.device.entity.DeviceEntity;
import com.ycwl.basic.model.pc.faceSample.resp.FaceSampleRespVO;
import com.ycwl.basic.model.pc.source.entity.MemberSourceEntity;
import com.ycwl.basic.model.pc.source.entity.SourceEntity;
import com.ycwl.basic.repository.TemplateRepository;
import com.ycwl.basic.storage.StorageFactory;
import com.ycwl.basic.storage.adapters.IStorageAdapter;
import com.ycwl.basic.utils.SnowFlakeUtil;
@ -31,10 +33,13 @@ import java.io.InputStream;
import java.io.InputStreamReader;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
@ -45,21 +50,21 @@ public class VideoPieceGetter {
@Autowired
private FaceSampleMapper faceSampleMapper;
@Autowired
private DeviceMapper deviceMapper;
@Autowired
private DeviceRepository deviceRepository;
@Autowired
private SourceMapper sourceMapper;
@Autowired
private OrderBiz orderBiz;
@Autowired
private TemplateRepository templateRepository;
@Data
public static class Task {
public String type = "normal";
public List<Long> faceSampleIds;
public Callback callback;
public Long memberId;
public Long faceId;
public Long templateId;
public static interface Callback {
void onInvoke();
@ -86,112 +91,149 @@ public class VideoPieceGetter {
return;
}
log.info("poll task: {}", task);
if (task.getType().equalsIgnoreCase("normal")) {
task.getFaceSampleIds().parallelStream().forEach(faceSampleId -> {
FaceSampleRespVO faceSample = faceSampleMapper.getById(faceSampleId);
DeviceEntity device = deviceRepository.getDevice(faceSample.getDeviceId());
DeviceConfigEntity config = deviceRepository.getDeviceConfig(faceSample.getDeviceId());
SourceEntity source = sourceMapper.querySameVideo(faceSample.getId(), device.getId());
IsBuyRespVO isBuy = orderBiz.isBuy(task.getMemberId(), faceSample.getScenicId(), 1, faceSample.getId());
if (source != null) {
// 有原视频
int count = sourceMapper.hasRelationTo(task.getMemberId(), source.getId(), 1);
if (count > 0) {
return;
}
MemberSourceEntity videoSource = new MemberSourceEntity();
videoSource.setId(SnowFlakeUtil.getLongId());
videoSource.setScenicId(faceSample.getScenicId());
videoSource.setFaceId(task.getFaceId());
videoSource.setMemberId(task.getMemberId());
videoSource.setType(1);
if (isBuy.isBuy()) { // 如果用户买过
videoSource.setIsBuy(1);
} else if (isBuy.isFree()) { // 全免费逻辑
videoSource.setIsBuy(1);
} else {
videoSource.setIsBuy(0);
}
videoSource.setSourceId(source.getId());
sourceMapper.addRelation(videoSource);
return;
}
BigDecimal cutPre = BigDecimal.valueOf(5L);
BigDecimal cutPost = BigDecimal.valueOf(4L);
if (config == null) {
return;
}
// 有配置
if (config.getCutPre() != null) {
cutPre = config.getCutPre();
}
if (config.getCutPost() != null) {
cutPost = config.getCutPost();
}
IDeviceStorageOperator pieceGetter = DeviceFactory.getDeviceStorageOperator(device, config);
if (pieceGetter == null) {
return;
}
BigDecimal duration = cutPre.add(cutPost);
List<FileObject> listByDtRange = pieceGetter.getFileListByDtRange(
new Date(faceSample.getCreateAt().getTime() - cutPre.multiply(BigDecimal.valueOf(1000)).longValue()),
new Date(faceSample.getCreateAt().getTime() + cutPost.multiply(BigDecimal.valueOf(1000)).longValue())
);
if (listByDtRange.isEmpty()) {
log.warn("没有可用的文件");
return;
}
log.info("查询到可用的文件: {}", listByDtRange);
long offset = faceSample.getCreateAt().getTime() - cutPre.multiply(BigDecimal.valueOf(1000)).longValue() - listByDtRange.get(0).getCreateTime().getTime();
FfmpegTask ffmpegTask = new FfmpegTask();
ffmpegTask.setFileList(listByDtRange);
ffmpegTask.setDuration(duration);
ffmpegTask.setOffsetStart(BigDecimal.valueOf(offset, 3));
File outFile = new File(faceSample.getDeviceId().toString() + "_" + faceSample.getId() + ".mp4");
ffmpegTask.setOutputFile(outFile.getAbsolutePath());
boolean result = startFfmpegTask(ffmpegTask);
if (!result) {
log.warn("视频裁切失败");
return;
}
log.info("视频裁切成功");
IStorageAdapter adapter = StorageFactory.use("assets");
String url = adapter.uploadFile(outFile, "video-source", outFile.getName());
// 上传成功后删除文件
outFile.delete();
SourceEntity imgSource = sourceMapper.findBySampleId(faceSample.getId());
SourceEntity sourceEntity = new SourceEntity();
sourceEntity.setId(SnowFlakeUtil.getLongId());
sourceEntity.setCreateTime(faceSample.getCreateAt());
MemberSourceEntity videoSource = new MemberSourceEntity();
videoSource.setMemberId(task.getMemberId());
videoSource.setType(1);
videoSource.setFaceId(task.getFaceId());
videoSource.setScenicId(faceSample.getScenicId());
videoSource.setSourceId(sourceEntity.getId());
if (imgSource != null) {
sourceEntity.setUrl(imgSource.getUrl());
sourceEntity.setPosJson(imgSource.getPosJson());
}
sourceEntity.setVideoUrl(url);
sourceEntity.setFaceSampleId(faceSample.getId());
sourceEntity.setScenicId(faceSample.getScenicId());
sourceEntity.setDeviceId(faceSample.getDeviceId());
sourceEntity.setType(1);
if (isBuy.isBuy()) { // 如果用户买过
videoSource.setIsBuy(1);
} else if (isBuy.isFree()) { // 全免费逻辑
videoSource.setIsBuy(1);
} else {
videoSource.setIsBuy(0);
}
sourceMapper.add(sourceEntity);
sourceMapper.addRelation(videoSource);
});
List<String> templatePlaceholder;
if (null != task.getTemplateId()) {
templatePlaceholder = templateRepository.getTemplatePlaceholder(task.getTemplateId());
} else {
templatePlaceholder = null;
}
AtomicBoolean invoke = new AtomicBoolean(false);
List<String> currentPlaceholder = new ArrayList<>();
List<FaceSampleEntity> list = faceSampleMapper.listByIds(task.getFaceSampleIds());
Collection<List<FaceSampleEntity>> collection = list.stream()
.filter(faceSample -> {
if (templatePlaceholder != null) {
return templatePlaceholder.contains(faceSample.getDeviceId().toString());
}
return true;
})
.collect(Collectors.groupingBy(FaceSampleEntity::getDeviceId))
.values();
collection
.stream()
.parallel()
.forEach(faceSampleList -> {
faceSampleList.forEach(faceSample -> {
DeviceEntity device = deviceRepository.getDevice(faceSample.getDeviceId());
DeviceConfigEntity config = deviceRepository.getDeviceConfig(faceSample.getDeviceId());
SourceEntity source = sourceMapper.querySameVideo(faceSample.getId(), device.getId());
IsBuyRespVO isBuy = orderBiz.isBuy(task.getMemberId(), faceSample.getScenicId(), 1, faceSample.getId());
if (source == null) {
BigDecimal cutPre = BigDecimal.valueOf(5L);
BigDecimal cutPost = BigDecimal.valueOf(4L);
if (config == null) {
return;
}
// 有配置
if (config.getCutPre() != null) {
cutPre = config.getCutPre();
}
if (config.getCutPost() != null) {
cutPost = config.getCutPost();
}
IDeviceStorageOperator pieceGetter = DeviceFactory.getDeviceStorageOperator(device, config);
if (pieceGetter == null) {
return;
}
BigDecimal duration = cutPre.add(cutPost);
List<FileObject> listByDtRange = pieceGetter.getFileListByDtRange(
new Date(faceSample.getCreateAt().getTime() - cutPre.multiply(BigDecimal.valueOf(1000)).longValue()),
new Date(faceSample.getCreateAt().getTime() + cutPost.multiply(BigDecimal.valueOf(1000)).longValue())
);
if (listByDtRange.isEmpty()) {
log.warn("没有可用的文件");
return;
}
log.info("查询到可用的文件: {}", listByDtRange);
long offset = faceSample.getCreateAt().getTime() - cutPre.multiply(BigDecimal.valueOf(1000)).longValue() - listByDtRange.get(0).getCreateTime().getTime();
FfmpegTask ffmpegTask = new FfmpegTask();
ffmpegTask.setFileList(listByDtRange);
ffmpegTask.setDuration(duration);
ffmpegTask.setOffsetStart(BigDecimal.valueOf(offset, 3));
File outFile = new File(faceSample.getDeviceId().toString() + "_" + faceSample.getId() + ".mp4");
ffmpegTask.setOutputFile(outFile.getAbsolutePath());
boolean result = startFfmpegTask(ffmpegTask);
if (!result) {
log.warn("视频裁切失败");
return;
}
log.info("视频裁切成功");
IStorageAdapter adapter = StorageFactory.use("assets");
String url = adapter.uploadFile(outFile, "video-source", outFile.getName());
// 上传成功后删除文件
outFile.delete();
SourceEntity imgSource = sourceMapper.findBySampleId(faceSample.getId());
SourceEntity sourceEntity = new SourceEntity();
sourceEntity.setId(SnowFlakeUtil.getLongId());
sourceEntity.setCreateTime(faceSample.getCreateAt());
MemberSourceEntity videoSource = new MemberSourceEntity();
videoSource.setMemberId(task.getMemberId());
videoSource.setType(1);
videoSource.setFaceId(task.getFaceId());
videoSource.setScenicId(faceSample.getScenicId());
videoSource.setSourceId(sourceEntity.getId());
if (imgSource != null) {
sourceEntity.setUrl(imgSource.getUrl());
sourceEntity.setPosJson(imgSource.getPosJson());
}
sourceEntity.setVideoUrl(url);
sourceEntity.setFaceSampleId(faceSample.getId());
sourceEntity.setScenicId(faceSample.getScenicId());
sourceEntity.setDeviceId(faceSample.getDeviceId());
sourceEntity.setType(1);
if (isBuy.isBuy()) { // 如果用户买过
videoSource.setIsBuy(1);
} else if (isBuy.isFree()) { // 全免费逻辑
videoSource.setIsBuy(1);
} else {
videoSource.setIsBuy(0);
}
sourceMapper.add(sourceEntity);
sourceMapper.addRelation(videoSource);
} else {
// 有原视频
int count = sourceMapper.hasRelationTo(task.getMemberId(), source.getId(), 1);
if (count <= 0) {
// 没有关联
MemberSourceEntity videoSource = new MemberSourceEntity();
videoSource.setId(SnowFlakeUtil.getLongId());
videoSource.setScenicId(faceSample.getScenicId());
videoSource.setFaceId(task.getFaceId());
videoSource.setMemberId(task.getMemberId());
videoSource.setType(1);
if (isBuy.isBuy()) { // 如果用户买过
videoSource.setIsBuy(1);
} else if (isBuy.isFree()) { // 全免费逻辑
videoSource.setIsBuy(1);
} else {
videoSource.setIsBuy(0);
}
videoSource.setSourceId(source.getId());
sourceMapper.addRelation(videoSource);
}
}
if (templatePlaceholder != null) {
if (templatePlaceholder.contains(faceSample.getDeviceId().toString())) {
if (!currentPlaceholder.contains(faceSample.getDeviceId().toString())) {
currentPlaceholder.add(faceSample.getDeviceId().toString());
}
}
log.info("当前进度:{}/{}", currentPlaceholder.size(), collection.size());
if (currentPlaceholder.size() >= collection.size()) {
if (!invoke.get()) {
invoke.set(true);
task.getCallback().onInvoke();
}
}
}
});
});
if (null != task.getCallback()) {
task.getCallback().onInvoke();
if (!invoke.get()) {
invoke.set(true);
task.getCallback().onInvoke();
}
}
}