3

私は、WAVファイルを30秒の長さのWAVファイルにトリミングするJavaのProcessBuilderを使用してSoXを実行しています。

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;
}
4

1 に答える 1

3

stdout に何かを書き込んでいるためにブロックされています。バッファーがいっぱいになったため、プロセスはバッファーにスペースができるまで待機していますが、プログラムはそれを読み取っていないため、バッファーはいっぱいのままです。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 を使用すると、processBuilder で出力をファイルにリダイレクトするという代替手段が得られます。

于 2011-08-11T13:38:16.517 に答える