zoukankan      html  css  js  c++  java
  • Java 视频处理,截帧操作

    1.maven

    <dependency>
                <groupId>org.bytedeco</groupId>
                <artifactId>javacv</artifactId>
                <version>1.4.1</version>
            </dependency>
            <dependency>
                <groupId>org.bytedeco</groupId>
                <artifactId>javacpp</artifactId>
                <version>1.4.1</version>
            </dependency>
            <dependency>
                <groupId>org.bytedeco.javacpp-presets</groupId>
                <artifactId>opencv-platform</artifactId>
                <version>3.4.1-1.4.1</version>
            </dependency>
            <dependency>
                <groupId>org.bytedeco.javacpp-presets</groupId>
                <artifactId>ffmpeg-platform</artifactId>
                <version>3.4.2-1.4.1</version>
    </dependency>

    2.工具类

    
    
    import org.bytedeco.javacpp.opencv_core;
    import org.bytedeco.javacpp.opencv_videoio;
    import org.bytedeco.javacv.FFmpegFrameGrabber;
    import org.bytedeco.javacv.Frame;
    import org.bytedeco.javacv.Java2DFrameConverter;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;

    import javax.imageio.ImageIO;
    import java.awt.*;
    import java.awt.image.BufferedImage;
    import java.io.File;
    import java.util.*;
    import java.util.List;

    import static org.bytedeco.javacpp.opencv_imgcodecs.cvSaveImage;
    import static org.bytedeco.javacpp.opencv_videoio.*;


    /**
    * 视频工具
    *
    * @author
    */
    public class VideoUtil {

    private static final int SECOND = 50;

    private static final Logger logger = LoggerFactory.getLogger(VideoUtil.class);

    /**
    * 获取指定视频的帧并保存为图片至指定目录
    *
    * @param videoFile 源视频文件
    * @param saveFile 截取帧的图片存放路径
    * @throws Exception
    */
    public static List<File> fetchPic(File videoFile, String saveFile, int second) throws Exception {

    java.util.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);
    files.add(writeToFile(frame, saveFile, i));
    }
    second++;
    }
    i += second;
    }
    ff.stop();
    return files;
    }

    public 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 saveFile, int count) throws Exception {

    java.util.List<File> files = new ArrayList<>();

    FFmpegFrameGrabber ff = new FFmpegFrameGrabber(videoFile);
    ff.start();

    int frameLength = ff.getLengthInFrames();


    System.out.println("length:" + frameLength);

    List<Integer> list = getList(count, frameLength);

    System.out.println(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);
    files.add(writeToFile(frame, saveFile, i));
    }
    }
    i++;
    }
    ff.stop();
    return files;
    }


    public static File writeToFile(Frame frame, String saveFile, int second) throws InvokeException {
    String fileName = String.valueOf(System.currentTimeMillis()) + second;
    File targetFile = new File(saveFile + 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 InvokeException(ResultEnum.FAILED.getCode(), "截帧失败");
    }
    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;
    }

    public static void getBySecond(String filePath, String directory) {
    opencv_videoio.CvCapture capture = cvCaptureFromFile(filePath);
    //帧率
    double fps = cvGetCaptureProperty(capture, CV_CAP_PROP_FRAME_COUNT);
    System.out.println("帧率:" + fps);
    opencv_core.IplImage frame = null;
    double pos1 = 0;

    double rootCount = 0;
    while (true) {

    //读取关键帧
    frame = cvQueryFrame(capture);

    rootCount = fps;
    while (rootCount > 0) {
    //这一段的目的是跳过每一秒钟的帧数,也就是说fps是帧率(一秒钟有多少帧),在读取一帧后,跳过fps数量的帧就相当于跳过了1秒钟。
    frame = cvQueryFrame(capture);
    rootCount--;
    }

    //获取当前帧的位置
    pos1 = cvGetCaptureProperty(capture, CV_CAP_PROP_POS_FRAMES);
    System.out.println(pos1);

    if (null == frame)
    break;

    cvSaveImage("E:/223/" + pos1 + ".jpg", frame);

    }

    cvReleaseCapture(capture);
    }

    /*public void getBySecond() {
    opencv_videoio.CvCapture capture = opencv_highgui.cvC("D:/085402.crf");



    //帧率
    int fps = (int) opencv_highgui.cvGetCaptureProperty(capture, opencv_highgui.CV_CAP_PROP_FPS);
    System.out.println("帧率:"+fps);

    opencv_core.IplImage frame = null;
    double pos1 = 0;

    int rootCount = 0;

    while (true) {

    //读取关键帧
    frame = opencv_highgui.cvQueryFrame(capture);

    rootCount = fps;
    while(rootCount > 0 ){
    //这一段的目的是跳过每一秒钟的帧数,也就是说fps是帧率(一秒钟有多少帧),在读取一帧后,跳过fps数量的帧就相当于跳过了1秒钟。
    frame = opencv_highgui.cvQueryFrame(capture);
    rootCount--;
    }

    //获取当前帧的位置
    pos1 = opencv_highgui.cvGetCaptureProperty(capture,opencv_highgui.CV_CAP_PROP_POS_FRAMES);
    System.out.println(pos1);

    if (null == frame)
    break;

    opencv_highgui.cvSaveImage("d:/img/" + pos1 + ".jpg",frame);

    }

    opencv_highgui.cvReleaseCapture(capture);
    }*/

    public static void main(String[] args) {
    try {
    //getList(10,113);

    File file = new File("E:/2.mp4");
    List<File> files = VideoUtil.fetchPicByCount(file, "E:/223", 100);
    System.out.println(files.get(0).getName());
    System.out.println(VideoUtil.getVideoTime(file));
    } catch (Exception e) {
    e.printStackTrace();
    }
    }
    }

     

    参考:https://blog.csdn.net/qq_22175485/article/details/81025525

  • 相关阅读:
    Sqlite中文排序
    关于java中实现在oracle数据库中实现对中文首字母进行排序的解决方案
    Java面试题全集(下)
    Java面试题全集(上)
    更新Svn客户端后,右键菜单中没有TortoiseSVN
    Maven项目报错:Failed to execute goal org.apache.maven.plugins:maven-clean-plugin:2.5:clean (default-clea
    华为机试题---1、字符串最后一个单词的长度
    ES6 类 继承
    JS 创建对象的几种方法(总结)
    80端口和8080端口的区别是什么
  • 原文地址:https://www.cnblogs.com/zgzf/p/10244453.html
Copyright © 2011-2022 走看看