获取视频帧图片

在实现了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 {@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/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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/461884.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

无人机动力系统高倍率锂聚合物电池介绍,无人机锂电池使用与保养,无人机飞行控制动力源详解

无人机电池使用及保养 电池是无人机飞行的动力来源,也是一个消耗品&#xff0c;对电池充分了解&#xff0c;采取正确的使用方法&#xff0c;妥善进行维护保养将有助于提高飞行的安全性、延长电池的使用寿命。以下将详细对电池的使用和管理进行讲解。 高倍率锂聚合物电池的含义…

LLM大语言模型(六):RAG模式下基于PostgreSQL pgvector插件实现vector向量相似性检索

目录 HightLightMac上安装PostgreSQLDBever图形界面管理端创建DB 使用向量检索vector相似度计算近似近邻索引HNSW近似近邻索引示例 HightLight 使用PostgreSQL来存储和检索vector&#xff0c;在数据规模非庞大的情况下&#xff0c;简单高效。 可以和在线业务共用一套DB&#…

代码随想录 Leetcode55. 跳跃游戏

题目&#xff1a; 代码(首刷自解 2024年2月9日&#xff09;&#xff1a; class Solution { public:bool canJump(vector<int>& nums) {int noz 0;for (int i nums.size() - 2; i > 0; --i) {if (nums[i] 0) {noz;continue;} else {if (nums[i] > noz) noz …

【UE】游戏运行流程的简单理解

流程图 官方的游戏流程图&#xff1a; 一般顺序为初始化引擎、创建并初始化 GameInstance、加载关卡&#xff0c;最后开始游戏。 总的来说就是&#xff1a; 开始游戏-》游戏实例-》关卡-》游戏模式-》玩家控制器-》Pawn、玩家状态、HUD、UMG&#xff08;可有可无&#xff09; …

ElasticSearch之search API

写在前面 本文看下查询相关内容&#xff0c;这也是我们在实际工作中接触的最多的&#xff0c;所以有必要好好学习下&#xff01; 1&#xff1a;查询的分类 主要分为如下2类&#xff1a; 1:基于get查询参数的URI search 2&#xff1a;基于post body的request body search&am…

排序算法的时间复杂度存在下界问题

对于几种常用的排序算法&#xff0c;无论是归并排序、快速排序、以及更加常见的冒泡排序等&#xff0c;这些排序算法的时间复杂度都是大于等于O(n*lg(n))的&#xff0c;而这些排序算法存在一个共同的行为&#xff0c;那就是这些算法在对元素进行排序的时候&#xff0c;都会进行…

双指针算法 最长连续不重复子序列

最长连续不重复子序列 C代码实现: #include<iostream> using namespace std;const int N 1000002; int a[N], count[N];int main() {int result 0;int n;// 输入数组长度cin >> n;// 输入数组元素for (int i 0; i < n; i) {cin >> a[i];}// 使用滑动…

【开源项目阅读】Java爬虫抓取豆瓣图书信息

原项目链接 Java爬虫抓取豆瓣图书信息 本地运行 运行过程 另建项目&#xff0c;把四个源代码文件拷贝到自己的包下面 在代码爆红处按ALTENTER自动导入maven依赖 直接运行Main.main方法&#xff0c;启动项目 运行结果 在本地磁盘上生成三个xml文件 其中的内容即位爬取…

以用户为中心,酷开科技荣获“消费者服务之星”

在企业顺应消费升级的道路中&#xff0c;企业自身不仅要着力强化对于消费者服务意识的提升&#xff0c;并且要树立诚信自律的行业示范带头作用&#xff0c;助力消费环境稳中向好&#xff0c;不断满足人民群众对美好生活的期待。企业的发展需要消费者的认可&#xff0c;酷开科技…

iPhone解锁 AnyMP4 iPhone Unlocker

AnyMP4 iPhone Unlocker是一款功能强大的iPhone解锁软件&#xff0c;旨在帮助用户轻松解决iPhone密码忘记、设备锁定等问题。无论是屏幕密码、指纹解锁还是Face ID&#xff0c;该软件都能提供有效的解决方案。 这款软件支持多种iPhone型号&#xff0c;包括最新的iPhone 14系列…

【EEG信号处理】对信号进行模拟生成

生成信号的目的还是主要是为了学习和探究后面的分析方法&#xff1b;本文主要是对方法进行整理 瞬态 transient 瞬态信号是指的是一瞬间信号上去了&#xff0c;这种情况我们可以用在时域上高斯模拟 peaktime 1; % seconds width .12; ampl 9; gaus ampl * exp( -(EEG.tim…

真正免费的文件恢复软件easyrecovery2024中文版

easyrecovery数据恢复软件是一款广受好评的数据恢复工具&#xff0c;它能够有效地帮助用户恢复各种类型的文件。无论是照片、视频、音乐还是文档&#xff0c;都能轻松地找回这些重要文件。操作安全、用户可自主操作的数据恢复方案&#xff0c;它支持从各种各样的存储介质恢复删…