package com.ycwl.basic.utils; 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.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; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import java.io.File; import java.util.UUID; import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.ThreadFactory; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; @Component @Slf4j public class VideoReUploader { private static final ThreadFactory threadFactory = new ThreadFactoryBuilder() .setNamePrefix("Vid-ReUp-") .build(); private static final ThreadPoolExecutor executor = new ThreadPoolExecutor(1, 1024, 0L, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<>(1024), threadFactory ); @Autowired private SourceMapper sourceMapper; @Autowired private ScenicService scenicService; @Autowired private VideoMapper videoMapper; @Autowired private VideoRepository videoRepository; @Autowired private ScenicRepository scenicRepository; public void addTask(Long sourceId) { SourceEntity entity = sourceMapper.getEntity(sourceId); if (entity == null) { return; } if (entity.getScenicId() == null) { return; } 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(entity.getVideoUrl(), adapter.getUrl(dstFilePath))) { return; } String tmpFilePath = UUID.randomUUID().toString(); executor.execute(() -> { // 先下载,后上传 File dstFile = new File(tmpFilePath); log.info("下载视频:{};sourceId:{}", entity.getVideoUrl(), sourceId); long size = HttpUtil.downloadFile(entity.getVideoUrl(), dstFile); log.info("下载视频完成:{};大小:{};sourceId:{}", entity.getVideoUrl(), size, sourceId); try { log.info("开始上传:{};sourceId:{}", dstFilePath, sourceId); String newUrl = adapter.uploadFile("video/mp4", dstFile, dstFilePath); log.info("上传成功:{};sourceId:{}", newUrl, sourceId); SourceEntity updateEntity = new SourceEntity(); updateEntity.setId(sourceId); updateEntity.setVideoUrl(newUrl); sourceMapper.update(updateEntity); } catch (Exception e) { log.info("上传失败:{};sourceId:{}", dstFilePath, sourceId, e); } finally { try { dstFile.delete(); } catch (Exception ignored) { } } }); } public void addVideoTask(Long videoId) { VideoEntity entity = videoMapper.getEntity(videoId); if (entity == null) { return; } if (entity.getScenicId() == 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(entity.getVideoUrl(), adapter.getUrl(dstFilePath))) { return; } String tmpFilePath = UUID.randomUUID().toString(); executor.execute(() -> { // 先下载,后上传 File dstFile = new File(tmpFilePath); log.info("下载视频:{};videoId:{}", entity.getVideoUrl(), videoId); long size = HttpUtil.downloadFile(entity.getVideoUrl(), dstFile); log.info("下载视频完成:{};大小:{};videoId:{}", entity.getVideoUrl(), 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) { } } }); } }