Завершить процесс, запущенный функцией exec () через некоторое время, и сохранить кадры в массиве.

Позвольте мне начать с того, что я совершенно новичок в Java. Я из PHP фон, но так случилось, что одну из моих задач PHP нужно преобразовать в Java.

Задача состоит в том, чтобы разбить видео на кадры с помощью ffmpeg и затем работать с этими кадрами. Я завершил этот процесс на PHP. И теперь я могу преобразовать его в Java.

Я просмотрел несколько руководств и рассмотрел основы (использование IDE, запуск Java-программы и т. Д.). Для этого я использую Eclipse.

Мне до сих пор удалось запустить ffmpeg из Java-программы, используя

public static void main(String[] args) throws IOException {

    String livestream = "D:/video.mpg";
    String folderpth = "D:/frames";
    String cmd="D:/ffmpeg/bin/ffmpeg.exe -i "+ livestream +" -r 10 "+folderpth+"/image%d.jpg";

    //System.out.println(cmd);
    Runtime r = Runtime.getRuntime();
    Process p = r.exec(cmd); // this starts creating frames
   // and stores them on local disk
   // any way to store that frame name in array?
   // something like String[] frames = {"image%d.jpg"}
   // so that frames array contains image1.jpg, image2.jpg..and so on?

}

Работает нормально, кадры попадают в папку. Теперь я хочу убить процесс через несколько минут, скажем, через 5 минут, так как видео длится более 2 часов, и я не хочу, чтобы мне приходилось переходить на панель задач и убивать процесс вручную. Я также хотел бы знать, есть ли способ сохранить имена фреймов, созданные ffmpeg, в массиве для будущего использования.

Я пробовал использовать p.destroy(), но это нисколько не остановило процесс. Как мне использовать что-то похожее, например setTimeout(), которое используется в jQuery?

Некоторые метаданные

ОС: Windows 7

IDE: Eclipse


person asprin    schedule 19.02.2013    source источник
comment
Вы пробовали это?   -  person StarPinkER    schedule 19.02.2013
comment
Было бы хорошо узнать вашу ОС   -  person SJuan76    schedule 19.02.2013
comment
Кажется, это не указывает продолжительность времени   -  person asprin    schedule 19.02.2013


Ответы (3)


p.destroy() отправляет kill PID на linux. Это означает, что процесс получает сигнал, но не обязательно завершается. Вы должны выполнить kill -9 PID, чтобы убедиться, что процесс действительно завершен. К сожалению, стандартный Java API не предоставляет такой возможности, поэтому вам придется сделать это самостоятельно.

Но это не так уж и сложно. Есть всего 2 команды: kill для Unix и killtask для windows. Оба принимают ID процесса. Вы можете обнаружить это путем отражения: личное поле int pid представляет собой подкласс Process, зависящий от платформы, который вы получаете от runtime.exec()

РЕДАКТИРОВАТЬ

В Linux runtime.exec() возвращает экземпляр UnixProcess, который расширяет Process. У меня сейчас нет доступных окон, и я не могу проверить это для вас, но, насколько я помню, в окнах он возвращает экземпляр WindowsProcess или что-то в этом роде. У обоих есть приватное поле int pid, которое можно извлечь с помощью отражения:

Process proc = Rutime.getRuntime().exec("my command");
Field f = proc.getClass().getDeclaredField("pid");
f.setAccessible(true);
int pid = (Integer)f.get(proc);
person AlexR    schedule 19.02.2013
comment
Ого! Для меня сейчас это как греческий и латинский языки. Прошу извинить за тупость, но я только новичок в Java. Фактически, это мой первый день сегодня. Из того, что я получил из вашего ответа, мне придется использовать команду killtask. Проблема в получении PID. Я предполагаю, что что-то вроде p.pid даст мне это? - person asprin; 19.02.2013
comment
@asprin, см. дополнение к моему ответу. Я дал вам образец кода. - person AlexR; 19.02.2013

Простой способ - использовать java.util.Timer и java.util.TimerTask, чтобы установите таймер на 5 минут (или на любую интересующую вас продолжительность), и задача таймера получит дескриптор процесса, чтобы убить его, когда таймер сработает и запустит задачу таймера.

person Vikdor    schedule 19.02.2013

Думаю, вам поможет сторожевой пес Apache. Он ожидает исполнения в течение заданного времени. Если время превышает заданное, процесс завершится. Он доступен в Commons exec.

Образец кода:

ExecuteWatchdog watchdog = new ExecuteWatchdog(1000*60*5);
Process process= Runtime.getRuntime().exec("cmd");
watchdog.start(process);
person SANN3    schedule 19.02.2013