diff --git a/src/main/java/com/github/kokorin/jaffree/ffmpeg/FFmpeg.java b/src/main/java/com/github/kokorin/jaffree/ffmpeg/FFmpeg.java index 0edf7932..6c1b65e3 100644 --- a/src/main/java/com/github/kokorin/jaffree/ffmpeg/FFmpeg.java +++ b/src/main/java/com/github/kokorin/jaffree/ffmpeg/FFmpeg.java @@ -23,6 +23,7 @@ import com.github.kokorin.jaffree.process.LoggingStdReader; import com.github.kokorin.jaffree.process.ProcessHandler; import com.github.kokorin.jaffree.process.ProcessHelper; +import com.github.kokorin.jaffree.process.ProcessListener; import com.github.kokorin.jaffree.process.StdReader; import com.github.kokorin.jaffree.process.Stopper; import org.slf4j.Logger; @@ -50,6 +51,7 @@ public class FFmpeg { private boolean overwriteOutput; private ProgressListener progressListener; private OutputListener outputListener; + private ProcessListener processListener; private String progress; //-filter_threads nb_threads (global) //-debug_ts (global) @@ -344,6 +346,17 @@ public FFmpeg setOutputListener(final OutputListener outputListener) { return this; } + /** + * Supply a ProcessListener to receive access to the Active Process instance of FFmpeg. + *

+ * Providing you self control on how the processes are kept alive or tracked. + * Since the commandline doesn't guarantee to listen to shutdown commands. + */ + public FFmpeg setProcessListener(final ProcessListener processListener) { + this.processListener = processListener; + return this; + } + /** * Send program-friendly progress information to url. *

@@ -506,6 +519,7 @@ protected ProcessHandler createProcessHandler() { .setStdErrReader(createStdErrReader(outputListener)) .setStdOutReader(createStdOutReader()) .setHelpers(helpers) + .setProcessListener(processListener) .setArguments(buildArguments()); if (executorTimeoutMillis != null) { processHandler.setExecutorTimeoutMillis(executorTimeoutMillis); diff --git a/src/main/java/com/github/kokorin/jaffree/ffprobe/FFprobe.java b/src/main/java/com/github/kokorin/jaffree/ffprobe/FFprobe.java index 9e58bb4c..f5f04b1b 100644 --- a/src/main/java/com/github/kokorin/jaffree/ffprobe/FFprobe.java +++ b/src/main/java/com/github/kokorin/jaffree/ffprobe/FFprobe.java @@ -22,6 +22,7 @@ import com.github.kokorin.jaffree.ffprobe.data.FormatParser; import com.github.kokorin.jaffree.ffprobe.data.JsonFormatParser; import com.github.kokorin.jaffree.process.ProcessHandler; +import com.github.kokorin.jaffree.process.ProcessListener; import com.github.kokorin.jaffree.process.ProcessHelper; import com.github.kokorin.jaffree.process.StdReader; @@ -68,6 +69,7 @@ public class FFprobe { private String format; private Input input; + private ProcessListener processListener; private FormatParser formatParser = new JsonFormatParser(); private final Path executable; @@ -472,6 +474,17 @@ public FFprobe setInput(final Input input) { return this; } + /** + * Supply a ProcessListener to receive access to the Active Process instance of FFprobe. + *

+ * Providing you self control on how the processes are kept alive or tracked. + * Since the commandline doesn't guarantee to listen to shutdown commands. + */ + public FFprobe setProcessListener(final ProcessListener processListener) { + this.processListener = processListener; + return this; + } + /** * Sets ffprobe output format parser (and corresponding output format). *

@@ -545,6 +558,7 @@ public FFprobeResult execute() { .setStdOutReader(createStdOutReader(formatParser)) .setStdErrReader(createStdErrReader()) .setHelpers(helpers) + .setProcessListener(processListener) .setArguments(buildArguments()) .execute(); } diff --git a/src/main/java/com/github/kokorin/jaffree/process/ProcessHandler.java b/src/main/java/com/github/kokorin/jaffree/process/ProcessHandler.java index 4ed9d280..ecd921e5 100644 --- a/src/main/java/com/github/kokorin/jaffree/process/ProcessHandler.java +++ b/src/main/java/com/github/kokorin/jaffree/process/ProcessHandler.java @@ -47,6 +47,7 @@ public class ProcessHandler { private StdReader stdOutReader = new GobblingStdReader<>(); private StdReader stdErrReader = new GobblingStdReader<>(); private List helpers = null; + private ProcessListener listener = null; private Stopper stopper = null; private List arguments = Collections.emptyList(); private int executorTimeoutMillis = DEFAULT_EXECUTOR_TIMEOUT_MILLIS; @@ -99,6 +100,17 @@ public synchronized ProcessHandler setHelpers(final List helpe return this; } + /** + * Sets a {@link ProcessListener Listener} that gets called when a process gets started or stopped. + * + * @param listener the listener + * @return this + */ + public synchronized ProcessHandler setProcessListener(final ProcessListener listener) { + this.listener = listener; + return this; + } + /** * Sets {@link Stopper} which can be used to interrupt program execution. * @@ -158,6 +170,9 @@ public synchronized T execute() { if (stopper != null) { stopper.setProcess(process); } + if(listener != null) { + listener.onProcessStart(process); + } return interactWithProcess(process); } catch (IOException e) { @@ -165,6 +180,9 @@ public synchronized T execute() { throw new JaffreeException("Failed to start process.", e); } finally { if (process != null) { + if(listener != null) { + listener.onProcessStop(process); + } process.destroy(); // Process must be destroyed before closing streams, can't use // try-with-resources, as resources are closing when leaving try block, diff --git a/src/main/java/com/github/kokorin/jaffree/process/ProcessListener.java b/src/main/java/com/github/kokorin/jaffree/process/ProcessListener.java new file mode 100644 index 00000000..fb9c571c --- /dev/null +++ b/src/main/java/com/github/kokorin/jaffree/process/ProcessListener.java @@ -0,0 +1,18 @@ +package com.github.kokorin.jaffree.process; + +/** + * @Author Speiger + */ +public class ProcessListener { + + /** + * Callback for when the Process is started. + * @param process the started process + */ + public void onProcessStart(Process process); + /** + * Callback for when the Process is stopped for whatever reason. + * @param process the stopped process + */ + public void onProcessStop(Process process); +} \ No newline at end of file