在实现了minio文件上传的基础上进行操作

一、编写pom

<dependency><groupId>org.jcodec</groupId><artifactId>jcodec</artifactId><version>0.2.5</version></dependency><dependency><groupId>org.jcodec</groupId><artifactId>jcodec-javase</artifactId><version>0.2.5</version></dependency>

二、新增创建FileItem的方法

@Slf4jpublic class FileUtil {// 默认文件名private static final String defaultFilename = "file";public static FileItem createFileItem(InputStream inputStream) {final String filename = defaultFilename + "." +MediaType.IMAGE_JPEG.getSubtype();FileItemFactory factory = new DiskFileItemFactory(16, null);FileItem item = factory.createItem(filename, MediaType.MULTIPART_FORM_DATA_VALUE, true, filename);try(OutputStream os = item.getOutputStream()) {IOUtils.copy(inputStream, os);} catch (IOException e) {log.error("create fileItem stream copy occurred exception", e);throw new VideoFrameException(VideoFrameExceptionTypes.FILE_CREATE_FAILED);}return item;}}

三、视频工具类获取帧

@Slf4jpublic class VideoUtil {private static final List<String> videoSuffix = Arrays.asList("avi", "wmv", "mov", "mpg", "mpeg", "rm", "ram", "flv", "swf", "mp4");public static MultipartFile getFirstFrame(MultipartFile videoFile) {return getFrame(videoFile, 1);}public static MultipartFile getFrame(MultipartFile multipartFile, int frameNumber) {String originalFilename = multipartFile.getOriginalFilename();if (StringUtils.isBlank(originalFilename) || !originalFilename.contains(".")) {throw new VideoFrameException(VideoFrameExceptionTypes.NOT_SUPPORTED_FILE_TYPE);}String[] filenameSplit = originalFilename.split("\\.");if (!videoSuffix.contains(filenameSplit[filenameSplit.length - 1])) {throw new VideoFrameException(VideoFrameExceptionTypes.NOT_SUPPORTED_FILE_TYPE);}CommonsMultipartFile cf = (CommonsMultipartFile) multipartFile;DiskFileItem fi = (DiskFileItem) cf.getFileItem();File file = fi.getStoreLocation();MultipartFile videoCover = null;try {Picture pic = FrameGrab.getFrameFromFile(file, frameNumber);BufferedImage bi = AWTUtil.toBufferedImage(pic);ByteArrayOutputStream baos = new ByteArrayOutputStream();ImageIO.write(bi, MediaType.IMAGE_JPEG.getSubtype(), baos);InputStream input = new ByteArrayInputStream(baos.toByteArray());FileItem fileItem = FileUtil.createFileItem(input);videoCover = new CommonsMultipartFile(fileItem);} catch (IOException | JCodecException e) {log.error("获取视频帧出现异常", e);throw new VideoFrameException(VideoFrameExceptionTypes.GET_VIDEO_FRAME_FAILED);}return videoCover;}}

四、编写Controller进行测试

@Slf4j@RequestMapping("video")@RestControllerpublic class VideoController {@Resourceprivate MinioService minioService;// 上传视频@PostMapping("/uploadVideo")public String uploadVideo(MultipartFile file) {String filename = minioService.upload(file);log.info("视频 {} 上传成功!", filename);MultipartFile firstFrame = VideoUtil.getFirstFrame(file);String firstFrameFilename = minioService.upload(firstFrame);log.info("封面 {} 上传成功!", firstFrameFilename);return filename;}}
### 上传POST http://127.0.0.1:8888/video/uploadVideoContent-Type: multipart/form-data; boundary=WebAppBoundary--WebAppBoundaryContent-Disposition: form-data; name="file"; filename="Grant_Gustin_share.mp4"< /Users/wangfeihu/IdeaProjects/video-frame/src/main/resources/video/Grant_Gustin_share.mp4--WebAppBoundary--



获取并上传视频首帧成功!

代码仓库: video-frame-demo