Java 视频处理,截帧操作

Wesley13
• 阅读 1019

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

点赞
收藏
评论区
推荐文章
待兔 待兔
4个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Wesley13 Wesley13
3年前
java生成二维码
1.maven引入如下      <!二维码       <dependency       <groupIdcom.google.zxing</groupId       <artifactIdcore</artifactId       <versi
Wesley13 Wesley13
3年前
Java将WKT格式的Geomotry转换成GeoJSON
一、Meven添加依赖<!引入json处理包<dependency<groupIdcom.alibaba</groupId<artifactIdfastjson</artifactId<version1.2.47</version</depend
Easter79 Easter79
3年前
SpringBoot权限管理开发实战2
1.添加依赖<dependency<groupIdorg.mybatis.spring.boot</groupId<artifactIdmybatisspringbootstarter</artifactId<version2.1.1</version</dependency<dependency<groupI
Easter79 Easter79
3年前
Springmvc 发送邮件功能
1、引入相关jar包<dependency<groupIdorg.apache.velocity</groupId<artifactIdvelocity</artifactId<version1.7</version</dependency
Stella981 Stella981
3年前
SpringBoot权限管理开发实战2
1.添加依赖<dependency<groupIdorg.mybatis.spring.boot</groupId<artifactIdmybatisspringbootstarter</artifactId<version2.1.1</version</dependency<dependency<groupI
Stella981 Stella981
3年前
ElasticSearch Java API 增删改查操作
1.添加pom.xml依赖<dependency<groupIdjunit</groupId<artifactIdjunit</artifactId<version4.11</version<scopetest</scope</dependency<dependency<groupI
Stella981 Stella981
3年前
HTTP请求客户端工具类
1.maven引入依赖<dependency<groupIdcommonshttpclient</groupId<artifactIdcommonshttpclient</artifactId<version3.1</version</dependency<!https://mvnrepos
Wesley13 Wesley13
3年前
Java原生API访问MongoDB
1.pom.xml<dependency<groupIdorg.mongodb</groupId<artifactIdmongojavadriver</artifactId<version3.5.0</version</dependency2.Java代码
Stella981 Stella981
3年前
Kafka客户端编程入门介绍
1.maven依赖<dependency<groupIdorg.apache.kafka</groupId<artifactIdkafka_2.11</artifactId<version1.0.0</version