Java: finding out if a process from cmd tool has completed


2 posts
by El Fred » Wed May 10, 2017 8:47 am
I have a "VidCamera" class, which basically runs the "raspivid" command tool for recording a video. The method for recording a video from that class looks like this:

Code: Select all
public void recordVideo(String filename, int duration) throws IOException {
    setFilename(filename);
    setDuration(duration);
    try {
        String cmdline = getCmdLine();
        Process sysprocess = Runtime.getRuntime().exec(cmdline);
    }
    catch (IOException e) {
        System.out.println("Exception while recording video.");
        e.printStackTrace();
    }
}


and the getCmdLine() method is constructed to output something like:
raspivid -w 640 -h 480 -fps 60 - t 5000 -o testvideo.h264
.

The video recording works as expected, since it's simply using the command line tool. However, my code does not know when the video has finished recording.

Example, when I test the video recording from my main class with:

Code: Select all
  try {
        camcorder.recordVideo("myVideoTest.h264", 5000);           
        System.out.println("Video recording completed.");
    }
    catch (Exception e) {
        System.out.println(e);
    }


then the text "Video recording completed." is printed immediately after calling the recordVideo() method. In the background, the 5s video recording is still busy in another thread.

How can I solve this? How can I make my code know when the video recording from the command line tool is ready?
Posts: 35
Joined: Mon Sep 26, 2016 11:14 am
by knute » Wed May 10, 2017 3:04 pm
First a suggestion, use ProcessBuilder.start() to create your process instead of Runtime.exec(). See the Java API docs for Process for Oracle's suggestion.

Second, you need some code to cause your thread to block until the recording is done. When you start a Process, that Process runs in its own thread independently of the thread that started the Process.

Code: Select all
ProcessBuilder builder = new ProcessBuilder(command);
try {
    Process process = builder.start();
    process.waitFor();
} catch (IOException|InterruptedException ex) {
    ex.printStackTrace();
}


The Process.waitFor() method blocks the current thread until your process is finished or the thread is interrupted.

The other issue is you need to collect the output from your process. To see a good example of how this all works you can look at my camera motion detection program at http://knutejohnson.com/pi. Look at the source code for the MotionDetection program. I make many calls in that program to create a process and wait for it to finish, sometimes checking the status from the command that was run. Near the end of the code is a class, ProcessManager, that I wrote to consolidate some of the code to create and manage a running process.
Posts: 252
Joined: Thu Oct 23, 2014 12:14 am