此处我尝试对来自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
答案 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();
}
}
}
}