From ade7193e641c8075911be779999136a4dbb68247 Mon Sep 17 00:00:00 2001 From: Jerry Yan <792602257@qq.com> Date: Thu, 2 Jan 2025 17:32:46 +0800 Subject: [PATCH] =?UTF-8?q?=E5=8A=A0=E7=82=B9=E7=BC=93=E5=AD=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../basic/face/repository/FaceRepository.java | 7 + .../basic/model/mobile/goods/GoodsPageVO.java | 1 + .../model/pc/source/resp/SourceRespVO.java | 1 + .../model/pc/video/resp/VideoRespVO.java | 1 + .../service/impl/mobile/GoodsServiceImpl.java | 41 +++-- .../com/ycwl/basic/task/VideoPieceGetter.java | 172 +++++++++--------- src/main/resources/application-dev.yml | 2 - src/main/resources/mapper/SourceMapper.xml | 2 +- src/main/resources/mapper/VideoMapper.xml | 2 +- 9 files changed, 125 insertions(+), 104 deletions(-) create mode 100644 src/main/java/com/ycwl/basic/face/repository/FaceRepository.java diff --git a/src/main/java/com/ycwl/basic/face/repository/FaceRepository.java b/src/main/java/com/ycwl/basic/face/repository/FaceRepository.java new file mode 100644 index 0000000..a4bda70 --- /dev/null +++ b/src/main/java/com/ycwl/basic/face/repository/FaceRepository.java @@ -0,0 +1,7 @@ +package com.ycwl.basic.face.repository; + +import org.springframework.stereotype.Component; + +@Component +public class FaceRepository { +} diff --git a/src/main/java/com/ycwl/basic/model/mobile/goods/GoodsPageVO.java b/src/main/java/com/ycwl/basic/model/mobile/goods/GoodsPageVO.java index d770661..336772d 100644 --- a/src/main/java/com/ycwl/basic/model/mobile/goods/GoodsPageVO.java +++ b/src/main/java/com/ycwl/basic/model/mobile/goods/GoodsPageVO.java @@ -17,6 +17,7 @@ public class GoodsPageVO { private String goodsName; @ApiModelProperty("景区id") private Long scenicId; + private Long faceId; @ApiModelProperty("景区名称") private String scenicName; @ApiModelProperty("商品类型 1:成片视频 2:源素材") diff --git a/src/main/java/com/ycwl/basic/model/pc/source/resp/SourceRespVO.java b/src/main/java/com/ycwl/basic/model/pc/source/resp/SourceRespVO.java index d332207..3ce66c6 100644 --- a/src/main/java/com/ycwl/basic/model/pc/source/resp/SourceRespVO.java +++ b/src/main/java/com/ycwl/basic/model/pc/source/resp/SourceRespVO.java @@ -35,6 +35,7 @@ public class SourceRespVO { */ @ApiModelProperty("来源设备id") private Long deviceId; + private Long faceId; @ApiModelProperty("原素材类型:1视频,2图像") private Integer type; /** diff --git a/src/main/java/com/ycwl/basic/model/pc/video/resp/VideoRespVO.java b/src/main/java/com/ycwl/basic/model/pc/video/resp/VideoRespVO.java index c267189..f293ebe 100644 --- a/src/main/java/com/ycwl/basic/model/pc/video/resp/VideoRespVO.java +++ b/src/main/java/com/ycwl/basic/model/pc/video/resp/VideoRespVO.java @@ -29,6 +29,7 @@ public class VideoRespVO { */ @ApiModelProperty("用户id") private Long memberId; + private Long faceId; /** * 模版id */ diff --git a/src/main/java/com/ycwl/basic/service/impl/mobile/GoodsServiceImpl.java b/src/main/java/com/ycwl/basic/service/impl/mobile/GoodsServiceImpl.java index af01f36..682a4ab 100644 --- a/src/main/java/com/ycwl/basic/service/impl/mobile/GoodsServiceImpl.java +++ b/src/main/java/com/ycwl/basic/service/impl/mobile/GoodsServiceImpl.java @@ -68,6 +68,7 @@ public class GoodsServiceImpl implements GoodsService { goodsPageVO.setScenicId(videoRespVO.getScenicId()); goodsPageVO.setScenicName(videoRespVO.getScenicName()); goodsPageVO.setGoodsType(0); + goodsPageVO.setFaceId(videoRespVO.getFaceId()); goodsPageVO.setGoodsId(videoRespVO.getId()); goodsPageVO.setTemplateName(videoRespVO.getTemplateName()); goodsPageVO.setTemplateCoverUrl(videoRespVO.getTemplateCoverUrl()); @@ -81,20 +82,32 @@ public class GoodsServiceImpl implements GoodsService { sourceReqQuery.setMemberId(Long.valueOf(BaseContextHandler.getUserId())); //查询源素材 List sourceList = sourceMapper.queryByRelation(sourceReqQuery); - sourceList.stream().collect(Collectors.groupingBy(SourceRespVO::getType)).forEach((type, value) -> { - GoodsPageVO goodsPageVO = new GoodsPageVO(); - if (type == 1) { - goodsPageVO.setGoodsName("原片集"); - goodsPageVO.setGoodsType(1); - } else { - goodsPageVO.setGoodsName("照片集"); - goodsPageVO.setGoodsType(2); - } - goodsPageVO.setScenicId(query.getScenicId()); - goodsList.add(goodsPageVO); - }); - - return ApiResponse.success(goodsList); + List sourceGoods = sourceList.stream().collect(Collectors.groupingBy(SourceRespVO::getFaceId)).entrySet().stream().flatMap((faceEntry) -> { + Long faceId = faceEntry.getKey(); + List goods = faceEntry.getValue(); + return goods.stream().collect(Collectors.groupingBy(SourceRespVO::getType)).entrySet().stream().map((typeEntry) -> { + Integer type = typeEntry.getKey(); + GoodsPageVO goodsPageVO = new GoodsPageVO(); + goodsPageVO.setFaceId(faceId); + if (type == 1) { + goodsPageVO.setGoodsName("原片集"); + goodsPageVO.setGoodsType(1); + } else { + goodsPageVO.setGoodsName("照片集"); + goodsPageVO.setGoodsType(2); + } + goodsPageVO.setScenicId(query.getScenicId()); + return goodsPageVO; + }); + }).collect(Collectors.toList()); + if (!sourceGoods.isEmpty()) { + if (goodsList.size() > 2) { + goodsList.addAll(2, sourceGoods); + } else { + goodsList.addAll(sourceGoods); + } + } + return ApiResponse.success(goodsList); } @Override diff --git a/src/main/java/com/ycwl/basic/task/VideoPieceGetter.java b/src/main/java/com/ycwl/basic/task/VideoPieceGetter.java index 7fbee5b..91551b0 100644 --- a/src/main/java/com/ycwl/basic/task/VideoPieceGetter.java +++ b/src/main/java/com/ycwl/basic/task/VideoPieceGetter.java @@ -78,106 +78,106 @@ public class VideoPieceGetter { queue.add(task); } - @Scheduled(fixedDelay = 1000L) + @Scheduled(fixedRate = 2000L) public void doTask() { Task task = queue.poll(); if (task == null) { return; } log.info("poll task: {}", task); - if (!task.getType().equalsIgnoreCase("normal")) { - task.getCallback().onInvoke(); - return; - } - task.getFaceSampleId().parallelStream().forEach(faceSampleId -> { - FaceSampleRespVO faceSample = faceSampleMapper.getById(faceSampleId); - DeviceEntity device = deviceRepository.getDevice(faceSample.getDeviceId()); - DeviceConfigEntity config = deviceRepository.getDeviceConfig(faceSample.getDeviceId()); + if (task.getType().equalsIgnoreCase("normal")) { + task.getFaceSampleId().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()); - if (source != null) { - // 有原视频 - int count = sourceMapper.hasRelationTo(task.getMemberId(), source.getId(), 1); - if (count > 0) { + SourceEntity source = sourceMapper.querySameVideo(faceSample.getId(), device.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); + 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 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; + } + 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.setId(SnowFlakeUtil.getLongId()); - videoSource.setScenicId(faceSample.getScenicId()); - videoSource.setFaceId(task.getFaceId()); videoSource.setMemberId(task.getMemberId()); videoSource.setType(1); videoSource.setIsBuy(0); - videoSource.setSourceId(source.getId()); + 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); + sourceMapper.add(sourceEntity); 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 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; - } - 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.setIsBuy(0); - 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); - sourceMapper.add(sourceEntity); - sourceMapper.addRelation(videoSource); - }); - + }); + } + if (null != task.getCallback()) { + task.getCallback().onInvoke(); + } } public boolean startFfmpegTask(FfmpegTask task) { diff --git a/src/main/resources/application-dev.yml b/src/main/resources/application-dev.yml index 55f439d..74140e1 100644 --- a/src/main/resources/application-dev.yml +++ b/src/main/resources/application-dev.yml @@ -55,8 +55,6 @@ mybatis-plus: # 开启驼峰命名法 map-underscore-to-camel-case: true use-generated-keys: true - # 这个配置会将执行的sql打印出来,在开发或测试的时候可以用 - log-impl: org.apache.ibatis.logging.stdout.StdOutImpl # 指定使用的日志配置文件 logging: config: classpath:logback-spring.xml diff --git a/src/main/resources/mapper/SourceMapper.xml b/src/main/resources/mapper/SourceMapper.xml index 6ab3cad..80b8b48 100644 --- a/src/main/resources/mapper/SourceMapper.xml +++ b/src/main/resources/mapper/SourceMapper.xml @@ -124,7 +124,7 @@ order by so.create_time desc