Reputation: 165
I am trying to transcode a video using ffmpeg with java.ProcessBuilder. I read the other threads regarding this but it doesn't really solve my problem.
I think everything goes well up till Process p=pb.start(). I know I have to read some stream of ProcessBuilder and convert it to a byte[] and write that to a file. I thought ffmpeg would do all that for me since I'm passing the "inputFile" and OutputFile paths. Anyway I post what I have till here. How can I fix this code so that I can see a fully transcoded video file after as result?
Currently all code execute with no error and the output file is created but its size is 0KB. I'm running the code from windows server in a Java (.jar) program.
This is a snippet of the program
try {
File encodingFile = new File("c:\\ffmpeg\\bin\\output.mp4");
File errorFile = new File("c:\\ffmpeg\\bin\\error.txt");
errorFile.createNewFile();
encodingFile.createNewFile();
ProcessBuilder pb = new ProcessBuilder("c:\\ffmpeg\\bin\\ffmpeg.exe", "-i", "c:\\ffmpeg\\bin\\input.mp4", "-y", "-s", "360" + "480" + "-1", "-vcodec", "libx264", "c:\\ffmpeg\\bin\\output.mp4"); //or other command....
pb.redirectErrorStream(true);
pb.redirectError(errorFile);
//pb.redirectOutput(encodingFile);
Process p=pb.start();
byte[] videoIn;
File file = new File("c:\\ffmpeg\\bin\\input.mp4");
videoIn = new byte[(int)file.length()];
FileInputStream fileInputStream = new FileInputStream(file);
fileInputStream.read(videoIn);
*/
gui.textArea1.append("\n+++++++Finished while converting!++++++++\n");
}catch(IOException ex){
gui.textArea1.append("\nIOException converting: "+ex.getMessage());
}finally{
try{
if(is!=null){
is.close();
}
if(fos!=null){
fos.close();
}
}catch(IOException ioe){
gui.textArea1.append("\nClosing streams while converting:"+ioe.getMessage());
}
}
gui.textArea1.append("converting finished!");
Upvotes: 0
Views: 2841
Reputation: 121830
Your problem is here:
pb.redirectErrorStream(true);
pb.redirectError(errorFile);
//pb.redirectOutput(encodingFile);
What you are doing here is redirect stderr to stdout; and both are redirected to errorFile
.
And your encodingFile
is just created with:
encodingFile.createNewFile();
which is not even guaranteed to succeed.
Fix:
final Path videoIn = Paths.get("c:\\ffmpeg\\bin\\input.mp4");
final Path encodingFile = Paths.get("c:\\ffmpeg\\bin\\output.mp4");
final Path errorFile = Paths.get("c:\\ffmpeg\\bin\\error.txt");
int retCode;
try {
Files.deleteIfExists(encodingFile);
Files.deleteIfExists(errorFile);
final ProcessBuilder pb
= new ProcessBuilder("c:\\ffmpeg\\bin\\ffmpeg.exe",
"-i", videoIn.toString(),
"-y",
"-s", "360x480", // stripped the extraneous "-1"
"-vcodec", "libx264",
"c:\\ffmpeg\\bin\\output.mp4"
); //or other command....
pb.redirectError(errorFile.toFile());
pb.redirectOutput(encodingFile.toFile());
final Process p = pb.start();
// CHECK FOR THIS!
retcode = p.waitFor();
// Reproduced here; not sure this is anything useful,
// since the old code, just like this one, just reads the contents
// from the video file to be converted... Huh?
final byte[] videoIn = Files.readAllBytes(videoIn);
} catch (IOException e) {
// deal with e here
}
Note about the original code:
.createNewFile()
; it can fail; here I use java.nio.file, this will throw an exception on error;retCode
variable which you MUST check afterwards. For possible error codes, refer to the ffmpeg man page.Upvotes: 2