设备关联逻辑
This commit is contained in:
parent
fb530a1eb4
commit
bcf8e8e88d
@ -60,4 +60,5 @@ public class DeviceConfigEntity {
|
||||
private Integer enablePreBook;
|
||||
private Integer imageFree;
|
||||
private Integer videoFree;
|
||||
private Long pairDevice;
|
||||
}
|
||||
|
@ -6,6 +6,7 @@ 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.model.pc.faceSample.entity.FaceSampleEntity;
|
||||
import com.ycwl.basic.model.pc.faceSample.resp.FaceSampleRespVO;
|
||||
import com.ycwl.basic.repository.DeviceRepository;
|
||||
import com.ycwl.basic.mapper.FaceSampleMapper;
|
||||
import com.ycwl.basic.mapper.SourceMapper;
|
||||
@ -20,6 +21,7 @@ import com.ycwl.basic.storage.adapters.IStorageAdapter;
|
||||
import com.ycwl.basic.utils.SnowFlakeUtil;
|
||||
import lombok.Data;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.scheduling.annotation.EnableScheduling;
|
||||
import org.springframework.scheduling.annotation.Scheduled;
|
||||
@ -35,7 +37,9 @@ import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ArrayBlockingQueue;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||
import java.util.concurrent.ThreadPoolExecutor;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
@ -117,6 +121,18 @@ public class VideoPieceGetter {
|
||||
final ThreadPoolExecutor executor = new ThreadPoolExecutor(16, 512, 0L, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<>(512));
|
||||
List<String> currentPlaceholder = new ArrayList<>();
|
||||
List<FaceSampleEntity> list = faceSampleMapper.listByIds(task.getFaceSampleIds());
|
||||
Map<Long, Long> pairDeviceMap = new ConcurrentHashMap<>();
|
||||
if (!list.isEmpty()) {
|
||||
Long scenicId = list.get(0).getScenicId();
|
||||
List<DeviceEntity> allDeviceByScenicId = deviceRepository.getAllDeviceByScenicId(scenicId);
|
||||
allDeviceByScenicId.forEach(device -> {
|
||||
Long deviceId = device.getId();
|
||||
DeviceConfigEntity deviceConfig = deviceRepository.getDeviceConfig(deviceId);
|
||||
if (deviceConfig != null && deviceConfig.getPairDevice() != null) {
|
||||
pairDeviceMap.putIfAbsent(deviceId, deviceConfig.getPairDevice());
|
||||
}
|
||||
});
|
||||
}
|
||||
Collection<List<FaceSampleEntity>> collection = list.stream()
|
||||
.filter(faceSample -> {
|
||||
if (templatePlaceholder != null) {
|
||||
@ -136,123 +152,45 @@ public class VideoPieceGetter {
|
||||
} catch (InterruptedException ignore) {
|
||||
}
|
||||
}
|
||||
if (pairDeviceMap.containsValue(faceSample.getDeviceId())) {
|
||||
// 有关联设备!
|
||||
// 找到对应的deviceId
|
||||
pairDeviceMap.entrySet().stream()
|
||||
.filter(entry -> entry.getValue().equals(faceSample.getDeviceId()))
|
||||
.map(Map.Entry::getKey).forEach(pairDeviceId -> {
|
||||
log.info("找到同景区关联设备:{} -> {}", pairDeviceId, faceSample.getDeviceId());
|
||||
if (pairDeviceId != null) {
|
||||
executor.execute(() -> {
|
||||
boolean result = doCut(pairDeviceId, faceSample.getId(), faceSample.getCreateAt(), task);
|
||||
if (templatePlaceholder != null) {
|
||||
if (templatePlaceholder.contains(faceSample.getDeviceId().toString())) {
|
||||
if (!currentPlaceholder.contains(faceSample.getDeviceId().toString())) {
|
||||
if (result) {
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
isFirst.set(false);
|
||||
executor.execute(() -> {
|
||||
DeviceEntity device = deviceRepository.getDevice(faceSample.getDeviceId());
|
||||
DeviceConfigEntity config = deviceRepository.getDeviceConfig(faceSample.getDeviceId());
|
||||
|
||||
SourceEntity source = sourceMapper.querySameVideo(faceSample.getId(), device.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);
|
||||
// 如果完全一致,就不需要裁切
|
||||
String url;
|
||||
if (listByDtRange.size() == 1 && listByDtRange.get(0).isExact()) {
|
||||
url = listByDtRange.get(0).getUrl();
|
||||
} else {
|
||||
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");
|
||||
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());
|
||||
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 (task.memberId != null && task.faceId != null) {
|
||||
MemberSourceEntity videoSource = new MemberSourceEntity();
|
||||
videoSource.setMemberId(task.getMemberId());
|
||||
videoSource.setType(1);
|
||||
videoSource.setFaceId(task.getFaceId());
|
||||
videoSource.setScenicId(faceSample.getScenicId());
|
||||
videoSource.setSourceId(sourceEntity.getId());
|
||||
IsBuyRespVO isBuy = orderBiz.isBuy(task.getMemberId(), faceSample.getScenicId(), 1, task.getFaceId());
|
||||
if (isBuy.isBuy()) { // 如果用户买过
|
||||
videoSource.setIsBuy(1);
|
||||
} else if (isBuy.isFree()) { // 全免费逻辑
|
||||
videoSource.setIsBuy(1);
|
||||
} else {
|
||||
videoSource.setIsBuy(0);
|
||||
}
|
||||
sourceMapper.addRelation(videoSource);
|
||||
}
|
||||
sourceMapper.add(sourceEntity);
|
||||
} else {
|
||||
// 有原视频
|
||||
if (task.memberId != null && task.faceId != null) {
|
||||
int count = sourceMapper.hasRelationTo(task.getMemberId(), source.getId(), 1);
|
||||
if (count <= 0) {
|
||||
// 没有关联
|
||||
IsBuyRespVO isBuy = orderBiz.isBuy(task.getMemberId(), faceSample.getScenicId(), 1, task.getFaceId());
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
boolean result = doCut(faceSample.getDeviceId(), faceSample.getId(), faceSample.getCreateAt(), task);
|
||||
if (templatePlaceholder != null) {
|
||||
if (templatePlaceholder.contains(faceSample.getDeviceId().toString())) {
|
||||
if (!currentPlaceholder.contains(faceSample.getDeviceId().toString())) {
|
||||
currentPlaceholder.add(faceSample.getDeviceId().toString());
|
||||
if (result) {
|
||||
currentPlaceholder.add(faceSample.getDeviceId().toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
log.info("当前进度:{}/{}", currentPlaceholder.size(), collection.size());
|
||||
@ -288,6 +226,120 @@ public class VideoPieceGetter {
|
||||
}
|
||||
}
|
||||
|
||||
private boolean doCut(Long deviceId, Long faceSampleId, Date baseTime, Task task) {
|
||||
DeviceEntity device = deviceRepository.getDevice(deviceId);
|
||||
DeviceConfigEntity config = deviceRepository.getDeviceConfig(deviceId);
|
||||
|
||||
SourceEntity source = sourceMapper.querySameVideo(faceSampleId, device.getId());
|
||||
|
||||
if (source == null) {
|
||||
BigDecimal cutPre = BigDecimal.valueOf(5L);
|
||||
BigDecimal cutPost = BigDecimal.valueOf(4L);
|
||||
if (config != null) {
|
||||
// 有配置
|
||||
if (config.getCutPre() != null) {
|
||||
cutPre = config.getCutPre();
|
||||
}
|
||||
if (config.getCutPost() != null) {
|
||||
cutPost = config.getCutPost();
|
||||
}
|
||||
}
|
||||
IDeviceStorageOperator pieceGetter = DeviceFactory.getDeviceStorageOperator(device, config);
|
||||
if (pieceGetter == null) {
|
||||
return false;
|
||||
}
|
||||
BigDecimal duration = cutPre.add(cutPost);
|
||||
List<FileObject> listByDtRange = pieceGetter.getFileListByDtRange(
|
||||
new Date(baseTime.getTime() - cutPre.multiply(BigDecimal.valueOf(1000)).longValue()),
|
||||
new Date(baseTime.getTime() + cutPost.multiply(BigDecimal.valueOf(1000)).longValue())
|
||||
);
|
||||
if (listByDtRange.isEmpty()) {
|
||||
log.warn("没有可用的文件");
|
||||
return false;
|
||||
}
|
||||
log.info("查询到可用的文件: {}", listByDtRange);
|
||||
// 如果完全一致,就不需要裁切
|
||||
String url;
|
||||
if (listByDtRange.size() == 1 && listByDtRange.get(0).isExact()) {
|
||||
url = listByDtRange.get(0).getUrl();
|
||||
} else {
|
||||
long offset = baseTime.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(deviceId.toString() + "_" + faceSampleId + ".mp4");
|
||||
ffmpegTask.setOutputFile(outFile.getAbsolutePath());
|
||||
boolean result = startFfmpegTask(ffmpegTask);
|
||||
if (!result) {
|
||||
log.warn("视频裁切失败");
|
||||
return false;
|
||||
}
|
||||
log.info("视频裁切成功");
|
||||
IStorageAdapter adapter = StorageFactory.use("assets");
|
||||
url = adapter.uploadFile(outFile, "video-source", outFile.getName());
|
||||
// 上传成功后删除文件
|
||||
outFile.delete();
|
||||
}
|
||||
SourceEntity imgSource = sourceMapper.findBySampleId(faceSampleId);
|
||||
SourceEntity sourceEntity = new SourceEntity();
|
||||
sourceEntity.setId(SnowFlakeUtil.getLongId());
|
||||
sourceEntity.setCreateTime(baseTime);
|
||||
if (imgSource != null) {
|
||||
sourceEntity.setUrl(imgSource.getUrl());
|
||||
sourceEntity.setPosJson(imgSource.getPosJson());
|
||||
}
|
||||
sourceEntity.setVideoUrl(url);
|
||||
sourceEntity.setFaceSampleId(faceSampleId);
|
||||
sourceEntity.setScenicId(device.getScenicId());
|
||||
sourceEntity.setDeviceId(deviceId);
|
||||
sourceEntity.setType(1);
|
||||
if (task.memberId != null && task.faceId != null) {
|
||||
MemberSourceEntity videoSource = new MemberSourceEntity();
|
||||
videoSource.setMemberId(task.getMemberId());
|
||||
videoSource.setType(1);
|
||||
videoSource.setFaceId(task.getFaceId());
|
||||
videoSource.setScenicId(device.getScenicId());
|
||||
videoSource.setSourceId(sourceEntity.getId());
|
||||
IsBuyRespVO isBuy = orderBiz.isBuy(task.getMemberId(), device.getScenicId(), 1, task.getFaceId());
|
||||
if (isBuy.isBuy()) { // 如果用户买过
|
||||
videoSource.setIsBuy(1);
|
||||
} else if (isBuy.isFree()) { // 全免费逻辑
|
||||
videoSource.setIsBuy(1);
|
||||
} else {
|
||||
videoSource.setIsBuy(0);
|
||||
}
|
||||
sourceMapper.addRelation(videoSource);
|
||||
}
|
||||
sourceMapper.add(sourceEntity);
|
||||
} else {
|
||||
// 有原视频
|
||||
if (task.memberId != null && task.faceId != null) {
|
||||
int count = sourceMapper.hasRelationTo(task.getMemberId(), source.getId(), 1);
|
||||
if (count <= 0) {
|
||||
// 没有关联
|
||||
IsBuyRespVO isBuy = orderBiz.isBuy(task.getMemberId(), device.getScenicId(), 1, task.getFaceId());
|
||||
MemberSourceEntity videoSource = new MemberSourceEntity();
|
||||
videoSource.setId(SnowFlakeUtil.getLongId());
|
||||
videoSource.setScenicId(device.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 true;
|
||||
}
|
||||
|
||||
public boolean startFfmpegTask(FfmpegTask task) {
|
||||
boolean result;
|
||||
if (task.getFileList().size() == 1) {
|
||||
|
@ -39,7 +39,8 @@
|
||||
cut_post = #{cutPost},
|
||||
enable_pre_book = #{enablePreBook},
|
||||
image_free = #{imageFree},
|
||||
video_free = #{videoFree}
|
||||
video_free = #{videoFree},
|
||||
pair_device = #{pairDevice}
|
||||
where id = #{id}
|
||||
</update>
|
||||
<update id="updateEntity">
|
||||
|
Loading…
x
Reference in New Issue
Block a user