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.bytedecojavacv1.4.4org.bytedecojavacpporg.bytedeco.javacpp-presetsflycaptureorg.bytedeco.javacpp-presetslibdc1394org.bytedeco.javacpp-presetslibfreenectorg.bytedeco.javacpp-presetslibfreenect2org.bytedeco.javacpp-presetslibrealsenseorg.bytedeco.javacpp-presetsvideoinputorg.bytedeco.javacpp-presetsopencvorg.bytedeco.javacpp-presetstesseractorg.bytedeco.javacpp-presetsleptonicaorg.bytedeco.javacpp-presetsflandmarkorg.bytedeco.javacpp-presetsartoolkitplus

org.bytedecojavacv-platform1.4.4org.bytedecojavacvorg.bytedeco.javacpp-presetsflycapture-platformorg.bytedeco.javacpp-presetslibdc1394-platformorg.bytedeco.javacpp-presetslibfreenect-platformorg.bytedeco.javacpp-presetslibfreenect2-platformorg.bytedeco.javacpp-presetslibrealsense-platformorg.bytedeco.javacpp-presetsvideoinput-platformorg.bytedeco.javacpp-presetsopencv-platformorg.bytedeco.javacpp-presetstesseract-platformorg.bytedeco.javacpp-presetsleptonica-platformorg.bytedeco.javacpp-presetsflandmark-platformorg.bytedeco.javacpp-presetsartoolkitplus-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;
}

如果本篇博客对您有一定的帮助,大家记得留言+点赞+收藏哦。


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部