I am new to using the ProcessBuilder
object to run commands inside of Java. My issue is that when I put my environment variables into the builder.command(...)
method, it doesn’t work. However, when I hardcode the strings of the environment variables, it works perfectly. Here is my code below along with an explanation to help make clear on what I am doing:
ProcessBuilder builder = new ProcessBuilder(); builder.directory(f); System.out.println("The user's chosen directory is: "+builder.directory()); Map<String, String> environment = builder.environment(); environment.put("WINDOW",w); environment.put("AUDIO",a); environment.forEach((key,value)->System.out.println("key is "+key+" "+"value: "+value)); builder.command("ffmpeg", "-i", "$WINDOW","-i", "$AUDIO", "-vcodec", "copy" ,"output.mp4"); Process pr= builder.start();
Explanation/Objective:
Basically I have a
JButton
in which anActionListener
is being fired off when the user clicks it. I am trying to useffmpeg
to convert an audio and video file together into one file if they desire. This code above will be executed in which I am trying to get the directory of the file they chose in my application to store the two files mentioned previously. Through usingbuilder.directory(f)
, I am able to change the current directory ofbuilder
to that of the user’s. I then created a map calledenvironment
in which I could add two environment variables calledWINDOW
andAUDIO
. The two env. variables were assigned file names such that the file names were assigned to two variablesw
anda
which are of type string. I did check to see if they were in the map and they were. I then attempt to make my set of instructions using thebuilder.command(...)
method and then start the process usingbuilder.start()
.
Conclusion:
However, the single
output.mp4
file was not created and when I checked my Process using thewaitFor()
method I get a “1”. On the contrary, when I don’t use env. variables at all and hardcode the file names in between the parantheses where the env. variables were, it works correctly. So, exactly what am I doing wrong in mybuilder.command(..)
? Thanks.
Advertisement
Answer
It strikes me that the simplest solution is:
builder.command("ffmpeg", "-i", w ,"-i", a, "-vcodec", "copy" ,"output.mp4");
There is no need to set environment variables if you are only going to use them to inject command line arguments.
However, if you do want to do it via environment variables, then the simple way is to use a subshell to do all of the command line parsing and expansion; e.g.
builder.command("/bin/sh", "-c", "ffmpeg -i $WINDOW -i $AUDIO -vcodec copy output.mp4");
You could also use quoting, globbing, pipelines, redirection and all of the other fancy shell features.