在这里,我正在尝试编码来自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();
}
}
}
}