现在视频网站展示列表都是用img标签展示的,动图用的是gif,但是我们上传视频时并没有视屏封面,就这需要上传到服务器时自动成功封面并保存
JavaCV 是一款开源的视觉处理库,基于GPLv2协议,对各种常用计算机视觉库封装后的一组jar包,
封装了OpenCV、libdc1394、OpenKinect、videoInput和ARToolKitPlus等计算机视觉编程人员常用库的接口。
此方法的好处是不需要再服务器上安装插件,直接代码中就可以实现视频截取。
我们需要截取视频第一帧,主要用到了ffmpeg和opencv。
目录
一 , 引入jar包
我用到的maven的目前最新javacv版本,1.4.2,它应该支持jdk1.7及以上,我项目用的还是jdk1.8.
不过需要注意的是在使用的过程当中 , maven引入jar的时候 会引入所有平台的版本
全部引入大小在五百兆左右(不建议使用)
<dependency>
<groupId>org.bytedeco</groupId>
<artifactId>javacpp</artifactId>
<version>1.4.1</version>
</dependency>
<dependency>
<groupId>org.bytedeco</groupId>
<artifactId>javacv</artifactId>
<version>1.4.1</version>
</dependency>
<dependency>
<groupId>org.bytedeco.javacpp-presets</groupId>
<artifactId>opencv-platform</artifactId>
<version>3.4.1-1.4.1</version>
</dependency>
<dependency>
<groupId>org.bytedeco.javacpp-presets</groupId>
<artifactId>ffmpeg-platform</artifactId>
<version>3.4.2-1.4.1</version>
</dependency>
修改后的 (适用于windows
<!-- https://mvnrepository.com/artifact/org.bytedeco/javacv -->
<dependency>
<groupId>org.bytedeco</groupId>
<artifactId>javacv</artifactId>
<version>1.4.2</version>
<exclusions>
<exclusion>
<groupId>org.bytedeco.javacpp-presets</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.bytedeco.javacpp-presets</groupId>
<artifactId>opencv</artifactId>
<version>3.4.2-1.4.2</version>
</dependency>
<dependency>
<groupId>org.bytedeco.javacpp-presets</groupId>
<artifactId>opencv</artifactId>
<version>3.4.2-1.4.2</version>
<classifier>windows-x86_64</classifier>
</dependency>
<!-- https://mvnrepository.com/artifact/org.bytedeco.javacpp-presets/ffmpeg -->
<dependency>
<groupId>org.bytedeco.javacpp-presets</groupId>
<artifactId>ffmpeg</artifactId>
<version>4.0.1-1.4.2</version>
</dependency>
<dependency>
<groupId>org.bytedeco.javacpp-presets</groupId>
<artifactId>ffmpeg</artifactId>
<version>4.0.1-1.4.2</version>
<classifier>windows-x86_64</classifier>
</dependency>
鉴于该项功能不仅仅应用于windows 所以还有其他各种系统可供选择
只需要改东西啊pom即可
<javacpp.platform.android-arm>android-arm</javacpp.platform.android-arm> | |
<javacpp.platform.android-arm64>android-arm64</javacpp.platform.android-arm64> | |
<javacpp.platform.android-x86>android-x86</javacpp.platform.android-x86> | |
<javacpp.platform.android-x86_64>android-x86_64</javacpp.platform.android-x86_64> | |
<javacpp.platform.ios-arm>ios-arm</javacpp.platform.ios-arm> | |
<javacpp.platform.ios-arm64>ios-arm64</javacpp.platform.ios-arm64> | |
<javacpp.platform.ios-x86>ios-x86</javacpp.platform.ios-x86> | |
<javacpp.platform.ios-x86_64>ios-x86_64</javacpp.platform.ios-x86_64> | |
<javacpp.platform.linux-armhf>linux-armhf</javacpp.platform.linux-armhf> | |
<javacpp.platform.linux-arm64>linux-arm64</javacpp.platform.linux-arm64> | |
<javacpp.platform.linux-ppc64le>linux-ppc64le</javacpp.platform.linux-ppc64le> | |
<javacpp.platform.linux-x86>linux-x86</javacpp.platform.linux-x86> | |
<javacpp.platform.linux-x86_64>linux-x86_64</javacpp.platform.linux-x86_64> | |
<javacpp.platform.macosx-x86_64>macosx-x86_64</javacpp.platform.macosx-x86_64> | |
<javacpp.platform.windows-x86>windows-x86</javacpp.platform.windows-x86> | |
<javacpp.platform.windows-x86_64>windows-x86_64</javacpp.platform.windows-x86_64> |
二 , java 代码实现
import org.bytedeco.javacv.FFmpegFrameGrabber;
import org.bytedeco.javacv.Frame;
import org.bytedeco.javacv.Java2DFrameConverter;
import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
// 以上为引入的包
// 以下为截取缩略图的方法
//参数:视频路径和缩略图保存路径
public static void fetchFrame(String videofile, String framefile)
throws Exception {
long start = System.currentTimeMillis();
File targetFile = new File(framefile);
FFmpegFrameGrabber ff = new FFmpegFrameGrabber(videofile);
ff.start();
int length = ff.getLengthInFrames();
int i = 0;
Frame f = null;
while (i < length) {
// 去掉前5帧,避免出现全黑的图片,依自己情况而定
f = ff.grabImage();
if ((i > 5) && (f.image != null)) {
break;
}
i++;
}
ImageIO.write(FrameToBufferedImage(f), "jpg", targetFile);
//ff.flush();
ff.stop();
System.out.println(System.currentTimeMillis() - start);
}
public static BufferedImage FrameToBufferedImage(Frame frame) {
//创建BufferedImage对象
Java2DFrameConverter converter = new Java2DFrameConverter();
BufferedImage bufferedImage = converter.getBufferedImage(frame);
return bufferedImage;
}