从Java运行时执行的avconv工具在8分钟后停止编码

时间:2014-01-23 06:48:00

标签: java video-streaming libav

此处我尝试对来自Flash Media Server的 live rtmp stream 进行编码,并使用 Libav avconv 工具广播低比特率流。 Libav安装在 Ubuntu OS 上。编码流仅运行 8分钟。因为avconv工具是使用java运行时环境启动的。 Java代码如下 -

    public class RunnableStream implements Runnable
    {
        String inStream,outStream,width,height,bitRate,frameRate,fname,line,ar,audioBitRate,audioChannel;
        public RunnableStream(String fname,String inStream,String outStream,String ar,String audioBitRate,String audioChannel,String width,String height,String bitRate,String frameRate)
        {
            this.fname=fname;
            this.inStream=inStream;
            this.outStream=outStream;
            this.width=width;
            this.height=height;
            this.bitRate=bitRate;
            this.frameRate=frameRate;
            this.ar=ar;
            this.audioBitRate=audioBitRate;
            this.audioChannel=audioChannel;

        }

        public void run() {
            Process pr;
            try {
                pr = Runtime.getRuntime().exec("avconv -async 15  -i  "+inStream+" -shortest -s "+width +"*"+height +"  -r " +frameRate+" -b:v "+bitRate+" -ab "+audioBitRate+" -ac "+audioChannel+" -ar "+ar+" -f flv "+outStream);

               InputStream in1 = pr.getInputStream();
               InputStream in = pr.getErrorStream();
    int c1;
    while ((c1 = in1.read()) != -1)
    {
        System.out.print((char)c1);
    }

    int c;
    while ((c = in.read()) != -1)
    {
        System.out.print((char)c);
    }
    pr.waitFor();
    in.close();
    in1.close();

            }catch(Exception e){e.printStackTrace();}
        }
    }

但是当相同的编码方案或命令直接应用于命令提示符时,它可以运行至少1小时。命令行语句如下所示 -

avconv -async 15 -i  rtmp://IP/live/streamname -shortest -s 176*144  -r 10 -b:v 56k  -ab 12k -ac 1 -ar 22050 -f flv rtmp://IP/live/streamname2

2 个答案:

答案 0 :(得分:1)

我认为这段代码是为了从进程中消耗stdout / stderr:

int c1;
while ((c1 = in1.read()) != -1)
{
    System.out.print((char)c1);
}

int c;
while ((c = in.read()) != -1)
{
    System.out.print((char)c);
}

不幸的是,它只会从in1(stdout)读取,直到进程完成,然后它将从in(stderr)读取。这意味着如果进程正在向stderr写入比缓冲区可容纳的数据更多的数据,它将阻止 - 准确地展示您所看到的行为。那不是肯定是的原因,但似乎我很可能。

你应该在不同的线程中读取这些流,基本上 - 这样你就可以从两个流中读取,而不必等待进程完成。

答案 1 :(得分:0)

    public class RunnableStream implements Runnable
    {
        String inStream,outStream,width,height,bitRate,frameRate,fname,line,ar,audioBitRate,audioChannel;
        public RunnableStream(String fname,String inStream,String outStream,String ar,String audioBitRate,String audioChannel,String width,String height,String bitRate,String frameRate)
        {
            this.fname=fname;
            this.inStream=inStream;
            this.outStream=outStream;
            this.width=width;
            this.height=height;
            this.bitRate=bitRate;
            this.frameRate=frameRate;
            this.ar=ar;
            this.audioBitRate=audioBitRate;
            this.audioChannel=audioChannel;

        }

        public void run() {
            Process pr;
            try {
                pr = Runtime.getRuntime().exec("avconv -async 15  -i  "+inStream+" -shortest -s "+width +"*"+height +"  -r " +frameRate+" -b:v "+bitRate+" -ab "+audioBitRate+" -ac "+audioChannel+" -ar "+ar+" -f flv "+outStream);

            StreamGobbler errorGobbler = new StreamGobbler(pr.getErrorStream(), "ERROR");             

                StreamGobbler outputGobbler = new StreamGobbler(pr.getInputStream(), "OUTPUT"); 

                errorGobbler.start(); 
                outputGobbler.start(); 

                int exitVal = pr.waitFor(); 
                System.out.println("ExitValue: " + exitVal); 

            }catch(Exception e){e.printStackTrace();}
        }


    }


    class StreamGobbler extends Thread { 
        InputStream is; 
        String type; 

        StreamGobbler(InputStream is, String type) { 
            this.is = is; 
            this.type = type; 
        } 

        public void run() { 
            try { 
                InputStreamReader isr = new InputStreamReader(is); 
                BufferedReader br = new BufferedReader(isr); 
                String line=null; 
                while ( (line = br.readLine()) != null) 
                    System.out.println(type + ">" + line);     
                } catch (IOException ioe) 
                  { 
                    ioe.printStackTrace();   
                  } 
        } 
    } 
}