java-FFmpeg(一) 實現視頻的轉碼和截圖功能


 

  FFmpeg是一個開源免費跨平台的視頻和音頻流方案,屬於自由軟件,采用LGPL或GPL許可證(依據你選擇的組件)。它提供了錄制、轉換以及流化音視頻的完整解決方案。它包含了非常先進的音頻/視頻編解碼庫libavcodec,為了保證高可移植性和編解碼質量,libavcodec里很多codec都是從頭開發的。FFmpeg在Linux平台下開發,但它同樣也可以在其它操作系統環境中編譯運行。

  在java開發中,FFmpeg也常被調用用來進行視頻的轉碼,錄播和直播,總的來說,FFmpeg是一款非常強大的,而且做與視頻相關的業務平台開發人員必須要學會的工具,那具體怎么實習呢,第一章我們先從分別windows和linux下調用FFmpeg進行視頻的轉碼,和對視頻的截圖做出說明解釋。

      ffmpeg能解析的格式:(asx,asf,mpg,wmv,3gp,mp4,mov,avi,flv等),而對於ffmpeg無法解析的文件格式(wmv9,rm,rmvb等),我們在下面采用了mencoder工具,先將視頻轉換成AVI格式再用ffmpeg進行轉碼;

      windows下:

        1.首先需要FFmpeg和mencoder的工具。一共五個文件,點此下載,將他解壓放在你的D盤FFmpeg文件夾下。

    

 

 

  linux下:

依次執行下面的指令

1.下載yasm-1.3.0.tar.gz這個版本:
yasm是一個完全重寫的NASM匯編。目前,它支持x86和AMD64指令集,接受NASM和氣體匯編語法,產出二進制, ELF32 , ELF64 , COFF , Mach - O的( 32和64 ) , RDOFF2 ,的Win32和Win64對象的格式,並生成STABS 調試信息的來源,DWARF 2 ,CodeView 8格式。之所以在FFmpeg中用這個,主要是支持編譯ffmpeg-x264.
wget http://www.tortall.net/projects/yasm/releases/yasm-1.3.0.tar.gz
tar xzvf yasm-1.3.0.tar.gz
cd yasm-1.3.0
./configure
make
make install

2.下載3.1.3 release ffmpeg
wget http://ffmpeg.org/releases/ffmpeg-3.1.3.tar.gz
tar -zxvf ffmpeg-3.1.3.tar.gz
cd ffmpeg-3.1.3
./configure
make
make install
第二步的時間可能會有點長,耐心等待~!安裝完成之后輸入  ffmpeg -version 可以看到版本說明安裝成功

 

下面直接上代碼,都寫好注釋的,很清楚。
package wordtopdf;

import java.io.File;  
import java.util.ArrayList;  
import java.util.Calendar;  
import java.util.List;  
  

public class ConvertVideo {
     private final static String PATH = "【需要轉碼的視頻路徑】";  
      
        public static void main(String[] args) {  
            if (!checkfile(PATH)) {   //判斷路徑是不是一個文件
                System.out.println(PATH + " is not file");  
                return;  
            }  
            if (process()) {        //執行轉碼任務
                System.out.println("ok");  
            }  
        }  
      
        private static boolean checkfile(String path) {  
            File file = new File(path);  
            if (!file.isFile()) {  
                return false;  
            }  
            return true;  
        }  
        
        private static boolean process() { 
            // 判斷視頻的類型
            int type = checkContentType();  
            boolean status = false;  
            //如果是ffmpeg可以轉換的類型直接轉碼,否則先用mencoder轉碼成AVI
            if (type == 0) {  
                System.out.println("直接將文件轉為flv文件");  
                status = processFLV(PATH);// 直接將文件轉為flv文件  
            } else if (type == 1) {  
                String avifilepath = processAVI(type);  
                if (avifilepath == null)  
                    return false;// avi文件沒有得到  
                status = processFLV(avifilepath);// 將avi轉為flv  
            }  
            return status;  
        }  
      
