使用java調用FFMPEG進行轉碼

使用java調用FFMPEG進行轉碼

import  java.io.BufferedReader;
import  java.io.IOException;
import  java.io.InputStream;
import  java.io.InputStreamReader;
import  java.io.OutputStream;



public class TestFFmpeg {

static String ffmpeg_cmd = "/home/andrew/Work/FFmpeg/ffmpeg-3.2/ffmpeg";

//static String in = "/home/andrew/Work/FFmpeg/ffmpeg-3.2/test_2200kbps.flv";
//static String out = "/home/andrew/Work/FFmpeg/ffmpeg-3.2/test_out.flv";
static String in = "rtmp://223.203.1.34:1936/live?vhost=cc.com/stream1_1";
static String out = "rtmp://223.203.1.34:1936/live?vhost=cc.com/stream2";
static Process p;



public static void main(String[] args) {

        Runtime rt = Runtime.getRuntime() ;
        int r = -1;
        Thread stoppingThread;
        Thread errorStream;
        Thread inputStream;


        System.out.println(in);
        System.out.println(out);
        String[] cmd1 = new String[] {ffmpeg_cmd, "-re", "-i", in, "-acodec", "aac", "-ar", "44100", "-vcodec", "copy", "-report" , "-y", "-f", "flv", out};
        //String cmd1 = ffmpeg_cmd + " -re" + " -i " + in + " -acodec", " aac", " -ar" + " 44100" + " -vcodec" + " copy" + " -report" + " -y"," -f" + " flv " + out;

        try {
                System.out.println(cmd1);
                p = rt.exec(cmd1);

                StopTranscoder stopRunnable = new StopTranscoder(p);
                stoppingThread = new Thread(stopRunnable);
                stoppingThread.start();

                final InputStream is1 = p.getErrorStream ();
                final InputStream is2 = p.getInputStream ();

                //啓動兩個線程,一個線程負責讀標準輸出流,另外一個負責讀標準錯誤流  
                GetStream streamErr = new GetStream(is1);
                errorStream = new Thread(streamErr);
                errorStream.start();


                GetStream streamIn = new GetStream(is2);
                inputStream = new Thread(streamIn);
                inputStream.start();
                System.out.println("waiting for");
                try {
                        r = p.waitFor();
                } catch (InterruptedException e) {
                        e.printStackTrace();
                }

        } catch (Exception e) {
                e.printStackTrace();
        }
        System.out.println(r);
        p.destroy();
       }

}
class StopTranscoder implements Runnable {
        private Process process  = null;

        public StopTranscoder(Process proc){
                this.process  = proc;
        }
        public void run() {
                try {
                        System.out.println("kill before sleep");
                        Thread.sleep(10000);
                        System.out.println("kill after sleep");
                        this.process.destroy();

                } catch (Exception e) {
                        e.printStackTrace();
                }
        }
}
class GetStream implements Runnable {

        private InputStream is;

        public GetStream(InputStream stream) {
                is = stream;
        }
        public void run() {
                BufferedReader br = new BufferedReader(new InputStreamReader(is));
                try {
                        String line = null;
                        while ((line = br.readLine()) != null) {
                                if (line != null){
                                        System.out.println(line);
                                }
                        }
                } catch (IOException e) {
                        e.printStackTrace();
                }
                finally{
                        try {
                                is.close();
                        } catch (IOException e) {
                                e.printStackTrace();
                        }
                }
        }
}

執行FFMPEG

啓動FFMPEG進程,Runtime.getRuntime().exec(cmd)java

 

 

啓動兩個線程,一個線程負責讀標準輸出流,另外一個負責讀標準錯誤流

當Runtime對象調用exec(cmd)後,JVM會啓動一個子進程,該進程會與JVM進程創建三個管道鏈接:標準輸入,標準輸出和標準錯誤流。假設該程序不斷在向標準輸出流和標準錯誤流寫數據,而JVM不讀取的話,當緩衝區滿以後將沒法繼續寫入數據,最終形成阻塞在waitfor()這裏。測試

 

註釋:this

以前遇到過調用process.destroy()有可能沒法使FFMPEG退出的狀況,因此增長了類StopTranscoder()進行測試,可是沒有復現以前的問題。spa

相關文章
相關標籤/搜索