Java 8 does not wait for ffmpeg process output buffer read completion

We need to create multiple clips from video, to do so we are using ProcessBuilder to create a new processes, Please fine code below

Process clipProcess = new ProcessBuilder("bash","-c",
            "ffmpeg -i input.mp4 -ss 0:36:00.000 -codec copy -t 0:03:00.200 -threads 0 -y output.mp4").start();
clipProcess.waitFor();

We need to perform some operation on the clips, as the processing get's done and file is completely written to disk. But program returns control to next statement, even though file is not completely written to disk. Any suggestion, what I am doing wrong?

Edit: We are able to handle clips generated from any video below 45 minutes, but after that generated clips does not completely get written to disk before processing

2 answers

  • answered 2018-02-13 03:30 Alex Taylor

    ffmpeg is buffering it's disk writes. When the process exits, it's output may not actually be on disk at that point. Adding -flush_packets 1 to your command line should tell ffmpeg to flush after each packet (source). Something like:

    Process clipProcess = new ProcessBuilder("bash","-c",
            "ffmpeg -i input.mp4 -ss 0:36:00.000 -flush_packets 1 -codec copy -t 0:03:00.200 -threads 0 -y output.mp4").start();
    clipProcess.waitFor();
    

  • answered 2018-02-13 05:45 gpasch

    I suggest you do something like the following - the same for pr.getErrorStream().

    waitFor() is a nice feature but doesnt work - they admit so in the doc.

    Just read the streams to see when the process ends.

        try {
          Runtime rt=Runtime.getRuntime();
          Process pr=rt.exec(" ...... "");
          final InputStreamReader isr=new nputStreamReader(pr.getInputStream());
          Thread th=new Thread() {
            public void run() {
              try {
                BufferedReader br=new BufferedReader(isr);
                String line=null;
                while((line=br.readLine())!=null) {
                  System.out.println(line);
                }
              }
              catch (Exception ex) { }
            }
          };
          th.start();
            int exitVal=pr.waitFor();
            System.out.println("ExitValue: " + exitVal);
       }
        catch (Exception ex) { ex.printStackTrace(); }