关于处理视频,谈谈自己的经验。
找到相关的资料,两种最多最常用。一个是ffmpeg工具,安装好了引用即可。这种暂时没尝试,不知道怎么样。那另外一种就是javacv了,关于这个遇到了一些坑,所以有必要总结一下。javacv尝试了两个版本:
1、javacv0.8版本
org.bytedeco
javacv
0.8
先上代码
public String fetchFrame(String videofile, String framefile)
throws Exception {
long start = System.currentTimeMillis();
File targetFile = new File(framefile);
FFmpegFrameGrabber ff = new FFmpegFrameGrabber(videofile);
ff.start();
int lenght = ff.getLengthInFrames();
int i = 0;
Frame f = null;
while (i < lenght) {
// 过滤前1帧,避免出现全黑的图片,依自己情况而定
f = ff.grabFrame();
if ((i > 1) && (f.image != null)) {
break;
}
i++;
}
IplImage img = f.image;
int owidth = img.width();
int oheight = img.height();
// 对截取的帧进行等比例缩放
int width = 800;
int height = (int) (((double) width / owidth) * oheight);
BufferedImage bi = new BufferedImage(width, height, BufferedImage.TYPE_3BYTE_BGR);
bi.getGraphics().drawImage(f.image.getBufferedImage().getScaledInstance(width, height, Image.SCALE_SMOOTH),
0, 0, null);
ImageIO.write(bi, "jpg", targetFile);
//ff.flush();
ff.stop();
System.out.println(System.currentTimeMillis() - start);
return
}
这个是首次尝试获取视频预览图,效果不错,一次成功。但是,还有但是。。。在Linux环境下就不行了,找不到类路径,java.lang.UnsatisfiedLinkError:no jniavcodec in java.library.path,然后具体的报错是NotClassFound这个类FFmpegFrameGrabber。在windows不会出现。然后,怎么办?正式上线可都是Linux系统环境。那就不得不说,接下来的第二种方法了。
2、javacv1.4.1,其实就是升级了
强大到 Android, Linux, MacOS 和 Windows都可以,而且是 x86 和 x64两个版本都有。依赖有所变化:
org.bytedeco
javacpp
1.4.1
org.bytedeco
javacv
1.4.1
org.bytedeco.javacpp-presets
opencv-platform
3.4.1-1.4.1
org.bytedeco.javacpp-presets
ffmpeg-platform
3.4.2-1.4.1
代码:
public String getTempPath() {
String tempPath=" ";//保存的目标路径
File targetFile = new File(tempPath);
if (!targetFile.getParentFile().exists()) {
targetFile.getParentFile().mkdirs();
}
try{
File file2 = new File("/data/photo/tempFile.mp4");
if (file2.exists()) {
log.info("文件存在,路径正确!");
FFmpegFrameGrabber ff = new FFmpegFrameGrabber(file2);
ff.start();
int ftp = ff.getLengthInFrames();
int flag=0;
Frame frame = null;
while (flag <= ftp) {
//获取帧
frame = ff.grabImage();
//过滤前3帧,避免出现全黑图片
if ((flag>3)&&(frame != null)) {
break;
}
flag++;
}
ImageIO.write(FrameToBufferedImage(frame), "jpg", targetFile);
ff.close();
ff.stop();
}
}catch(Exception e){
log.error("获取预览图失败",e)
}
}
private RenderedImage FrameToBufferedImage(Frame frame) {
//创建BufferedImage对象
Java2DFrameConverter converter = new Java2DFrameConverter();
BufferedImage bufferedImage = converter.getBufferedImage(frame);
return bufferedImage;
}
好了,问题解决!
ps:
org.bytedeco.javacpp-presets
opencv-platform
3.4.1-1.4.1
仅仅出图片是可以不要这个的。