如何读取/写入ProcessBuilder的流,最后创建一个输出文件(output.mp4)ffmpeg

时间:2015-01-17 22:30:22

标签: java video ffmpeg

我正在尝试使用ffmpeg和java.ProcessBuilder对视频进行转码。我阅读了有关此问题的其他主题,但它并没有真正解决我的问题。我觉得一切顺利,直到Process p = pb.start()。我知道我必须读取一些ProcessBuilder流并将其转换为byte []并将其写入文件。我认为ffmpeg会为我做所有这些,因为我通过" inputFile"和OutputFile路径。无论如何,我发布了我在这里的东西。你能为我提供正确的代码,以便我可以看到一个完全转码后的视频文件。 目前,所有代码都执行时没有错误,并且创建了输出文件,但其大小为0KB。我在java(.jar)程序中运行Windows服务器中的代码。

这是该计划的一小部分

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!");  

1 个答案:

答案 0 :(得分:1)

你的问题在这里:

pb.redirectErrorStream(true);
pb.redirectError(errorFile);
//pb.redirectOutput(encodingFile);

你在这里做的是将stderr重定向到stdout;并且都被重定向到errorFile

您的encodingFile刚刚创建:

encodingFile.createNewFile();

甚至不能保证成功。

修正:

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
}

注意原始代码:

  • 你为什么要阅读原始视频文件的内容?它没有意义;
  • 您没有检查.createNewFile()的返回值;它会失败;这里我使用java.nio.file,这会在出错时抛出异常;
  • 您没有检查过程'返回码;这是一个retCode变量,你必须事后检查。有关可能的错误代码,请参阅ffmpeg手册页。