2015-05-18 6 views
0

Я пишу небольшой инструмент для создания нескольких миниатюр в java автоматически.Runtime.getRuntime(). Exec() в циклах

поэтому я выполняю Runtime.getRuntime().exec(command); в for -loop. Теперь моя проблема в том, что создается только первая миниатюра.

Мой код до сих пор:

public static void testFFMpeg(File videoFile) throws IOException { 
    FFMpegWrapper wraper = new FFMpegWrapper(videoFile); 
    int length = (int) wraper.getInputDuration()/1000; 
    String absolutePath = videoFile.getAbsolutePath(); 
    String path = absolutePath.substring(0, absolutePath.lastIndexOf('/') + 1); 
    int c = 1; 
    System.out.println(path + "thumb_" + c + ".png"); 
    for (int i = 1; i <= length; i = i + 10) { 
     int h = i/3600; 
     int m = i/60; 
     int s = i % 60; 
     String command = "ffmpeg -i " + absolutePath + " -ss " + h + ":" + m + ":" + s + " -vframes 1 " + path 
      + "thumb_" + c + "_" + videoFile.getName() + ".png"; 
     System.out.println(command); 
     Runtime.getRuntime().exec(command); 
     c++; 
    } 
} 

выход:

ffmpeg -i /mnt/Speicherschwein/workspace/testVideos/Roentgen_A_VisarioG2_005.avi -ss 0:0:1 -vframes 1 /mnt/Speicherschwein/workspace/testVideos/thumb_1_Roentgen_A_VisarioG2_005.avi.png 
ffmpeg -i /mnt/Speicherschwein/workspace/testVideos/Roentgen_A_VisarioG2_005.avi -ss 0:0:11 -vframes 1 /mnt/Speicherschwein/workspace/testVideos/thumb_2_Roentgen_A_VisarioG2_005.avi.png 
ffmpeg -i /mnt/Speicherschwein/workspace/testVideos/Roentgen_A_VisarioG2_005.avi -ss 0:0:21 -vframes 1 /mnt/Speicherschwein/workspace/testVideos/thumb_3_Roentgen_A_VisarioG2_005.avi.png 

поэтому цикл работает нормально, и команда также хорошо, если я запустить его вручную из командной строки ее создавая каждый миниатюру, так что, похоже, проблема в том, что в 2. call Runtime.getRuntime().exec(command); он не запускается, потому что первый запуск еще не завершен.

S есть возможность приостановить поток или что-то в этом роде до тех пор, пока команда, запущенная Runtime.getRuntime().exec(command);, не исправит?

+0

Проверьте класс процесса в Java, то есть методы Waitfor(), который будет решать ваши цели. –

+1

1. Используйте 'ProcessBuilder'; 2. Разбейте команду и каждый параметр на свой собственный элемент 'String', который может быть передан' ProcessBuilder', это действительно помогает с сохранением вещей в чистоте и поддерживает пути с пробелами; 3. Прочтите 'Process'' OutputStream' (и поток ошибок); 4. Используйте 'Process # waitFor' и проверьте значение выхода; – MadProgrammer

ответ

0

Runtime.exec возвращает экземпляр Process, который вы можете использовать для контроля состояния.

Process process = Runtime.getRuntime().exec(command); 
boolean finished = process.waitFor(3, TimeUnit.SECONDS); 

Эта последняя строка может быть введена в цикл или просто установить разумный тайм-аут.

+0

Это решает проблему для меня. Я пытался использовать «ProcessBuilder», но у меня всегда было исключение «ERROR-2: Datei oder Verzeichnis nicht gefunden!». –

+0

У вас есть ссылка на метод 'waitFor'? Единственное, что я могу найти, это ['int waitFor()'] (http://docs.oracle.com/javase/7/docs/api/java/lang/Process.html#waitFor()) – MadProgrammer

+0

Было введено в Java 8 -https: //docs.oracle.com/javase/8/docs/api/java/lang/Process.html#waitFor-long-java.util.concurrent.TimeUnit- –

0

Поскольку вы в настоящее время запускаете его в одном потоке, попробуйте открыть новый поток каждый раз, когда вы выполняете команду exec. И присоедините поток после завершения процесса создания эскиза.