私は Java でビデオ アプリケーションを作成してffmpeg
おり、その出力を実行して標準出力にキャプチャしています。Java の の代わりに Apache Commons-Exec を使用することにしRuntime
ました。ただし、すべての出力をキャプチャするのは困難です。
プロセス間通信の標準的な方法であるため、パイプを使用するのがよいと思いました。ただし、 and を使用した私のセットアップPipedInputStream
はPipedOutputStream
間違っています。動作しているように見えますが、ストリームの最初の 1042 バイトのみで、不思議なことにPipedInputStream.PIPE_SIZE
.
私はパイプの使用にあまり関心がありませんが、データの速度と量 (解像度 512x384 の 1 分 20 秒のビデオでは 690M
のパイプ データが生成される) のために、(可能であれば) ディスク I/O の使用を避けたいと考えています。
パイプからの大量のデータを処理するための最適なソリューションについて考えていますか? 私の 2 つのクラスのコードは以下のとおりです。(はい、sleep
悪いです。それについての考えは? wait()
とnotifyAll()
?)
WriteFrames.java
public class WriteFrames {
public static void main(String[] args) {
String commandName = "ffmpeg";
CommandLine commandLine = new CommandLine(commandName);
File filename = new File(args[0]);
String[] options = new String[] {
"-i",
filename.getAbsolutePath(),
"-an",
"-f",
"yuv4mpegpipe",
"-"};
for (String s : options) {
commandLine.addArgument(s);
}
PipedOutputStream output = new PipedOutputStream();
PumpStreamHandler streamHandler = new PumpStreamHandler(output, System.err);
DefaultExecutor executor = new DefaultExecutor();
try {
DataInputStream is = new DataInputStream(new PipedInputStream(output));
YUV4MPEGPipeParser p = new YUV4MPEGPipeParser(is);
p.start();
executor.setStreamHandler(streamHandler);
executor.execute(commandLine);
} catch (IOException e) {
e.printStackTrace();
}
}
}
YUV4MPEGPipeParser.java
public class YUV4MPEGPipeParser extends Thread {
private InputStream is;
int width, height;
public YUV4MPEGPipeParser(InputStream is) {
this.is = is;
}
public void run() {
try {
while (is.available() == 0) {
Thread.sleep(100);
}
while (is.available() != 0) {
// do stuff.... like write out YUV frames
}
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}