        private static int checkContentType() {  
            String type = PATH.substring(PATH.lastIndexOf(".") + 1, PATH.length())  
                    .toLowerCase();  
            // ffmpeg能解析的格式:(asx,asf,mpg,wmv,3gp,mp4,mov,avi,flv等)  
            if (type.equals("avi")) {  
                return 0;  
            } else if (type.equals("mpg")) {  
                return 0;  
            } else if (type.equals("wmv")) {  
                return 0;  
            } else if (type.equals("3gp")) {  
                return 0;  
            } else if (type.equals("mov")) {  
                return 0;  
            } else if (type.equals("mp4")) {  
                return 0;  
            } else if (type.equals("asf")) {  
                return 0;  
            } else if (type.equals("asx")) {  
                return 0;  
            } else if (type.equals("flv")) {  
                return 0;  
            }  
            // 對ffmpeg無法解析的文件格式(wmv9,rm,rmvb等),  
            // 可以先用別的工具(mencoder)轉換為avi(ffmpeg能解析的)格式.  
            else if (type.equals("wmv9")) {  
                return 1;  
            } else if (type.equals("rm")) {  
                return 1;  
            } else if (type.equals("rmvb")) {  
                return 1;  
            }  
            return 9;  
        }  
           
      
        // 對ffmpeg無法解析的文件格式(wmv9,rm,rmvb等), 可以先用別的工具(mencoder)轉換為avi(ffmpeg能解析的)格式.  
        private static String processAVI(int type) {  
            List<String> commend = new ArrayList<String>();  
            commend.add("D:\\ffmpeg\\mencoder");  
            commend.add(PATH);  
            commend.add("-oac");  
            commend.add("lavc");  
            commend.add("-lavcopts");  
            commend.add("acodec=mp3:abitrate=64");  
            commend.add("-ovc");  
            commend.add("xvid");  
            commend.add("-xvidencopts");  
            commend.add("bitrate=600");  
            commend.add("-of");  
            commend.add("avi");  
            commend.add("-o");  
            commend.add("【存放轉碼后視頻的路徑,記住一定是.avi后綴的文件名】");  
            try {  
                //調用線程命令啟動轉碼
                ProcessBuilder builder = new ProcessBuilder();  
                builder.command(commend);  
                builder.start();  
                return "【存放轉碼后視頻的路徑,記住一定是.avi后綴的文件名】";  
            } catch (Exception e) {  
                e.printStackTrace();  
                return null;  
            }  
        }  
      
        // ffmpeg能解析的格式:(asx,asf,mpg,wmv,3gp,mp4,mov,avi,flv等)  
        private static boolean processFLV(String oldfilepath) {  
      
            if (!checkfile(PATH)) {  
                System.out.println(oldfilepath + " is not file");  
                return false;  
            }  
              
            // 文件命名  
            Calendar c = Calendar.getInstance();  
            String savename = String.valueOf(c.getTimeInMillis())+ Math.round(Math.random() * 100000);  
            List<String> commend = new ArrayList<String>();  
            commend.add("D:\\ffmpeg\\ffmpeg");  
            commend.add("-i");  
            commend.add(oldfilepath);  
            commend.add("-ab");  
            commend.add("56");  
            commend.add("-ar");  
            commend.add("22050");  
            commend.add("-qscale");  
            commend.add("8");  
            commend.add("-r");  
            commend.add("15");  
            commend.add("-s");  
            commend.add("600x500");  
            commend.add("【存放轉碼后視頻的路徑,記住一定是.flv后綴的文件名】");  
      
            try {  
                Runtime runtime = Runtime.getRuntime();  
                Process proce = null; 
                //視頻截圖命令,封面圖。  8是代表第8秒的時候截圖
                String cmd = "";  
                String cut = "     c:\\ffmpeg\\ffmpeg.exe   -i   "  
                        + oldfilepath  
                        + "   -y   -f   image2   -ss   8   -t   0.001   -s   600x500   c:\\ffmpeg\\output\\"  
                        + "a.jpg";  
                String cutCmd = cmd + cut;  
                proce = runtime.exec(cutCmd);  
                //調用線程命令進行轉碼
                ProcessBuilder builder = new ProcessBuilder(commend);                 
                 builder.command(commend);  
                builder.start();  
      
                return true;  
            } catch (Exception e) {  
                e.printStackTrace();  
                return false;  
            }  
        }  
}

 

 注:ffmpeg的功能十分強大,但是命令也非常多,轉換每種格式的命令都不相同!需要轉換其他格式的,請寫對命令。

       命令格式:

    普通轉碼:
    ffmpeg -i [輸入文件名] [參數選項] -f [格式] [輸出文件]
    比如:MP4轉avi c:\ffmpeg\ffmpeg -i c:\ffmpeg\input\c.mp4 -f avi c:\ffmpeg\output\a.avi

    參數:-an 去掉音頻
    -b 1000K 壓縮碼率為1000K
    -s 800*500 壓縮尺寸為800*500
    -aspect 寬高比,格式 16:9 或 1.778
    (當源尺寸是16:9,要壓縮成非16:9的,一方面要設定 -s,另一方面要給出 -aspect)
    -ss 開始時間​
    -t 持續時長





免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM