【问题标题】:SoX running slow using a ProcessBuilderSoX 使用 ProcessBuilder 运行缓慢
【发布时间】:2011-08-11 11:32:47
【问题描述】:

我正在使用 Java 中的 ProcessBuilder 运行 SoX,它将 WAV 文件修剪为 30 秒长的 WAV 文件。

SoX 正在运行,因为我可以成功修剪文件的前 30 秒并将其保存为新文件,但它停在那里,但它仍在运行。

这是命令生成的代码:

command.add (soxCommand);
    if (SoxWrapper.getMetadata (srcFile, MetadataField.SAMPLE_RATE) != 16000) {
        command.add ("-V3");
        command.add ("-G");
        command.add (FilenameUtils.normalize (srcFile.getAbsolutePath ()));
        command.add ("-b 16");
        command.add (FilenameUtils.normalize (destFile.getAbsolutePath ()));
        command.add ("channels");
        command.add ("1");
        command.add ("rate");
        command.add ("16000");
        command.add ("trim");
        command.add (startTime.toString ());
        command.add ('=' + endTime.toString ());
    } else {
        command.add ("-V3");
        command.add (FilenameUtils.normalize (srcFile.getAbsolutePath ()));
        command.add ("-b 16");
        command.add (FilenameUtils.normalize (destFile.getAbsolutePath ()));
        command.add ("trim");
        command.add (startTime.toString ());
        command.add ('=' + endTime.toString ());
    }

这是创建进程的代码:

    private static Process createProcess (List<String> command) {

    ProcessBuilder soxProcessBuilder = new ProcessBuilder (command);
    soxProcessBuilder.redirectErrorStream (true);

    Process soxProcess = null;
    try {
        soxProcess = soxProcessBuilder.start ();

        int soxreturn = soxProcess.waitFor ();
        soxLogger.info ("SoX returned: " + soxreturn);

    } catch (IOException t) {
        logger.error ("SoX Process failed", t);
    } catch (InterruptedException e) {
        logger.error ("Failed to wait for SoX to finish", e);
    }

    return soxProcess;
}

【问题讨论】:

    标签: java sox


    【解决方案1】:

    它被阻塞了,因为它正在向标准输出写入内容,缓冲区已填满,因此进程正在等待缓冲区为其腾出空间,但您的程序没有读取它,因此缓冲区保持满状态。由于您将 stderr 重定向到 stdout ,因此可能会出现某种错误并且您不知道它,因为您没有从流中读取。您需要读取进程的getInputStream,例如:

    new Thread(new Runnable() {
        @Override public void run() {
            try {
                org.apache.commons.io.IOUtils.copy(soxProcess.getInputStream(), System.out);
            } catch (IOException e) {
                e.printStackTrace(System.err);
            }
        }    
    }).start();
    

    (这里你需要将 soxProcess 设为 final 以便内部类方法可以看到它。)

    使用新的 JDK,您现在可以选择 having the processBuilder redirect the output to a file

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-10-20
      • 2021-11-25
      • 2020-07-22
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多