Capturing large volumes of products from Apache Commons-Exec

I am writing a video application in Java, executing ffmpegand writing its output to standard output. I decided to use Apache Commons-Exec instead of Java Runtimebecause it looks better. However, it is difficult for me to draw the whole conclusion.

I thought that using pipes is the way to go because it is the standard way of interaction between processes. However, my setup using PipedInputStreamand PipedOutputStreamis incorrect. This seems to work, but only for the first 1042 bytes of the stream, which, oddly enough, is a value PipedInputStream.PIPE_SIZE.

I don’t have a love affair using pipes, but I want to avoid using disk I / O (if possible) because of the speed and amount of data (video with a resolution of 1 m 20 with a resolution of 512x384 gives 690 Mdata with channels).

Thoughts on the best solution for processing large amounts of data coming from a pipe? My code for my two classes is below. (yes, sleepbad. Thoughts on this? wait()and 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();
        }
    }
}
+5
source share
1 answer

YUV4MPEGPipeParser. . , (, , ffmpeg , β†’ () == 0 β†’ β†’ ).

read() , - . , , ()/notify() sleep(), .

run() :

public class YUV4MPEGPipeParser extends Thread {

    ...

    // optimal size of buffer for reading from pipe stream :-)
    private static final int BUFSIZE = PipedInputStream.PIPE_SIZE; 

    public void run() {
        try {
            byte buffer[] = new byte[BUFSIZE];
            int len = 0;
            while ((len = is.read(buffer, 0, BUFSIZE) != -1) {
                // we have valid data available 
                // in first 'len' bytes of 'buffer' array.

                // do stuff.... like write out YUV frames
            }
         } catch ...
     }
 }
+4

All Articles