Java|Java 截取视频资料中的某一帧作为缩略图

目录

  • 基础知识
    • FFmpegFrameGrabber
    • BufferedImage,ImageIO
    • 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文件上传实例并解决跨域问题


具体实现

引入依赖

本功能使用的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-presetsartoolkitplusorg.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 */publicString 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; }

【Java|Java 截取视频资料中的某一帧作为缩略图】到此这篇关于Java 截取视频资料中的某一帧作为缩略图的文章就介绍到这了,更多相关Java 视频缩略图内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

    推荐阅读