|
@@ -1,360 +0,0 @@
|
|
|
-package com.face.video;
|
|
|
-
|
|
|
-
|
|
|
-import com.iden.common.util.DateUtils;
|
|
|
-import net.bramp.ffmpeg.FFmpeg;
|
|
|
-import net.bramp.ffmpeg.FFmpegExecutor;
|
|
|
-import net.bramp.ffmpeg.FFprobe;
|
|
|
-import net.bramp.ffmpeg.builder.FFmpegBuilder;
|
|
|
-import org.bytedeco.javacpp.avcodec;
|
|
|
-import org.bytedeco.javacv.*;
|
|
|
-import org.bytedeco.javacv.Frame;
|
|
|
-import org.slf4j.Logger;
|
|
|
-import org.slf4j.LoggerFactory;
|
|
|
-
|
|
|
-import javax.imageio.ImageIO;
|
|
|
-import javax.swing.*;
|
|
|
-import java.awt.*;
|
|
|
-import java.awt.image.BufferedImage;
|
|
|
-import java.io.File;
|
|
|
-import java.util.ArrayList;
|
|
|
-import java.util.Date;
|
|
|
-import java.util.List;
|
|
|
-import java.util.UUID;
|
|
|
-
|
|
|
-
|
|
|
-/**
|
|
|
- * 视频工具
|
|
|
- *
|
|
|
- * @author
|
|
|
- */
|
|
|
-public class VideoTest {
|
|
|
-
|
|
|
- private static final int SECOND = 50;
|
|
|
-
|
|
|
- private static final Logger logger = LoggerFactory.getLogger(VideoTest.class);
|
|
|
-
|
|
|
- /**
|
|
|
- * 获取指定视频的帧并保存为图片至指定目录
|
|
|
- *
|
|
|
- * @param videoFile 源视频文件
|
|
|
- * @param saveFile 截取帧的图片存放路径
|
|
|
- * @throws Exception
|
|
|
- */
|
|
|
- public static List<File> fetchPic(File videoFile, String saveFile, int second) throws Exception {
|
|
|
-
|
|
|
- List<File> files = new ArrayList<>();
|
|
|
-
|
|
|
- FFmpegFrameGrabber ff = new FFmpegFrameGrabber(videoFile);
|
|
|
- ff.start();
|
|
|
- int lenght = ff.getLengthInAudioFrames();
|
|
|
- System.out.println(ff.getFrameRate());
|
|
|
-
|
|
|
- int i = 0;
|
|
|
- Frame frame = null;
|
|
|
-
|
|
|
- while (i < lenght) {
|
|
|
- // 过滤前5帧,避免出现全黑的图片,依自己情况而定
|
|
|
- frame = ff.grabImage();
|
|
|
- if (i >= (int) (ff.getFrameRate() * second) && frame.image != null) {
|
|
|
- System.out.print(i + ",");
|
|
|
- if (frame != null && frame.image != null) {
|
|
|
- System.out.println(i);
|
|
|
- String fileName = String.valueOf(System.currentTimeMillis()) + i;
|
|
|
- files.add(writeToFile(frame, saveFile, fileName));
|
|
|
- }
|
|
|
- second++;
|
|
|
- }
|
|
|
- i += second;
|
|
|
- }
|
|
|
- ff.stop();
|
|
|
- return files;
|
|
|
- }
|
|
|
-
|
|
|
- private static List<Integer> getList(int count, int length) {
|
|
|
- if (count > length) {
|
|
|
- count = length;
|
|
|
- }
|
|
|
-// System.out.println(length);
|
|
|
-// System.out.println(count);
|
|
|
- int total = (int) (length / count);
|
|
|
- List<Integer> list = new ArrayList<>();
|
|
|
- for (int i = 0; i < count; i++) {
|
|
|
- list.add(i * total);
|
|
|
- System.out.println(i * total);
|
|
|
- }
|
|
|
- return list;
|
|
|
- }
|
|
|
-
|
|
|
- public static List<File> fetchPicByCount(File videoFile, String saveDir, int count) throws Exception {
|
|
|
-
|
|
|
- List<File> files = new ArrayList<>();
|
|
|
-
|
|
|
- FFmpegFrameGrabber ff = new FFmpegFrameGrabber(videoFile);
|
|
|
- ff.start();
|
|
|
-
|
|
|
- // 此视频时长(s/秒)
|
|
|
- Long duration = ff.getLengthInTime() / (1000 * 1000);
|
|
|
- System.out.println("duration==" + duration);
|
|
|
- // 视频总帧数
|
|
|
- int frameLength = ff.getLengthInFrames();
|
|
|
-
|
|
|
- System.out.println("length==" + frameLength);
|
|
|
-
|
|
|
- List<Integer> list = getList(count, frameLength);
|
|
|
-
|
|
|
- System.out.println("ff.getFrameRate() == " + ff.getFrameRate());
|
|
|
-
|
|
|
- int i = 0;
|
|
|
- Frame frame = null;
|
|
|
-
|
|
|
- while (i < frameLength) {
|
|
|
- frame = ff.grabImage();
|
|
|
- if (list.contains(i)) {
|
|
|
- if (frame != null && frame.image != null) {
|
|
|
- System.out.println(i);
|
|
|
- String fileName = String.valueOf(System.currentTimeMillis()) + i;
|
|
|
- files.add(writeToFile(frame, saveDir, fileName));
|
|
|
- }
|
|
|
- }
|
|
|
- i++;
|
|
|
- }
|
|
|
- ff.stop();
|
|
|
- return files;
|
|
|
- }
|
|
|
-
|
|
|
- public static Long fetchAllPic(File videoFile, String saveDir, Date shootEndTime) throws Exception {
|
|
|
-
|
|
|
- Long endTime = shootEndTime.getTime() ;
|
|
|
-
|
|
|
- List<File> files = new ArrayList<>();
|
|
|
-
|
|
|
- FFmpegFrameGrabber ff = new FFmpegFrameGrabber(videoFile);
|
|
|
- ff.start();
|
|
|
-
|
|
|
- // 此视频时长(ms/毫秒秒)
|
|
|
- Long duration = ff.getLengthInTime() / 1000;
|
|
|
- System.out.println("duration==" + duration);
|
|
|
-
|
|
|
- Long beginTime = endTime - duration;
|
|
|
-
|
|
|
- // 视频总帧数
|
|
|
- int frameLength = ff.getLengthInFrames();
|
|
|
-
|
|
|
- System.out.println("length==" + frameLength);
|
|
|
-
|
|
|
- //帧率(1秒多少帧)
|
|
|
- double framRate = ff.getFrameRate();
|
|
|
-
|
|
|
- int i = 0;
|
|
|
- Frame frame = null;
|
|
|
-
|
|
|
- while (i < frameLength) {
|
|
|
- frame = ff.grabImage();
|
|
|
- if (frame != null && frame.image != null) {
|
|
|
- Double time = beginTime + (i * (1000/framRate));
|
|
|
- String fileName = DateUtils.formatToDateStr(new Date(time.longValue()),"yyyyMMddHHmmss") + "_" + UUID.randomUUID().toString();
|
|
|
- files.add(writeToFile(frame, saveDir, fileName));
|
|
|
- }
|
|
|
- i++;
|
|
|
- }
|
|
|
- ff.stop();
|
|
|
- return duration;
|
|
|
- }
|
|
|
-
|
|
|
- private static File writeToFile(Frame frame, String saveDir, String fileName) throws Exception {
|
|
|
- File saveDirFile = new File(saveDir);
|
|
|
- if(!saveDirFile.exists()) {
|
|
|
- saveDirFile.mkdirs();
|
|
|
- }
|
|
|
- File targetFile = new File(saveDir + File.separator + fileName + ".jpg");
|
|
|
- String imgSuffix = "jpg";
|
|
|
-
|
|
|
- Java2DFrameConverter converter = new Java2DFrameConverter();
|
|
|
- BufferedImage srcBi = converter.getBufferedImage(frame);
|
|
|
- int owidth = srcBi.getWidth();
|
|
|
- int oheight = srcBi.getHeight();
|
|
|
- // 对截取的帧进行等比例缩放
|
|
|
- int width = 800;
|
|
|
- int height = (int) (((double) width / owidth) * oheight);
|
|
|
- BufferedImage bi = new BufferedImage(width, height, BufferedImage.TYPE_3BYTE_BGR);
|
|
|
- bi.getGraphics().drawImage(srcBi.getScaledInstance(width, height, Image.SCALE_SMOOTH), 0, 0, null);
|
|
|
- try {
|
|
|
- ImageIO.write(bi, imgSuffix, targetFile);
|
|
|
- } catch (Exception e) {
|
|
|
- throw new Exception( "截帧失败");
|
|
|
- }
|
|
|
- return targetFile;
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- /**
|
|
|
- * 获取视频时长,单位为秒
|
|
|
- *
|
|
|
- * @param file
|
|
|
- * @return 时长(s)
|
|
|
- */
|
|
|
- public static Long getVideoTime(File file) {
|
|
|
- Long times = 0L;
|
|
|
- try {
|
|
|
- FFmpegFrameGrabber ff = new FFmpegFrameGrabber(file);
|
|
|
- ff.start();
|
|
|
- times = ff.getLengthInTime() / (1000 * 1000);
|
|
|
- ff.stop();
|
|
|
- } catch (Exception e) {
|
|
|
- e.printStackTrace();
|
|
|
- }
|
|
|
- return times;
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-/**********=======================================================以下实验没成功===============================***************/
|
|
|
- /**
|
|
|
- * 视频截取
|
|
|
- * @param videoFile
|
|
|
- * @throws Exception
|
|
|
- */
|
|
|
- public static void cut(File videoFile, File outputFile) throws Exception{
|
|
|
- boolean isStart = true;// 该变量建议设置为全局控制变量,用于控制录制结束
|
|
|
- FFmpegFrameGrabber grabber = new FFmpegFrameGrabber(videoFile);
|
|
|
-// // 微秒 大概为设置时间的两倍
|
|
|
- // grabber.setOption(TimeoutOption.RW_TIMEOUT.getKey(), "10000000");
|
|
|
- // rtsp 默认udp 丢包 改为tcp
|
|
|
- // grabber.setOption("rtsp_transport", "tcp");
|
|
|
-
|
|
|
- grabber.start();
|
|
|
- //好多视频熟悉可以获取后打印 示例几个
|
|
|
- System.out.println("ImageWidth:" + grabber.getImageWidth());
|
|
|
- System.out.println("ImageHeight:" + grabber.getImageHeight());
|
|
|
- System.out.println("AudioChannels:" + grabber.getAudioChannels());
|
|
|
- System.out.println("Format:" + grabber.getFormat());
|
|
|
- FrameRecorder recorder = new FFmpegFrameRecorder(outputFile, grabber.getImageWidth(), grabber.getImageHeight(),grabber.getAudioChannels());
|
|
|
- recorder.setVideoCodec(avcodec.AV_CODEC_ID_H264); // avcodec.AV_CODEC_ID_H264,编码
|
|
|
- recorder.setFormat("flv");//封装格式,如果是推送到rtmp就必须是flv封装格式
|
|
|
- recorder.setFrameRate( grabber.getFrameRate());
|
|
|
-
|
|
|
- recorder.start();//开启录制器
|
|
|
- long startTime=0;
|
|
|
- long videoTS=0;
|
|
|
- CanvasFrame frame = new CanvasFrame("camera", CanvasFrame.getDefaultGamma() / grabber.getGamma());
|
|
|
- frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
|
|
- frame.setAlwaysOnTop(true);
|
|
|
- Frame rotatedFrame= null;
|
|
|
- while (frame.isVisible() && (rotatedFrame = grabber.grabFrame()) != null) {
|
|
|
- rotatedFrame = grabber.grabFrame();
|
|
|
- frame.showImage(rotatedFrame);
|
|
|
- if (startTime == 0) {
|
|
|
- startTime = System.currentTimeMillis();
|
|
|
- }
|
|
|
- videoTS = 1000 * (System.currentTimeMillis() - startTime);
|
|
|
- recorder.setTimestamp(videoTS);
|
|
|
- recorder.record(rotatedFrame);
|
|
|
- Thread.sleep(40);
|
|
|
- }
|
|
|
- frame.dispose();
|
|
|
- recorder.stop();
|
|
|
- recorder.release();
|
|
|
- grabber.stop();
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 视频截取
|
|
|
- * @param videoFile
|
|
|
- * @throws Exception
|
|
|
- */
|
|
|
- public static void cut2(File videoFile, File outputFile) throws Exception{
|
|
|
- boolean isStart = true;// 该变量建议设置为全局控制变量,用于控制录制结束
|
|
|
- FFmpegFrameGrabber grabber = new FFmpegFrameGrabber(videoFile);
|
|
|
-// // 微秒 大概为设置时间的两倍
|
|
|
- // grabber.setOption(TimeoutOption.RW_TIMEOUT.getKey(), "10000000");
|
|
|
- // rtsp 默认udp 丢包 改为tcp
|
|
|
- // grabber.setOption("rtsp_transport", "tcp");
|
|
|
-
|
|
|
- grabber.start();
|
|
|
- //好多视频熟悉可以获取后打印 示例几个
|
|
|
- System.out.println("ImageWidth:" + grabber.getImageWidth());
|
|
|
- System.out.println("ImageHeight:" + grabber.getImageHeight());
|
|
|
- System.out.println("AudioChannels:" + grabber.getAudioChannels());
|
|
|
- System.out.println("Format:" + grabber.getFormat());
|
|
|
- FFmpegFrameRecorder recorder = new FFmpegFrameRecorder(outputFile, grabber.getImageWidth(), grabber.getImageHeight(),grabber.getAudioChannels());
|
|
|
- recorder.setFrameRate(grabber.getFrameRate());
|
|
|
- recorder.setAudioBitrate(grabber.getAudioBitrate());
|
|
|
- recorder.setSampleRate(grabber.getSampleRate());
|
|
|
-// recorder.setGopSize(2);
|
|
|
- recorder.setFormat("mp4");
|
|
|
- recorder.setAudioCodecName("aac");
|
|
|
- recorder.setVideoCodec(grabber.getVideoCodec());
|
|
|
- recorder.start();
|
|
|
- Frame frame = null;
|
|
|
- //如果想截取规定时间段视频 请看系列文章二
|
|
|
- while (isStart) {
|
|
|
- frame = grabber.grabFrame();
|
|
|
- if(frame != null){
|
|
|
- recorder.record(frame);
|
|
|
- }
|
|
|
-
|
|
|
- }
|
|
|
- recorder.stop();
|
|
|
- recorder.release();
|
|
|
- grabber.stop();
|
|
|
- grabber.release();
|
|
|
- }
|
|
|
-
|
|
|
- public static void cut3() throws Exception{
|
|
|
- FFmpeg ffmpeg = new FFmpeg("C:\\Users\\STW\\Downloads\\ffmpeg-3.1.3\\ffmpeg-3.1.3\\ffmpeg");
|
|
|
- FFprobe ffprobe = new FFprobe("C:\\Users\\STW\\Downloads\\ffmpeg-3.1.3\\ffmpeg-3.1.3\\ffprobe");
|
|
|
-
|
|
|
- FFmpegBuilder builder = new FFmpegBuilder()
|
|
|
-
|
|
|
- .setInput("e:/20211223123223_76639ced-6400-11ec-b8f9-fa163e4e1e9f.mp4") // Filename, or a FFmpegProbeResult
|
|
|
- .overrideOutputFiles(true) // Override the output if it exists
|
|
|
-
|
|
|
- .addOutput("e:/output.mp4") // Filename for the destination
|
|
|
- .setFormat("mp4") // Format is inferred from filename, or can be set
|
|
|
- .setTargetSize(250_000) // Aim for a 250KB file
|
|
|
-
|
|
|
- .disableSubtitle() // No subtiles
|
|
|
-
|
|
|
- .setAudioChannels(1) // Mono audio
|
|
|
- .setAudioCodec("aac") // using the aac codec
|
|
|
- .setAudioSampleRate(48_000) // at 48KHz
|
|
|
- .setAudioBitRate(32768) // at 32 kbit/s
|
|
|
-
|
|
|
- .setVideoCodec("libx264") // Video using x264
|
|
|
- .setVideoFrameRate(24, 1) // at 24 frames per second
|
|
|
- .setVideoResolution(640, 480) // at 640x480 resolution
|
|
|
-
|
|
|
- .setStrict(FFmpegBuilder.Strict.EXPERIMENTAL) // Allow FFmpeg to use experimental specs
|
|
|
- .done();
|
|
|
-
|
|
|
- FFmpegExecutor executor = new FFmpegExecutor(ffmpeg, ffprobe);
|
|
|
-
|
|
|
-// Run a one-pass encode
|
|
|
- executor.createJob(builder).run();
|
|
|
-
|
|
|
-// Or run a two-pass encode (which is better quality at the cost of being slower)
|
|
|
- executor.createTwoPassJob(builder).run();
|
|
|
- }
|
|
|
-
|
|
|
- /**********=======================================================以上实验没成功===============================***************/
|
|
|
-
|
|
|
-
|
|
|
- public static void main(String[] args) {
|
|
|
- try {
|
|
|
- //getList(10,113);
|
|
|
-
|
|
|
- File file = new File("e:/20211223123223_76639ced-6400-11ec-b8f9-fa163e4e1e9f.mp4");
|
|
|
-// List<File> files = VideoUtil.fetchPicByCount(file, "E:/223", 100);
|
|
|
-// System.out.println(files.get(0).getName());
|
|
|
-// System.out.println(VideoUtil.getVideoTime(file));
|
|
|
-
|
|
|
- Date shootEndTime = DateUtils.strToDate("20211223123223","yyyyMMddHHmmss");
|
|
|
- fetchAllPic(file,"E:/223",shootEndTime);
|
|
|
-// cut3(file,new File("e:/a.mp4"));
|
|
|
- // cut3();
|
|
|
- } catch (Exception e) {
|
|
|
- e.printStackTrace();
|
|
|
- }
|
|
|
- }
|
|
|
-}
|