zoukankan      html  css  js  c++  java
  • 通过 ffmpeg 获取视频第一帧(指定时间)图片

    FFMPEG 功能很强大,做视频必备的软件。大家可通过 http://ffmpeg.org/ 了解。Windows版本的软件,可通过 http://ffmpeg.zeranoe.com/builds/ 下载。

    因为有这个需求,通过 ffmpeg 获取视频第一帧图片,没办法,自己觉得比别人强的,就是会搜索,会google ^_^。

    Google一把,就有了结果。

    1、VideoInfo.java 获取视频信息。读者可认真研究此方法。

    import java.io.*;
    import java.util.regex.Matcher;
    import java.util.regex.Pattern;
    
    /**
     * 获取视频的信息
     * FFMPEG homepage http://ffmpeg.org/about.html
     */
    public class VideoInfo
    {
        //视频路径
        private String ffmpegApp;
        //视频时
        private int hours;
        //视频分
        private int minutes;
        //视频秒
        private float seconds;
        //视频width
        private int width;
        //视频height
        private int heigt;
        
    
        public VideoInfo() {}
        
        public VideoInfo(String ffmpegApp)
        {
            this.ffmpegApp = ffmpegApp;
        }
        
        public String toString()
        {
            return "time: " + hours + ":" + minutes + ":" + seconds + ", width = " + width + ", height= " + heigt;
        }
        
        public void getInfo(String videoFilename) throws IOException,
                InterruptedException
        {
            String tmpFile = videoFilename + ".tmp.png";
            ProcessBuilder processBuilder = new ProcessBuilder(ffmpegApp, "-y",
                    "-i", videoFilename, "-vframes", "1", "-ss", "0:0:0", "-an",
                    "-vcodec", "png", "-f", "rawvideo", "-s", "100*100", tmpFile);
    
            Process process = processBuilder.start();
    
            InputStream stderr = process.getErrorStream();
            InputStreamReader isr = new InputStreamReader(stderr);
            BufferedReader br = new BufferedReader(isr);
            String line;
            //打印 sb,获取更多信息。 如 bitrate、width、heigt
            StringBuffer sb = new StringBuffer();
            while ((line = br.readLine()) != null)
            {
                sb.append(line);
            }
    
            new File(tmpFile).delete();
            
            System.out.println("video info:\n" + sb);
            Pattern pattern = Pattern.compile("Duration: (.*?),");
            Matcher matcher = pattern.matcher(sb);
            
            if (matcher.find())
            {
                String time = matcher.group(1);
                calcTime(time);
            }
    
            pattern = Pattern.compile("w:\\d+ h:\\d+");
            matcher = pattern.matcher(sb);
            
            if (matcher.find())
            {
                String wh = matcher.group();
                //w:100 h:100
                String[] strs = wh.split("\\s+");
                if(strs != null && strs.length == 2)
                {
                    width = Integer.parseInt(strs[0].split(":")[1]);
                    heigt = Integer.parseInt(strs[1].split(":")[1]);
                }
            }
            
            process.waitFor();
            if(br != null)
                br.close();
            if(isr != null)
                isr.close();
            if(stderr != null)
                stderr.close();
        }
    
        private void calcTime(String timeStr)
        {
            String[] parts = timeStr.split(":");
            hours = Integer.parseInt(parts[0]);
            minutes = Integer.parseInt(parts[1]);
            seconds = Float.parseFloat(parts[2]);
        }
    
        public String getFfmpegApp()
        {
            return ffmpegApp;
        }
    
        public void setFfmpegApp(String ffmpegApp)
        {
            this.ffmpegApp = ffmpegApp;
        }
    
        public int getHours()
        {
            return hours;
        }
    
        public void setHours(int hours)
        {
            this.hours = hours;
        }
    
        public int getMinutes()
        {
            return minutes;
        }
    
        public void setMinutes(int minutes)
        {
            this.minutes = minutes;
        }
    
        public float getSeconds()
        {
            return seconds;
        }
    
        public void setSeconds(float seconds)
        {
            this.seconds = seconds;
        }
    
        public int getWidth()
        {
            return width;
        }
    
        public void setWidth(int width)
        {
            this.width = width;
        }
    
        public int getHeigt()
        {
            return heigt;
        }
    
        public void setHeigt(int heigt)
        {
            this.heigt = heigt;
        }
    
        public static void main(String[] args)
        {
            VideoInfo videoInfo = new VideoInfo("D:\\ffmpeg\\bin\\ffmpeg.exe");
            try
            {
                videoInfo.getInfo("f:/sun/Diana_Vickers_-_The_Boy_Who_Murdered_Love.mkv");
                System.out.println(videoInfo);
            } catch (Exception e)
            {
                e.printStackTrace();
            }
        }
    }

    从此类,可以看出,我把 ffmpeg,解压在了 D:\\ffmpeg\\bin\\ffmpeg.exe 路径下,传入一个视频地址,就可以得出视频信息。

    2、VideoThumbTaker.java 获取视频指定播放时间的图片

    import java.io.IOException;
    import java.io.InputStream;
    import java.io.InputStreamReader;
    import java.io.BufferedReader;
    
    /**
     * @author Bashan
     * FFMPEG homepage http://ffmpeg.org/about.html
     * By Google Get first and last thumb of a video using Java and FFMpeg
     * From http://www.codereye.com/2010/05/get-first-and-last-thumb-of-video-using.html
     */
    
    public class VideoThumbTaker
    {
        protected String ffmpegApp;
    
        public VideoThumbTaker(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 width,
                int height, 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", "-s", width + "*" + height,
                    "-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)
        {
            VideoThumbTaker videoThumbTaker = new VideoThumbTaker("D:\\ffmpeg\\bin\\ffmpeg.exe");
            try
            {
                videoThumbTaker.getThumb("f:/sun/Diana_Vickers_-_The_Boy_Who_Murdered_Love.mkv", "C:\\thumbTest.png",    800, 600, 0, 0, 9);
                System.out.println("over");
            } catch (Exception e)
            {
                e.printStackTrace();
            }
        }
    }

    3、VideoFirstThumbTaker.java 获取第一帧图片

    import java.io.IOException;
    
    /***
     * 
     * 得到第一秒(也是第一帧)图片
     */
    public class VideoFirstThumbTaker extends VideoThumbTaker
    {
        public VideoFirstThumbTaker(String ffmpegApp)
        {
            super(ffmpegApp);
        }
    
        public void getThumb(String videoFilename, String thumbFilename, int width,
                int height) throws IOException, InterruptedException
        {
            super.getThumb(videoFilename, thumbFilename, width, height, 0, 0, 1);
        }
    }

    4、VideoLastThumbTaker.java 获取最后一帧图片

    /**
     * 得到最后一秒(也是最后一帧)图片
     */
    
    public class VideoLastThumbTaker extends VideoThumbTaker
    {
        public VideoLastThumbTaker(String ffmpegApp)
        {
            super(ffmpegApp);
        }
    
        public void getThumb(String videoFilename, String thumbFilename, int width,
                int height) throws IOException, InterruptedException
        {
            VideoInfo videoInfo = new VideoInfo(ffmpegApp);
            videoInfo.getInfo(videoFilename);
            super.getThumb(videoFilename, thumbFilename, width, height,
                    videoInfo.getHours(), videoInfo.getMinutes(),
                    videoInfo.getSeconds() - 0.2f);
        }
    }

    参考:

    1、http://www.codereye.com/2010/05/get-first-and-last-thumb-of-video-using.html

    2、Google真的好方便。如何学google http://www.it-ebooks.com/html/Internet/Google_For_Dummies_53773_140278_3.html


     

  • 相关阅读:
    Tomcat模型结构
    BASE64编码的图片在网页中的显示问题的解决
    详解 Java 中的三种代理模式
    JVM运行原理
    关于浏览器对html, js,css的解析先后顺序的理解
    springboot中使用拦截器、监听器、过滤器
    jQuery中ajax如何返回值到上层函数里?
    FORM表单中onclick()、submit()与onsubmit()的问题
    Java对象的序列化和反序列化
    java传值和传引用区别
  • 原文地址:https://www.cnblogs.com/heyus/p/2731076.html
Copyright © 2011-2022 走看看