转载大佬文章,以备后期再次需要,亲测使用有效
添加依赖
在pom.xml中添加依赖配置
org.bytedeco
javacv-platform
1.3.1
1、获取视频中间的帧作为缩略图,并返回缩略图实际存放地址
package com.lyz.medis.image;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import javax.imageio.ImageIO;
import org.bytedeco.javacpp.opencv_core;
import org.bytedeco.javacpp.opencv_core.IplImage;
import org.bytedeco.javacv.FFmpegFrameGrabber;
import org.bytedeco.javacv.Frame;
import org.bytedeco.javacv.FrameGrabber.Exception;
import org.bytedeco.javacv.Java2DFrameConverter;
import org.bytedeco.javacv.OpenCVFrameConverter;
/**
* 获取视频缩略图
* @author liuyazhuang
*
*/
public class VideoImage {
private static final String IMAGEMAT = "png";
private static final String ROTATE = "rotate";
/**
* 默认截取视频的中间帧为封面
*/
public static final int MOD = 2;
public static void main(String[] args) throws Exception {
System.out.println(randomGrabberFFmpegImage("C:/lyz/1522372294724_79583.mov", 2));
}
/**
* 获取视频缩略图
* @param filePath:视频路径
* @param mod:视频长度/mod获取第几帧
* @throws Exception
*/
public static String randomGrabberFFmpegImage(String filePath, int mod) throws Exception {
String targetFilePath = "";
FFmpegFrameGrabber ff = FFmpegFrameGrabber.createDefault(filePath);
ff.start();
String rotate = ff.getVideoMetadata(ROTATE);
int ffLength = ff.getLengthInFrames();
Frame f;
int i = 0;
int index = ffLength / mod;
while (i < ffLength) {
f = ff.grabImage();
if(i == index){
if (null != rotate && rotate.length() > 1) {
OpenCVFrameConverter.ToIplImage converter = new OpenCVFrameConverter.ToIplImage();
IplImage src = converter.convert(f);
f = converter.convert(rotate(src, Integer.valueOf(rotate)));
}
targetFilePath = getImagePath(filePath, i);
doExecuteFrame(f, targetFilePath);
break;
}
i++;
}
ff.stop();
return targetFilePath;
}
/**
* 根据视频路径生成缩略图存放路径
* @param filePath:视频路径
* @param index:第几帧
* @return:缩略图的存放路径
*/
private static String getImagePath(String filePath, int index){
if(filePath.contains(".") && filePath.lastIndexOf(".") < filePath.length() - 1){
filePath = filePath.substring(0, filePath.lastIndexOf(".")).concat("_").concat(String.valueOf(index)).concat(".").concat(IMAGEMAT);
}
return filePath;
}
/**
* 旋转图片
* @param src
* @param angle
* @return
*/
public static IplImage rotate(IplImage src, int angle) {
IplImage img = IplImage.create(src.height(), src.width(), src.depth(), src.nChannels());
opencv_core.cvTranspose(src, img);
opencv_core.cvFlip(img, img, angle);
return img;
}
/**
* 截取缩略图
* @param f
* @param targerFilePath:封面图片
*/
public static void doExecuteFrame(Frame f, String targerFilePath) {
if (null == f || null == f.image) {
return;
}
Java2DFrameConverter converter = new Java2DFrameConverter();
BufferedImage bi = converter.getBufferedImage(f);
File output = new File(targerFilePath);
try {
ImageIO.write(bi, IMAGEMAT, output);
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 根据视频长度随机生成随机数集合
* @param baseNum:基础数字,此处为视频长度
* @param length:随机数集合长度
* @return:随机数集合
*/
public static List random(int baseNum, int length) {
List list = new ArrayList(length);
while (list.size() < length) {
Integer next = (int) (Math.random() * baseNum);
if (list.contains(next)) {
continue;
}
list.add(next);
}
Collections.sort(list);
return list;
}
}
2、随机生成多张缩略图,不返回缩略图实际存放地址
package com.lyz.medis.image;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import javax.imageio.ImageIO;
import org.bytedeco.javacpp.opencv_core;
import org.bytedeco.javacpp.opencv_core.IplImage;
import org.bytedeco.javacv.FFmpegFrameGrabber;
import org.bytedeco.javacv.Frame;
import org.bytedeco.javacv.FrameGrabber.Exception;
import org.bytedeco.javacv.Java2DFrameConverter;
import org.bytedeco.javacv.OpenCVFrameConverter;
/**
* 获取图片缩略图
* @author liuyazhuang
*
*/
public abstract class VideoImageFrame {
public static void main(String[] args) throws Exception {
randomGrabberFFmpegImage("e:/lyz/ffmpeg.mp4", "./target", "screenshot", 5);
}
/**
* 生成图片缩略图
* @param filePath:视频完整路径
* @param targerFilePath:缩略图存放目录
* @param targetFileName:缩略图文件名称
* @param randomSize:生成随机数的数量
* @throws Exception
*/
public static void randomGrabberFFmpegImage(String filePath, String targerFilePath, String targetFileName, int randomSize) throws Exception {
FFmpegFrameGrabber ff = FFmpegFrameGrabber.createDefault(filePath);
ff.start();
String rotate = ff.getVideoMetadata("rotate");
int ffLength = ff.getLengthInFrames();
List randomGrab = random(ffLength, randomSize);
int maxRandomGrab = randomGrab.get(randomGrab.size() - 1);
Frame f;
int i = 0;
while (i < ffLength) {
f = ff.grabImage();
if (randomGrab.contains(i)) {
if (null != rotate && rotate.length() > 1) {
OpenCVFrameConverter.ToIplImage converter = new OpenCVFrameConverter.ToIplImage();
IplImage src = converter.convert(f);
f = converter.convert(rotate(src, Integer.valueOf(rotate)));
}
doExecuteFrame(f, targerFilePath, targetFileName, i);
}
if (i >= maxRandomGrab) {
break;
}
i++;
}
ff.stop();
}
/**
* 旋转图片
* @param src:图片
* @param angle:旋转角度
* @return
*/
public static IplImage rotate(IplImage src, int angle) {
IplImage img = IplImage.create(src.height(), src.width(), src.depth(), src.nChannels());
opencv_core.cvTranspose(src, img);
opencv_core.cvFlip(img, img, angle);
return img;
}
/**
* 生成缩略图
* @param f Frame对象
* @param targerFilePath
* @param targetFileName
* @param index
*/
public static void doExecuteFrame(Frame f, String targerFilePath, String targetFileName, int index) {
if (null == f || null == f.image) {
return;
}
Java2DFrameConverter converter = new Java2DFrameConverter();
String imageMat = "png";
String FileName = targerFilePath + File.separator + targetFileName + "_" + index + "." + imageMat;
BufferedImage bi = converter.getBufferedImage(f);
File output = new File(FileName);
try {
ImageIO.write(bi, imageMat, output);
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 随机生成随机数集合
* @param baseNum:随机种子
* @param length:随机数集合长度
* @return:随机数集合
*/
public static List random(int baseNum, int length) {
List list = new ArrayList<>(length);
while (list.size() < length) {
Integer next = (int) (Math.random() * baseNum);
if (list.contains(next)) {
continue;
}
list.add(next);
}
Collections.sort(list);
return list;
}
}