java实现MinIO文件上传,并将视频文件截图,将视频封面及视频通过MinIo上传到服务器中
java实现MinIO文件上传,并将视频文件截图,将视频封面及视频通过MinIo上传到服务器中
- 配置完毕,接下来开始代码编写。
- 说明
总过程分为两步。
1.配置MinIO的环境。
2.代码编写。
下面开始配置MinIO的环境。
(1)导入依赖
<dependency><groupId>io.minio</groupId><artifactId>minio</artifactId><version>7.1.0</version></dependency>
之前用过3.0的版本,可以上传,但是不符合需求。用过8.1,报版本依赖冲突的错误。只有这个7.1是能正常使用的。
(2)在配置文件的yml中配置minio的endpoint,bucketName,accessKey,secretKey,port。
minio:endpoint: http://192.168.1.2 #Minio服务所在地址bucketName: abc #存储桶名称accessKey: mio2021 #访问的keysecretKey: 123458 #访问的秘钥port: 9000 #端口号
配置完毕,接下来开始代码编写。
(1)将配置文件中的信息依赖注入
@Value(value = "${minio.endpoint}")private String endpoint;@Value(value = "${minio.accessKey}")private String accessKey;@Value(value = "${minio.secretKey}")private String secretKey;@Value("${minio.bucketName}")private String bucketName;@Value("${minio.port}")private Integer port;
(2)功能实现
/*** 文件创建* 如果文件是视频类型的,那么将文件截图,并将截图和视频上传到MinIO存储* 如果文件是图片类型的,那么将图片上传到MinIo存储*/@Override@SneakyThrowspublic HashMap minioFileUpload(MultipartFile file,String type) {HashMap map=new HashMap();WuhanzghEnum.TYPE_NULL.assertIsTrue(MagicPoint.STRING_ZERO.equals(type)||MagicPoint.STRING_ONE.equals(type));String date= DateUtil.formatDate(new Date());String filename = DateUtil.currentSeconds()+file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf("."));if (MagicPoint.STRING_ZERO.equals(type)){String imgName="img"+"/"+date+"/"+filename;minIoClientUpload(file.getInputStream(),imgName);String imgPathOne=endpoint + "/" + bucketName + "/" + imgName;map.put("imgPath",imgPathOne);return map;}String videoType = file.getContentType();// 文件存储的目录结构String videoName =videoType+"/"+date+"/"+filename;String imgPath = this.ffmpegGetScreenshot(file);String imgPathName = DateUtil.currentSeconds()+imgPath.substring(imgPath.lastIndexOf("."));BufferedInputStream imgInputStream = FileUtil.getInputStream(imgPath);String imgName="img"+"/"+date+"/"+imgPathName;minIoClientUpload(imgInputStream,imgName);minIoClientUpload(file.getInputStream(),videoName);log.info("图片文件上传成功!");// 存储文件log.info("视频文件上传成功!");String videoPath=endpoint + "/" + bucketName + "/" + videoName;String imgPathOne=endpoint + "/" + bucketName + "/" + imgName;map.put("videoPath",videoPath);map.put("imgPath",imgPathOne);// log.info("上传发生错误: {}!", e.getMessage());return map;}
public String ffmpegGetScreenshot(MultipartFile file) throws IOException {File tofile = new File(file.getOriginalFilename());FileUtils.copyInputStreamToFile(file.getInputStream(),tofile);String absolutePath = tofile.getAbsoluteFile().getAbsolutePath();Map<String, Object> screenshot = VideoUtil.getScreenshot(absolutePath);String imgPath =(String) screenshot.get("imgPath");return imgPath;}@SneakyThrowspublic void minIoClientUpload(InputStream imgInputStream,String objectName) {//创建头部信息Map<String, String> headers = new HashMap<>(10);//添加自定义内容类型headers.put("Content-Type", "application/octet-stream");//添加存储类headers.put("X-Amz-Storage-Class", "REDUCED_REDUNDANCY");//添加自定义/用户元数据Map<String, String> userMetadata = new HashMap<>(10);userMetadata.put("My-Project", "Project One");MinioClient minioClient =MinioClient.builder().endpoint(endpoint, port, false).credentials(accessKey, secretKey).build();minioClient.putObject(PutObjectArgs.builder().bucket(bucketName).object(objectName).stream(imgInputStream,imgInputStream.available(),-1).userMetadata(userMetadata).build());imgInputStream.close();}
完成!!!
说明
由于我将文件上传到MinIO之前还将视频截图并将封面及视频上传,所以不需要这功能的用以下的代码即可
String imgName="img"+"/"+date+"/"+filename;minIoClientUpload(file.getInputStream(),imgName);String imgPathOne=endpoint + "/" + bucketName + "/" + imgName;map.put("imgPath",imgPathOne);return map;
若要使用视频截图的功能还需一个依赖和一个工具类
<!--视频截取依赖--><dependency><groupId>org.bytedeco</groupId><artifactId>javacv-platform</artifactId><version>1.5.3</version></dependency>
工具类:
package com.whrfjd.wuhanzgh.util;import cn.hutool.core.io.FileUtil;
import org.bytedeco.javacv.FFmpegFrameGrabber;
import org.bytedeco.javacv.Frame;
import org.bytedeco.javacv.Java2DFrameConverter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.util.HashMap;
import java.util.Map;/*** 视频工具类** @Author: szw* @Date: 2020/7/9 9:42*/
public class VideoUtil {private static final Logger LOGGER = LoggerFactory.getLogger(VideoUtil.class);public static void main(String[] args) {System.out.println("视频加密---------------------------"+new BCryptPasswordEncoder().encode("rainbow-whrfjd.oss-cn-shanghai.aliyuncs.com/video/20200818/d06e306d3f5c49768ef7c7118eb66253.mp4"));
// Map<String, Object> screenshot = getScreenshot("D:\\项目备份\\华林梦想-视频素材\\技能操作视频素材\\123.mp4");
// LOGGER.debug("-------------------------screenshot"+screenshot);// MultipartFile multipartFile = new MockMultipartFile("aaa.jpg","aaa.jpg","jpg",inputStream);
// File tofile = new File(multipartFile.getOriginalFilename());
// FileUtils.copyInputStreamToFile(multipartFile.getInputStream(),tofile);
// System.out.println(tofile);
// String path = tofile.getPath();
// if (tofile.exists()){// tofile.delete();
// }System.out.println("1341654");}/*** 通过Javacv的方式获取视频截图** @param deviceFile 视频文件路径* @return Map<String, Object>*/public static Map<String, Object> getScreenshot(File deviceFile) {try {LOGGER.debug("截取视频截图开始:" + System.currentTimeMillis());Map<String, Object> result = new HashMap<String, Object>();FFmpegFrameGrabber grabber = FFmpegFrameGrabber.createDefault(deviceFile);String fileName = FileUtil.getName(deviceFile);String absolutePath = FileUtil.getAbsolutePath(deviceFile);// // 第一帧图片存储位置
// String targerFilePath = filePath.substring(0, filePath.lastIndexOf("\\"));
// // 视频文件名
// String fileName = filePath.substring(filePath.lastIndexOf("\\") + 1);// 图片名称String targetFileName = fileName.substring(0, fileName.lastIndexOf("."));
// LOGGER.debug("视频路径是:" + targerFilePath);
// LOGGER.debug("视频文件名:" + fileName);LOGGER.debug("图片名称是:" + targetFileName);grabber.start();//设置视频截取帧(默认取第一帧)Frame frame = grabber.grabImage();int i = 0;int lenght = grabber.getLengthInFrames();Frame f = null;while (i < lenght) {// 过滤前300帧,避免出现全黑的图片,依自己情况而定
// f = grabber.grabFrame();f=grabber.grabImage();if ((i > 150) && (f.image != null)) {break;}i++;}//视频旋转度String rotate = grabber.getVideoMetadata("rotate");Java2DFrameConverter converter = new Java2DFrameConverter();//绘制图片BufferedImage bi = converter.getBufferedImage(f);if (rotate != null) {// 旋转图片bi = rotate(bi, Integer.parseInt(rotate));}//图片的类型String imageMat = "jpg";//图片的完整路径String imagePath = absolutePath + File.separator + targetFileName + "." + imageMat;//创建文件File output = new File(imagePath);ImageIO.write(bi, imageMat, output);// //拼接Map信息
// result.put("videoWide", bi.getWidth());
// result.put("videoHigh", bi.getHeight());
// long duration = grabber.getLengthInTime() / (1000 * 1000);
// result.put("rotate", StringUtils.isBlank(rotate) ? "0" : rotate);
// result.put("format", grabber.getFormat());result.put("imgPath", output.getPath());
// result.put("time", duration);
// LOGGER.debug("视频的宽:" + bi.getWidth());
// LOGGER.debug("视频的高:" + bi.getHeight());
// LOGGER.debug("视频的旋转度:" + rotate);
// LOGGER.debug("视频的格式:" + grabber.getFormat());
// LOGGER.debug("此视频时长(s/秒):" + duration);grabber.stop();LOGGER.debug("截取视频截图结束:" + System.currentTimeMillis());return result;} catch (Exception e) {// LOGGER.error("VideoUtil getScreenshot fail: {}", ExceptionStackTrace.printStackTrace(e));return null;}}/*** 截取视频的某一帧作为封面图片 方法*/public static Map<String, Object> getScreenshot(String filePath) {try {LOGGER.info("截取视频截图开始:" + System.currentTimeMillis());Map<String, Object> result = new HashMap<String, Object>();FFmpegFrameGrabber grabber = FFmpegFrameGrabber.createDefault(filePath);// 第一帧图片存储位置String targerFilePath = filePath.substring(0, filePath.lastIndexOf(File.separator));// 视频文件名String fileName = filePath.substring(filePath.lastIndexOf(File.separator) + 1);// 图片名称String targetFileName = fileName.substring(0, fileName.lastIndexOf("."));LOGGER.info("视频路径是:" + targerFilePath);LOGGER.info("视频文件名:" + fileName);LOGGER.info("图片名称是:" + targetFileName);grabber.start();//设置视频截取帧(默认取第一帧)
// Frame frame = grabber.grabImage();int i = 0;int lenght = grabber.getLengthInFrames();LOGGER.info("----------------------------length="+lenght);Frame f = null;while (i < lenght) {// 过滤前300帧,避免出现全黑的图片,依自己情况而定
// f = grabber.grabFrame();f=grabber.grabImage();
// LOGGER.info("-----------------------------f="+f);if ((i > 500) && (f.image != null)) {break;}i++;}//视频旋转度String rotate = grabber.getVideoMetadata("rotate");LOGGER.info("-----------------------------------------rotate="+rotate);Java2DFrameConverter converter = new Java2DFrameConverter();//绘制图片BufferedImage bi = converter.getBufferedImage(f);LOGGER.info("----------------------------------bi="+bi);if (rotate != null) {// 旋转图片bi = rotate(bi, Integer.parseInt(rotate));LOGGER.info("------------------------------bi="+bi);}//图片的类型String imageMat = "jpg";LOGGER.info("---------------------------------targerFilePath="+targerFilePath);LOGGER.info("---------------------------------File.separator="+File.separator);LOGGER.info("---------------------------------targetFileName="+targetFileName);LOGGER.info("---------------------------------imageMat="+imageMat);//图片的完整路径String imagePath = targerFilePath + File.separator + targetFileName + "." + imageMat;LOGGER.info("---------------------------------imagePath="+imagePath);//创建文件File output = new File(imagePath);ImageIO.write(bi, imageMat, output);LOGGER.info("-----------------------------------------output="+output);LOGGER.info("----------------------------------------------output.getPath()="+output.getPath());// //拼接Map信息
// result.put("videoWide", bi.getWidth());
// result.put("videoHigh", bi.getHeight());
// long duration = grabber.getLengthInTime() / (1000 * 1000);
// result.put("rotate", StringUtils.isBlank(rotate) ? "0" : rotate);
// result.put("format", grabber.getFormat());result.put("imgPath", output.getPath());
// result.put("time", duration);
// LOGGER.debug("视频的宽:" + bi.getWidth());
// LOGGER.debug("视频的高:" + bi.getHeight());
// LOGGER.debug("视频的旋转度:" + rotate);
// LOGGER.debug("视频的格式:" + grabber.getFormat());
// LOGGER.debug("此视频时长(s/秒):" + duration);grabber.stop();LOGGER.info("截取视频截图结束:" + System.currentTimeMillis());return result;} catch (Exception e) {LOGGER.error("VideoUtil getScreenshot fail: {}", e);return null;}}/*** 通过Javacv的方式获取视频截图*linux操作系统方法* @param filePath 视频文件路径* @return Map<String, Object>*/// public static Map<String, Object> getScreenshot(String filePath) {// try {// System.out.println("截取视频截图开始");
// LOGGER.debug("截取视频截图开始:" + System.currentTimeMillis());
// Map<String, Object> result = new HashMap<String, Object>();
// FFmpegFrameGrabber grabber = FFmpegFrameGrabber.createDefault(filePath);
//
// // 第一帧图片存储位置
// String targerFilePath = filePath.substring(0, filePath.lastIndexOf("/"));
// System.out.println("----------------------targerFilePath="+targerFilePath);
// // 视频文件名
// String fileName = filePath.substring(filePath.lastIndexOf("/") + 1);
// System.out.println("----------------------fileName="+fileName);
// // 图片名称
// String targetFileName = fileName.substring(0, fileName.lastIndexOf("."));
// System.out.println("视频路径是:" + targerFilePath);
// System.out.println("视频文件名:" + fileName);
// System.out.println("图片名称是:" + targetFileName);
// LOGGER.debug("视频路径是:" + targerFilePath);
// LOGGER.debug("视频文件名:" + fileName);
// LOGGER.debug("图片名称是:" + targetFileName);
//
// grabber.start();
// //设置视频截取帧(默认取第一帧)
// Frame frame = grabber.grabImage();
// int i = 0;
// int lenght = grabber.getLengthInFrames();
// Frame f = null;
// while (i < lenght) {// // 过滤前300帧,避免出现全黑的图片,依自己情况而定
f = grabber.grabFrame();
// f=grabber.grabImage();
// if ((i > 300) && (f.image != null)) {// break;
// }
// i++;
// }
//
// //视频旋转度
// String rotate = grabber.getVideoMetadata("rotate");
// Java2DFrameConverter converter = new Java2DFrameConverter();
// //绘制图片
// BufferedImage bi = converter.getBufferedImage(f);
// if (rotate != null) {// // 旋转图片
// bi = rotate(bi, Integer.parseInt(rotate));
// }
// //图片的类型
// String imageMat = "jpg";
// //图片的完整路径
// String imagePath = targerFilePath + File.separator + targetFileName + "." + imageMat;
// //创建文件
// File output = new File(imagePath);
// ImageIO.write(bi, imageMat, output);
//
//拼接Map信息
result.put("videoWide", bi.getWidth());
result.put("videoHigh", bi.getHeight());
long duration = grabber.getLengthInTime() / (1000 * 1000);
result.put("rotate", StringUtils.isBlank(rotate) ? "0" : rotate);
result.put("format", grabber.getFormat());
// result.put("imgPath", output.getPath());
result.put("time", duration);
LOGGER.debug("视频的宽:" + bi.getWidth());
LOGGER.debug("视频的高:" + bi.getHeight());
LOGGER.debug("视频的旋转度:" + rotate);
LOGGER.debug("视频的格式:" + grabber.getFormat());
LOGGER.debug("此视频时长(s/秒):" + duration);
// grabber.stop();
// System.out.println("截取视频截图结束:" + System.currentTimeMillis());
// LOGGER.debug("截取视频截图结束:" + System.currentTimeMillis());
// return result;
// } catch (Exception e) { LOGGER.error("VideoUtil getScreenshot fail: {}", ExceptionStackTrace.printStackTrace(e));
// return null;
// }
// }/*** 根据视频旋转度来调整图片** @param src BufferedImage* @param angel angel 视频旋转度* @return BufferedImage*/public static BufferedImage rotate(BufferedImage src, int angel) {int src_width = src.getWidth(null);int src_height = src.getHeight(null);int type = src.getColorModel().getTransparency();Rectangle rect_des = calcRotatedSize(new Rectangle(new Dimension(src_width, src_height)), angel);BufferedImage bi = new BufferedImage(rect_des.width, rect_des.height, type);Graphics2D g2 = bi.createGraphics();g2.translate((rect_des.width - src_width) / 2, (rect_des.height - src_height) / 2);g2.rotate(Math.toRadians(angel), src_width / 2, src_height / 2);g2.drawImage(src, 0, 0, null);g2.dispose();return bi;}/*** 计算图片旋转大小** @param src Rectangle* @param angel int* @return Rectangle*/public static Rectangle calcRotatedSize(Rectangle src, int angel) {if (angel >= 90) {if (angel / 90 % 2 == 1) {int temp = src.height;src.height = src.width;src.width = temp;}angel = angel % 90;}double r = Math.sqrt(src.height * src.height + src.width * src.width) / 2;double len = 2 * Math.sin(Math.toRadians(angel) / 2) * r;double angel_alpha = (Math.PI - Math.toRadians(angel)) / 2;double angel_dalta_width = Math.atan((double) src.height / src.width);double angel_dalta_height = Math.atan((double) src.width / src.height);int len_dalta_width = (int) (len * Math.cos(Math.PI - angel_alpha - angel_dalta_width));int len_dalta_height = (int) (len * Math.cos(Math.PI - angel_alpha - angel_dalta_height));int des_width = src.width + len_dalta_width * 2;int des_height = src.height + len_dalta_height * 2;return new Rectangle(new Dimension(des_width, des_height));}
}
大功告成!!!!
java实现MinIO文件上传,并将视频文件截图,将视频封面及视频通过MinIo上传到服务器中相关推荐
- java如何处理csv文件上传_java处理csv文件上传示例
前言:示例只是做了一个最最基础的上传csv的示例,如果要引用到代码中去,还需要根据自己的业务自行添加一些逻辑处理. ReadCsvUtil工具类 package com.hanfengyeqiao.g ...
- java图片上传下载_java web 文件上传与下载
组件工作流程:WEB服务器request ServletFil eupLoad DiskFileItem Factory代表普通字段的FileItem代表上传文件1FileItem代表上传文件2Fil ...
- java上传rar文件_java实现上传zip/rar压缩文件,自动解压
在pom中添加解压jar依赖 4.0.0 org.springframework.boot spring-boot-starter-parent 2.1.2.RELEASE com.hf uncomp ...
- java上传csv文件上传_java处理csv文件上传示例详解
前言:示例只是做了一个最最基础的上传csv的示例,如果要引用到代码中去,还需要根据自己的业务自行添加一些逻辑处理. readcsvutil工具类 package com.hanfengyeqiao.g ...
- java上传ftp_java实现FTP文件上传与文件下载
本文实例为大家分享了两种java实现FTP文件上传下载的方式,供大家参考,具体内容如下 第一种方式: package com.cloudpower.util; import java.io.File; ...
- java 上传断点续传_JAVA大文件上传断点续传解决方案
javaweb上传文件 上传文件的jsp中的部分 上传文件同样可以使用form表单向后端发请求,也可以使用 ajax向后端发请求 1.通过form表单向后端发送请求 Save 改进后的代码不需要for ...
- java实现上传zip/rar压缩文件,自动解压
在pom中添加解压jar依赖 <?xml version="1.0" encoding="UTF-8"?> <project xmlns=&q ...
- java视频文件分片上传
Java视频分块上传 环境:springboot2.5.6+jdk1.8 1.在启动类中配置静态资源映射 springboot项目中配置了静态资源映射之后就启动项目之后就可以通过地址访问了 @Spri ...
- java使用sftp上传(文件)图片到服务器中
最近租了一个服务器,想着上线个小项目,结果图片上传卡壳了,自从11号看了一篇文章就入了ftp的坑.研究了十多个小时的ftp文件传输,无果.睡前看到了一篇关于sftp上传文件的文章,抱着试一试的心态,结 ...
最新文章
- c语言实现指定路径文件读取_C语言实现文件复制功能(包括文本文件和二进制文件)...
- python读取excel表格-python xlrd读取excel(表格)详解
- jenkins配置小结
- sql在线模拟器_力荐一款在线SQL模拟器
- 决策树学习笔记整理【转】
- UnicodeDecodeError: 'gbk' codec can't decode byte 0xb4 in position xx
- i350在linux系统刷MAC,MAC 10.14 安装教程10-基于黑果小兵大神EFI文件的修改过程
- word双引号间距大_word
- 程序员不要轻易去上海
- CSS消除absolute 的影响
- 文件共享服务:FTP Server
- Word文档丢失找回之没有保存Word文档就关闭了怎么解决
- 音乐服务器制作教程,分享硬盘中的音乐 DLNA服务搭建教程
- 日内趋势票如何把握?
- json后台的一些处理方式
- Amy姐白富美训练营内部资料
- Docker 镜像,基于 alpine 系统的时区配置
- 什么是 返点、分销、直销、代理、代销
- C语言 | 求字符串的长度
- DailyMart01:一起来玩DDD吧?
热门文章
- 腾讯第一“伪娘” 他是最会化妆的IT男
- python给图片添加全屏水印(透明度/字体)
- 我的世界服务器怎么修改血量,我的世界怎么设置血量指令 | 手游网游页游攻略大全...
- 共识算法之Pow工作量证明算法go语言实现
- SVT APB VIP
- 从世界各地测试网站访问速度
- ASRock is Challenging reviewers with their own test of ARC A380 graphics card【外媒VedioCardz报道(手工翻译)】
- 如何解决matlab共享中独立桌面app选项为灰色的问题
- 不会中毒的浏览器:Mozilla Firefox(火狐浏览器) 官方简体中文正式
- openlayers加载动态gif及css样式