Open nolawnchairs opened 6 years ago
Additionally, when grabbing a screen:
final FFmpegBuilder builder = new FFmpegBuilder()
.setVerbosity(Verbosity.ERROR)
.setFormat("x11grab") // Format is not always a media format name
.addInput("+1920,540") // Input is not always a filename
.overrideOutputFiles(true)
.addOutput("/tmp/output.mp4")
.setVideoFrameRate(25, 1)
.setVideoResolution(640, 480)
.addExtraArgs("-threads", "0",
"-hide_banner")
.done();
ffmpeg
never terminates by itself, so it can only be terminated by external means.
It would be a good idea to also add a JVM shutdown hook to terminate any child processes remaining alive, just in case.
The problem can be worked around by using a custom ProcessFunction
:
final FFmpeg ffmpeg = new FFmpeg("/usr/bin/ffmpeg", new RunProcessFunction() {
@Override
public Process run(final List<String> args) throws IOException {
final Process process = super.run(args);
if (!(args.size() == 2 && args.get(1).equals("-version"))) {
/*
* Remember all child processes except "ffmpeg -version"
*/
processes.add(process);
}
Runtime.getRuntime().addShutdownHook(new Thread(() -> {
terminateFfmpeg(process);
}, "FFmpeg process destroyer"));
return process;
}
});
where terminateFfmpeg(Process)
can be implemented like this:
/**
* @return the exit code of the terminated process as an {@code unsigned
* byte} (0..255 range), or -1 if the current thread has been
* interrupted.
*/
int terminateFfmpeg(final Process process) {
if (!process.isAlive()) {
/*
* ffmpeg -version, do nothing
*/
return process.exitValue();
}
/*
* ffmpeg -f x11grab
*/
System.out.println("About to destroy the child process...");
try (final OutputStreamWriter out = new OutputStreamWriter(process.getOutputStream(), UTF_8)) {
out.write('q');
} catch (final IOException ioe) {
ioe.printStackTrace();
}
try {
if (!process.waitFor(5L, TimeUnit.SECONDS)) {
process.destroy();
process.waitFor();
}
return process.exitValue();
} catch (final InterruptedException ie) {
System.out.println("Interrupted");
ie.printStackTrace();
Thread.currentThread().interrupt();
return -1;
}
}
Question,
I include this library in a small FX application, and I would like to know how to go about killing (SIGINT) the ffmpeg process in the event of the user closing the application.