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



在这里,我正在尝试编码来自Flash Media Server来自Flash Media Server的Live RTMP流,并通过使用 AVCONV 工具来广播低比特率流。 libav 。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

我假设此代码旨在从该过程中排出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,则它将阻止您所看到的行为。这不是肯定的原因,但在我看来似乎很可能。

您应该从不同线程中从这些流中读取这些流 - 这样 - 这样,您将从 act ot 流中阅读而不必等待该过程完成。

    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();   
                  } 
        } 
    } 
}

最新更新