使用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

相关文章
相关标签/搜索