From b5b9064f30160a6c31d67184ed202d9862c54569 Mon Sep 17 00:00:00 2001 From: Jerry Yan <792602257@qq.com> Date: Fri, 11 Apr 2025 16:20:55 +0800 Subject: [PATCH] =?UTF-8?q?=E5=8C=BA=E5=88=86=E4=B8=B4=E6=97=B6=E5=92=8C?= =?UTF-8?q?=E6=9C=AC=E5=9C=B0=E5=AD=98=E5=82=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../basic/controller/vpt/VptController.java | 4 +- .../basic/controller/wvp/WvpController.java | 4 +- .../pc/scenic/entity/ScenicConfigEntity.java | 2 + .../ycwl/basic/service/pc/ScenicService.java | 2 + .../service/pc/impl/ScenicServiceImpl.java | 21 +++++ .../task/impl/TaskTaskServiceImpl.java | 8 +- .../com/ycwl/basic/utils/VideoReUploader.java | 78 ++++++++++++++++--- src/main/resources/mapper/ScenicMapper.xml | 2 + 8 files changed, 104 insertions(+), 17 deletions(-) diff --git a/src/main/java/com/ycwl/basic/controller/vpt/VptController.java b/src/main/java/com/ycwl/basic/controller/vpt/VptController.java index b41412e..120d1ad 100644 --- a/src/main/java/com/ycwl/basic/controller/vpt/VptController.java +++ b/src/main/java/com/ycwl/basic/controller/vpt/VptController.java @@ -40,7 +40,7 @@ public class VptController { } @PostMapping("/scenic/{scenicId}/{taskId}/uploadUrl") public String uploadUrl(@PathVariable("scenicId") Long scenicId, @PathVariable("taskId") Long taskId) { - IStorageAdapter adapter = scenicService.getScenicTmpStorageAdapter(scenicId); + IStorageAdapter adapter = scenicService.getScenicLocalStorageAdapter(scenicId); String filename = StorageUtil.joinPath(StorageConstant.VIDEO_PIECE_PATH, taskId.toString() + ".mp4"); String urlForUpload = adapter.getUrlForUpload(new Date(System.currentTimeMillis() + 1000 * 60 * 60), "video/mp4", filename); urlForUpload = urlForUpload.replace("-internal.aliyuncs.com", ".aliyuncs.com"); @@ -48,7 +48,7 @@ public class VptController { } @PostMapping("/scenic/{scenicId}/{taskId}/success") public ApiResponse success(@PathVariable("scenicId") Long scenicId, @PathVariable("taskId") Long taskId, @RequestBody FileObject fileObject) { - IStorageAdapter adapter = scenicService.getScenicTmpStorageAdapter(scenicId); + IStorageAdapter adapter = scenicService.getScenicLocalStorageAdapter(scenicId); String filename = StorageUtil.joinPath(StorageConstant.VIDEO_PIECE_PATH, taskId.toString() + ".mp4"); fileObject.setUrl(adapter.getUrl(filename)); adapter.setAcl(StorageAcl.PUBLIC_READ, filename); diff --git a/src/main/java/com/ycwl/basic/controller/wvp/WvpController.java b/src/main/java/com/ycwl/basic/controller/wvp/WvpController.java index c9a0562..31ca6fc 100644 --- a/src/main/java/com/ycwl/basic/controller/wvp/WvpController.java +++ b/src/main/java/com/ycwl/basic/controller/wvp/WvpController.java @@ -45,7 +45,7 @@ public class WvpController { @PostMapping("/scenic/{scenicId}/{taskId}/uploadUrl") public String uploadUrl(@PathVariable("scenicId") Long scenicId, @PathVariable("taskId") Long taskId) { - IStorageAdapter adapter = scenicService.getScenicTmpStorageAdapter(scenicId); + IStorageAdapter adapter = scenicService.getScenicLocalStorageAdapter(scenicId); String filename = StorageUtil.joinPath(StorageConstant.VIDEO_PIECE_PATH, taskId.toString() + ".mp4"); String urlForUpload = adapter.getUrlForUpload(new Date(System.currentTimeMillis() + 1000 * 60 * 60), "video/mp4", filename); urlForUpload = urlForUpload.replace("-internal.aliyuncs.com", ".aliyuncs.com"); @@ -53,7 +53,7 @@ public class WvpController { } @PostMapping("/scenic/{scenicId}/{taskId}/success") public ApiResponse success(@PathVariable("scenicId") Long scenicId, @PathVariable("taskId") Long taskId, @RequestBody FileObject fileObject) { - IStorageAdapter adapter = scenicService.getScenicTmpStorageAdapter(scenicId); + IStorageAdapter adapter = scenicService.getScenicLocalStorageAdapter(scenicId); String filename = StorageUtil.joinPath(StorageConstant.VIDEO_PIECE_PATH, taskId.toString() + ".mp4"); fileObject.setUrl(adapter.getUrl(filename)); adapter.setAcl(StorageAcl.PUBLIC_READ, filename); diff --git a/src/main/java/com/ycwl/basic/model/pc/scenic/entity/ScenicConfigEntity.java b/src/main/java/com/ycwl/basic/model/pc/scenic/entity/ScenicConfigEntity.java index 253056d..d97dee8 100644 --- a/src/main/java/com/ycwl/basic/model/pc/scenic/entity/ScenicConfigEntity.java +++ b/src/main/java/com/ycwl/basic/model/pc/scenic/entity/ScenicConfigEntity.java @@ -73,6 +73,8 @@ public class ScenicConfigEntity { private String storeConfigJson; private StorageType tmpStoreType; private String tmpStoreConfigJson; + private StorageType localStoreType; + private String localStoreConfigJson; private BigDecimal brokerDirectRate; private Integer faceDetectHelperThreshold; diff --git a/src/main/java/com/ycwl/basic/service/pc/ScenicService.java b/src/main/java/com/ycwl/basic/service/pc/ScenicService.java index 781fda8..d456315 100644 --- a/src/main/java/com/ycwl/basic/service/pc/ScenicService.java +++ b/src/main/java/com/ycwl/basic/service/pc/ScenicService.java @@ -38,5 +38,7 @@ public interface ScenicService { IStorageAdapter getScenicTmpStorageAdapter(Long scenicId); + IStorageAdapter getScenicLocalStorageAdapter(Long scenicId); + IFaceBodyAdapter getScenicFaceBodyAdapter(Long scenicId); } diff --git a/src/main/java/com/ycwl/basic/service/pc/impl/ScenicServiceImpl.java b/src/main/java/com/ycwl/basic/service/pc/impl/ScenicServiceImpl.java index a61aa0e..bc90eb6 100644 --- a/src/main/java/com/ycwl/basic/service/pc/impl/ScenicServiceImpl.java +++ b/src/main/java/com/ycwl/basic/service/pc/impl/ScenicServiceImpl.java @@ -199,6 +199,7 @@ public class ScenicServiceImpl implements ScenicService { scenicFaceBodyAdapterMap.remove(config.getScenicId()); scenicStorageAdapterMap.remove(config.getScenicId()); scenicTmpStorageAdapterMap.remove(config.getScenicId()); + scenicLocalStorageAdapterMap.remove(config.getScenicId()); } @@ -240,6 +241,26 @@ public class ScenicServiceImpl implements ScenicService { return adapter; }); } + private static final Map scenicLocalStorageAdapterMap = new ConcurrentHashMap<>(); + @Override + public IStorageAdapter getScenicLocalStorageAdapter(Long scenicId) { + return scenicLocalStorageAdapterMap.computeIfAbsent(scenicId, (key) -> { + IStorageAdapter adapter; + ScenicConfigEntity scenicConfig = scenicRepository.getScenicConfig(scenicId); + if (scenicConfig != null && scenicConfig.getLocalStoreType() != null) { + try { + adapter = StorageFactory.get(scenicConfig.getLocalStoreType()); + adapter.loadConfig(JSONObject.parseObject(scenicConfig.getLocalStoreConfigJson(), Map.class)); + } catch (StorageUnsupportedException ignored) { + return getScenicStorageAdapter(scenicId); + } + } else { + return getScenicStorageAdapter(scenicId); + } + return adapter; + }); + } + private static final Map scenicFaceBodyAdapterMap = new ConcurrentHashMap<>(); @Override public IFaceBodyAdapter getScenicFaceBodyAdapter(Long scenicId) { diff --git a/src/main/java/com/ycwl/basic/service/task/impl/TaskTaskServiceImpl.java b/src/main/java/com/ycwl/basic/service/task/impl/TaskTaskServiceImpl.java index f5ad39c..b6971dd 100644 --- a/src/main/java/com/ycwl/basic/service/task/impl/TaskTaskServiceImpl.java +++ b/src/main/java/com/ycwl/basic/service/task/impl/TaskTaskServiceImpl.java @@ -58,6 +58,7 @@ import com.ycwl.basic.storage.utils.StorageUtil; import com.ycwl.basic.task.VideoPieceGetter; import com.ycwl.basic.repository.TemplateRepository; import com.ycwl.basic.utils.SnowFlakeUtil; +import com.ycwl.basic.utils.VideoReUploader; import lombok.NonNull; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; @@ -124,6 +125,8 @@ public class TaskTaskServiceImpl implements TaskService { private TaskStatusBiz taskStatusBiz; @Autowired private DeviceRepository deviceRepository; + @Autowired + private VideoReUploader videoReUploader; private RenderWorkerEntity getWorker(@NonNull WorkerAuthReqVo req) { @@ -587,9 +590,10 @@ public class TaskTaskServiceImpl implements TaskService { videoMapper.add(video); } ScenicConfigEntity scenicConfig = scenicRepository.getScenicConfig(task.getScenicId()); - IStorageAdapter adapter = scenicService.getScenicStorageAdapter(task.getScenicId()); + IStorageAdapter adapter = scenicService.getScenicTmpStorageAdapter(task.getScenicId()); String filename = StorageUtil.joinPath(StorageConstant.VLOG_PATH, task.getId() + "_" + task.getScenicId() + ".mp4"); adapter.setAcl(StorageAcl.PUBLIC_READ, filename); + videoReUploader.addVideoTask(task.getVideoUrl(), video.getId()); int isBuy = 0; FaceEntity face = faceRepository.getFace(task.getFaceId()); if (face != null) { @@ -646,7 +650,7 @@ public class TaskTaskServiceImpl implements TaskService { if (task == null) { return null; } - IStorageAdapter adapter = scenicService.getScenicStorageAdapter(task.getScenicId()); + IStorageAdapter adapter = scenicService.getScenicTmpStorageAdapter(task.getScenicId()); String filename = StorageUtil.joinPath(StorageConstant.VLOG_PATH, task.getId() + "_" + task.getScenicId() + ".mp4"); if (StringUtils.isBlank(task.getVideoUrl())) { // 生成 diff --git a/src/main/java/com/ycwl/basic/utils/VideoReUploader.java b/src/main/java/com/ycwl/basic/utils/VideoReUploader.java index f29ea0d..2dbf6b9 100644 --- a/src/main/java/com/ycwl/basic/utils/VideoReUploader.java +++ b/src/main/java/com/ycwl/basic/utils/VideoReUploader.java @@ -4,9 +4,16 @@ import cn.hutool.core.thread.ThreadFactoryBuilder; import cn.hutool.http.HttpUtil; import com.ycwl.basic.constant.StorageConstant; import com.ycwl.basic.mapper.SourceMapper; +import com.ycwl.basic.mapper.VideoMapper; +import com.ycwl.basic.model.pc.scenic.entity.ScenicConfigEntity; import com.ycwl.basic.model.pc.source.entity.SourceEntity; +import com.ycwl.basic.model.pc.video.entity.VideoEntity; +import com.ycwl.basic.repository.ScenicRepository; +import com.ycwl.basic.repository.VideoRepository; +import com.ycwl.basic.repository.VideoTaskRepository; import com.ycwl.basic.service.pc.ScenicService; import com.ycwl.basic.storage.adapters.IStorageAdapter; +import com.ycwl.basic.storage.enums.StorageAcl; import com.ycwl.basic.storage.utils.StorageUtil; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; @@ -43,16 +50,14 @@ public class VideoReUploader { private SourceMapper sourceMapper; @Autowired private ScenicService scenicService; + @Autowired + private VideoMapper videoMapper; + @Autowired + private VideoRepository videoRepository; + @Autowired + private ScenicRepository scenicRepository; public void addTask(String url, Long sourceId) { - try { - URL _url = new URL(url); - if (!StringUtils.startsWith(_url.getHost(), "100.64.")) { - return; - } - } catch (MalformedURLException ignored) { - return; - } SourceEntity entity = sourceMapper.getEntity(sourceId); if (entity == null) { return; @@ -63,6 +68,15 @@ public class VideoReUploader { if (entity.getType() != 1) { return; } + ScenicConfigEntity scenicConfig = scenicRepository.getScenicConfig(entity.getScenicId()); + if (scenicConfig == null || scenicConfig.getLocalStoreType() == null || scenicConfig.getLocalStoreConfigJson() == null) { + return; + } + final String dstFilePath = StorageUtil.joinPath(StorageConstant.VIDEO_PIECE_PATH, entity.getId().toString() + ".mp4"); + final IStorageAdapter adapter = scenicService.getScenicStorageAdapter(entity.getScenicId()); + if (StringUtils.equals(url, adapter.getUrl(dstFilePath))) { + return; + } String tmpFilePath = UUID.randomUUID().toString(); executor.execute(() -> { // 先下载,后上传 @@ -70,11 +84,9 @@ public class VideoReUploader { log.info("下载视频:{};sourceId:{}", url, sourceId); long size = HttpUtil.downloadFile(url, dstFile); log.info("下载视频完成:{};大小:{};sourceId:{}", url, size, sourceId); - String dstFilePath = StorageUtil.joinPath(StorageConstant.VIDEO_PIECE_PATH, entity.getId().toString() + ".mp4"); - IStorageAdapter dstAdapter = scenicService.getScenicStorageAdapter(entity.getScenicId()); try { log.info("开始上传:{};sourceId:{}", dstFilePath, sourceId); - String newUrl = dstAdapter.uploadFile("video/mp4", dstFile, dstFilePath); + String newUrl = adapter.uploadFile("video/mp4", dstFile, dstFilePath); log.info("上传成功:{};sourceId:{}", newUrl, sourceId); SourceEntity updateEntity = new SourceEntity(); updateEntity.setId(sourceId); @@ -90,4 +102,48 @@ public class VideoReUploader { } }); } + public void addVideoTask(String url, Long videoId) { + VideoEntity entity = videoMapper.getEntity(videoId); + if (entity == null) { + return; + } + if (entity.getScenicId() == null) { + return; + } + ScenicConfigEntity scenicConfig = scenicRepository.getScenicConfig(entity.getScenicId()); + if (scenicConfig == null || scenicConfig.getTmpStoreType() == null || scenicConfig.getTmpStoreConfigJson() == null) { + return; + } + final String dstFilePath = StorageUtil.joinPath(StorageConstant.VLOG_PATH, entity.getTaskId() + "_" + entity.getScenicId() + ".mp4"); + final IStorageAdapter adapter = scenicService.getScenicStorageAdapter(entity.getScenicId()); + if (StringUtils.equals(url, adapter.getUrl(dstFilePath))) { + return; + } + String tmpFilePath = UUID.randomUUID().toString(); + executor.execute(() -> { + // 先下载,后上传 + File dstFile = new File(tmpFilePath); + log.info("下载视频:{};videoId:{}", url, videoId); + long size = HttpUtil.downloadFile(url, dstFile); + log.info("下载视频完成:{};大小:{};videoId:{}", url, size, videoId); + try { + log.info("开始上传:{};videoId:{}", dstFilePath, videoId); + String newUrl = adapter.uploadFile("video/mp4", dstFile, dstFilePath); + adapter.setAcl(StorageAcl.PUBLIC_READ, dstFilePath); + log.info("上传成功:{};videoId:{}", newUrl, videoId); + VideoEntity updateEntity = new VideoEntity(); + updateEntity.setId(videoId); + updateEntity.setVideoUrl(newUrl); + videoMapper.update(updateEntity); + } catch (Exception e) { + log.info("上传失败:{};videoId:{}", dstFilePath, videoId, e); + } finally { + videoRepository.clearVideoCache(videoId); + try { + dstFile.delete(); + } catch (Exception ignored) { + } + } + }); + } } diff --git a/src/main/resources/mapper/ScenicMapper.xml b/src/main/resources/mapper/ScenicMapper.xml index 2fa83a0..1092602 100644 --- a/src/main/resources/mapper/ScenicMapper.xml +++ b/src/main/resources/mapper/ScenicMapper.xml @@ -111,6 +111,8 @@ store_config_json=#{storeConfigJson}, tmp_store_type=#{tmpStoreType}, tmp_store_config_json=#{tmpStoreConfigJson}, + local_store_type=#{localStoreType}, + local_store_config_json=#{localStoreConfigJson}, broker_direct_rate=#{brokerDirectRate}, watermark_type=#{watermarkType}, watermark_scenic_text=#{watermarkScenicText},