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();
Basically I have a
JButtonin which an
ActionListeneris being fired off when the user clicks it. I am trying to use
ffmpegto 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 using
builder.directory(f), I am able to change the current directory of
builderto that of the user’s. I then created a map called
environmentin which I could add two environment variables called
AUDIO. The two env. variables were assigned file names such that the file names were assigned to two variables
awhich 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 the
builder.command(...)method and then start the process using
However, the single
output.mp4file was not created and when I checked my Process using the
waitFor()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 my
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.