java生成视频缩略图
java生成视频缩略图
需要给前端返回视频的缩略图链接,本来使用的是阿里云的OSS,它提供了缩略图功能的,但是最近换成了Minio....就只有自己写了;
要求:返回给前端一个连接,缩略图实时生成,不会保存.
使用javacv包
流程: 先从Minio中读取视频,然后使用javacv获取某一帧的图,最后使用thumbnailator将图片压缩
但是,视频几十上百M的时候很慢,大视频1分钟都出不来_(:з」∠)_
若是缩略图会保存起来,使用的时候直接读取缩略图的话,这个方案还可以,但是实时读取就不行了
<dependency>
<groupId>org.bytedeco</groupId>
<artifactId>javacv-platform</artifactId>
<version>1.5.4</version>
</dependency>
使用
public void getViewResize(GlobalAccessoryFile accessory) throws Exception {
// 获取Minio服务
MinioClient client = this.getOSSClient();
//从服务器获取图片
InputStream inputStream = client.getObject(GetObjectArgs.builder()
.bucket(ossCfg.bucketName) //桶
.object(accessory.getFileDirectoryPath()) //图片在桶内位置
.build());
FFmpegFrameGrabber grabber;
InputStream img = null;
try {
grabber = new FFmpegFrameGrabber(inputStream,0);
grabber.start();
// 视频总帧数
int videoLength = grabber.getLengthInFrames();
Frame frame = null;
int i = 0;
while (i < videoLength) {
// 过滤前5帧,因为前5帧可能是全黑的
frame = grabber.grabFrame();
if (i>5&&frame.image != null) {
break;
}
i++;
}
Java2DFrameConverter converter = new Java2DFrameConverter();
// 绘制图片
BufferedImage bi = converter.getBufferedImage(frame);
img = bufferedImageToInputStream(bi);
grabber.stop();
grabber.close();
} catch (IOException e) {
e.printStackTrace();
}
HttpServletResponse response = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getResponse();
response.setContentType("multipart/form-data");
int h = accessory.getTHeight() != null ? accessory.getTHeight() : 200;
Thumbnails.Builder<? extends InputStream> tb = Thumbnails.of(img).height(h);
if (accessory.getTWidth() != null) {
tb.width(accessory.getTWidth());
}
tb.toOutputStream(response.getOutputStream());
}
/**
* 将BufferedImage转换为InputStream
*
* @param image
* @return
*/
public static InputStream bufferedImageToInputStream(BufferedImage image) {
ByteArrayOutputStream os = new ByteArrayOutputStream();
try {
ImageIO.write(image, "png", os);
InputStream input = new ByteArrayInputStream(os.toByteArray());
return input;
} catch (IOException e) {
}
return null;
}
vidio查看--失败了
本来用这种方法,看着没有加载视频以为是成功了,后来发现,是之前浏览器缓存了,强制刷新之后还是会加载整个视频_(:з」∠)_
直接返回给前端查看视频的链接,前端使用这个连接显示缩略图
比如我的视频链接是 http://192.168.3.179:9111/achieve8321280.mov?X-Amz-Algorithm=Aac6f7a9e6a34
前端需要缩略图展示的时候(这样会自动展示缩略图,并且没有操作按钮)
<video height="200px" width="200" src="http://192.168.3.179:9111/achieve8321280.mov?X-Amz-Algorithm=Aac6f7a9e6a34"/>
前端需要播放视频的时候
<video controls height="800px" width="1000" style="outline: none;width:100%" autoplay src="http://192.168.3.179:9111/achieve8321280.mov?X-Amz-Algorithm=Aac6f7a9e6a34"/>
前端下载
<a href="http://192.168.3.179:9111/achieve8321280.mov?X-Amz-Algorithm=Aac6f7a9e6a34" download="achieve8321280.mov">视频下载</a>