Kill a process started by exec() after som

2019-06-24 16:00发布

问题:

Let me start off by saying that I'm completely new to Java. I'm from PHP background, but it so happens that one of my PHP tasks need to be converted into Java.

The task is splitting a video into frames using ffmpeg and then working with those frames. I've completed this process in PHP. And now I can to convert it into Java.

I went over some tutorials and have got the bases covered (Using IDE, Running a java program etc). I'm using Eclipse for this purpose.

I've so far managed to start ffmpeg from withing a java program by using

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?

}

This is working fine, I'm getting the frames in the folder. Now what I want to do is kill the process after some, say 5 minutes, as the video is over 2 hours long and I don't want to have to go to the taskbar and kill the process manually. I also would like to know if there is a way to store the frame names created by ffmpeg into an array for future use.

I tried using p.destroy() but that didn't stop the process at all. How would I go about using something similar like setTimeout() which is used in jQuery?

Some Metadata

OS : Windows 7

IDE : Eclipse

回答1:

p.destroy() sends kill PID on linux. This means that process receives the signal but not necessarily terminates. You have to execute kill -9 PID to be sure that the process indeed terminated. Unfortunately standard java API does not provide such functionality, so you have to do this yourself.

But it is not so complicated. There are only 2 commands: kill for Unix and killtask for windows. Both accept process ID. You can discover it by reflection: the private int filed pid presents in platform specific subclass of Process instance of which you get from runtime.exec()

EDIT

On linux runtime.exec() returns instance of UnixProcess that extends Process. I am do not have windows available now and cannot check it for you but as far as I remember on windows it returns instance of WindowsProcess or something like that. Both have private int field pid that can be extracted using reflection:

Process proc = Rutime.getRuntime().exec("my command");
Field f = proc.getClass().getDeclaredField("pid");
f.setAccessible(true);
int pid = (Integer)f.get(proc);


回答2:

A simple way is to use java.util.Timer and java.util.TimerTask to set the timer for 5 min (or whatever duration of interest for you) and the timer task would get the process handle to kill it when the timer goes off and triggers the timer task.



回答3:

I think Apache watchdog will help you. It waits for execution for the given time . If the time the exceeds the given time it will terminate the process. It is available in commons exec

Sample code:

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


标签: java ffmpeg exec