Java-截取视频资料中的某一帧作为缩略图
目录
基础知识
JavaCV:功能很强大,封装了很多很视频、图片相关的内容。
FFmpegFrameGrabber
BufferedImage,ImageIO
MultipartFile
具体实现
引入依赖
Java代码
两个文件类型转换的方法Frame->BufferedImage->MultipartFile
如果本篇博客对您有一定的帮助,大家记得留言+点赞+收藏哦。
最近项目中有一个需求,就是要实现视频资料的收藏功能,当时想了想,收藏记录实现并不是很难,但是想展现出视频的缩略图,就要想想其他办法了,所以就想到了截取视频资料中的某一帧作为缩略图,我没有选择截取第一帧,选择的是第五帧,因为第一帧可能没有内容。
基础知识
JavaCV:功能很强大,封装了很多很视频、图片相关的内容。
JavaCV 是一款基于JavaCPP
调用方式(JNI的一层封装),由多种开源计算机视觉库组成的包装库,封装了包含FFmpeg、OpenCV、tensorflow、caffe、tesseract、libdc1394、OpenKinect、videoInput和ARToolKitPlus等在内的计算机视觉领域的常用库和实用程序类。JavaCV基于Apache License Version 2.0协议和GPLv2两种协议 ,
JavaCV支持Windows、Linux、MacOS,Android、IOS在内的Java平台上调用这些接口。
FFmpegFrameGrabber
FFmpegFrameGrabber可以理解为解码器,也可以理解为帧收集器,可以获取视频资料的各种详细信息,时长,宽高,帧等,很强大。
BufferedImage,ImageIO
BufferedImage类是Image的一个子类,是一个带缓冲区图像类,主要作用是将一幅图片加载到内存中。
ImageIO提供read()和write()静态方法,读写照片
将图片加载到内存中
//需要是一个本地文件String imgPath = "C:\Users\Administrator\Videos\999.jpg"; BufferedImage image = ImageIO.read(new FileInputStream(imgPath));
将内存中的图片写到本地
BufferedImage bi=~某个值
File outputfile = new File("save.png");
//参数
// bi:要写入的RenderedImage
// png:格式类型
// outputfile:要写入的OutputStream
ImageIO.write(bi,"png",outputfile);
MultipartFile
MultipartFile在上一篇文章中介绍过了。Java文件上传实例并解决跨域问题https://blog.csdn.net/promsing/article/details/120089365https://blog.csdn.net/promsing/article/details/120089365
具体实现
引入依赖
本功能使用的Jar包是javacv,javacv-platform。因为这个包有150多M,很多依赖项都用不到,所以,将不需要的移除取出。
org.bytedeco javacv 1.4.4 org.bytedeco javacpp org.bytedeco.javacpp-presets flycapture org.bytedeco.javacpp-presets libdc1394 org.bytedeco.javacpp-presets libfreenect org.bytedeco.javacpp-presets libfreenect2 org.bytedeco.javacpp-presets librealsense org.bytedeco.javacpp-presets videoinput org.bytedeco.javacpp-presets opencv org.bytedeco.javacpp-presets tesseract org.bytedeco.javacpp-presets leptonica org.bytedeco.javacpp-presets flandmark org.bytedeco.javacpp-presets artoolkitplus
org.bytedeco javacv-platform 1.4.4 org.bytedeco javacv org.bytedeco.javacpp-presets flycapture-platform org.bytedeco.javacpp-presets libdc1394-platform org.bytedeco.javacpp-presets libfreenect-platform org.bytedeco.javacpp-presets libfreenect2-platform org.bytedeco.javacpp-presets librealsense-platform org.bytedeco.javacpp-presets videoinput-platform org.bytedeco.javacpp-presets opencv-platform org.bytedeco.javacpp-presets tesseract-platform org.bytedeco.javacpp-presets leptonica-platform org.bytedeco.javacpp-presets flandmark-platform org.bytedeco.javacpp-presets artoolkitplus-platform
Java代码
/*** 将视频文件帧处理并以“jpg”格式进行存储。* 依赖FrameToBufferedImage方法:将frame转换为bufferedImage对象* 参数可串本地文件,或者网络文件* @param videoFileName http://d-godone.dmsd.tech/goDone/M00/00/0A/wKg8O2D2mnqEMg7wAAAAALbl5Ys275.mp4*/
public String videoFramer(String videoFileName){//最后获取到的视频的图片的路径String videPicture="";//Frame对象Frame frame = null;//标识int flag = 0;try {/*获取视频文件*/FFmpegFrameGrabber fFmpegFrameGrabber = new FFmpegFrameGrabber( videoFileName);log.info("开始截取视频:");
// av_register_all();//解决报错 avformat_open_input() error -138: Could not open input
// avcodec_register_all();
// 当视频打不开时,会报错fFmpegFrameGrabber.start();//获取视频总帧数int ftp = fFmpegFrameGrabber.getLengthInFrames();log.info("时长 " + ftp / fFmpegFrameGrabber.getFrameRate() / 60);while (flag <= ftp) {//获得每一帧frame = fFmpegFrameGrabber.grabImage();/*对视频的第五帧进行处理*/if (frame != null && flag==5) {//将文件转换BufferedImage bufferedImage = FrameToBufferedImage(frame);//将bufferedImage转换成MultipartFile--方便文件上传MultipartFile multipartFile = fileCase(bufferedImage);log.info("开始文件上传:");//文件上传--上传到FastDFS中,并返回URLString fileLoad = fileLoad(multipartFile);videPicture=fileLoad;log.info("文件上传成功{}",fileLoad);break;}flag++;}fFmpegFrameGrabber.stop();fFmpegFrameGrabber.close();} catch (Exception E) {E.printStackTrace();}return videPicture;
}
两个文件类型转换的方法Frame->BufferedImage->MultipartFile
/*** 文件转换,将Frame转换成BufferedImage* @param frame Frame* @return*/
public static BufferedImage FrameToBufferedImage(Frame frame) {//创建BufferedImage对象Java2DFrameConverter converter = new Java2DFrameConverter();BufferedImage bufferedImage = converter.getBufferedImage(frame);return bufferedImage;
}/*** 文件转换将BufferedImage转换成MultipartFile:为了文件上传* @param image* @return*/
public static MultipartFile fileCase(BufferedImage image){//得到BufferedImage对象// BufferedImage bufferedImage = JoinTwoImage.testEncode(200, 200, url);MultipartFile multipartFile= null;try {//创建一个ByteArrayOutputStreamByteArrayOutputStream os = new ByteArrayOutputStream();//把BufferedImage写入ByteArrayOutputStreamImageIO.write(image, "jpg", os);//ByteArrayOutputStream转成InputStreamInputStream input = new ByteArrayInputStream(os.toByteArray());//InputStream转成MultipartFilemultipartFile =new MockMultipartFile("file", "file.jpg", "text/plain", input);} catch (IOException e) {e.printStackTrace();}return multipartFile;
}
如果本篇博客对您有一定的帮助,大家记得留言+点赞+收藏哦。
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
