package com.fuyuanshen.app.service; import com.fuyuanshen.web.util.VideoProcessUtil; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; import org.springframework.web.multipart.MultipartFile; import java.io.File; import java.util.Arrays; import java.util.List; /** * 视频处理服务 */ @Slf4j @Service @RequiredArgsConstructor public class VideoProcessService { // 配置参数 private static final int MAX_VIDEO_SIZE = 10 * 1024 * 1024; private static final List SUPPORTED_FORMATS = Arrays.asList(".mp4", ".avi", ".mov", ".mkv"); private static final int FRAME_RATE = 15; private static final int DURATION = 2; private static final int WIDTH = 160; private static final int HEIGHT = 80; private final VideoProcessUtil videoProcessUtil; public List processVideo(MultipartFile file, int code) { // 1. 参数校验 validateVideoFile(file); File tempFile = null; try { // 2. 创建临时文件 tempFile = videoProcessUtil.createTempVideoFile(file); // 3. 处理视频并提取帧数据 List hexList = videoProcessUtil.processVideoToHex( tempFile, FRAME_RATE, DURATION, WIDTH, HEIGHT, code ); log.info("code: {} hexList(前100个): {}", code, hexList.subList(0, Math.min(100, hexList.size()))); log.info("视频处理成功,生成Hex数据长度: {}", hexList.size()); return hexList; } catch (Exception e) { log.error("视频处理失败", e); throw new RuntimeException("视频处理失败", e); } finally { // 4. 清理临时文件 videoProcessUtil.deleteTempFile(tempFile); } } /** * 验证视频文件 */ private void validateVideoFile(MultipartFile file) { if (file == null || file.isEmpty()) { throw new IllegalArgumentException("上传文件不能为空"); } if (!isVideoFile(file.getOriginalFilename())) { throw new IllegalArgumentException("只允许上传视频文件"); } if (file.getSize() > MAX_VIDEO_SIZE) { throw new IllegalArgumentException("视频大小不能超过10MB"); } } /** * 判断是否是支持的视频格式 */ private boolean isVideoFile(String filename) { if (filename == null || filename.lastIndexOf('.') == -1) { return false; } String ext = filename.substring(filename.lastIndexOf('.')).toLowerCase(); return SUPPORTED_FORMATS.contains(ext); } }