获取视频帧图片

在实现了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的方法

@Slf4j
public 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;
    }
}

三、视频工具类获取帧

@Slf4j
public 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")
@RestController
public class VideoController {
   

    @Resource
    private 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/uploadVideo
Content-Type: multipart/form-data; boundary=WebAppBoundary

--WebAppBoundary
Content-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

相关推荐

  1. opencv逐获取视频图片

    2024-02-09 09:34:02       47 阅读
  2. Qt如何将视频获取

    2024-02-09 09:34:02       41 阅读
  3. 视频中截取指定图片

    2024-02-09 09:34:02       53 阅读
  4. 关于逐读取视频,并且读取视频图片标注

    2024-02-09 09:34:02       30 阅读
  5. 获取视频第一,以及后续上传

    2024-02-09 09:34:02       48 阅读
  6. ffmpeg 从视频文件抓取图片)的用法

    2024-02-09 09:34:02       51 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-02-09 09:34:02       91 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-02-09 09:34:02       97 阅读
  3. 在Django里面运行非项目文件

    2024-02-09 09:34:02       78 阅读
  4. Python语言-面向对象

    2024-02-09 09:34:02       88 阅读

热门阅读

  1. Nginx 缓存集成、清除、设置不缓存资源

    2024-02-09 09:34:02       58 阅读
  2. 【FreeRTOS】堆栈管理:任务执行的基石

    2024-02-09 09:34:02       55 阅读
  3. C#阿里云消息列队推送消息

    2024-02-09 09:34:02       52 阅读
  4. mysql线程锁(latch)源码级详解

    2024-02-09 09:34:02       50 阅读
  5. 法国实习面试——计算机相关专业词汇

    2024-02-09 09:34:02       50 阅读
  6. Ansible

    Ansible

    2024-02-09 09:34:02      34 阅读
  7. 【C#】Xasset加载资源模块

    2024-02-09 09:34:02       51 阅读
  8. K8S系列文章之 [Alpine搭建docker环境]

    2024-02-09 09:34:02       49 阅读