You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@commons.apache.org by Edgar H <ka...@gmail.com> on 2017/02/04 18:47:39 UTC

[exec] Misconcepting PumpStreamHandler's way of working with streams?

I've been struggling with this problem for quite some time now as it's my
very first time doing an application related to streaming and I just can't
figure out why. Here's the problem...

What I'm trying to achieve is to send a command's output as an input for
the next one, which is basically what the pipe operator does. As I knew
this couldn't be executed directly with Exec library from Apache Commons I
started looking for ways to solve this. I've seen quite a few examples of
similar things to this but none of them covers my situation:

I have two Java applications separated, one is the main application and the
second one is initialized by the first one. This second applications sends
to the Standard Output bytes, which FFMPEG should receive.

The code that I have so far is the following one...

public void initStream(String path) {
    File file = new File(path);
    for (File s : file.listFiles()) {
        if (s.getName().equals("ffmpeg.exe")) {
            try {

                // Second app, supposedly, writes here.
                PipedOutputStream output = new PipedOutputStream();

                DefaultExecutor executor = new DefaultExecutor();
                //DefaultExecutor executorFFMPEG = new DefaultExecutor();
                executor.setWorkingDirectory(file);
                //executor.setWorkingDirectory(file);

                CommandLine commandLine = new
CommandLine(s.getParentFile().getAbsolutePath());
                System.out.println("Path: " + commandLine.toString());

                String executeMe = "java -jar streamer.jar";
                commandLine = CommandLine.parse(executeMe);

                System.out.println("[testing] streamer about to launch.");
                executor.setStreamHandler(new PumpStreamHandler(output, null));
                executor.execute(commandLine, new
DefaultExecuteResultHandler());
                System.out.println("[testing] streamer started.");

                PipedInputStream input = new PipedInputStream();
                output.connect(input);

                String feedMe = "ffmpeg"; // more attributes here
                commandLine = CommandLine.parse(feedMe);

                System.out.println("[testing] ffmpeg about to launch.");
                executor.setStreamHandler(new PumpStreamHandler(null,
null, input));
                executor.execute(commandLine, new
DefaultExecuteResultHandler());
                System.out.println("[testing] ffmpeg started.");

            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }}

And the code for the second application (the zone where I send data to
the stdout) is the following one.

static OutputStream stdout = System.out;

(more code and other things around here)

try {
        line = (TargetDataLine) mixer.getLine(info);
        line.open(format);

        int bytesRead, CHUNK_SIZE = 4096;
        byte[] data = new byte[line.getBufferSize() / 5];

        line.start();

        while (true) {
            bytesRead = line.read(data, 0, CHUNK_SIZE);
            stdout.write(data, 0, bytesRead);
            stdout.flush();
        }

    } catch (LineUnavailableException ex) {
        System.out.println("Line is unavailable.");
        ex.printStackTrace();
    }

At the moment, no communication seems to be made between both commands as
ffmpeg isn't receiving anything.

Hope you guys can tell what I'm missing out, or if I'm incorrectly working
with the library thinking it works in a way when it works in another one.

Re: [exec] Misconcepting PumpStreamHandler's way of working with streams?

Posted by Edgar H <ka...@gmail.com>.
Perfect, I'll modify my current project later with the changes you made.

Thank you so much for dedicating a little bit of your time looking for the
issue.

All the best,
Edgar

2017-02-09 0:54 GMT+01:00 Raymond DeCampo <ra...@decampo.org>:

> OK, Edgar I pared your example down a bunch and got to a working demo.  I
> submitted it as a pull request against the repo you created.  I think the
> key thing was not re-using the executors.
>
> This should be enough for you to start modifying it back into what you
> needed it to be.
>
> HTH,
> Ray
>
> On Mon, Feb 6, 2017 at 12:00 PM, Edgar H <ka...@gmail.com> wrote:
>
> > Completly forgot about ffmpeg being Windows compilation, sorry for that.
> >
> > I've already updated the git project, even though ffmpeg and Icecast
> still
> > there (I don't really know why...) the new classes don't use them
> anymore.
> >
> >
> > 2017-02-06 13:43 GMT+01:00 Raymond DeCampo <ra...@decampo.org>:
> >
> > > Well, we are still going to run into issues when I try it on my Linux
> > > machine.
> > >
> > > I'd suggest just leaving ffmpeg out of it.  Make a pair of simple Java
> > > classes which take a file and output to standard out and then one which
> > > reads from standard in and writes to a file; then a main class which
> > starts
> > > processes for the other two and hooks them up.
> > >
> > >
> > > On Sun, Feb 5, 2017 at 7:04 PM, Edgar H <ka...@gmail.com> wrote:
> > >
> > > > There it goes, here is the link for the git repo.
> > > >
> > > > https://github.com/turbobrick/exec_dmo
> > > >
> > > > I've included ffmpeg and also Icecast so you can start the server in
> > your
> > > > machine via console and see if the mount "/stream" is active at
> > > > 127.0.0.1:8000 once you start streaming audio from the system via
> the
> > > test
> > > > app. An already compiled .jar from the SecondApp class has already
> been
> > > > generated, and it is inside /bin folder in /ffmpeg. Everything should
> > be
> > > > ready to go.
> > > >
> > > > Thanks for helping, really appreciated.
> > > >
> > > > 2017-02-05 22:51 GMT+01:00 Raymond DeCampo <ra...@decampo.org>:
> > > >
> > > > > If I were to try to run this on my system, it would fail because
> > there
> > > is
> > > > > no ffmpeg.exe file on my machine.
> > > > >
> > > > > You need to make it easier for me to help you by making a truly
> > > > > self-contained minimal example of the issue (see
> > > > > http://www.catb.org/~esr/faqs/smart-questions.html#code for more
> > > details
> > > > > on
> > > > > this).  Preferably the example will contain a pom.xml so it can be
> > > built
> > > > > easily and maybe put in on a gist in github so it can be downloaded
> > > > easily.
> > > > >
> > > > >
> > > > >
> > > > > On Sun, Feb 5, 2017 at 3:46 PM, Edgar H <ka...@gmail.com>
> wrote:
> > > > >
> > > > > > Sure, here's a minimal example.
> > > > > >
> > > > > > The following code belongs to a "MainApp" class, which is the
> > > basically
> > > > > the
> > > > > > application which starts the .jar responsible of capturing live
> > audio
> > > > > data
> > > > > > from the system and sending it live to FFMPEG, which streams to
> an
> > > > > Icecast
> > > > > > Server, like a continuous stream using pipes.
> > > > > >
> > > > > > public class MainApp {
> > > > > >
> > > > > >     public static void main(String[] args) {
> > > > > >         initStream("Path to FFMPEG bin folder, which should
> include
> > > the
> > > > > > .jar of the second application that you need to copy and
> paste.");
> > > > > >     }
> > > > > >
> > > > > >     public static void initStream(String path) {
> > > > > >         File file = new File(path);
> > > > > >         for (File s : file.listFiles()) {
> > > > > >             if (s.getName().equals("ffmpeg.exe")) {
> > > > > >                 try {
> > > > > >                     DefaultExecutor executor = new
> > DefaultExecutor();
> > > > > >                     executor.setWorkingDirectory(file);
> > > > > >
> > > > > >                     CommandLine commandLine = new
> > > > > > CommandLine(s.getParentFile().getAbsolutePath());
> > > > > >                     System.out.println("Path: " +
> > > > > commandLine.toString());
> > > > > >
> > > > > >                     String executeMe = "java -jar secondapp.jar";
> > //
> > > > > > Execute "SecondApp" .jar to start sending sound bytes to stdout.
> > > > > >                     commandLine = CommandLine.parse(executeMe);
> > > > > >
> > > > > >                     PipedOutputStream output = new
> > > PipedOutputStream();
> > > > > //
> > > > > > Fill this with bytes.
> > > > > >                     PipedInputStream input = new
> > PipedInputStream();
> > > > > >                     output.connect(input); // Send audio bytes
> from
> > > > > output
> > > > > > to this input stream.
> > > > > >
> > > > > >                     executor.setStreamHandler(new
> > > > > PumpStreamHandler(output,
> > > > > > null)); // Stream all the bytes to the output.
> > > > > >                     executor.execute(commandLine, new
> > > > > > DefaultExecuteResultHandler()); // Execute APP2 (The one which
> > > > captures
> > > > > > the
> > > > > > live audio bytes).
> > > > > >
> > > > > >                     String feedMe = "ffmpeg -f s16le -ar 48000
> -ac
> > 2
> > > > -i -
> > > > > > -f ogg -content_type application/ogg icecast://source:hackme@
> > > localhost
> > > > > > :8000/stream";
> > > > > >                     commandLine = CommandLine.parse(feedMe);
> > > > > >
> > > > > >                     executor.setStreamHandler(new
> > > > PumpStreamHandler(null,
> > > > > > null, input)); // Send the bytes being received in real time to
> > > FFMPEG.
> > > > > >                     executor.execute(commandLine, new
> > > > > > DefaultExecuteResultHandler()); // Execute FFMPEG.
> > > > > >                 } catch (IOException e) {
> > > > > >                     e.printStackTrace();
> > > > > >                 }
> > > > > >             }
> > > > > >         }
> > > > > >     }
> > > > > > }
> > > > > >
> > > > > > Now, this is the code for the executable .jar which is the class
> > > > > > "SecondApp". This one just sends bytes to the Standard Output and
> > > it's
> > > > > > started by "MainApp".
> > > > > >
> > > > > > public class SecondApp {
> > > > > >
> > > > > >     public static void main(String[] args) throws
> > > > ClassNotFoundException,
> > > > > > IOException {
> > > > > >         Mixer mixer =
> > > > > > AudioSystem.getMixer(AudioSystem.getMixerInfo()[
> > > > > > Integer.parseInt(args[0])]);
> > > > > >         AudioFormat af = new AudioFormat(Encoding.PCM_SIGNED,
> > > 48000f,
> > > > > 16,
> > > > > > 2, 4, 48000f, false);
> > > > > >
> > > > > >         TargetDataLine line;
> > > > > >         DataLine.Info info = new DataLine.Info(TargetDataLine.
> > class,
> > > > > af);
> > > > > >         if (!AudioSystem.isLineSupported(info))
> > > > > >             System.out.println("Line is not supported.");
> > > > > >
> > > > > >         try {
> > > > > >             line = (TargetDataLine) mixer.getLine(info);
> > > > > >             line.open(af);
> > > > > >
> > > > > >             int bytesRead, CHUNK_SIZE = 4096;
> > > > > >             byte[] data = new byte[line.getBufferSize() / 5];
> > > > > >
> > > > > >             line.start();
> > > > > >
> > > > > >             while (true) {
> > > > > >                 bytesRead = line.read(data, 0, CHUNK_SIZE);
> > > > > >                 System.out.write(data, 0, bytesRead);
> > > > > >                 System.out.flush();
> > > > > >             }
> > > > > >
> > > > > >         } catch (LineUnavailableException ex) {
> > > > > >             System.out.println("Line is unavailable.");
> > > > > >             ex.printStackTrace();
> > > > > >         }
> > > > > >     }
> > > > > > }
> > > > > >
> > > > > > 2017-02-05 16:31 GMT+01:00 Raymond DeCampo <ra...@decampo.org>:
> > > > > >
> > > > > > > Edgar, I didn't see anything obvious wrong with what you
> posted.
> > > If
> > > > > you
> > > > > > > can distill it down to a minimal self-contained example that
> > > > reproduces
> > > > > > the
> > > > > > > behavior I can take a closer look.
> > > > > > >
> > > > > > > On Sat, Feb 4, 2017 at 1:47 PM, Edgar H <ka...@gmail.com>
> > > wrote:
> > > > > > >
> > > > > > > > I've been struggling with this problem for quite some time
> now
> > as
> > > > > it's
> > > > > > my
> > > > > > > > very first time doing an application related to streaming
> and I
> > > > just
> > > > > > > can't
> > > > > > > > figure out why. Here's the problem...
> > > > > > > >
> > > > > > > > What I'm trying to achieve is to send a command's output as
> an
> > > > input
> > > > > > for
> > > > > > > > the next one, which is basically what the pipe operator does.
> > As
> > > I
> > > > > knew
> > > > > > > > this couldn't be executed directly with Exec library from
> > Apache
> > > > > > Commons
> > > > > > > I
> > > > > > > > started looking for ways to solve this. I've seen quite a few
> > > > > examples
> > > > > > of
> > > > > > > > similar things to this but none of them covers my situation:
> > > > > > > >
> > > > > > > > I have two Java applications separated, one is the main
> > > application
> > > > > and
> > > > > > > the
> > > > > > > > second one is initialized by the first one. This second
> > > > applications
> > > > > > > sends
> > > > > > > > to the Standard Output bytes, which FFMPEG should receive.
> > > > > > > >
> > > > > > > > The code that I have so far is the following one...
> > > > > > > >
> > > > > > > > public void initStream(String path) {
> > > > > > > >     File file = new File(path);
> > > > > > > >     for (File s : file.listFiles()) {
> > > > > > > >         if (s.getName().equals("ffmpeg.exe")) {
> > > > > > > >             try {
> > > > > > > >
> > > > > > > >                 // Second app, supposedly, writes here.
> > > > > > > >                 PipedOutputStream output = new
> > > PipedOutputStream();
> > > > > > > >
> > > > > > > >                 DefaultExecutor executor = new
> > DefaultExecutor();
> > > > > > > >                 //DefaultExecutor executorFFMPEG = new
> > > > > > DefaultExecutor();
> > > > > > > >                 executor.setWorkingDirectory(file);
> > > > > > > >                 //executor.setWorkingDirectory(file);
> > > > > > > >
> > > > > > > >                 CommandLine commandLine = new
> > > > > > > > CommandLine(s.getParentFile().getAbsolutePath());
> > > > > > > >                 System.out.println("Path: " +
> > > > > commandLine.toString());
> > > > > > > >
> > > > > > > >                 String executeMe = "java -jar streamer.jar";
> > > > > > > >                 commandLine = CommandLine.parse(executeMe);
> > > > > > > >
> > > > > > > >                 System.out.println("[testing] streamer about
> to
> > > > > > > launch.");
> > > > > > > >                 executor.setStreamHandler(new
> > > > > PumpStreamHandler(output,
> > > > > > > > null));
> > > > > > > >                 executor.execute(commandLine, new
> > > > > > > > DefaultExecuteResultHandler());
> > > > > > > >                 System.out.println("[testing] streamer
> > > started.");
> > > > > > > >
> > > > > > > >                 PipedInputStream input = new
> > PipedInputStream();
> > > > > > > >                 output.connect(input);
> > > > > > > >
> > > > > > > >                 String feedMe = "ffmpeg"; // more attributes
> > here
> > > > > > > >                 commandLine = CommandLine.parse(feedMe);
> > > > > > > >
> > > > > > > >                 System.out.println("[testing] ffmpeg about to
> > > > > > launch.");
> > > > > > > >                 executor.setStreamHandler(new
> > > > PumpStreamHandler(null,
> > > > > > > > null, input));
> > > > > > > >                 executor.execute(commandLine, new
> > > > > > > > DefaultExecuteResultHandler());
> > > > > > > >                 System.out.println("[testing] ffmpeg
> > started.");
> > > > > > > >
> > > > > > > >             } catch (IOException e) {
> > > > > > > >                 e.printStackTrace();
> > > > > > > >             }
> > > > > > > >         }
> > > > > > > >     }}
> > > > > > > >
> > > > > > > > And the code for the second application (the zone where I
> send
> > > data
> > > > > to
> > > > > > > > the stdout) is the following one.
> > > > > > > >
> > > > > > > > static OutputStream stdout = System.out;
> > > > > > > >
> > > > > > > > (more code and other things around here)
> > > > > > > >
> > > > > > > > try {
> > > > > > > >         line = (TargetDataLine) mixer.getLine(info);
> > > > > > > >         line.open(format);
> > > > > > > >
> > > > > > > >         int bytesRead, CHUNK_SIZE = 4096;
> > > > > > > >         byte[] data = new byte[line.getBufferSize() / 5];
> > > > > > > >
> > > > > > > >         line.start();
> > > > > > > >
> > > > > > > >         while (true) {
> > > > > > > >             bytesRead = line.read(data, 0, CHUNK_SIZE);
> > > > > > > >             stdout.write(data, 0, bytesRead);
> > > > > > > >             stdout.flush();
> > > > > > > >         }
> > > > > > > >
> > > > > > > >     } catch (LineUnavailableException ex) {
> > > > > > > >         System.out.println("Line is unavailable.");
> > > > > > > >         ex.printStackTrace();
> > > > > > > >     }
> > > > > > > >
> > > > > > > > At the moment, no communication seems to be made between both
> > > > > commands
> > > > > > as
> > > > > > > > ffmpeg isn't receiving anything.
> > > > > > > >
> > > > > > > > Hope you guys can tell what I'm missing out, or if I'm
> > > incorrectly
> > > > > > > working
> > > > > > > > with the library thinking it works in a way when it works in
> > > > another
> > > > > > one.
> > > > > > > >
> > > > > > >
> > > > > >
> > > > >
> > > >
> > >
> >
>

Re: [exec] Misconcepting PumpStreamHandler's way of working with streams?

Posted by Raymond DeCampo <ra...@decampo.org>.
OK, Edgar I pared your example down a bunch and got to a working demo.  I
submitted it as a pull request against the repo you created.  I think the
key thing was not re-using the executors.

This should be enough for you to start modifying it back into what you
needed it to be.

HTH,
Ray

On Mon, Feb 6, 2017 at 12:00 PM, Edgar H <ka...@gmail.com> wrote:

> Completly forgot about ffmpeg being Windows compilation, sorry for that.
>
> I've already updated the git project, even though ffmpeg and Icecast still
> there (I don't really know why...) the new classes don't use them anymore.
>
>
> 2017-02-06 13:43 GMT+01:00 Raymond DeCampo <ra...@decampo.org>:
>
> > Well, we are still going to run into issues when I try it on my Linux
> > machine.
> >
> > I'd suggest just leaving ffmpeg out of it.  Make a pair of simple Java
> > classes which take a file and output to standard out and then one which
> > reads from standard in and writes to a file; then a main class which
> starts
> > processes for the other two and hooks them up.
> >
> >
> > On Sun, Feb 5, 2017 at 7:04 PM, Edgar H <ka...@gmail.com> wrote:
> >
> > > There it goes, here is the link for the git repo.
> > >
> > > https://github.com/turbobrick/exec_dmo
> > >
> > > I've included ffmpeg and also Icecast so you can start the server in
> your
> > > machine via console and see if the mount "/stream" is active at
> > > 127.0.0.1:8000 once you start streaming audio from the system via the
> > test
> > > app. An already compiled .jar from the SecondApp class has already been
> > > generated, and it is inside /bin folder in /ffmpeg. Everything should
> be
> > > ready to go.
> > >
> > > Thanks for helping, really appreciated.
> > >
> > > 2017-02-05 22:51 GMT+01:00 Raymond DeCampo <ra...@decampo.org>:
> > >
> > > > If I were to try to run this on my system, it would fail because
> there
> > is
> > > > no ffmpeg.exe file on my machine.
> > > >
> > > > You need to make it easier for me to help you by making a truly
> > > > self-contained minimal example of the issue (see
> > > > http://www.catb.org/~esr/faqs/smart-questions.html#code for more
> > details
> > > > on
> > > > this).  Preferably the example will contain a pom.xml so it can be
> > built
> > > > easily and maybe put in on a gist in github so it can be downloaded
> > > easily.
> > > >
> > > >
> > > >
> > > > On Sun, Feb 5, 2017 at 3:46 PM, Edgar H <ka...@gmail.com> wrote:
> > > >
> > > > > Sure, here's a minimal example.
> > > > >
> > > > > The following code belongs to a "MainApp" class, which is the
> > basically
> > > > the
> > > > > application which starts the .jar responsible of capturing live
> audio
> > > > data
> > > > > from the system and sending it live to FFMPEG, which streams to an
> > > > Icecast
> > > > > Server, like a continuous stream using pipes.
> > > > >
> > > > > public class MainApp {
> > > > >
> > > > >     public static void main(String[] args) {
> > > > >         initStream("Path to FFMPEG bin folder, which should include
> > the
> > > > > .jar of the second application that you need to copy and paste.");
> > > > >     }
> > > > >
> > > > >     public static void initStream(String path) {
> > > > >         File file = new File(path);
> > > > >         for (File s : file.listFiles()) {
> > > > >             if (s.getName().equals("ffmpeg.exe")) {
> > > > >                 try {
> > > > >                     DefaultExecutor executor = new
> DefaultExecutor();
> > > > >                     executor.setWorkingDirectory(file);
> > > > >
> > > > >                     CommandLine commandLine = new
> > > > > CommandLine(s.getParentFile().getAbsolutePath());
> > > > >                     System.out.println("Path: " +
> > > > commandLine.toString());
> > > > >
> > > > >                     String executeMe = "java -jar secondapp.jar";
> //
> > > > > Execute "SecondApp" .jar to start sending sound bytes to stdout.
> > > > >                     commandLine = CommandLine.parse(executeMe);
> > > > >
> > > > >                     PipedOutputStream output = new
> > PipedOutputStream();
> > > > //
> > > > > Fill this with bytes.
> > > > >                     PipedInputStream input = new
> PipedInputStream();
> > > > >                     output.connect(input); // Send audio bytes from
> > > > output
> > > > > to this input stream.
> > > > >
> > > > >                     executor.setStreamHandler(new
> > > > PumpStreamHandler(output,
> > > > > null)); // Stream all the bytes to the output.
> > > > >                     executor.execute(commandLine, new
> > > > > DefaultExecuteResultHandler()); // Execute APP2 (The one which
> > > captures
> > > > > the
> > > > > live audio bytes).
> > > > >
> > > > >                     String feedMe = "ffmpeg -f s16le -ar 48000 -ac
> 2
> > > -i -
> > > > > -f ogg -content_type application/ogg icecast://source:hackme@
> > localhost
> > > > > :8000/stream";
> > > > >                     commandLine = CommandLine.parse(feedMe);
> > > > >
> > > > >                     executor.setStreamHandler(new
> > > PumpStreamHandler(null,
> > > > > null, input)); // Send the bytes being received in real time to
> > FFMPEG.
> > > > >                     executor.execute(commandLine, new
> > > > > DefaultExecuteResultHandler()); // Execute FFMPEG.
> > > > >                 } catch (IOException e) {
> > > > >                     e.printStackTrace();
> > > > >                 }
> > > > >             }
> > > > >         }
> > > > >     }
> > > > > }
> > > > >
> > > > > Now, this is the code for the executable .jar which is the class
> > > > > "SecondApp". This one just sends bytes to the Standard Output and
> > it's
> > > > > started by "MainApp".
> > > > >
> > > > > public class SecondApp {
> > > > >
> > > > >     public static void main(String[] args) throws
> > > ClassNotFoundException,
> > > > > IOException {
> > > > >         Mixer mixer =
> > > > > AudioSystem.getMixer(AudioSystem.getMixerInfo()[
> > > > > Integer.parseInt(args[0])]);
> > > > >         AudioFormat af = new AudioFormat(Encoding.PCM_SIGNED,
> > 48000f,
> > > > 16,
> > > > > 2, 4, 48000f, false);
> > > > >
> > > > >         TargetDataLine line;
> > > > >         DataLine.Info info = new DataLine.Info(TargetDataLine.
> class,
> > > > af);
> > > > >         if (!AudioSystem.isLineSupported(info))
> > > > >             System.out.println("Line is not supported.");
> > > > >
> > > > >         try {
> > > > >             line = (TargetDataLine) mixer.getLine(info);
> > > > >             line.open(af);
> > > > >
> > > > >             int bytesRead, CHUNK_SIZE = 4096;
> > > > >             byte[] data = new byte[line.getBufferSize() / 5];
> > > > >
> > > > >             line.start();
> > > > >
> > > > >             while (true) {
> > > > >                 bytesRead = line.read(data, 0, CHUNK_SIZE);
> > > > >                 System.out.write(data, 0, bytesRead);
> > > > >                 System.out.flush();
> > > > >             }
> > > > >
> > > > >         } catch (LineUnavailableException ex) {
> > > > >             System.out.println("Line is unavailable.");
> > > > >             ex.printStackTrace();
> > > > >         }
> > > > >     }
> > > > > }
> > > > >
> > > > > 2017-02-05 16:31 GMT+01:00 Raymond DeCampo <ra...@decampo.org>:
> > > > >
> > > > > > Edgar, I didn't see anything obvious wrong with what you posted.
> > If
> > > > you
> > > > > > can distill it down to a minimal self-contained example that
> > > reproduces
> > > > > the
> > > > > > behavior I can take a closer look.
> > > > > >
> > > > > > On Sat, Feb 4, 2017 at 1:47 PM, Edgar H <ka...@gmail.com>
> > wrote:
> > > > > >
> > > > > > > I've been struggling with this problem for quite some time now
> as
> > > > it's
> > > > > my
> > > > > > > very first time doing an application related to streaming and I
> > > just
> > > > > > can't
> > > > > > > figure out why. Here's the problem...
> > > > > > >
> > > > > > > What I'm trying to achieve is to send a command's output as an
> > > input
> > > > > for
> > > > > > > the next one, which is basically what the pipe operator does.
> As
> > I
> > > > knew
> > > > > > > this couldn't be executed directly with Exec library from
> Apache
> > > > > Commons
> > > > > > I
> > > > > > > started looking for ways to solve this. I've seen quite a few
> > > > examples
> > > > > of
> > > > > > > similar things to this but none of them covers my situation:
> > > > > > >
> > > > > > > I have two Java applications separated, one is the main
> > application
> > > > and
> > > > > > the
> > > > > > > second one is initialized by the first one. This second
> > > applications
> > > > > > sends
> > > > > > > to the Standard Output bytes, which FFMPEG should receive.
> > > > > > >
> > > > > > > The code that I have so far is the following one...
> > > > > > >
> > > > > > > public void initStream(String path) {
> > > > > > >     File file = new File(path);
> > > > > > >     for (File s : file.listFiles()) {
> > > > > > >         if (s.getName().equals("ffmpeg.exe")) {
> > > > > > >             try {
> > > > > > >
> > > > > > >                 // Second app, supposedly, writes here.
> > > > > > >                 PipedOutputStream output = new
> > PipedOutputStream();
> > > > > > >
> > > > > > >                 DefaultExecutor executor = new
> DefaultExecutor();
> > > > > > >                 //DefaultExecutor executorFFMPEG = new
> > > > > DefaultExecutor();
> > > > > > >                 executor.setWorkingDirectory(file);
> > > > > > >                 //executor.setWorkingDirectory(file);
> > > > > > >
> > > > > > >                 CommandLine commandLine = new
> > > > > > > CommandLine(s.getParentFile().getAbsolutePath());
> > > > > > >                 System.out.println("Path: " +
> > > > commandLine.toString());
> > > > > > >
> > > > > > >                 String executeMe = "java -jar streamer.jar";
> > > > > > >                 commandLine = CommandLine.parse(executeMe);
> > > > > > >
> > > > > > >                 System.out.println("[testing] streamer about to
> > > > > > launch.");
> > > > > > >                 executor.setStreamHandler(new
> > > > PumpStreamHandler(output,
> > > > > > > null));
> > > > > > >                 executor.execute(commandLine, new
> > > > > > > DefaultExecuteResultHandler());
> > > > > > >                 System.out.println("[testing] streamer
> > started.");
> > > > > > >
> > > > > > >                 PipedInputStream input = new
> PipedInputStream();
> > > > > > >                 output.connect(input);
> > > > > > >
> > > > > > >                 String feedMe = "ffmpeg"; // more attributes
> here
> > > > > > >                 commandLine = CommandLine.parse(feedMe);
> > > > > > >
> > > > > > >                 System.out.println("[testing] ffmpeg about to
> > > > > launch.");
> > > > > > >                 executor.setStreamHandler(new
> > > PumpStreamHandler(null,
> > > > > > > null, input));
> > > > > > >                 executor.execute(commandLine, new
> > > > > > > DefaultExecuteResultHandler());
> > > > > > >                 System.out.println("[testing] ffmpeg
> started.");
> > > > > > >
> > > > > > >             } catch (IOException e) {
> > > > > > >                 e.printStackTrace();
> > > > > > >             }
> > > > > > >         }
> > > > > > >     }}
> > > > > > >
> > > > > > > And the code for the second application (the zone where I send
> > data
> > > > to
> > > > > > > the stdout) is the following one.
> > > > > > >
> > > > > > > static OutputStream stdout = System.out;
> > > > > > >
> > > > > > > (more code and other things around here)
> > > > > > >
> > > > > > > try {
> > > > > > >         line = (TargetDataLine) mixer.getLine(info);
> > > > > > >         line.open(format);
> > > > > > >
> > > > > > >         int bytesRead, CHUNK_SIZE = 4096;
> > > > > > >         byte[] data = new byte[line.getBufferSize() / 5];
> > > > > > >
> > > > > > >         line.start();
> > > > > > >
> > > > > > >         while (true) {
> > > > > > >             bytesRead = line.read(data, 0, CHUNK_SIZE);
> > > > > > >             stdout.write(data, 0, bytesRead);
> > > > > > >             stdout.flush();
> > > > > > >         }
> > > > > > >
> > > > > > >     } catch (LineUnavailableException ex) {
> > > > > > >         System.out.println("Line is unavailable.");
> > > > > > >         ex.printStackTrace();
> > > > > > >     }
> > > > > > >
> > > > > > > At the moment, no communication seems to be made between both
> > > > commands
> > > > > as
> > > > > > > ffmpeg isn't receiving anything.
> > > > > > >
> > > > > > > Hope you guys can tell what I'm missing out, or if I'm
> > incorrectly
> > > > > > working
> > > > > > > with the library thinking it works in a way when it works in
> > > another
> > > > > one.
> > > > > > >
> > > > > >
> > > > >
> > > >
> > >
> >
>

Re: [exec] Misconcepting PumpStreamHandler's way of working with streams?

Posted by Edgar H <ka...@gmail.com>.
Completly forgot about ffmpeg being Windows compilation, sorry for that.

I've already updated the git project, even though ffmpeg and Icecast still
there (I don't really know why...) the new classes don't use them anymore.


2017-02-06 13:43 GMT+01:00 Raymond DeCampo <ra...@decampo.org>:

> Well, we are still going to run into issues when I try it on my Linux
> machine.
>
> I'd suggest just leaving ffmpeg out of it.  Make a pair of simple Java
> classes which take a file and output to standard out and then one which
> reads from standard in and writes to a file; then a main class which starts
> processes for the other two and hooks them up.
>
>
> On Sun, Feb 5, 2017 at 7:04 PM, Edgar H <ka...@gmail.com> wrote:
>
> > There it goes, here is the link for the git repo.
> >
> > https://github.com/turbobrick/exec_dmo
> >
> > I've included ffmpeg and also Icecast so you can start the server in your
> > machine via console and see if the mount "/stream" is active at
> > 127.0.0.1:8000 once you start streaming audio from the system via the
> test
> > app. An already compiled .jar from the SecondApp class has already been
> > generated, and it is inside /bin folder in /ffmpeg. Everything should be
> > ready to go.
> >
> > Thanks for helping, really appreciated.
> >
> > 2017-02-05 22:51 GMT+01:00 Raymond DeCampo <ra...@decampo.org>:
> >
> > > If I were to try to run this on my system, it would fail because there
> is
> > > no ffmpeg.exe file on my machine.
> > >
> > > You need to make it easier for me to help you by making a truly
> > > self-contained minimal example of the issue (see
> > > http://www.catb.org/~esr/faqs/smart-questions.html#code for more
> details
> > > on
> > > this).  Preferably the example will contain a pom.xml so it can be
> built
> > > easily and maybe put in on a gist in github so it can be downloaded
> > easily.
> > >
> > >
> > >
> > > On Sun, Feb 5, 2017 at 3:46 PM, Edgar H <ka...@gmail.com> wrote:
> > >
> > > > Sure, here's a minimal example.
> > > >
> > > > The following code belongs to a "MainApp" class, which is the
> basically
> > > the
> > > > application which starts the .jar responsible of capturing live audio
> > > data
> > > > from the system and sending it live to FFMPEG, which streams to an
> > > Icecast
> > > > Server, like a continuous stream using pipes.
> > > >
> > > > public class MainApp {
> > > >
> > > >     public static void main(String[] args) {
> > > >         initStream("Path to FFMPEG bin folder, which should include
> the
> > > > .jar of the second application that you need to copy and paste.");
> > > >     }
> > > >
> > > >     public static void initStream(String path) {
> > > >         File file = new File(path);
> > > >         for (File s : file.listFiles()) {
> > > >             if (s.getName().equals("ffmpeg.exe")) {
> > > >                 try {
> > > >                     DefaultExecutor executor = new DefaultExecutor();
> > > >                     executor.setWorkingDirectory(file);
> > > >
> > > >                     CommandLine commandLine = new
> > > > CommandLine(s.getParentFile().getAbsolutePath());
> > > >                     System.out.println("Path: " +
> > > commandLine.toString());
> > > >
> > > >                     String executeMe = "java -jar secondapp.jar"; //
> > > > Execute "SecondApp" .jar to start sending sound bytes to stdout.
> > > >                     commandLine = CommandLine.parse(executeMe);
> > > >
> > > >                     PipedOutputStream output = new
> PipedOutputStream();
> > > //
> > > > Fill this with bytes.
> > > >                     PipedInputStream input = new PipedInputStream();
> > > >                     output.connect(input); // Send audio bytes from
> > > output
> > > > to this input stream.
> > > >
> > > >                     executor.setStreamHandler(new
> > > PumpStreamHandler(output,
> > > > null)); // Stream all the bytes to the output.
> > > >                     executor.execute(commandLine, new
> > > > DefaultExecuteResultHandler()); // Execute APP2 (The one which
> > captures
> > > > the
> > > > live audio bytes).
> > > >
> > > >                     String feedMe = "ffmpeg -f s16le -ar 48000 -ac 2
> > -i -
> > > > -f ogg -content_type application/ogg icecast://source:hackme@
> localhost
> > > > :8000/stream";
> > > >                     commandLine = CommandLine.parse(feedMe);
> > > >
> > > >                     executor.setStreamHandler(new
> > PumpStreamHandler(null,
> > > > null, input)); // Send the bytes being received in real time to
> FFMPEG.
> > > >                     executor.execute(commandLine, new
> > > > DefaultExecuteResultHandler()); // Execute FFMPEG.
> > > >                 } catch (IOException e) {
> > > >                     e.printStackTrace();
> > > >                 }
> > > >             }
> > > >         }
> > > >     }
> > > > }
> > > >
> > > > Now, this is the code for the executable .jar which is the class
> > > > "SecondApp". This one just sends bytes to the Standard Output and
> it's
> > > > started by "MainApp".
> > > >
> > > > public class SecondApp {
> > > >
> > > >     public static void main(String[] args) throws
> > ClassNotFoundException,
> > > > IOException {
> > > >         Mixer mixer =
> > > > AudioSystem.getMixer(AudioSystem.getMixerInfo()[
> > > > Integer.parseInt(args[0])]);
> > > >         AudioFormat af = new AudioFormat(Encoding.PCM_SIGNED,
> 48000f,
> > > 16,
> > > > 2, 4, 48000f, false);
> > > >
> > > >         TargetDataLine line;
> > > >         DataLine.Info info = new DataLine.Info(TargetDataLine.class,
> > > af);
> > > >         if (!AudioSystem.isLineSupported(info))
> > > >             System.out.println("Line is not supported.");
> > > >
> > > >         try {
> > > >             line = (TargetDataLine) mixer.getLine(info);
> > > >             line.open(af);
> > > >
> > > >             int bytesRead, CHUNK_SIZE = 4096;
> > > >             byte[] data = new byte[line.getBufferSize() / 5];
> > > >
> > > >             line.start();
> > > >
> > > >             while (true) {
> > > >                 bytesRead = line.read(data, 0, CHUNK_SIZE);
> > > >                 System.out.write(data, 0, bytesRead);
> > > >                 System.out.flush();
> > > >             }
> > > >
> > > >         } catch (LineUnavailableException ex) {
> > > >             System.out.println("Line is unavailable.");
> > > >             ex.printStackTrace();
> > > >         }
> > > >     }
> > > > }
> > > >
> > > > 2017-02-05 16:31 GMT+01:00 Raymond DeCampo <ra...@decampo.org>:
> > > >
> > > > > Edgar, I didn't see anything obvious wrong with what you posted.
> If
> > > you
> > > > > can distill it down to a minimal self-contained example that
> > reproduces
> > > > the
> > > > > behavior I can take a closer look.
> > > > >
> > > > > On Sat, Feb 4, 2017 at 1:47 PM, Edgar H <ka...@gmail.com>
> wrote:
> > > > >
> > > > > > I've been struggling with this problem for quite some time now as
> > > it's
> > > > my
> > > > > > very first time doing an application related to streaming and I
> > just
> > > > > can't
> > > > > > figure out why. Here's the problem...
> > > > > >
> > > > > > What I'm trying to achieve is to send a command's output as an
> > input
> > > > for
> > > > > > the next one, which is basically what the pipe operator does. As
> I
> > > knew
> > > > > > this couldn't be executed directly with Exec library from Apache
> > > > Commons
> > > > > I
> > > > > > started looking for ways to solve this. I've seen quite a few
> > > examples
> > > > of
> > > > > > similar things to this but none of them covers my situation:
> > > > > >
> > > > > > I have two Java applications separated, one is the main
> application
> > > and
> > > > > the
> > > > > > second one is initialized by the first one. This second
> > applications
> > > > > sends
> > > > > > to the Standard Output bytes, which FFMPEG should receive.
> > > > > >
> > > > > > The code that I have so far is the following one...
> > > > > >
> > > > > > public void initStream(String path) {
> > > > > >     File file = new File(path);
> > > > > >     for (File s : file.listFiles()) {
> > > > > >         if (s.getName().equals("ffmpeg.exe")) {
> > > > > >             try {
> > > > > >
> > > > > >                 // Second app, supposedly, writes here.
> > > > > >                 PipedOutputStream output = new
> PipedOutputStream();
> > > > > >
> > > > > >                 DefaultExecutor executor = new DefaultExecutor();
> > > > > >                 //DefaultExecutor executorFFMPEG = new
> > > > DefaultExecutor();
> > > > > >                 executor.setWorkingDirectory(file);
> > > > > >                 //executor.setWorkingDirectory(file);
> > > > > >
> > > > > >                 CommandLine commandLine = new
> > > > > > CommandLine(s.getParentFile().getAbsolutePath());
> > > > > >                 System.out.println("Path: " +
> > > commandLine.toString());
> > > > > >
> > > > > >                 String executeMe = "java -jar streamer.jar";
> > > > > >                 commandLine = CommandLine.parse(executeMe);
> > > > > >
> > > > > >                 System.out.println("[testing] streamer about to
> > > > > launch.");
> > > > > >                 executor.setStreamHandler(new
> > > PumpStreamHandler(output,
> > > > > > null));
> > > > > >                 executor.execute(commandLine, new
> > > > > > DefaultExecuteResultHandler());
> > > > > >                 System.out.println("[testing] streamer
> started.");
> > > > > >
> > > > > >                 PipedInputStream input = new PipedInputStream();
> > > > > >                 output.connect(input);
> > > > > >
> > > > > >                 String feedMe = "ffmpeg"; // more attributes here
> > > > > >                 commandLine = CommandLine.parse(feedMe);
> > > > > >
> > > > > >                 System.out.println("[testing] ffmpeg about to
> > > > launch.");
> > > > > >                 executor.setStreamHandler(new
> > PumpStreamHandler(null,
> > > > > > null, input));
> > > > > >                 executor.execute(commandLine, new
> > > > > > DefaultExecuteResultHandler());
> > > > > >                 System.out.println("[testing] ffmpeg started.");
> > > > > >
> > > > > >             } catch (IOException e) {
> > > > > >                 e.printStackTrace();
> > > > > >             }
> > > > > >         }
> > > > > >     }}
> > > > > >
> > > > > > And the code for the second application (the zone where I send
> data
> > > to
> > > > > > the stdout) is the following one.
> > > > > >
> > > > > > static OutputStream stdout = System.out;
> > > > > >
> > > > > > (more code and other things around here)
> > > > > >
> > > > > > try {
> > > > > >         line = (TargetDataLine) mixer.getLine(info);
> > > > > >         line.open(format);
> > > > > >
> > > > > >         int bytesRead, CHUNK_SIZE = 4096;
> > > > > >         byte[] data = new byte[line.getBufferSize() / 5];
> > > > > >
> > > > > >         line.start();
> > > > > >
> > > > > >         while (true) {
> > > > > >             bytesRead = line.read(data, 0, CHUNK_SIZE);
> > > > > >             stdout.write(data, 0, bytesRead);
> > > > > >             stdout.flush();
> > > > > >         }
> > > > > >
> > > > > >     } catch (LineUnavailableException ex) {
> > > > > >         System.out.println("Line is unavailable.");
> > > > > >         ex.printStackTrace();
> > > > > >     }
> > > > > >
> > > > > > At the moment, no communication seems to be made between both
> > > commands
> > > > as
> > > > > > ffmpeg isn't receiving anything.
> > > > > >
> > > > > > Hope you guys can tell what I'm missing out, or if I'm
> incorrectly
> > > > > working
> > > > > > with the library thinking it works in a way when it works in
> > another
> > > > one.
> > > > > >
> > > > >
> > > >
> > >
> >
>

Re: [exec] Misconcepting PumpStreamHandler's way of working with streams?

Posted by Raymond DeCampo <ra...@decampo.org>.
Well, we are still going to run into issues when I try it on my Linux
machine.

I'd suggest just leaving ffmpeg out of it.  Make a pair of simple Java
classes which take a file and output to standard out and then one which
reads from standard in and writes to a file; then a main class which starts
processes for the other two and hooks them up.


On Sun, Feb 5, 2017 at 7:04 PM, Edgar H <ka...@gmail.com> wrote:

> There it goes, here is the link for the git repo.
>
> https://github.com/turbobrick/exec_dmo
>
> I've included ffmpeg and also Icecast so you can start the server in your
> machine via console and see if the mount "/stream" is active at
> 127.0.0.1:8000 once you start streaming audio from the system via the test
> app. An already compiled .jar from the SecondApp class has already been
> generated, and it is inside /bin folder in /ffmpeg. Everything should be
> ready to go.
>
> Thanks for helping, really appreciated.
>
> 2017-02-05 22:51 GMT+01:00 Raymond DeCampo <ra...@decampo.org>:
>
> > If I were to try to run this on my system, it would fail because there is
> > no ffmpeg.exe file on my machine.
> >
> > You need to make it easier for me to help you by making a truly
> > self-contained minimal example of the issue (see
> > http://www.catb.org/~esr/faqs/smart-questions.html#code for more details
> > on
> > this).  Preferably the example will contain a pom.xml so it can be built
> > easily and maybe put in on a gist in github so it can be downloaded
> easily.
> >
> >
> >
> > On Sun, Feb 5, 2017 at 3:46 PM, Edgar H <ka...@gmail.com> wrote:
> >
> > > Sure, here's a minimal example.
> > >
> > > The following code belongs to a "MainApp" class, which is the basically
> > the
> > > application which starts the .jar responsible of capturing live audio
> > data
> > > from the system and sending it live to FFMPEG, which streams to an
> > Icecast
> > > Server, like a continuous stream using pipes.
> > >
> > > public class MainApp {
> > >
> > >     public static void main(String[] args) {
> > >         initStream("Path to FFMPEG bin folder, which should include the
> > > .jar of the second application that you need to copy and paste.");
> > >     }
> > >
> > >     public static void initStream(String path) {
> > >         File file = new File(path);
> > >         for (File s : file.listFiles()) {
> > >             if (s.getName().equals("ffmpeg.exe")) {
> > >                 try {
> > >                     DefaultExecutor executor = new DefaultExecutor();
> > >                     executor.setWorkingDirectory(file);
> > >
> > >                     CommandLine commandLine = new
> > > CommandLine(s.getParentFile().getAbsolutePath());
> > >                     System.out.println("Path: " +
> > commandLine.toString());
> > >
> > >                     String executeMe = "java -jar secondapp.jar"; //
> > > Execute "SecondApp" .jar to start sending sound bytes to stdout.
> > >                     commandLine = CommandLine.parse(executeMe);
> > >
> > >                     PipedOutputStream output = new PipedOutputStream();
> > //
> > > Fill this with bytes.
> > >                     PipedInputStream input = new PipedInputStream();
> > >                     output.connect(input); // Send audio bytes from
> > output
> > > to this input stream.
> > >
> > >                     executor.setStreamHandler(new
> > PumpStreamHandler(output,
> > > null)); // Stream all the bytes to the output.
> > >                     executor.execute(commandLine, new
> > > DefaultExecuteResultHandler()); // Execute APP2 (The one which
> captures
> > > the
> > > live audio bytes).
> > >
> > >                     String feedMe = "ffmpeg -f s16le -ar 48000 -ac 2
> -i -
> > > -f ogg -content_type application/ogg icecast://source:hackme@localhost
> > > :8000/stream";
> > >                     commandLine = CommandLine.parse(feedMe);
> > >
> > >                     executor.setStreamHandler(new
> PumpStreamHandler(null,
> > > null, input)); // Send the bytes being received in real time to FFMPEG.
> > >                     executor.execute(commandLine, new
> > > DefaultExecuteResultHandler()); // Execute FFMPEG.
> > >                 } catch (IOException e) {
> > >                     e.printStackTrace();
> > >                 }
> > >             }
> > >         }
> > >     }
> > > }
> > >
> > > Now, this is the code for the executable .jar which is the class
> > > "SecondApp". This one just sends bytes to the Standard Output and it's
> > > started by "MainApp".
> > >
> > > public class SecondApp {
> > >
> > >     public static void main(String[] args) throws
> ClassNotFoundException,
> > > IOException {
> > >         Mixer mixer =
> > > AudioSystem.getMixer(AudioSystem.getMixerInfo()[
> > > Integer.parseInt(args[0])]);
> > >         AudioFormat af = new AudioFormat(Encoding.PCM_SIGNED, 48000f,
> > 16,
> > > 2, 4, 48000f, false);
> > >
> > >         TargetDataLine line;
> > >         DataLine.Info info = new DataLine.Info(TargetDataLine.class,
> > af);
> > >         if (!AudioSystem.isLineSupported(info))
> > >             System.out.println("Line is not supported.");
> > >
> > >         try {
> > >             line = (TargetDataLine) mixer.getLine(info);
> > >             line.open(af);
> > >
> > >             int bytesRead, CHUNK_SIZE = 4096;
> > >             byte[] data = new byte[line.getBufferSize() / 5];
> > >
> > >             line.start();
> > >
> > >             while (true) {
> > >                 bytesRead = line.read(data, 0, CHUNK_SIZE);
> > >                 System.out.write(data, 0, bytesRead);
> > >                 System.out.flush();
> > >             }
> > >
> > >         } catch (LineUnavailableException ex) {
> > >             System.out.println("Line is unavailable.");
> > >             ex.printStackTrace();
> > >         }
> > >     }
> > > }
> > >
> > > 2017-02-05 16:31 GMT+01:00 Raymond DeCampo <ra...@decampo.org>:
> > >
> > > > Edgar, I didn't see anything obvious wrong with what you posted.  If
> > you
> > > > can distill it down to a minimal self-contained example that
> reproduces
> > > the
> > > > behavior I can take a closer look.
> > > >
> > > > On Sat, Feb 4, 2017 at 1:47 PM, Edgar H <ka...@gmail.com> wrote:
> > > >
> > > > > I've been struggling with this problem for quite some time now as
> > it's
> > > my
> > > > > very first time doing an application related to streaming and I
> just
> > > > can't
> > > > > figure out why. Here's the problem...
> > > > >
> > > > > What I'm trying to achieve is to send a command's output as an
> input
> > > for
> > > > > the next one, which is basically what the pipe operator does. As I
> > knew
> > > > > this couldn't be executed directly with Exec library from Apache
> > > Commons
> > > > I
> > > > > started looking for ways to solve this. I've seen quite a few
> > examples
> > > of
> > > > > similar things to this but none of them covers my situation:
> > > > >
> > > > > I have two Java applications separated, one is the main application
> > and
> > > > the
> > > > > second one is initialized by the first one. This second
> applications
> > > > sends
> > > > > to the Standard Output bytes, which FFMPEG should receive.
> > > > >
> > > > > The code that I have so far is the following one...
> > > > >
> > > > > public void initStream(String path) {
> > > > >     File file = new File(path);
> > > > >     for (File s : file.listFiles()) {
> > > > >         if (s.getName().equals("ffmpeg.exe")) {
> > > > >             try {
> > > > >
> > > > >                 // Second app, supposedly, writes here.
> > > > >                 PipedOutputStream output = new PipedOutputStream();
> > > > >
> > > > >                 DefaultExecutor executor = new DefaultExecutor();
> > > > >                 //DefaultExecutor executorFFMPEG = new
> > > DefaultExecutor();
> > > > >                 executor.setWorkingDirectory(file);
> > > > >                 //executor.setWorkingDirectory(file);
> > > > >
> > > > >                 CommandLine commandLine = new
> > > > > CommandLine(s.getParentFile().getAbsolutePath());
> > > > >                 System.out.println("Path: " +
> > commandLine.toString());
> > > > >
> > > > >                 String executeMe = "java -jar streamer.jar";
> > > > >                 commandLine = CommandLine.parse(executeMe);
> > > > >
> > > > >                 System.out.println("[testing] streamer about to
> > > > launch.");
> > > > >                 executor.setStreamHandler(new
> > PumpStreamHandler(output,
> > > > > null));
> > > > >                 executor.execute(commandLine, new
> > > > > DefaultExecuteResultHandler());
> > > > >                 System.out.println("[testing] streamer started.");
> > > > >
> > > > >                 PipedInputStream input = new PipedInputStream();
> > > > >                 output.connect(input);
> > > > >
> > > > >                 String feedMe = "ffmpeg"; // more attributes here
> > > > >                 commandLine = CommandLine.parse(feedMe);
> > > > >
> > > > >                 System.out.println("[testing] ffmpeg about to
> > > launch.");
> > > > >                 executor.setStreamHandler(new
> PumpStreamHandler(null,
> > > > > null, input));
> > > > >                 executor.execute(commandLine, new
> > > > > DefaultExecuteResultHandler());
> > > > >                 System.out.println("[testing] ffmpeg started.");
> > > > >
> > > > >             } catch (IOException e) {
> > > > >                 e.printStackTrace();
> > > > >             }
> > > > >         }
> > > > >     }}
> > > > >
> > > > > And the code for the second application (the zone where I send data
> > to
> > > > > the stdout) is the following one.
> > > > >
> > > > > static OutputStream stdout = System.out;
> > > > >
> > > > > (more code and other things around here)
> > > > >
> > > > > try {
> > > > >         line = (TargetDataLine) mixer.getLine(info);
> > > > >         line.open(format);
> > > > >
> > > > >         int bytesRead, CHUNK_SIZE = 4096;
> > > > >         byte[] data = new byte[line.getBufferSize() / 5];
> > > > >
> > > > >         line.start();
> > > > >
> > > > >         while (true) {
> > > > >             bytesRead = line.read(data, 0, CHUNK_SIZE);
> > > > >             stdout.write(data, 0, bytesRead);
> > > > >             stdout.flush();
> > > > >         }
> > > > >
> > > > >     } catch (LineUnavailableException ex) {
> > > > >         System.out.println("Line is unavailable.");
> > > > >         ex.printStackTrace();
> > > > >     }
> > > > >
> > > > > At the moment, no communication seems to be made between both
> > commands
> > > as
> > > > > ffmpeg isn't receiving anything.
> > > > >
> > > > > Hope you guys can tell what I'm missing out, or if I'm incorrectly
> > > > working
> > > > > with the library thinking it works in a way when it works in
> another
> > > one.
> > > > >
> > > >
> > >
> >
>

Re: [exec] Misconcepting PumpStreamHandler's way of working with streams?

Posted by Edgar H <ka...@gmail.com>.
There it goes, here is the link for the git repo.

https://github.com/turbobrick/exec_dmo

I've included ffmpeg and also Icecast so you can start the server in your
machine via console and see if the mount "/stream" is active at
127.0.0.1:8000 once you start streaming audio from the system via the test
app. An already compiled .jar from the SecondApp class has already been
generated, and it is inside /bin folder in /ffmpeg. Everything should be
ready to go.

Thanks for helping, really appreciated.

2017-02-05 22:51 GMT+01:00 Raymond DeCampo <ra...@decampo.org>:

> If I were to try to run this on my system, it would fail because there is
> no ffmpeg.exe file on my machine.
>
> You need to make it easier for me to help you by making a truly
> self-contained minimal example of the issue (see
> http://www.catb.org/~esr/faqs/smart-questions.html#code for more details
> on
> this).  Preferably the example will contain a pom.xml so it can be built
> easily and maybe put in on a gist in github so it can be downloaded easily.
>
>
>
> On Sun, Feb 5, 2017 at 3:46 PM, Edgar H <ka...@gmail.com> wrote:
>
> > Sure, here's a minimal example.
> >
> > The following code belongs to a "MainApp" class, which is the basically
> the
> > application which starts the .jar responsible of capturing live audio
> data
> > from the system and sending it live to FFMPEG, which streams to an
> Icecast
> > Server, like a continuous stream using pipes.
> >
> > public class MainApp {
> >
> >     public static void main(String[] args) {
> >         initStream("Path to FFMPEG bin folder, which should include the
> > .jar of the second application that you need to copy and paste.");
> >     }
> >
> >     public static void initStream(String path) {
> >         File file = new File(path);
> >         for (File s : file.listFiles()) {
> >             if (s.getName().equals("ffmpeg.exe")) {
> >                 try {
> >                     DefaultExecutor executor = new DefaultExecutor();
> >                     executor.setWorkingDirectory(file);
> >
> >                     CommandLine commandLine = new
> > CommandLine(s.getParentFile().getAbsolutePath());
> >                     System.out.println("Path: " +
> commandLine.toString());
> >
> >                     String executeMe = "java -jar secondapp.jar"; //
> > Execute "SecondApp" .jar to start sending sound bytes to stdout.
> >                     commandLine = CommandLine.parse(executeMe);
> >
> >                     PipedOutputStream output = new PipedOutputStream();
> //
> > Fill this with bytes.
> >                     PipedInputStream input = new PipedInputStream();
> >                     output.connect(input); // Send audio bytes from
> output
> > to this input stream.
> >
> >                     executor.setStreamHandler(new
> PumpStreamHandler(output,
> > null)); // Stream all the bytes to the output.
> >                     executor.execute(commandLine, new
> > DefaultExecuteResultHandler()); // Execute APP2 (The one which captures
> > the
> > live audio bytes).
> >
> >                     String feedMe = "ffmpeg -f s16le -ar 48000 -ac 2 -i -
> > -f ogg -content_type application/ogg icecast://source:hackme@localhost
> > :8000/stream";
> >                     commandLine = CommandLine.parse(feedMe);
> >
> >                     executor.setStreamHandler(new PumpStreamHandler(null,
> > null, input)); // Send the bytes being received in real time to FFMPEG.
> >                     executor.execute(commandLine, new
> > DefaultExecuteResultHandler()); // Execute FFMPEG.
> >                 } catch (IOException e) {
> >                     e.printStackTrace();
> >                 }
> >             }
> >         }
> >     }
> > }
> >
> > Now, this is the code for the executable .jar which is the class
> > "SecondApp". This one just sends bytes to the Standard Output and it's
> > started by "MainApp".
> >
> > public class SecondApp {
> >
> >     public static void main(String[] args) throws ClassNotFoundException,
> > IOException {
> >         Mixer mixer =
> > AudioSystem.getMixer(AudioSystem.getMixerInfo()[
> > Integer.parseInt(args[0])]);
> >         AudioFormat af = new AudioFormat(Encoding.PCM_SIGNED, 48000f,
> 16,
> > 2, 4, 48000f, false);
> >
> >         TargetDataLine line;
> >         DataLine.Info info = new DataLine.Info(TargetDataLine.class,
> af);
> >         if (!AudioSystem.isLineSupported(info))
> >             System.out.println("Line is not supported.");
> >
> >         try {
> >             line = (TargetDataLine) mixer.getLine(info);
> >             line.open(af);
> >
> >             int bytesRead, CHUNK_SIZE = 4096;
> >             byte[] data = new byte[line.getBufferSize() / 5];
> >
> >             line.start();
> >
> >             while (true) {
> >                 bytesRead = line.read(data, 0, CHUNK_SIZE);
> >                 System.out.write(data, 0, bytesRead);
> >                 System.out.flush();
> >             }
> >
> >         } catch (LineUnavailableException ex) {
> >             System.out.println("Line is unavailable.");
> >             ex.printStackTrace();
> >         }
> >     }
> > }
> >
> > 2017-02-05 16:31 GMT+01:00 Raymond DeCampo <ra...@decampo.org>:
> >
> > > Edgar, I didn't see anything obvious wrong with what you posted.  If
> you
> > > can distill it down to a minimal self-contained example that reproduces
> > the
> > > behavior I can take a closer look.
> > >
> > > On Sat, Feb 4, 2017 at 1:47 PM, Edgar H <ka...@gmail.com> wrote:
> > >
> > > > I've been struggling with this problem for quite some time now as
> it's
> > my
> > > > very first time doing an application related to streaming and I just
> > > can't
> > > > figure out why. Here's the problem...
> > > >
> > > > What I'm trying to achieve is to send a command's output as an input
> > for
> > > > the next one, which is basically what the pipe operator does. As I
> knew
> > > > this couldn't be executed directly with Exec library from Apache
> > Commons
> > > I
> > > > started looking for ways to solve this. I've seen quite a few
> examples
> > of
> > > > similar things to this but none of them covers my situation:
> > > >
> > > > I have two Java applications separated, one is the main application
> and
> > > the
> > > > second one is initialized by the first one. This second applications
> > > sends
> > > > to the Standard Output bytes, which FFMPEG should receive.
> > > >
> > > > The code that I have so far is the following one...
> > > >
> > > > public void initStream(String path) {
> > > >     File file = new File(path);
> > > >     for (File s : file.listFiles()) {
> > > >         if (s.getName().equals("ffmpeg.exe")) {
> > > >             try {
> > > >
> > > >                 // Second app, supposedly, writes here.
> > > >                 PipedOutputStream output = new PipedOutputStream();
> > > >
> > > >                 DefaultExecutor executor = new DefaultExecutor();
> > > >                 //DefaultExecutor executorFFMPEG = new
> > DefaultExecutor();
> > > >                 executor.setWorkingDirectory(file);
> > > >                 //executor.setWorkingDirectory(file);
> > > >
> > > >                 CommandLine commandLine = new
> > > > CommandLine(s.getParentFile().getAbsolutePath());
> > > >                 System.out.println("Path: " +
> commandLine.toString());
> > > >
> > > >                 String executeMe = "java -jar streamer.jar";
> > > >                 commandLine = CommandLine.parse(executeMe);
> > > >
> > > >                 System.out.println("[testing] streamer about to
> > > launch.");
> > > >                 executor.setStreamHandler(new
> PumpStreamHandler(output,
> > > > null));
> > > >                 executor.execute(commandLine, new
> > > > DefaultExecuteResultHandler());
> > > >                 System.out.println("[testing] streamer started.");
> > > >
> > > >                 PipedInputStream input = new PipedInputStream();
> > > >                 output.connect(input);
> > > >
> > > >                 String feedMe = "ffmpeg"; // more attributes here
> > > >                 commandLine = CommandLine.parse(feedMe);
> > > >
> > > >                 System.out.println("[testing] ffmpeg about to
> > launch.");
> > > >                 executor.setStreamHandler(new PumpStreamHandler(null,
> > > > null, input));
> > > >                 executor.execute(commandLine, new
> > > > DefaultExecuteResultHandler());
> > > >                 System.out.println("[testing] ffmpeg started.");
> > > >
> > > >             } catch (IOException e) {
> > > >                 e.printStackTrace();
> > > >             }
> > > >         }
> > > >     }}
> > > >
> > > > And the code for the second application (the zone where I send data
> to
> > > > the stdout) is the following one.
> > > >
> > > > static OutputStream stdout = System.out;
> > > >
> > > > (more code and other things around here)
> > > >
> > > > try {
> > > >         line = (TargetDataLine) mixer.getLine(info);
> > > >         line.open(format);
> > > >
> > > >         int bytesRead, CHUNK_SIZE = 4096;
> > > >         byte[] data = new byte[line.getBufferSize() / 5];
> > > >
> > > >         line.start();
> > > >
> > > >         while (true) {
> > > >             bytesRead = line.read(data, 0, CHUNK_SIZE);
> > > >             stdout.write(data, 0, bytesRead);
> > > >             stdout.flush();
> > > >         }
> > > >
> > > >     } catch (LineUnavailableException ex) {
> > > >         System.out.println("Line is unavailable.");
> > > >         ex.printStackTrace();
> > > >     }
> > > >
> > > > At the moment, no communication seems to be made between both
> commands
> > as
> > > > ffmpeg isn't receiving anything.
> > > >
> > > > Hope you guys can tell what I'm missing out, or if I'm incorrectly
> > > working
> > > > with the library thinking it works in a way when it works in another
> > one.
> > > >
> > >
> >
>

Re: [exec] Misconcepting PumpStreamHandler's way of working with streams?

Posted by Raymond DeCampo <ra...@decampo.org>.
If I were to try to run this on my system, it would fail because there is
no ffmpeg.exe file on my machine.

You need to make it easier for me to help you by making a truly
self-contained minimal example of the issue (see
http://www.catb.org/~esr/faqs/smart-questions.html#code for more details on
this).  Preferably the example will contain a pom.xml so it can be built
easily and maybe put in on a gist in github so it can be downloaded easily.



On Sun, Feb 5, 2017 at 3:46 PM, Edgar H <ka...@gmail.com> wrote:

> Sure, here's a minimal example.
>
> The following code belongs to a "MainApp" class, which is the basically the
> application which starts the .jar responsible of capturing live audio data
> from the system and sending it live to FFMPEG, which streams to an Icecast
> Server, like a continuous stream using pipes.
>
> public class MainApp {
>
>     public static void main(String[] args) {
>         initStream("Path to FFMPEG bin folder, which should include the
> .jar of the second application that you need to copy and paste.");
>     }
>
>     public static void initStream(String path) {
>         File file = new File(path);
>         for (File s : file.listFiles()) {
>             if (s.getName().equals("ffmpeg.exe")) {
>                 try {
>                     DefaultExecutor executor = new DefaultExecutor();
>                     executor.setWorkingDirectory(file);
>
>                     CommandLine commandLine = new
> CommandLine(s.getParentFile().getAbsolutePath());
>                     System.out.println("Path: " + commandLine.toString());
>
>                     String executeMe = "java -jar secondapp.jar"; //
> Execute "SecondApp" .jar to start sending sound bytes to stdout.
>                     commandLine = CommandLine.parse(executeMe);
>
>                     PipedOutputStream output = new PipedOutputStream(); //
> Fill this with bytes.
>                     PipedInputStream input = new PipedInputStream();
>                     output.connect(input); // Send audio bytes from output
> to this input stream.
>
>                     executor.setStreamHandler(new PumpStreamHandler(output,
> null)); // Stream all the bytes to the output.
>                     executor.execute(commandLine, new
> DefaultExecuteResultHandler()); // Execute APP2 (The one which captures
> the
> live audio bytes).
>
>                     String feedMe = "ffmpeg -f s16le -ar 48000 -ac 2 -i -
> -f ogg -content_type application/ogg icecast://source:hackme@localhost
> :8000/stream";
>                     commandLine = CommandLine.parse(feedMe);
>
>                     executor.setStreamHandler(new PumpStreamHandler(null,
> null, input)); // Send the bytes being received in real time to FFMPEG.
>                     executor.execute(commandLine, new
> DefaultExecuteResultHandler()); // Execute FFMPEG.
>                 } catch (IOException e) {
>                     e.printStackTrace();
>                 }
>             }
>         }
>     }
> }
>
> Now, this is the code for the executable .jar which is the class
> "SecondApp". This one just sends bytes to the Standard Output and it's
> started by "MainApp".
>
> public class SecondApp {
>
>     public static void main(String[] args) throws ClassNotFoundException,
> IOException {
>         Mixer mixer =
> AudioSystem.getMixer(AudioSystem.getMixerInfo()[
> Integer.parseInt(args[0])]);
>         AudioFormat af = new AudioFormat(Encoding.PCM_SIGNED, 48000f, 16,
> 2, 4, 48000f, false);
>
>         TargetDataLine line;
>         DataLine.Info info = new DataLine.Info(TargetDataLine.class, af);
>         if (!AudioSystem.isLineSupported(info))
>             System.out.println("Line is not supported.");
>
>         try {
>             line = (TargetDataLine) mixer.getLine(info);
>             line.open(af);
>
>             int bytesRead, CHUNK_SIZE = 4096;
>             byte[] data = new byte[line.getBufferSize() / 5];
>
>             line.start();
>
>             while (true) {
>                 bytesRead = line.read(data, 0, CHUNK_SIZE);
>                 System.out.write(data, 0, bytesRead);
>                 System.out.flush();
>             }
>
>         } catch (LineUnavailableException ex) {
>             System.out.println("Line is unavailable.");
>             ex.printStackTrace();
>         }
>     }
> }
>
> 2017-02-05 16:31 GMT+01:00 Raymond DeCampo <ra...@decampo.org>:
>
> > Edgar, I didn't see anything obvious wrong with what you posted.  If you
> > can distill it down to a minimal self-contained example that reproduces
> the
> > behavior I can take a closer look.
> >
> > On Sat, Feb 4, 2017 at 1:47 PM, Edgar H <ka...@gmail.com> wrote:
> >
> > > I've been struggling with this problem for quite some time now as it's
> my
> > > very first time doing an application related to streaming and I just
> > can't
> > > figure out why. Here's the problem...
> > >
> > > What I'm trying to achieve is to send a command's output as an input
> for
> > > the next one, which is basically what the pipe operator does. As I knew
> > > this couldn't be executed directly with Exec library from Apache
> Commons
> > I
> > > started looking for ways to solve this. I've seen quite a few examples
> of
> > > similar things to this but none of them covers my situation:
> > >
> > > I have two Java applications separated, one is the main application and
> > the
> > > second one is initialized by the first one. This second applications
> > sends
> > > to the Standard Output bytes, which FFMPEG should receive.
> > >
> > > The code that I have so far is the following one...
> > >
> > > public void initStream(String path) {
> > >     File file = new File(path);
> > >     for (File s : file.listFiles()) {
> > >         if (s.getName().equals("ffmpeg.exe")) {
> > >             try {
> > >
> > >                 // Second app, supposedly, writes here.
> > >                 PipedOutputStream output = new PipedOutputStream();
> > >
> > >                 DefaultExecutor executor = new DefaultExecutor();
> > >                 //DefaultExecutor executorFFMPEG = new
> DefaultExecutor();
> > >                 executor.setWorkingDirectory(file);
> > >                 //executor.setWorkingDirectory(file);
> > >
> > >                 CommandLine commandLine = new
> > > CommandLine(s.getParentFile().getAbsolutePath());
> > >                 System.out.println("Path: " + commandLine.toString());
> > >
> > >                 String executeMe = "java -jar streamer.jar";
> > >                 commandLine = CommandLine.parse(executeMe);
> > >
> > >                 System.out.println("[testing] streamer about to
> > launch.");
> > >                 executor.setStreamHandler(new PumpStreamHandler(output,
> > > null));
> > >                 executor.execute(commandLine, new
> > > DefaultExecuteResultHandler());
> > >                 System.out.println("[testing] streamer started.");
> > >
> > >                 PipedInputStream input = new PipedInputStream();
> > >                 output.connect(input);
> > >
> > >                 String feedMe = "ffmpeg"; // more attributes here
> > >                 commandLine = CommandLine.parse(feedMe);
> > >
> > >                 System.out.println("[testing] ffmpeg about to
> launch.");
> > >                 executor.setStreamHandler(new PumpStreamHandler(null,
> > > null, input));
> > >                 executor.execute(commandLine, new
> > > DefaultExecuteResultHandler());
> > >                 System.out.println("[testing] ffmpeg started.");
> > >
> > >             } catch (IOException e) {
> > >                 e.printStackTrace();
> > >             }
> > >         }
> > >     }}
> > >
> > > And the code for the second application (the zone where I send data to
> > > the stdout) is the following one.
> > >
> > > static OutputStream stdout = System.out;
> > >
> > > (more code and other things around here)
> > >
> > > try {
> > >         line = (TargetDataLine) mixer.getLine(info);
> > >         line.open(format);
> > >
> > >         int bytesRead, CHUNK_SIZE = 4096;
> > >         byte[] data = new byte[line.getBufferSize() / 5];
> > >
> > >         line.start();
> > >
> > >         while (true) {
> > >             bytesRead = line.read(data, 0, CHUNK_SIZE);
> > >             stdout.write(data, 0, bytesRead);
> > >             stdout.flush();
> > >         }
> > >
> > >     } catch (LineUnavailableException ex) {
> > >         System.out.println("Line is unavailable.");
> > >         ex.printStackTrace();
> > >     }
> > >
> > > At the moment, no communication seems to be made between both commands
> as
> > > ffmpeg isn't receiving anything.
> > >
> > > Hope you guys can tell what I'm missing out, or if I'm incorrectly
> > working
> > > with the library thinking it works in a way when it works in another
> one.
> > >
> >
>

Re: [exec] Misconcepting PumpStreamHandler's way of working with streams?

Posted by Edgar H <ka...@gmail.com>.
Sure, here's a minimal example.

The following code belongs to a "MainApp" class, which is the basically the
application which starts the .jar responsible of capturing live audio data
from the system and sending it live to FFMPEG, which streams to an Icecast
Server, like a continuous stream using pipes.

public class MainApp {

    public static void main(String[] args) {
        initStream("Path to FFMPEG bin folder, which should include the
.jar of the second application that you need to copy and paste.");
    }

    public static void initStream(String path) {
        File file = new File(path);
        for (File s : file.listFiles()) {
            if (s.getName().equals("ffmpeg.exe")) {
                try {
                    DefaultExecutor executor = new DefaultExecutor();
                    executor.setWorkingDirectory(file);

                    CommandLine commandLine = new
CommandLine(s.getParentFile().getAbsolutePath());
                    System.out.println("Path: " + commandLine.toString());

                    String executeMe = "java -jar secondapp.jar"; //
Execute "SecondApp" .jar to start sending sound bytes to stdout.
                    commandLine = CommandLine.parse(executeMe);

                    PipedOutputStream output = new PipedOutputStream(); //
Fill this with bytes.
                    PipedInputStream input = new PipedInputStream();
                    output.connect(input); // Send audio bytes from output
to this input stream.

                    executor.setStreamHandler(new PumpStreamHandler(output,
null)); // Stream all the bytes to the output.
                    executor.execute(commandLine, new
DefaultExecuteResultHandler()); // Execute APP2 (The one which captures the
live audio bytes).

                    String feedMe = "ffmpeg -f s16le -ar 48000 -ac 2 -i -
-f ogg -content_type application/ogg icecast://source:hackme@localhost
:8000/stream";
                    commandLine = CommandLine.parse(feedMe);

                    executor.setStreamHandler(new PumpStreamHandler(null,
null, input)); // Send the bytes being received in real time to FFMPEG.
                    executor.execute(commandLine, new
DefaultExecuteResultHandler()); // Execute FFMPEG.
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

Now, this is the code for the executable .jar which is the class
"SecondApp". This one just sends bytes to the Standard Output and it's
started by "MainApp".

public class SecondApp {

    public static void main(String[] args) throws ClassNotFoundException,
IOException {
        Mixer mixer =
AudioSystem.getMixer(AudioSystem.getMixerInfo()[Integer.parseInt(args[0])]);
        AudioFormat af = new AudioFormat(Encoding.PCM_SIGNED, 48000f, 16,
2, 4, 48000f, false);

        TargetDataLine line;
        DataLine.Info info = new DataLine.Info(TargetDataLine.class, af);
        if (!AudioSystem.isLineSupported(info))
            System.out.println("Line is not supported.");

        try {
            line = (TargetDataLine) mixer.getLine(info);
            line.open(af);

            int bytesRead, CHUNK_SIZE = 4096;
            byte[] data = new byte[line.getBufferSize() / 5];

            line.start();

            while (true) {
                bytesRead = line.read(data, 0, CHUNK_SIZE);
                System.out.write(data, 0, bytesRead);
                System.out.flush();
            }

        } catch (LineUnavailableException ex) {
            System.out.println("Line is unavailable.");
            ex.printStackTrace();
        }
    }
}

2017-02-05 16:31 GMT+01:00 Raymond DeCampo <ra...@decampo.org>:

> Edgar, I didn't see anything obvious wrong with what you posted.  If you
> can distill it down to a minimal self-contained example that reproduces the
> behavior I can take a closer look.
>
> On Sat, Feb 4, 2017 at 1:47 PM, Edgar H <ka...@gmail.com> wrote:
>
> > I've been struggling with this problem for quite some time now as it's my
> > very first time doing an application related to streaming and I just
> can't
> > figure out why. Here's the problem...
> >
> > What I'm trying to achieve is to send a command's output as an input for
> > the next one, which is basically what the pipe operator does. As I knew
> > this couldn't be executed directly with Exec library from Apache Commons
> I
> > started looking for ways to solve this. I've seen quite a few examples of
> > similar things to this but none of them covers my situation:
> >
> > I have two Java applications separated, one is the main application and
> the
> > second one is initialized by the first one. This second applications
> sends
> > to the Standard Output bytes, which FFMPEG should receive.
> >
> > The code that I have so far is the following one...
> >
> > public void initStream(String path) {
> >     File file = new File(path);
> >     for (File s : file.listFiles()) {
> >         if (s.getName().equals("ffmpeg.exe")) {
> >             try {
> >
> >                 // Second app, supposedly, writes here.
> >                 PipedOutputStream output = new PipedOutputStream();
> >
> >                 DefaultExecutor executor = new DefaultExecutor();
> >                 //DefaultExecutor executorFFMPEG = new DefaultExecutor();
> >                 executor.setWorkingDirectory(file);
> >                 //executor.setWorkingDirectory(file);
> >
> >                 CommandLine commandLine = new
> > CommandLine(s.getParentFile().getAbsolutePath());
> >                 System.out.println("Path: " + commandLine.toString());
> >
> >                 String executeMe = "java -jar streamer.jar";
> >                 commandLine = CommandLine.parse(executeMe);
> >
> >                 System.out.println("[testing] streamer about to
> launch.");
> >                 executor.setStreamHandler(new PumpStreamHandler(output,
> > null));
> >                 executor.execute(commandLine, new
> > DefaultExecuteResultHandler());
> >                 System.out.println("[testing] streamer started.");
> >
> >                 PipedInputStream input = new PipedInputStream();
> >                 output.connect(input);
> >
> >                 String feedMe = "ffmpeg"; // more attributes here
> >                 commandLine = CommandLine.parse(feedMe);
> >
> >                 System.out.println("[testing] ffmpeg about to launch.");
> >                 executor.setStreamHandler(new PumpStreamHandler(null,
> > null, input));
> >                 executor.execute(commandLine, new
> > DefaultExecuteResultHandler());
> >                 System.out.println("[testing] ffmpeg started.");
> >
> >             } catch (IOException e) {
> >                 e.printStackTrace();
> >             }
> >         }
> >     }}
> >
> > And the code for the second application (the zone where I send data to
> > the stdout) is the following one.
> >
> > static OutputStream stdout = System.out;
> >
> > (more code and other things around here)
> >
> > try {
> >         line = (TargetDataLine) mixer.getLine(info);
> >         line.open(format);
> >
> >         int bytesRead, CHUNK_SIZE = 4096;
> >         byte[] data = new byte[line.getBufferSize() / 5];
> >
> >         line.start();
> >
> >         while (true) {
> >             bytesRead = line.read(data, 0, CHUNK_SIZE);
> >             stdout.write(data, 0, bytesRead);
> >             stdout.flush();
> >         }
> >
> >     } catch (LineUnavailableException ex) {
> >         System.out.println("Line is unavailable.");
> >         ex.printStackTrace();
> >     }
> >
> > At the moment, no communication seems to be made between both commands as
> > ffmpeg isn't receiving anything.
> >
> > Hope you guys can tell what I'm missing out, or if I'm incorrectly
> working
> > with the library thinking it works in a way when it works in another one.
> >
>

Re: [exec] Misconcepting PumpStreamHandler's way of working with streams?

Posted by Raymond DeCampo <ra...@decampo.org>.
Edgar, I didn't see anything obvious wrong with what you posted.  If you
can distill it down to a minimal self-contained example that reproduces the
behavior I can take a closer look.

On Sat, Feb 4, 2017 at 1:47 PM, Edgar H <ka...@gmail.com> wrote:

> I've been struggling with this problem for quite some time now as it's my
> very first time doing an application related to streaming and I just can't
> figure out why. Here's the problem...
>
> What I'm trying to achieve is to send a command's output as an input for
> the next one, which is basically what the pipe operator does. As I knew
> this couldn't be executed directly with Exec library from Apache Commons I
> started looking for ways to solve this. I've seen quite a few examples of
> similar things to this but none of them covers my situation:
>
> I have two Java applications separated, one is the main application and the
> second one is initialized by the first one. This second applications sends
> to the Standard Output bytes, which FFMPEG should receive.
>
> The code that I have so far is the following one...
>
> public void initStream(String path) {
>     File file = new File(path);
>     for (File s : file.listFiles()) {
>         if (s.getName().equals("ffmpeg.exe")) {
>             try {
>
>                 // Second app, supposedly, writes here.
>                 PipedOutputStream output = new PipedOutputStream();
>
>                 DefaultExecutor executor = new DefaultExecutor();
>                 //DefaultExecutor executorFFMPEG = new DefaultExecutor();
>                 executor.setWorkingDirectory(file);
>                 //executor.setWorkingDirectory(file);
>
>                 CommandLine commandLine = new
> CommandLine(s.getParentFile().getAbsolutePath());
>                 System.out.println("Path: " + commandLine.toString());
>
>                 String executeMe = "java -jar streamer.jar";
>                 commandLine = CommandLine.parse(executeMe);
>
>                 System.out.println("[testing] streamer about to launch.");
>                 executor.setStreamHandler(new PumpStreamHandler(output,
> null));
>                 executor.execute(commandLine, new
> DefaultExecuteResultHandler());
>                 System.out.println("[testing] streamer started.");
>
>                 PipedInputStream input = new PipedInputStream();
>                 output.connect(input);
>
>                 String feedMe = "ffmpeg"; // more attributes here
>                 commandLine = CommandLine.parse(feedMe);
>
>                 System.out.println("[testing] ffmpeg about to launch.");
>                 executor.setStreamHandler(new PumpStreamHandler(null,
> null, input));
>                 executor.execute(commandLine, new
> DefaultExecuteResultHandler());
>                 System.out.println("[testing] ffmpeg started.");
>
>             } catch (IOException e) {
>                 e.printStackTrace();
>             }
>         }
>     }}
>
> And the code for the second application (the zone where I send data to
> the stdout) is the following one.
>
> static OutputStream stdout = System.out;
>
> (more code and other things around here)
>
> try {
>         line = (TargetDataLine) mixer.getLine(info);
>         line.open(format);
>
>         int bytesRead, CHUNK_SIZE = 4096;
>         byte[] data = new byte[line.getBufferSize() / 5];
>
>         line.start();
>
>         while (true) {
>             bytesRead = line.read(data, 0, CHUNK_SIZE);
>             stdout.write(data, 0, bytesRead);
>             stdout.flush();
>         }
>
>     } catch (LineUnavailableException ex) {
>         System.out.println("Line is unavailable.");
>         ex.printStackTrace();
>     }
>
> At the moment, no communication seems to be made between both commands as
> ffmpeg isn't receiving anything.
>
> Hope you guys can tell what I'm missing out, or if I'm incorrectly working
> with the library thinking it works in a way when it works in another one.
>