-
需求
(1)使用照片墙方式将图片上传到Minio
(2)将上传的图片生成缩略图
(3)将缩略图上传到Minio -
目的:节省空间、避免图片过多加载不出来
-
Java端
(1)pom.xml引入依赖
<!--视频缩略图 --><dependency<groupId>org.bytedeco</groupId><artifactId>javacv</artifactId><version>1.4.3</version></dependency><dependency><groupId>org.bytedeco.javacpp-presets</groupId><artifactId>ffmpeg-platform</artifactId><version>4.0.2-1.4.3</version></dependency>
(2)Controller.java
/*** 批量新增上传的视频*/@PostMapping("/batchSaveMediaVideo")@ApiOperationSupport(order = 11)@ApiOperation(value = "批量新增", notes = "传入List<archiveMediaVideo>")public R batchSaveMediaVideo(@Valid @RequestBody List<ArchiveMediaVideoEntity> archiveMediaVideo) throws FrameGrabber.Exception {boolean result = archiveMediaVideoService.batchSaveMediaVideo(archiveMediaVideo);return R.status(result);}
(3)Service.java
boolean batchSaveMediaVideo(List<ArchiveMediaVideoEntity> archiveMediaVideo) throws FrameGrabber.Exception;
(4)ServiceImpl.java
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import org.bytedeco.javacv.FFmpegFrameGrabber;
import org.bytedeco.javacv.Frame;
import org.bytedeco.javacv.FrameGrabber;
import org.bytedeco.javacv.Java2DFrameConverter;
import org.springblade.core.mp.base.BaseServiceImpl;
import org.springblade.core.oss.model.BladeFile;
import org.springblade.modules.archive.vo.ArchiveMediaVideoVO;
import org.springblade.modules.resource.builder.oss.OssBuilder;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.util.ArrayList;@Service
public class ArchiveMediaVideoServiceImpl{// 对象存储构建类Minioprivate final OssBuilder ossBuilder;public ArchiveMediaVideoServiceImpl(OssBuilder ossBuilder) {this.ossBuilder = ossBuilder;}// 具体方法@Overridepublic boolean batchSaveMediaVideo(List<ArchiveMediaVideoEntity> archiveMediaVideo) throws FrameGrabber.Exception {ArrayList<ArchiveMediaVideoEntity> archiveList = new ArrayList<>();for(ArchiveMediaVideoEntity archiveVideoFile : archiveMediaVideo){// 定义缩略图的名称String substring = archiveVideoFile.getOriginalName().substring(0, archiveVideoFile.getOriginalName().indexOf("."));String fileName = substring + ".jpg";// 根据原视频路径生成缩略图流并上传到MinioFFmpegFrameGrabber ff = new FFmpegFrameGrabber(archiveVideoFile.getLink());try {ff.start();int lenght = ff.getLengthInFrames();int i = 0;Frame f = null;while (i < lenght) {// 过滤前5帧f = ff.grabFrame();if ((i > 48) && (f.image != null)) {break;}i++;}int owidth = f.imageWidth;int oheight = f.imageHeight;// 对截取的帧进行等比例缩放int width = 300;int height = (int) (((double) width / owidth) * oheight);Java2DFrameConverter converter = new Java2DFrameConverter();BufferedImage fecthedImage = converter.getBufferedImage(f);BufferedImage bi = new BufferedImage(width, height, BufferedImage.TYPE_3BYTE_BGR);// 缩略图流bi.getGraphics().drawImage(fecthedImage.getScaledInstance(width, height, Image.SCALE_SMOOTH),0, 0, null);//创建一个空字节输出流ByteArrayOutputStream out1 = new ByteArrayOutputStream();InputStream in = null;// 将缩略图流转为.jpg后缀的图片boolean jpg = ImageIO.write(bi, "jpg", out1);// .jpg后缀的图片转换成输入流in = new ByteArrayInputStream(out1.toByteArray());// 上传缩略图到 minio并命名BladeFile bladeFile = ossBuilder.template().putFile(fileName, in);// 将缩略图更新到表 admin_archive_media_video中archiveVideoFile.setThumbLink(bladeFile.getLink());archiveList.add(archiveVideoFile);// 删除临时文件以及目录} catch (Exception e) {e.printStackTrace();System.out.println("ImgBase64Util fetchFrame() error.");} finally {ff.stop();ff.close();}}boolean result = this.saveOrUpdateBatch(archiveList);return result;}
}
- 问题
(1)Could not initialize class org.bytedeco.javacpp.avutil
原因:引入的依赖包之间不匹配(最开始引入的javac版本是1.4.1)
参考:https://blog.csdn.net/weixin_42534940/article/details/84673956
(2)java.io.FileNotFoundException(拒绝访问)
原因:找不到目标路径,是要具体到文件名称。
参考:参考1 和 参考2
(3)OpenJDK 64-Bit Server VM warning: Sharing is only supported for boot loader classes because bootstrap classpath has been appended
现象:启动项目时报错
方法:在顶部栏里选择File → Settings… → 输入async+回车 → 把图中的勾选的√去掉 → 保存
(4)获取字符串
例如:test.mp4
需求:获取test
方法:String substring = name().substring(0, name.indexOf(“.”));
参考:https://www.php1.cn/detail/java_ZiFuChuanJi_107d53e8.html
(5)生成视频缩略图,如果使用临时存储在本地的方法,那么需要考虑如何删除临时文件。而使用空字节输出流不会有这个问题。