package com.lijinke.screenshots.util;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.ArrayList;
import javax.imageio.ImageIO;
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;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.lijinke.screenshots.util.entity.VideoInfo;
import it.sauronsoftware.jave.Encoder;
import it.sauronsoftware.jave.EncoderException;
import it.sauronsoftware.jave.InputFormatException;
import it.sauronsoftware.jave.MultimediaInfo;
public class VideoUtil3 {
private static final Logger log = LoggerFactory.getLogger(VideoUtil3.class);
private static final String IMAGEMAT = "jpg";
public static void main(String[] args) throws IOException {
getVideoInfo("D:/HTHT/8.8/aa.mp4");
// makePicByFrame("D:/HTHT/8.8/aa.mp4",
// "d://HTHT/8.8/picture/", 160);
//makePicBySecond("D:/Data/javacvtest/video/3.mp4", "d://Data/javacvtest/picture/picture3.jpg", 160);
//makePicBySecond("D:/HTHT/8.8/aa.mp4", "d://HTHT/8.8/picture/", 4);
}
/**
* 根据时间(秒)截取视频图片
*
* @param filePath
* @param targetPath
* @param i
* @throws IOException
*/
public static void makePicBySecond(String filePath, String targetPath, int i) throws IOException {
/*
* String picName = new String(); int index = targetPath.lastIndexOf(".");
* String prefix = targetPath.substring(0, index); String temTargetPath = prefix
* + "_" + i + "." + IMAGEMAT; picName = temTargetPath;
*/
File folder = new File(targetPath);
if (!folder.exists()) {
folder.mkdirs();// 如果文件夹不存在则创建
}
try {
//FFmpegFrameGrabber grabber = new FFmpegFrameGrabber(targetPath + File.separator + filePath);
FFmpegFrameGrabber ff = new FFmpegFrameGrabber(filePath);
ff.start();
long ftp = ff.getLengthInFrames();
int flag = 0;
int sum = 0;
Frame frame = null;
int count = (int) Math.round(ff.getFrameRate());
while (flag <= ftp) {
if (count < ftp && count > flag) {
flag++;
continue;
} else if (count > ftp) {
break;
} else {
count += (int) Math.round(ff.getFrameRate());
}
sum++;
// 获取帧跳帧
ff.setFrameNumber(count);
frame = ff.grabImage();
// 过滤前 second 帧,避免出现全黑图片
/*
* if ((flag>second)&&(frame != null)) { break; }
*/
if (sum == i) {
// 创建BufferedImage对象
//Java2DFrameConverter converter = new Java2DFrameConverter();
//BufferedImage bufferedImage = converter.getBufferedImage(frame);
String newFileName = targetPath + sum + "." + IMAGEMAT;
makePicFormFrame(frame, newFileName);
flag += (int) Math.round(ff.getFrameRate());
break;
}
}
ff.close();
ff.stop();
} catch (Exception e) {
System.out.printf("获取视频图片失败!", e);
}
}
/**
* 根据帧数截取视频图片
*
* @param filePath
* @param targetPath
* @param i
* @throws Exception
*/
public static void makePicByFrame(String filePath, String targetPath, int i) throws Exception {
//String picName = new String();
//int index = targetPath.lastIndexOf(".");
//String prefix = targetPath.substring(0, index);
//String temTargetPath = prefix + "_" + i + "." + IMAGEMAT;
//picName = temTargetPath;
File folder = new File(targetPath);
if (!folder.exists()) {
folder.mkdirs();// 如果文件夹不存在则创建
}
FFmpegFrameGrabber ff = FFmpegFrameGrabber.createDefault(filePath);
ff.start();
double ffLength = getDivideValue(ff.getLengthInTime(), 1000000);
log.info(" 视频时长:" + ffLength);
int frameLength = ff.getLengthInFrames();
for (int j = 0; j < frameLength; j++) {
if (j == i) {
ff.setFrameNumber(i);
Frame f = ff.grabImage();
OpenCVFrameConverter.ToIplImage converter = new OpenCVFrameConverter.ToIplImage();
IplImage src = converter.convert(f);
f = converter.convert(src);
String newFileName = targetPath + i + "." + IMAGEMAT;
makePicFormFrame(f, newFileName);
}
}
ff.stop();
}
/**
* 生成缩略图 生成原图
*
* @param f 视频文件
* @param targetPath 输出路径
*/
private static void makePicFormFrame(Frame f, String targetPath) {
if (null == f || null == f.image) {
return;
}
System.out.println("文件输出路径及文件名" + targetPath);
Java2DFrameConverter converter = new Java2DFrameConverter();
BufferedImage bi = converter.getBufferedImage(f);
BufferedImage newbi = scaleImage(bi, 800, 800, IMAGEMAT);
File output = new File(targetPath);
try {
ImageIO.write(newbi, IMAGEMAT, output);
} catch (IOException e) {
log.error("生成缩略图失败", e);
}
}
/**
* 根据比例处理图片
*
*/
private static BufferedImage scaleImage(BufferedImage bufferedImage, int width, int height, String format) {
ArrayList<Integer> paramsArrayList = getAutoWidthAndHeight(bufferedImage, width, height);
width = paramsArrayList.get(0);
height = paramsArrayList.get(1);
log.info("自动调整比例,width=" + width + " height=" + height);
Image image = bufferedImage.getScaledInstance(width, height, Image.SCALE_DEFAULT);
BufferedImage outputImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
Graphics graphics = outputImage.getGraphics();
graphics.drawImage(image, 0, 0, null);
graphics.dispose();
return outputImage;
}
/***
* @param bufferedImage 要缩放的图片对象
* @param widthScale 要缩放到的宽度
* @param heightScale 要缩放到的高度
* @return 一个集合,第一个元素为宽度,第二个元素为高度
*
*/
private static ArrayList<Integer> getAutoWidthAndHeight(BufferedImage bufferedImage, int widthScale,
int heightScale) {
ArrayList<Integer> arrayList = new ArrayList<Integer>();
int width = bufferedImage.getWidth();
int height = bufferedImage.getHeight();
double scaleW = getDivideValue(widthScale, width);
double scaleH = getDivideValue(heightScale, height);
if (scaleW < scaleH) {
arrayList.add(parseDoubleToInt(scaleW * width));
arrayList.add(parseDoubleToInt(scaleW * height));
} else {
arrayList.add(parseDoubleToInt(scaleH * width));
arrayList.add(parseDoubleToInt(scaleH * height));
}
return arrayList;
}
/**
* 将double类型的数据转换为int
*
*/
private static int parseDoubleToInt(double sourceDouble) {
return (int) sourceDouble;
}
/**
* 获取视频信息并返回
*
* @param filePath
* @return
*/
public static VideoInfo getVideoInfo(String filePath) {
VideoInfo videoInfo = new VideoInfo();
try {
File file = new File(filePath);
Encoder encoder = new Encoder();
MultimediaInfo m;
m = encoder.getInfo(file);
long millisecond = m.getDuration();// 毫秒数
int totalLen = 0;
totalLen += millisecond;
long fileSize = file.length();// 字节
double MB = fileSize / (1024 * 1024 * 1.0);
FFmpegFrameGrabber ff;
ff = FFmpegFrameGrabber.createDefault(filePath);
ff.start();
// 读取视频帧数
int lengthInVideoFrames = ff.getLengthInVideoFrames();
System.out.println("视频帧数" + lengthInVideoFrames);
videoInfo.setLengthInVideoFrames(lengthInVideoFrames);
// 读取视频帧率
double videoFrameRate = ff.getVideoFrameRate();
System.out.println("视频帧率" + videoFrameRate);
videoInfo.setVideoFrameRate(videoFrameRate);
// 读取视频宽度
int imageWidth = ff.getImageWidth();
System.out.println("视频宽度" + imageWidth);
videoInfo.setImageWidth(imageWidth);
// 读取视频高度
int imageHeight = ff.getImageHeight();
System.out.println("视频高度" + imageHeight);
videoInfo.setImageHeight(imageHeight);
// 视频格式
String format = ff.getFormat();
System.out.println("视频格式" + format);
videoInfo.setFormat(format);
// 获取视频时长, / 1000000 将单位转换为秒
long lengthInSecond = ff.getLengthInTime() / 1000000;
System.out.println("视频秒数" + lengthInSecond);
videoInfo.setLengthInSecond(lengthInSecond);
// 获取视频时长
int hour = (int) millisecond / (60 * 60 * 1000);// 小时
int minute = (int) (millisecond % (60 * 60 * 1000)) / 60000;// 分钟
int second = (int) ((millisecond % (60 * 60 * 1000)) % 60000) / 1000;// 秒
String lengthInTime = hour + ":" + minute + ":" + second;
System.out.println("视频时长" + lengthInTime);
videoInfo.setLengthInTime(lengthInTime);
// 获取视频名称
String videoName = file.getName();
System.out.println("视频文件名称:" + videoName);
videoInfo.setVideoName(videoName);
// 获取视频大小
String videoSize = String.valueOf(MB) + String.valueOf(fileSize);
System.out.printf("视频大小" + "%.2f MB(%d字节)\n", MB, fileSize);
videoInfo.setVideoSize(videoSize);
ff.stop();
} catch (Exception e) {
e.printStackTrace();
} catch (InputFormatException e) {
e.printStackTrace();
} catch (EncoderException e) {
e.printStackTrace();
}
return videoInfo;
}
/**
* 打印视频信息
*
* @param filePath
*/
public static void printVideoInfo(String filePath) {
try {
File file = new File(filePath);
Encoder encoder = new Encoder();
MultimediaInfo m;
m = encoder.getInfo(file);
long millisecond = m.getDuration();// 毫秒数
int totalLen = 0;
totalLen += millisecond;
long fileSize = file.length();// 字节
Double MB = fileSize / (1024 * 1024 * 1.0);
FFmpegFrameGrabber ff;
ff = FFmpegFrameGrabber.createDefault(filePath);
ff.start();
// 读取视频帧数
System.out.println("视频帧数" + ff.getLengthInVideoFrames());
// 读取视频帧率
System.out.println("视频帧率" + ff.getVideoFrameRate());
// 读取视频宽度
System.out.println("视频宽度" + ff.getImageWidth());
// 读取视频高度
System.out.println("视频高度" + ff.getImageHeight());
// 视频格式
System.out.println("视频格式" + ff.getFormat());
// 获取视频秒数,
System.out.println("视频秒数" + ff.getLengthInTime() / 1000000);
// 获取视频时长
int hour = (int) millisecond / (60 * 60 * 1000);// 小时
int minute = (int) (millisecond % (60 * 60 * 1000)) / 60000;// 分钟
int second = (int) ((millisecond % (60 * 60 * 1000)) % 60000) / 1000;// 秒
System.out.println("视频时长" + hour + ":" + minute + ":" + second + " ");
// 获取视频名称
System.out.println("视频文件名称:" + file.getName());
// 获取视频大小
System.out.printf("视频大小" + "%.2f MB(%d字节)\n", MB, fileSize);
ff.stop();
} catch (Exception e) {
e.printStackTrace();
} catch (InputFormatException e) {
e.printStackTrace();
} catch (EncoderException e) {
e.printStackTrace();
}
}
/**
* 获取视频时长 获取两数相除的结果,保留两位小数
*
*/
public static double getDivideValue(long num1, long num2) {
BigDecimal bigDecimal1 = new BigDecimal(num1);
BigDecimal bigDecimal2 = new BigDecimal(num2);
BigDecimal result = bigDecimal1.divide(bigDecimal2, 2, BigDecimal.ROUND_HALF_UP);// 第一个参数是除数,第二个参数代表保留几位小数,第三个代表的是使用的模式。
return result.doubleValue();
}
/**
* 每隔一秒截取视频帧数
*
* @param filePath 路径
* @param fileName 文件名称
* @param second 暂且为空
* @throws IOException
*/
private static void getImage(String filePath, String targetPath, int i) throws IOException {
File folder = new File(targetPath);
if (!folder.exists()) {
folder.mkdirs();// 如果文件夹不存在则创建
}
try {
//FFmpegFrameGrabber grabber = new FFmpegFrameGrabber(targetPath + File.separator + filePath);
FFmpegFrameGrabber grabber = new FFmpegFrameGrabber(filePath);
grabber.start();
long ftp = grabber.getLengthInFrames();
int flag = 0;
int sum = 0;
Frame frame = null;
int count = (int) Math.round(grabber.getFrameRate());
while (flag <= ftp) {
if (count < ftp && count > flag) {
flag++;
continue;
} else if (count > ftp) {
break;
} else {
count += (int) Math.round(grabber.getFrameRate());
}
sum++;
// 获取帧跳帧
grabber.setFrameNumber(count);
frame = grabber.grabImage();
// 过滤前 second 帧,避免出现全黑图片
/*
* if ((flag>second)&&(frame != null)) { break; }
*/
if (sum == i) {
String rotate = grabber.getVideoMetadata("rotate");
// 创建BufferedImage对象
Java2DFrameConverter converter = new Java2DFrameConverter();
BufferedImage bufferedImage = converter.getBufferedImage(frame);
String newFileName = targetPath + sum + ".jpeg";
ImageIO.write(bufferedImage, "jpeg", new File(newFileName));
flag += (int) Math.round(grabber.getFrameRate());
break;
}
}
grabber.close();
grabber.stop();
} catch (Exception e) {
System.out.printf("获取视频图片失败!", e);
}
}
}
实体类
package com.lijinke.screenshots.util.entity;
public class VideoInfo {
// 读取视频帧数
private Integer lengthInVideoFrames;
// 读取视频帧率
private double videoFrameRate;
// 读取视频宽度
private Integer imageWidth;
// 读取视频高度
private Integer imageHeight;
// 视频格式
private String format;
// 获取视频秒数
private long lengthInSecond;
private String lengthInTime;
private String videoName;
private String videoSize;
public VideoInfo() {
super();
}
public VideoInfo(Integer lengthInVideoFrames, double videoFrameRate, Integer imageWidth, Integer imageHeight,
String format, long lengthInSecond, String lengthInTime, String videoName, String videoSize) {
super();
this.lengthInVideoFrames = lengthInVideoFrames;
this.videoFrameRate = videoFrameRate;
this.imageWidth = imageWidth;
this.imageHeight = imageHeight;
this.format = format;
this.lengthInSecond = lengthInSecond;
this.lengthInTime = lengthInTime;
this.videoName = videoName;
this.videoSize = videoSize;
}
public Integer getLengthInVideoFrames() {
return lengthInVideoFrames;
}
public void setLengthInVideoFrames(Integer lengthInVideoFrames) {
this.lengthInVideoFrames = lengthInVideoFrames;
}
public double getVideoFrameRate() {
return videoFrameRate;
}
public void setVideoFrameRate(double videoFrameRate) {
this.videoFrameRate = videoFrameRate;
}
public Integer getImageWidth() {
return imageWidth;
}
public void setImageWidth(Integer imageWidth) {
this.imageWidth = imageWidth;
}
public Integer getImageHeight() {
return imageHeight;
}
public void setImageHeight(Integer imageHeight) {
this.imageHeight = imageHeight;
}
public String getFormat() {
return format;
}
public void setFormat(String format) {
this.format = format;
}
public long getLengthInSecond() {
return lengthInSecond;
}
public void setLengthInSecond(long lengthInSecond) {
this.lengthInSecond = lengthInSecond;
}
public String getLengthInTime() {
return lengthInTime;
}
public void setLengthInTime(String lengthInTime) {
this.lengthInTime = lengthInTime;
}
public String getVideoName() {
return videoName;
}
public void setVideoName(String videoName) {
this.videoName = videoName;
}
public String getVideoSize() {
return videoSize;
}
public void setVideoSize(String videoSize) {
this.videoSize = videoSize;
}
}