如何从java读取ffmpeg响应并使用它来创建进度条?

sha*_*lki 9 java ffmpeg progress-bar

我正在为java中的ffmpeg创建进度条.因此,我需要执行一个命令,然后读取所有进度:

String[] command = {"gnome-terminal", "-x", "/bin/sh", "-c","ffmpeg -i /home/tmp/F.webm /home/tmp/converted1.mp4"};

Process process = Runtime.getRuntime().exec(command);
Run Code Online (Sandbox Code Playgroud)

这完美运行.但是,我需要捕获所有进度来制作进度条.那么如何从java中读取数据呢?

aio*_*obe 19

这是一个完整的例子,可以帮助您入门

import java.io.*;
import java.util.Scanner;
import java.util.regex.Pattern;

class Test {
  public static void main(String[] args) throws IOException {
    ProcessBuilder pb = new ProcessBuilder("ffmpeg","-i","in.webm","out.mp4");
    final Process p = pb.start();

    new Thread() {
      public void run() {

        Scanner sc = new Scanner(p.getErrorStream());

        // Find duration
        Pattern durPattern = Pattern.compile("(?<=Duration: )[^,]*");
        String dur = sc.findWithinHorizon(durPattern, 0);
        if (dur == null)
          throw new RuntimeException("Could not parse duration.");
        String[] hms = dur.split(":");
        double totalSecs = Integer.parseInt(hms[0]) * 3600
                         + Integer.parseInt(hms[1]) *   60
                         + Double.parseDouble(hms[2]);
        System.out.println("Total duration: " + totalSecs + " seconds.");

        // Find time as long as possible.
        Pattern timePattern = Pattern.compile("(?<=time=)[\\d.]*");
        String match;
        while (null != (match = sc.findWithinHorizon(timePattern, 0))) {
          double progress = Double.parseDouble(match) / totalSecs;
          System.out.printf("Progress: %.2f%%%n", progress * 100);
        }
      }
    }.start();

  }
}
Run Code Online (Sandbox Code Playgroud)

输出:

Total duration: 117.7 seconds.
Progress: 7.71%
Progress: 16.40%
Progress: 25.00%
Progress: 33.16%
Progress: 42.67%
Progress: 51.35%
Progress: 60.57%
Progress: 69.07%
Progress: 78.02%
Progress: 86.49%
Progress: 95.94%
Progress: 99.97%
Run Code Online (Sandbox Code Playgroud)

您也可以考虑为ffmpeg使用某种Java绑定,例如jjmpeg,它可以以更健壮的方式提供您所需的内容.

编辑

与FFMPEG 2.0,时间输出是HH:mm:ss.S这样的timePattern需求的掺入:

Pattern timePattern = Pattern.compile("(?<=time=)[\\d:.]*");
Run Code Online (Sandbox Code Playgroud)

此外,dur需要将需要拆分:并汇总在一起

String[] matchSplit;
while (null != (match = sc.findWithinHorizon(timePattern, 0))) {
    matchSplit = match.split(":")
    double progress = Integer.parseInt(matchSplit[0]) * 3600 +
        Integer.parseInt(matchSplit[1]) * 60 +
        Double.parseDouble(matchSplit[2]) / totalSecs;
//...
Run Code Online (Sandbox Code Playgroud)