通过 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 width:图片长
     * @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

 


 

posted @ 2012-10-19 15:04  safetys  阅读(10229)  评论(0编辑  收藏  举报