import org.apache.commons.lang3.StringUtils;
import org.bytedeco.ffmpeg.global.avcodec;
import org.bytedeco.ffmpeg.global.avutil;
import org.bytedeco.javacv.FFmpegFrameGrabber;
import org.bytedeco.javacv.FFmpegFrameRecorder;
import org.bytedeco.javacv.Frame;
import org.bytedeco.javacv.Java2DFrameConverter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;
/**
* @author Mr.superbeyone
* @project
* @className FfmpegUtil2
* @description
* @date 2023-10-20 15:15
**/
public class FfmpegUtil2 {
private static Logger logger = LoggerFactory.getLogger(FfmpegUtil2.class);
/**
* 生成标注后的视频文件
*
* @param srcVideoPath 源视频文件路径
* @param frameRate 跳帧请求RPC的步数
* @param extName 生成的文件扩展名 如: mp4 flv
* @return 标注后的视频文件路径
*/
public static String generateTagVideo(String srcVideoPath, int frameRate, String extName) {
return generateTagVideo(srcVideoPath, null, frameRate, extName);
}
public static String generateTagVideo(String srcVideoPath, String targetVideoPath, int frameRate, String extName) {
long start = System.currentTimeMillis();
//视频文件路径
File srcVideoFile = new File(srcVideoPath);
if (!srcVideoFile.exists() || !srcVideoFile.isFile()) {
logger.info("generateTagVideo srcVideoPath is not video file {}", srcVideoPath);
return "";
}
if (StringUtils.isBlank(targetVideoPath)) {
targetVideoPath = srcVideoFile.getParentFile() + File.separator + StringUtils.substringBeforeLast(srcVideoFile.getName(), ".") + "_tag." + extName;
}
String targetVideo = doGenerateTagVideo(srcVideoPath, targetVideoPath, frameRate, extName);
logger.info("generateTagVideo 耗时 {}", (System.currentTimeMillis() - start));
logger.info("generateTagVideo srcVideo {} targetVideo {}", srcVideoPath, targetVideo);
return targetVideo;
}
public static String doGenerateTagVideo(String srcVideoPath, String targetVideoPath, int frameRate, String extName) {
FFmpegFrameGrabber grabber = null;
FFmpegFrameRecorder recorder = null;
try {
grabber = FFmpegFrameGrabber.createDefault(new File(srcVideoPath));
grabber.setFormat(StringUtils.substringAfterLast(srcVideoPath, ".").toLowerCase());
grabber.start();
int imageHeight = grabber.getImageHeight();
int imageWidth = grabber.getImageWidth();
recorder = FFmpegFrameRecorder.createDefault(new File(targetVideoPath), imageWidth, imageHeight);
recorder.setVideoCodec(avcodec.AV_CODEC_ID_H264);
recorder.setPixelFormat(avutil.AV_PIX_FMT_YUV420P);
recorder.setFormat(extName);
recorder.setVideoBitrate(10000);//数值越大,存储空间越大
recorder.setVideoOption("preset", "ultrafast");//究极快
recorder.start();
Java2DFrameConverter converter = new Java2DFrameConverter();
int index = 0, x = 0, y = 0, width = 0, height = 0;
Frame frame;
while ((frame = grabber.grabImage()) != null) {
if (null == frame.image) {
continue;
}
index++;
BufferedImage image = converter.getBufferedImage(frame);
if (frameRate > 0 && index % frameRate == 0) {
Map<String, Integer> location = rpcFindLocation(image);
x = location.get("x");
y = location.get("y");
width = location.get("w");
height = location.get("h");
}
Graphics graphics = image.getGraphics();
graphics.setColor(Color.RED);
graphics.drawRect(x, y, width, height);
Frame drawFrame = converter.convert(image);
recorder.record(drawFrame);
}
recorder.close();
grabber.close();
} catch (Exception e) {
logger.error("doGenerateTagVideo exception ", e);
} finally {
if (grabber != null) {
try {
grabber.close();
} catch (Exception ex) {
logger.error("close grabber error", ex);
}
}
if (recorder != null) {
try {
recorder.close();
} catch (Exception ex) {
logger.error("close recorder error", ex);
}
}
}
return targetVideoPath;
}
/**
* 对图片文件RPC调用
*
* @param image 图片文件
* @return x, y, w, h
*/
private static Map<String, Integer> rpcFindLocation(BufferedImage image) {
Map<String, Integer> location = new HashMap<>(8);
Random random = new Random();
location.put("x", 800 + random.nextInt(100));
location.put("y", 750 + random.nextInt(50));
location.put("w", 50 + random.nextInt(10));
location.put("h", 50 + random.nextInt(10));
return location;
}
public static void main(String[] args) {
long start = System.currentTimeMillis();
String srcPath = "D:\\WorkSpace\\video\\src\\b.mp4";
String destPath = "D:\\WorkSpace\\video\\src\\test\\" + System.currentTimeMillis() + ".flv";
generateTagVideo(srcPath, destPath, 10, "flv");
System.out.println(destPath + "耗时\t" + (System.currentTimeMillis() - start) + "毫秒");
}
}
参考