ffmpeg-cli-wrapper icon indicating copy to clipboard operation
ffmpeg-cli-wrapper copied to clipboard

Kill ffmpeg process?

Open nolawnchairs opened this issue 7 years ago • 2 comments
trafficstars

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.

nolawnchairs avatar Jul 21 '18 07:07 nolawnchairs

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.

unix-junkie avatar Oct 05 '18 22:10 unix-junkie

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;
		}
	}

unix-junkie avatar Oct 09 '18 14:10 unix-junkie