java用ffmpeg插件來捕獲視頻第一幀

簡介:  以下是一個完整的實現java捕獲視頻第一幀(最後一幀或固定時間)圖片的方法,如果參閱此文章只需要把以下java代碼完整拷貝下來作爲util即可使用

           代碼之後有ffmpeg在linux下的完整安裝教程.


1.獲取視頻信息

 

package com.qs.util.videoUtil;
import java.io.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
 
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("/data/qinyi/ffmpeg/bin/ffmpeg.exe");
//        try
//        {
//            videoInfo.getInfo("d:/aa.mp4");
//            System.out.println(videoInfo);
//        } catch (Exception e)
//        {
//            e.printStackTrace();
//        }
//    }
 
}


 

 

 

2.獲取指定時分秒及保存圖片的大小設置

 

package com.qs.util.videoUtil;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.BufferedReader;
 
/**
 * @author reyo
 * 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 StringffmpegApp;
 
    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("d:/aa.mp4", "d:\\first3.png",    204, 140, 0, 0, 0);
//            System.out.println("over");
//        } catch (Exception e)
//        {
//            e.printStackTrace();
//        }
//    }
}


 

 

3.測試類

 

package com.qs.util.videoUtil;
import java.io.IOException;
 
/***
 *
 * 得到第一秒(也是第一幀)圖片
 */
public class VideoFirstThumbTakerextends 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.測試類

 

/**
 * 得到最後一秒(也是最後一幀)圖片
 */
public class VideoLastThumbTakerextends 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);
    }
}



注意:windows下可以直接下載ffmpeg.exe  來指定其路徑操作視頻.而在linux下不支持exe可執行文件,需要單獨安裝ffmpeg 及其所需的插件.具體方法如下:


Linux下安裝ffmpeg

 

ffmpeg是一個很強大的音視頻處理工具,官網是:http://ffmpeg.org/ 官網介紹ffmpeg是:一個完整的、跨平臺的解決方案,可以記錄、轉換和傳輸音頻和視頻。ffmpeg既可以播放視頻,也提供命令行工具來處理視頻,另外還有強大的視頻處理庫用於開發,下面是以Linux爲例介紹ffmpeg的安裝流程的簡單的命令行對視頻進行轉碼操作,是ffmpeg中最最簡單的入門內容.

  首先去官網下載源碼包,這裏下載的是最新的ffmpeg-3.3.1.tar.bz2,下載之後上傳至Linux準備安裝,首先解壓安裝包:

tar -xjvf ffmpeg-3.3.1.tar.bz2

cd ffmpeg-3.3.1/

 

 

 如果現在直接執行configure配置的話,可能會報如下的錯誤:


錯誤的意思是 yasm/nasm 包不存在或者很舊,可以使用--disable-yasm禁用這個選項編譯,yasm是一款彙編器,並且是完全重寫了nasm的彙編環境,接收nasm和gas語法,支持x86和amd64指令集,所以這裏安裝一下yasm即可,下載地址是:http://yasm.tortall.net/Download.html 進入後下載1.3.0的源碼包,執行下面命令安裝:

tar -xvzf yasm-1.3.0.tar.gz

cd yasm-1.3.0/

./configure

Make

make install

 

 

編譯參數都是默認的,直接安裝到系統中即可,安裝成功之後繼續回到ffmpeg解壓後的目錄,執行下面命令編譯並安裝:

./configure --enable-shared --prefix=/monchickey/ffmpeg

Make

make install

 

編譯過程有點長,耐心等待完成之後執行 cd /monchickey/ffmpeg/ 進入安裝目錄,查看一下發現有bin,include,lib,share這4個目錄,其中bin是ffmpeg主程序二進制目錄,include是C/C++頭文件目錄,lib是編譯好的庫文件目錄,share是文檔目錄,然後進入bin目錄,執行 ./ffmpeg -version 查看當前版本的詳細信息,默認情況下一般會報libavdevice.so.57: cannot open shared object file: No such file or directory,原因是lib目錄未加載到鏈接到系統庫中,系統ld目錄列表在/etc/ld.so.conf中,打開文件會發現,裏面引用了/etc/ld.so.conf.d/下面所有的.conf文件,比如mariadb-x86_64.conf我們只需要創建一個文件並寫入lib路徑即可,執行命令: vim /etc/ld.so.conf.d/ffmpeg.conf 然後添加一行內容: /monchickey/ffmpeg/lib 之後保存並退出,然後執行 ldconfig 使配置生效,現在再次執行 ./ffmpeg -version 顯示就正常了


  然後可以根據需要將bin目錄添加至環境變量中以保證任何時候都能使用ffmpeg命令,下面測試一下對視頻進行轉碼:

  首先由一個avi格式的視頻文件,大小是37M,現在使用ffmpeg轉換爲mp4格式,執行下面命令:

ffmpeg -i test.avi out.mp4

確認之後,看到屏幕滾動開始處理,大約半分鐘之後視頻就轉換完畢了,轉換後mp4視頻大小是17M,具體可以下載下來看一下


 現在ffmpeg安裝和最簡單的命令行視頻轉換就完成了,實際上ffmpeg命令行工具可以有很多參數不用編程就可以實現強大的功能




註明:本文內容並非原創,爲轉載整合,方便查閱使用


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章