zoukankan      html  css  js  c++  java
  • javacv获取视频第一帧

    第一种是用ffmpeg工具,不过还得安装客户端软件,于是放弃了,还有一种是javacv开源工具,所以选择第二种:

    第一种:ffmpeg工具

    需要安装ffmpeg软件,支持windows和linux,视频安装教程参考:https://www.cnblogs.com/rxbook/p/9652185.html

    然后用以下代码:

    import java.awt.Image;
    import java.awt.image.BufferedImage;
    import java.io.*;
    import javax.imageio.IIOImage;
    import javax.imageio.ImageIO;
    import javax.imageio.ImageWriteParam;
    import javax.imageio.ImageWriter;
    
    public class FirstFrameUtil {
        protected String ffmpegApp;
        public FirstFrameUtil(String ffmpegApp) {
            this.ffmpegApp = ffmpegApp;
        }
        @SuppressWarnings("unused")
        /****
         * 获取指定时间内的图片
         * @param videoFilename:视频路径
         * @param thumbFilename:图片保存路径
         * @param 图片长
         * @param height:图片宽
         * @param hour:指定时
         * @param min:指定分
         * @param sec:指定秒
         * @throws IOException
         * @throws InterruptedException
         */
        public void getThumb(String videoFilename, String thumbFilename,  int hour, int min, float sec) throws IOException, InterruptedException {
                ProcessBuilder processBuilder = new ProcessBuilder(ffmpegApp, "-y", "-i", videoFilename, "-vframes", "1", "-ss", hour + ":" + min + ":" + sec, "-f", "mjpeg",  "-an",
                        thumbFilename);
            Process process = processBuilder.start();
            InputStream stderr = process.getErrorStream();
            InputStreamReader isr = new InputStreamReader(stderr);
            BufferedReader br = new BufferedReader(isr);
            String line;
            while ((line = br.readLine()) != null)
                ;
            process.waitFor();   
            if (br != null)
                br.close();
            if (isr != null)
                isr.close();
            if (stderr != null)
                stderr.close();
        }
        public static void main(String[] args) {
            String path = "D:\config\ffmpeg-win64\bin\ffmpeg.exe";
    
            FirstFrameUtil videoThumbTaker = new FirstFrameUtil(path);
            try {
                videoThumbTaker.getThumb("D:\test2.mp4", "D:\test\result.png", 0, 0, 1);
                File ffmpegFile = new File("D:\test\result.png");
                FileInputStream input=new FileInputStream(ffmpegFile);
                
                System.out.println("over");
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
    View Code

    即可获取第一帧图片

    第二种javacv

    直接上代码:(后边有介绍pom文件的引用)

    import org.bytedeco.javacpp.opencv_core;
    import org.bytedeco.javacpp.opencv_core.IplImage;
    import org.bytedeco.javacv.FFmpegFrameGrabber;
    import org.bytedeco.javacv.Java2DFrameConverter;
    import org.bytedeco.javacv.OpenCVFrameConverter;
    import org.bytedeco.javacv.Frame;
    
    import javax.imageio.ImageIO;
    
    import java.awt.image.BufferedImage;
    import java.io.File;
    import java.io.IOException;
    
    public class VideoTool {
    
        public static void main(String[] args) throws Exception {
    
           // randomGrabberFFmpegImage("http://101.132.110.90/group1/M00/00/05/rBN4LFq8p5SAJT0wA5k4vpHKf7Q325.mp4", "D:\test", "test2");
            randomGrabberFFmpegImage("D:\test2.mp4", "D:\test", "test2");
            //randomGrabberFFmpegImage("C:/Users\Administrator\Desktop\VID_20171229_162251.mp4", "G:\test", "111");
        }
    
        public static void randomGrabberFFmpegImage(String filePath, String targerFilePath, String targetFileName)
                throws Exception {
            //创建视频帧抓取工具
            FFmpegFrameGrabber ff = FFmpegFrameGrabber.createDefault(filePath);
            ff.start();
            //获取旋转角度信息(90度)
            String rotate =ff.getVideoMetadata("rotate");
            //
            Frame f;
            //i可以控制获取第几帧
            int i = 0;
            while (i <5) {
                //一帧一帧去抓取视频图片,ff.grabImage();每次抓取下一帧
                f =ff.grabImage();
                IplImage src = null;
                //旋转图像并输出第29帧
                if(i==4){
                    //手机录的视频有旋转角度,需要旋转处理
                    if(null !=rotate &&rotate.length() > 1) {
                        OpenCVFrameConverter.ToIplImage converter =new OpenCVFrameConverter.ToIplImage();
                        src =converter.convert(f);
                        f =converter.convert(rotate(src, Integer.valueOf(rotate)));
                    }
                    //输出第几帧图片
                    doExecuteFrame(f,targerFilePath,targetFileName+i+i);
                }           
                i++;
            }
            ff.stop();
        }
    
        /*
         * 旋转角度的
         */
        public static IplImage rotate(IplImage src, int angle) {
            IplImage img = IplImage.create(src.height(), src.width(), src.depth(), src.nChannels());
            opencv_core.cvTranspose(src, img);
            opencv_core.cvFlip(img, img, angle);
            return img;
        }
    
        public static void doExecuteFrame(Frame f, String targerFilePath, String targetFileName) {
    
            if (null ==f ||null ==f.image) {
                return;
            }
            Java2DFrameConverter converter =new Java2DFrameConverter();
            String imageMat ="jpg";
            String FileName =targerFilePath + File.separator +targetFileName +"." +imageMat;
            BufferedImage bi =converter.getBufferedImage(f);
            System.out.println("" + bi.getWidth());
            System.out.println("height:" + bi.getHeight());
            File output =new File(FileName);
            try {
                ImageIO.write(bi,imageMat,output);
            }catch (IOException e) {
                e.printStackTrace();
            }
        }   
       
    }

    如果不判断旋转,把手机视频放上去,截出来的是方向不对,如图左边是旋转过的,右边没有旋转的:

    解决图片旋转问题参考:http://blog.csdn.net/z562743237/article/details/54667252,通过一段时间的搜索了解到,如果拍摄的视频中带有旋转(rotate)信息,那么截取出来的图片就会被旋转。通过查询API发现FFmpegFrameGrabber的getVideoMetadata("rotate")方法可以获取到视频的旋转信息。根据获取到的rotate信息对ff.grabImage()得到的Frame进行旋转,但是Frame并没有提供旋转接口。但IpImage对象提供了旋转方法 。

    大多数人都是直接引入

    javacv-platform
    <dependency>
       <groupId>org.bytedeco</groupId>
       <artifactId>javacv-platform</artifactId>
       <version>1.3.1</version>
    </dependency>
    javacv-platform这种方式依赖的jar包300M,太大了,经过精简后pom文件如下:(在用,40兆左右)
        <properties>
            <javacpp.version>1.3</javacpp.version>
        </properties>  
    
        <dependencies>
            <dependency>
                <groupId>org.bytedeco</groupId>
                <artifactId>javacv</artifactId>
                <version>1.3.1</version>
                <exclusions>
                    <exclusion>
                        <groupId>org.bytedeco.javacpp-presets</groupId>
                        <artifactId>flycapture</artifactId>
                    </exclusion>
                    <exclusion>
                        <groupId>org.bytedeco.javacpp-presets</groupId>
                        <artifactId>libdc1394</artifactId>
                    </exclusion>
                    <exclusion>
                        <groupId>org.bytedeco.javacpp-presets</groupId>
                        <artifactId>libfreenect</artifactId>
                    </exclusion>
                    <exclusion>
                        <groupId>org.bytedeco.javacpp-presets</groupId>
                        <artifactId>libfreenect2</artifactId>
                    </exclusion>
                    <exclusion>
                        <groupId>org.bytedeco.javacpp-presets</groupId>
                        <artifactId>librealsense</artifactId>
                    </exclusion>
                    <exclusion>
                        <groupId>org.bytedeco.javacpp-presets</groupId>
                        <artifactId>videoinput</artifactId>
                    </exclusion>
                    <exclusion>
                        <groupId>org.bytedeco.javacpp-presets</groupId>
                        <artifactId>artoolkitplus</artifactId>
                    </exclusion>
                    <exclusion>
                        <groupId>org.bytedeco.javacpp-presets</groupId>
                        <artifactId>artoolkitplus</artifactId>
                    </exclusion>
                    <exclusion>
                        <groupId>org.bytedeco.javacpp-presets</groupId>
                        <artifactId>flandmark</artifactId>
                    </exclusion>
                </exclusions>
            </dependency>
    
          <dependency>
                <groupId>org.bytedeco.javacpp-presets</groupId>
                <artifactId>opencv</artifactId>
                <version>3.1.0-${javacpp.version}</version>
                <classifier>linux-x86_64</classifier>
            </dependency>
            <dependency>
                <groupId>org.bytedeco.javacpp-presets</groupId>
                <artifactId>opencv</artifactId>
                <version>3.1.0-${javacpp.version}</version>
                <classifier>windows-x86_64</classifier>
            </dependency>
            <dependency>
                <groupId>org.bytedeco.javacpp-presets</groupId>
                <artifactId>ffmpeg</artifactId>
                <version>3.2.1-${javacpp.version}</version>
                <classifier>windows-x86_64</classifier>
            </dependency>
            <dependency>
                <groupId>org.bytedeco.javacpp-presets</groupId>
                <artifactId>ffmpeg</artifactId>
                <version>3.2.1-${javacpp.version}</version>
                <classifier>linux-x86_64</classifier>
            </dependency>
       </dependencies>

    共8个jar

  • 相关阅读:
    最短Hamilton路径-状压dp解法
    泡芙
    斗地主
    楼间跳跃
    联合权值
    虫食算
    抢掠计划
    间谍网络
    城堡the castle
    【模板】缩点
  • 原文地址:https://www.cnblogs.com/zhaoyanhaoBlog/p/11465516.html
Copyright © 2011-2022 走看看