commons-user mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Edgar H <kaotix...@gmail.com>
Subject Re: [exec] Misconcepting PumpStreamHandler's way of working with streams?
Date Mon, 06 Feb 2017 00:04:52 GMT
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 <ray@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 <kaotixpro@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 <ray@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 <kaotixpro@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.
> > > >
> > >
> >
>

Mime
  • Unnamed multipart/alternative (inline, None, 0 bytes)
View raw message