|
|
@@ -0,0 +1,198 @@
|
|
|
+package cn.reghao.oss.store.task.processor;
|
|
|
+
|
|
|
+import cn.reghao.jutil.media.FFmpegWrapper;
|
|
|
+import cn.reghao.jutil.media.ImageOps;
|
|
|
+import cn.reghao.jutil.media.MediaQuality;
|
|
|
+import cn.reghao.jutil.media.MediaResolution;
|
|
|
+import cn.reghao.jutil.media.model.AudioProps;
|
|
|
+import cn.reghao.jutil.media.model.MediaProps;
|
|
|
+import cn.reghao.jutil.media.model.VideoProps;
|
|
|
+import cn.reghao.oss.store.api.dto.ObjectMeta;
|
|
|
+import cn.reghao.oss.store.api.dto.media.AudioInfo;
|
|
|
+import cn.reghao.oss.store.api.dto.media.ConvertedImageInfo;
|
|
|
+import cn.reghao.oss.store.api.dto.media.ImageInfo;
|
|
|
+import cn.reghao.oss.store.api.dto.media.VideoInfo;
|
|
|
+import cn.reghao.oss.store.db.repository.ObjectRepository;
|
|
|
+import cn.reghao.oss.store.model.vo.ObjectResult;
|
|
|
+import cn.reghao.oss.store.service.FileStoreService;
|
|
|
+import cn.reghao.oss.store.service.ObjectNameService;
|
|
|
+import cn.reghao.oss.store.service.PutObjectService;
|
|
|
+import cn.reghao.oss.store.util.FileType;
|
|
|
+import lombok.extern.slf4j.Slf4j;
|
|
|
+import org.springframework.stereotype.Service;
|
|
|
+
|
|
|
+import java.io.File;
|
|
|
+import java.time.LocalDateTime;
|
|
|
+import java.util.List;
|
|
|
+import java.util.Objects;
|
|
|
+import java.util.UUID;
|
|
|
+import java.util.stream.Collectors;
|
|
|
+
|
|
|
+/**
|
|
|
+ * @author reghao
|
|
|
+ * @date 2023-01-11 10:40:17
|
|
|
+ */
|
|
|
+@Slf4j
|
|
|
+@Service
|
|
|
+public class MediaFileProcessor {
|
|
|
+ private final ObjectRepository objectRepository;
|
|
|
+ private final ObjectNameService objectNameService;
|
|
|
+ private final FileStoreService fileStoreService;
|
|
|
+ private final PutObjectService putObjectService;
|
|
|
+
|
|
|
+ public MediaFileProcessor(ObjectRepository objectRepository, ObjectNameService objectNameService,
|
|
|
+ FileStoreService fileStoreService, PutObjectService putObjectService) {
|
|
|
+ this.objectRepository = objectRepository;
|
|
|
+ this.objectNameService = objectNameService;
|
|
|
+ this.fileStoreService = fileStoreService;
|
|
|
+ this.putObjectService = putObjectService;
|
|
|
+ }
|
|
|
+
|
|
|
+ public VideoInfo getVideoInfo(String videoFileId) throws Exception {
|
|
|
+ ObjectMeta objectMeta = objectRepository.getObjectMetaById(videoFileId);
|
|
|
+ if (objectMeta == null) {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ String absolutePath = objectMeta.getAbsolutePath();
|
|
|
+ MediaProps mediaProps = FFmpegWrapper.getMediaProps(absolutePath);
|
|
|
+ if (mediaProps == null) {
|
|
|
+ String errMsg = String.format("%s 的 FFmpeg 媒体信息为 null", videoFileId);
|
|
|
+ throw new Exception(errMsg);
|
|
|
+ }
|
|
|
+
|
|
|
+ VideoProps videoProps = mediaProps.getVideoProps();
|
|
|
+ if (videoProps == null) {
|
|
|
+ String errMsg = String.format("%s 的 FFmpeg 视频信息为 null", videoFileId);
|
|
|
+ throw new Exception(errMsg);
|
|
|
+ }
|
|
|
+
|
|
|
+ String videoCodec = videoProps.getCodecName();
|
|
|
+ long vbitRate = videoProps.getBitRate();
|
|
|
+
|
|
|
+ String audioCodec = null;
|
|
|
+ long abitRate = 0;
|
|
|
+ AudioProps audioProps1 = mediaProps.getAudioProps();
|
|
|
+ if (audioProps1 != null) {
|
|
|
+ audioCodec = audioProps1.getCodecName();
|
|
|
+ abitRate = audioProps1.getBitRate();
|
|
|
+ }
|
|
|
+
|
|
|
+ String objectId = videoFileId;
|
|
|
+ String objectName = objectMeta.getObjectName();
|
|
|
+ String objectUrl = objectNameService.getObjectUrl(objectName);
|
|
|
+ int width = videoProps.getCodedWidth().intValue();
|
|
|
+ int height = videoProps.getCodedHeight().intValue();
|
|
|
+ int duration = videoProps.getDuration().intValue();
|
|
|
+ MediaResolution mediaResolution = MediaQuality.getQuality(width, height);
|
|
|
+ String quality = mediaResolution.getQualityStr();
|
|
|
+ String urlType = FileType.getVideoUrlType(absolutePath);
|
|
|
+ LocalDateTime createTime = mediaProps.getCreateTime();
|
|
|
+
|
|
|
+ return new VideoInfo(videoFileId, objectId, videoCodec, vbitRate, audioCodec, abitRate,
|
|
|
+ urlType, objectUrl, quality, width, height, duration, createTime);
|
|
|
+ }
|
|
|
+
|
|
|
+ public ImageInfo getImageInfo(String imageFileId) throws Exception {
|
|
|
+ ObjectMeta objectMeta = objectRepository.getObjectMetaById(imageFileId);
|
|
|
+ if (objectMeta == null) {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ String absolutePath = objectMeta.getAbsolutePath();
|
|
|
+ File file = new File(absolutePath);
|
|
|
+ String format = ImageOps.getFormat(file);
|
|
|
+ ImageOps.Size size = ImageOps.info(new File(absolutePath));
|
|
|
+ int width = size.getWidth();
|
|
|
+ int height = size.getHeight();
|
|
|
+ String objectId = imageFileId;
|
|
|
+ String objectName = objectMeta.getObjectName();
|
|
|
+ String objectUrl = objectNameService.getObjectUrl(objectName);
|
|
|
+
|
|
|
+ ImageInfo imageInfo = new ImageInfo(imageFileId, objectId, format, objectUrl, width, height);
|
|
|
+ return imageInfo;
|
|
|
+ }
|
|
|
+
|
|
|
+ public List<ConvertedImageInfo> getWebpInfos(List<String> imageFileIds) {
|
|
|
+ return imageFileIds.stream()
|
|
|
+ .map(imageFileId -> {
|
|
|
+ try {
|
|
|
+ return getWebpInfo(imageFileId);
|
|
|
+ } catch (Exception e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+ return null;
|
|
|
+ })
|
|
|
+ .filter(Objects::nonNull)
|
|
|
+ .collect(Collectors.toList());
|
|
|
+ }
|
|
|
+
|
|
|
+ public ConvertedImageInfo getWebpInfo(String imageFileId) throws Exception {
|
|
|
+ ObjectMeta objectMeta = objectRepository.getObjectMetaById(imageFileId);
|
|
|
+ if (objectMeta == null) {
|
|
|
+ log.error("{} not exist", imageFileId);
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ String originalObjectName = objectMeta.getObjectName();
|
|
|
+ String absolutePath = objectMeta.getAbsolutePath();
|
|
|
+ File srcFile = new File(absolutePath);
|
|
|
+
|
|
|
+ String format = "webp";
|
|
|
+ String suffix = "." + format;
|
|
|
+ String contentId = UUID.randomUUID().toString().replace("-", "");
|
|
|
+ String destPath = fileStoreService.genFilePath(contentId, srcFile.length(), suffix);
|
|
|
+ File destFile = new File(destPath);
|
|
|
+ ImageOps.convert2webp(srcFile, destFile);
|
|
|
+
|
|
|
+ if (destFile.exists()) {
|
|
|
+ ObjectResult objectResult1 = putObjectService.putObject(originalObjectName, contentId, suffix, destFile);
|
|
|
+ String objectName1 = objectResult1.getObjectName();
|
|
|
+ String objectId1 = objectResult1.getObjectId();
|
|
|
+ String objectUrl1 = objectNameService.getObjectUrl(objectName1);
|
|
|
+ ConvertedImageInfo convertedImageInfo = new ConvertedImageInfo(imageFileId, objectId1, format, objectUrl1);
|
|
|
+ return convertedImageInfo;
|
|
|
+ } else {
|
|
|
+ log.error("image conversion failed");
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public List<ImageInfo> getImagesInfo(List<String> imageFileIds) {
|
|
|
+ return imageFileIds.stream()
|
|
|
+ .map(imageFileId -> {
|
|
|
+ try {
|
|
|
+ return getImageInfo(imageFileId);
|
|
|
+ } catch (Exception e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+ return null;
|
|
|
+ })
|
|
|
+ .filter(Objects::nonNull)
|
|
|
+ .collect(Collectors.toList());
|
|
|
+ }
|
|
|
+
|
|
|
+ public AudioInfo getAudioInfo(String audioFileId) throws Exception {
|
|
|
+ ObjectMeta objectMeta = objectRepository.getObjectMetaById(audioFileId);
|
|
|
+ if (objectMeta == null) {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ String absolutePath = objectMeta.getAbsolutePath();
|
|
|
+ MediaProps mediaProps = FFmpegWrapper.getMediaProps(absolutePath);
|
|
|
+ if (mediaProps == null || mediaProps.getAudioProps() == null) {
|
|
|
+ String errMsg = String.format("%s 的 FFmpeg 音频信息为 null", audioFileId);
|
|
|
+ throw new Exception(errMsg);
|
|
|
+ }
|
|
|
+
|
|
|
+ AudioProps audioProps = mediaProps.getAudioProps();
|
|
|
+ String audioCodec = audioProps.getCodecName();
|
|
|
+ int duration = audioProps.getDuration().intValue();
|
|
|
+ long bitRate = audioProps.getBitRate();
|
|
|
+ String objectId = audioFileId;
|
|
|
+ String objectName = objectMeta.getObjectName();
|
|
|
+ String objectUrl = objectNameService.getObjectUrl(objectName);
|
|
|
+
|
|
|
+ return new AudioInfo(audioFileId, objectId, duration, audioCodec, bitRate, objectUrl);
|
|
|
+ }
|
|
|
+}
|