You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
As requested in #88 (comment) , here is sample code and output demonstrating exceptions being thrown when stopping ffmpeg input with different methods.
Context: this is with the CAPTURE_INPUT branch, up-to-date as of today.
Basically:
when the input is ffmpeg's "testsrc", no exception is thrown and no stacktrace appears on the console
when the input is desktop capture, an exception is thrown with stopForcefully(), and stacktraces appear on the console for stopWithException() and stopWithInterruption(). stopGracefully() is OK.
Probably the output should be hidden or at least not propagated up.
Regarding the resulting files:
the 3 video files generated with the methods that threw an exception (caught or not) cannot be played by VLC
the 5 others are OK.
I think this is perfectly acceptable, as graceful stop is the normal way of stopping a capture, and all others are "brutal".
Here is the test code;
package examples.ffmpeg;
import com.github.kokorin.jaffree.ffmpeg.*;
import java.nio.file.Paths;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicReference;
public class Stop {
public static void stopWithException(final FFmpeg ffmpeg) throws Exception {
final AtomicBoolean stopped = new AtomicBoolean();
ffmpeg.setProgressListener(
new ProgressListener() {
@Override
public void onProgress(FFmpegProgress progress) {
if (stopped.get()) {
throw new RuntimeException("Stopped with exception!");
}
}
}
);
final AtomicReference<FFmpegResult> result = new AtomicReference<>();
new Thread() {
@Override
public void run() {
FFmpegResult r = ffmpeg.execute();
result.set(r);
}
}.start();
Thread.sleep(5_000);
stopped.set(true);
Thread.sleep(1_000);
System.out.println(result.get());
}
public static void stopWithInterruption(final FFmpeg ffmpeg) throws Exception {
final AtomicReference<FFmpegResult> result = new AtomicReference<>();
Thread thread = new Thread() {
@Override
public void run() {
FFmpegResult r = ffmpeg.execute();
result.set(r);
}
};
thread.start();
Thread.sleep(5_000);
thread.interrupt();
Thread.sleep(1_000);
System.out.println(result.get());
}
public static void stopForcefully(final FFmpeg ffmpeg) throws Exception {
FFmpegResultFuture future = ffmpeg.executeAsync();
Thread.sleep(5_000);
future.forceStop();
Thread.sleep(1_000);
System.out.println(future.get());
// Uncaught exception in executeAsync thread:
// Process execution has ended with non-zero status: 1
}
public static void stopGracefully(final FFmpeg ffmpeg) throws Exception {
FFmpegResultFuture future = ffmpeg.executeAsync();
Thread.sleep(5_000);
future.graceStop();
Thread.sleep(1_000);
System.out.println(future.get());
}
public static void main(String[] args) throws Exception {
System.out.println("\n-----------------------------TESTSRC-----------------------------------");
performStopTests(false);
System.out.println("\n-----------------------------DESKTOP----------------------------------");
performStopTests(true);
}
private static void performStopTests(boolean isDesktopSource) throws Exception {
FFmpeg ffmpeg;
System.out.println("\n------- stopWithException -------");
ffmpeg = createTestFFmpeg(isDesktopSource,1);
stopWithException(ffmpeg);
System.out.println("\n------- stopWithInterruption -------");
ffmpeg = createTestFFmpeg(isDesktopSource, 2);
stopWithInterruption(ffmpeg);
try {
System.out.println("\n------- stopForcefully -------");
ffmpeg = createTestFFmpeg(isDesktopSource, 3);
stopForcefully(ffmpeg);
}
catch (ExecutionException e) {
System.err.println("\n!!======= EXCEPTION CAUGHT BY THE CALLER ======!!\n");
e.printStackTrace();
}
System.out.println("\n------- stopGracefully -------");
ffmpeg = createTestFFmpeg(isDesktopSource, 4);
stopGracefully(ffmpeg);
}
public static FFmpeg createTestFFmpeg(boolean isDesktopSource, int n) {
if (isDesktopSource) {
return FFmpeg.atPath()
.addInput(CaptureInput
.captureDesktop()
.setCaptureFrameRate(25)
.setCaptureCursor(true)
)
.setProgressListener(new ProgressListener() {
@Override
public void onProgress(FFmpegProgress progress) {
System.out.println(progress);
}
})
.addOutput(UrlOutput
.toPath(Paths.get("desktop" + n + ".mp4"))
.addArguments("-preset", "ultrafast")
.setDuration(10, TimeUnit.SECONDS)
)
.setOverwriteOutput(true);
}
else {
return FFmpeg.atPath()
.addInput(
UrlInput
.fromUrl("testsrc=duration=3600:size=1280x720:rate=30")
.setFormat("lavfi")
)
.setProgressListener(new ProgressListener() {
@Override
public void onProgress(FFmpegProgress progress) {
System.out.println(progress);
}
})
.addOutput(UrlOutput
.toPath(Paths.get("test" + n + ".mp4"))
.addArguments("-preset", "ultrafast")
.setDuration(10, TimeUnit.SECONDS)
)
.setOverwriteOutput(true);
}
}
}
And here is the console output :
C:\Java\openjdk-14.0.1\bin\java.exe "-javaagent:C:\Program Files\JetBrains\IntelliJ IDEA Community Edition 2020.1.1\lib\idea_rt.jar=60826:C:\Program Files\JetBrains\IntelliJ IDEA Community Edition 2020.1.1\bin" -Dfile.encoding=UTF-8 -classpath "D:\Important\Documents Vincent\Programmation\Java\Jaffree\target\test-classes;D:\Important\Documents Vincent\Programmation\Java\Jaffree\target\classes;C:\Users\Vincent\.m2\repository\org\slf4j\slf4j-api\1.7.25\slf4j-api-1.7.25.jar;C:\Users\Vincent\.m2\repository\org\slf4j\slf4j-log4j12\1.7.25\slf4j-log4j12-1.7.25.jar;C:\Users\Vincent\.m2\repository\log4j\log4j\1.2.17\log4j-1.2.17.jar;C:\Users\Vincent\.m2\repository\commons-io\commons-io\2.5\commons-io-2.5.jar;C:\Users\Vincent\.m2\repository\commons-cli\commons-cli\1.4\commons-cli-1.4.jar;C:\Users\Vincent\.m2\repository\junit\junit\4.12\junit-4.12.jar;C:\Users\Vincent\.m2\repository\org\hamcrest\hamcrest-core\1.3\hamcrest-core-1.3.jar" examples.ffmpeg.Stop
-----------------------------TESTSRC-----------------------------------
------- stopWithException -------
INFO Thread-0 com.github.kokorin.jaffree.process.ProcessHandler - Command constructed:
ffmpeg -f lavfi -i testsrc=duration=3600:size=1280x720:rate=30 -y -t 10.000 -preset ultrafast test1.mp4
INFO Thread-0 com.github.kokorin.jaffree.process.ProcessHandler - Starting process: ffmpeg
INFO Thread-0 com.github.kokorin.jaffree.process.ProcessHandler - Waiting for process to finish
INFO Thread-0 com.github.kokorin.jaffree.process.ProcessHandler - Process has finished with status: 0
FFmpegResult{videoSize=280000, audioSize=0, subtitleSize=0, otherStreamsSize=0, globalHeadersSize=0, muxingOverheadRatio=0.00712398}
------- stopWithInterruption -------
INFO Thread-1 com.github.kokorin.jaffree.process.ProcessHandler - Command constructed:
ffmpeg -f lavfi -i testsrc=duration=3600:size=1280x720:rate=30 -y -t 10.000 -preset ultrafast test2.mp4
INFO Thread-1 com.github.kokorin.jaffree.process.ProcessHandler - Starting process: ffmpeg
INFO Thread-1 com.github.kokorin.jaffree.process.ProcessHandler - Waiting for process to finish
FFmpegProgress{frame=45, fps=0.0, q=15.0, size=null, time=1030, dup=null, drop=null, bitrate=0.4, speed=2.05}
FFmpegProgress{frame=96, fps=95.0, q=15.0, size=null, time=2730, dup=null, drop=null, bitrate=0.1, speed=2.7}
FFmpegProgress{frame=145, fps=96.0, q=15.0, size=null, time=4360, dup=null, drop=null, bitrate=0.1, speed=2.89}
FFmpegProgress{frame=191, fps=95.0, q=15.0, size=null, time=5900, dup=null, drop=null, bitrate=0.1, speed=2.93}
FFmpegProgress{frame=235, fps=93.0, q=15.0, size=null, time=7360, dup=null, drop=null, bitrate=0.1, speed=2.93}
FFmpegProgress{frame=284, fps=94.0, q=15.0, size=null, time=9000, dup=null, drop=null, bitrate=233.1, speed=2.99}
FFmpegProgress{frame=300, fps=93.0, q=-1.0, size=282000, time=9960, dup=null, drop=null, bitrate=231.8, speed=3.1}
INFO Thread-1 com.github.kokorin.jaffree.process.ProcessHandler - Process has finished with status: 0
FFmpegResult{videoSize=280000, audioSize=0, subtitleSize=0, otherStreamsSize=0, globalHeadersSize=0, muxingOverheadRatio=0.00712398}
------- stopForcefully -------
INFO FFmpeg-async-runner com.github.kokorin.jaffree.process.ProcessHandler - Command constructed:
ffmpeg -f lavfi -i testsrc=duration=3600:size=1280x720:rate=30 -y -t 10.000 -preset ultrafast test3.mp4
INFO FFmpeg-async-runner com.github.kokorin.jaffree.process.ProcessHandler - Starting process: ffmpeg
INFO FFmpeg-async-runner com.github.kokorin.jaffree.process.ProcessHandler - Waiting for process to finish
FFmpegProgress{frame=47, fps=0.0, q=15.0, size=null, time=1100, dup=null, drop=null, bitrate=0.3, speed=2.2}
FFmpegProgress{frame=97, fps=97.0, q=15.0, size=null, time=2760, dup=null, drop=null, bitrate=0.1, speed=2.76}
FFmpegProgress{frame=145, fps=96.0, q=15.0, size=null, time=4360, dup=null, drop=null, bitrate=0.1, speed=2.9}
FFmpegProgress{frame=193, fps=96.0, q=15.0, size=null, time=5960, dup=null, drop=null, bitrate=0.1, speed=2.97}
FFmpegProgress{frame=243, fps=97.0, q=17.0, size=null, time=7630, dup=null, drop=null, bitrate=0.1, speed=3.03}
FFmpegProgress{frame=295, fps=98.0, q=15.0, size=null, time=9360, dup=null, drop=null, bitrate=223.9, speed=3.1}
FFmpegProgress{frame=300, fps=97.0, q=-1.0, size=282000, time=9960, dup=null, drop=null, bitrate=231.8, speed=3.22}
INFO FFmpeg-async-runner com.github.kokorin.jaffree.process.ProcessHandler - Process has finished with status: 0
FFmpegResult{videoSize=280000, audioSize=0, subtitleSize=0, otherStreamsSize=0, globalHeadersSize=0, muxingOverheadRatio=0.00712398}
------- stopGracefully -------
INFO FFmpeg-async-runner com.github.kokorin.jaffree.process.ProcessHandler - Command constructed:
ffmpeg -f lavfi -i testsrc=duration=3600:size=1280x720:rate=30 -y -t 10.000 -preset ultrafast test4.mp4
INFO FFmpeg-async-runner com.github.kokorin.jaffree.process.ProcessHandler - Starting process: ffmpeg
INFO FFmpeg-async-runner com.github.kokorin.jaffree.process.ProcessHandler - Waiting for process to finish
FFmpegProgress{frame=46, fps=0.0, q=15.0, size=null, time=1060, dup=null, drop=null, bitrate=0.4, speed=2.1}
FFmpegProgress{frame=98, fps=97.0, q=15.0, size=null, time=2800, dup=null, drop=null, bitrate=0.1, speed=2.78}
FFmpegProgress{frame=148, fps=98.0, q=15.0, size=null, time=4460, dup=null, drop=null, bitrate=0.1, speed=2.95}
FFmpegProgress{frame=199, fps=98.0, q=15.0, size=null, time=6160, dup=null, drop=null, bitrate=0.1, speed=3.05}
FFmpegProgress{frame=250, fps=99.0, q=15.0, size=null, time=7860, dup=null, drop=null, bitrate=0.0, speed=3.11}
FFmpegProgress{frame=298, fps=98.0, q=15.0, size=null, time=9460, dup=null, drop=null, bitrate=221.6, speed=3.12}
FFmpegProgress{frame=300, fps=97.0, q=-1.0, size=282000, time=9960, dup=null, drop=null, bitrate=231.8, speed=3.23}
INFO FFmpeg-async-runner com.github.kokorin.jaffree.process.ProcessHandler - Process has finished with status: 0
INFO main com.github.kokorin.jaffree.ffmpeg.FFmpegStopper - Ignoring class java.io.IOException: Stream Closed
FFmpegResult{videoSize=280000, audioSize=0, subtitleSize=0, otherStreamsSize=0, globalHeadersSize=0, muxingOverheadRatio=0.00712398}
-----------------------------DESKTOP----------------------------------
------- stopWithException -------
INFO Thread-2 com.github.kokorin.jaffree.process.ProcessHandler - Command constructed:
ffmpeg -f gdigrab -framerate 25 -draw_mouse 1 -i desktop -y -t 10.000 -preset ultrafast desktop1.mp4
INFO Thread-2 com.github.kokorin.jaffree.process.ProcessHandler - Starting process: ffmpeg
INFO Thread-2 com.github.kokorin.jaffree.process.ProcessHandler - Waiting for process to finish
WARN StdErr com.github.kokorin.jaffree.process.Executor - Interrupting starter thread (Thread-2) because of exception: Stopped with exception!
WARN Thread-2 com.github.kokorin.jaffree.process.ProcessHandler - Process has been interrupted
WARN Thread-2 com.github.kokorin.jaffree.process.Executor - Interrupting ALIVE thread: StdOut
Exception in thread "Thread-2" java.lang.RuntimeException: Failed to execute, exception appeared in one of helper threads
at com.github.kokorin.jaffree.process.ProcessHandler.interactWithProcess(ProcessHandler.java:138)
at com.github.kokorin.jaffree.process.ProcessHandler.execute(ProcessHandler.java:94)
at com.github.kokorin.jaffree.ffmpeg.FFmpeg.execute(FFmpeg.java:219)
at examples.ffmpeg.Stop$2.run(Stop.java:30)
Caused by: java.lang.RuntimeException: Exception during execution
at com.github.kokorin.jaffree.process.Executor.getException(Executor.java:95)
at com.github.kokorin.jaffree.process.ProcessHandler.interactWithProcess(ProcessHandler.java:135)
... 3 more
Caused by: java.lang.RuntimeException: Stopped with exception!
at examples.ffmpeg.Stop$1.onProgress(Stop.java:19)
at com.github.kokorin.jaffree.ffmpeg.FFmpegResultReader.read(FFmpegResultReader.java:58)
at com.github.kokorin.jaffree.ffmpeg.FFmpegResultReader.read(FFmpegResultReader.java:32)
at com.github.kokorin.jaffree.process.ProcessHandler$1.run(ProcessHandler.java:166)
at com.github.kokorin.jaffree.process.Executor$1.run(Executor.java:67)
at java.base/java.lang.Thread.run(Thread.java:832)
null
------- stopWithInterruption -------
INFO Thread-3 com.github.kokorin.jaffree.process.ProcessHandler - Command constructed:
ffmpeg -f gdigrab -framerate 25 -draw_mouse 1 -i desktop -y -t 10.000 -preset ultrafast desktop2.mp4
INFO Thread-3 com.github.kokorin.jaffree.process.ProcessHandler - Starting process: ffmpeg
INFO Thread-3 com.github.kokorin.jaffree.process.ProcessHandler - Waiting for process to finish
FFmpegProgress{frame=17, fps=0.0, q=13.0, size=null, time=120, dup=11, drop=0, bitrate=34933.0, speed=0.216}
FFmpegProgress{frame=32, fps=28.0, q=13.0, size=null, time=720, dup=20, drop=0, bitrate=8737.7, speed=0.623}
FFmpegProgress{frame=47, fps=27.0, q=13.0, size=null, time=1320, dup=29, drop=0, bitrate=4766.3, speed=0.751}
FFmpegProgress{frame=60, fps=27.0, q=13.0, size=null, time=1840, dup=37, drop=0, bitrate=3419.3, speed=0.814}
FFmpegProgress{frame=75, fps=26.0, q=13.0, size=null, time=2440, dup=46, drop=0, bitrate=2578.5, speed=0.855}
FFmpegProgress{frame=88, fps=26.0, q=13.0, size=null, time=2960, dup=54, drop=0, bitrate=2125.6, speed=0.877}
FFmpegProgress{frame=100, fps=26.0, q=13.0, size=null, time=3440, dup=61, drop=0, bitrate=1829.0, speed=0.888}
FFmpegProgress{frame=113, fps=26.0, q=13.0, size=null, time=3960, dup=69, drop=0, bitrate=1588.8, speed=0.904}
WARN Thread-3 com.github.kokorin.jaffree.process.ProcessHandler - Process has been interrupted
WARN Thread-3 com.github.kokorin.jaffree.process.Executor - Interrupting ALIVE thread: StdErr
WARN Thread-3 com.github.kokorin.jaffree.process.Executor - Interrupting ALIVE thread: StdOut
Exception in thread "Thread-3" java.lang.RuntimeException: Failed to execute, was interrupted
at com.github.kokorin.jaffree.process.ProcessHandler.interactWithProcess(ProcessHandler.java:142)
at com.github.kokorin.jaffree.process.ProcessHandler.execute(ProcessHandler.java:94)
at com.github.kokorin.jaffree.ffmpeg.FFmpeg.execute(FFmpeg.java:219)
at examples.ffmpeg.Stop$3.run(Stop.java:48)
Caused by: java.lang.InterruptedException
at java.base/java.lang.ProcessImpl.waitFor(ProcessImpl.java:549)
at com.github.kokorin.jaffree.process.ProcessHandler.interactWithProcess(ProcessHandler.java:120)
... 3 more
null
------- stopForcefully -------
INFO FFmpeg-async-runner com.github.kokorin.jaffree.process.ProcessHandler - Command constructed:
ffmpeg -f gdigrab -framerate 25 -draw_mouse 1 -i desktop -y -t 10.000 -preset ultrafast desktop3.mp4
INFO FFmpeg-async-runner com.github.kokorin.jaffree.process.ProcessHandler - Starting process: ffmpeg
INFO FFmpeg-async-runner com.github.kokorin.jaffree.process.ProcessHandler - Waiting for process to finish
FFmpegProgress{frame=17, fps=0.0, q=13.0, size=null, time=120, dup=11, drop=0, bitrate=34933.0, speed=0.212}
FFmpegProgress{frame=32, fps=27.0, q=13.0, size=null, time=720, dup=20, drop=0, bitrate=8737.7, speed=0.617}
FFmpegProgress{frame=47, fps=27.0, q=13.0, size=null, time=1320, dup=29, drop=0, bitrate=4766.3, speed=0.745}
FFmpegProgress{frame=62, fps=26.0, q=13.0, size=null, time=1920, dup=38, drop=0, bitrate=3276.9, speed=0.811}
FFmpegProgress{frame=75, fps=26.0, q=13.0, size=null, time=2440, dup=46, drop=0, bitrate=2578.5, speed=0.85}
FFmpegProgress{frame=90, fps=26.0, q=13.0, size=null, time=3040, dup=55, drop=0, bitrate=2069.6, speed=0.878}
FFmpegProgress{frame=102, fps=26.0, q=13.0, size=null, time=3520, dup=62, drop=0, bitrate=1787.4, speed=0.888}
FFmpegProgress{frame=115, fps=26.0, q=13.0, size=null, time=4040, dup=70, drop=0, bitrate=1557.4, speed=0.905}
INFO FFmpeg-async-runner com.github.kokorin.jaffree.process.ProcessHandler - Process has finished with status: 1
!!======= EXCEPTION CAUGHT BY THE CALLER ======!!
java.util.concurrent.ExecutionException: java.lang.RuntimeException: Process execution has ended with non-zero status: 1
at java.base/java.util.concurrent.FutureTask.report(FutureTask.java:122)
at java.base/java.util.concurrent.FutureTask.get(FutureTask.java:191)
at com.github.kokorin.jaffree.ffmpeg.FFmpegResultFuture.get(FFmpegResultFuture.java:93)
at examples.ffmpeg.Stop.stopForcefully(Stop.java:68)
at examples.ffmpeg.Stop.performStopTests(Stop.java:105)
at examples.ffmpeg.Stop.main(Stop.java:88)
Caused by: java.lang.RuntimeException: Process execution has ended with non-zero status: 1
at com.github.kokorin.jaffree.process.ProcessHandler.interactWithProcess(ProcessHandler.java:146)
at com.github.kokorin.jaffree.process.ProcessHandler.execute(ProcessHandler.java:94)
at com.github.kokorin.jaffree.ffmpeg.FFmpeg$1.call(FFmpeg.java:236)
at com.github.kokorin.jaffree.ffmpeg.FFmpeg$1.call(FFmpeg.java:233)
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
at java.base/java.lang.Thread.run(Thread.java:832)
------- stopGracefully -------
INFO FFmpeg-async-runner com.github.kokorin.jaffree.process.ProcessHandler - Command constructed:
ffmpeg -f gdigrab -framerate 25 -draw_mouse 1 -i desktop -y -t 10.000 -preset ultrafast desktop4.mp4
INFO FFmpeg-async-runner com.github.kokorin.jaffree.process.ProcessHandler - Starting process: ffmpeg
INFO FFmpeg-async-runner com.github.kokorin.jaffree.process.ProcessHandler - Waiting for process to finish
FFmpegProgress{frame=17, fps=0.0, q=13.0, size=null, time=120, dup=11, drop=0, bitrate=34933.0, speed=0.212}
FFmpegProgress{frame=32, fps=28.0, q=13.0, size=null, time=720, dup=20, drop=0, bitrate=8737.7, speed=0.619}
FFmpegProgress{frame=47, fps=27.0, q=13.0, size=null, time=1320, dup=29, drop=0, bitrate=4766.3, speed=0.747}
FFmpegProgress{frame=62, fps=26.0, q=13.0, size=null, time=1920, dup=38, drop=0, bitrate=3276.9, speed=0.812}
FFmpegProgress{frame=75, fps=26.0, q=13.0, size=null, time=2440, dup=46, drop=0, bitrate=2578.5, speed=0.846}
FFmpegProgress{frame=90, fps=26.0, q=13.0, size=null, time=3040, dup=55, drop=0, bitrate=2069.6, speed=0.873}
FFmpegProgress{frame=105, fps=26.0, q=13.0, size=null, time=3640, dup=64, drop=0, bitrate=1728.5, speed=0.89}
FFmpegProgress{frame=120, fps=26.0, q=13.0, size=null, time=4240, dup=73, drop=0, bitrate=1483.9, speed=0.904}
FFmpegProgress{frame=123, fps=25.0, q=-1.0, size=994000, time=4880, dup=75, drop=0, bitrate=1668.6, speed=0.992}
INFO FFmpeg-async-runner com.github.kokorin.jaffree.process.ProcessHandler - Process has finished with status: 0
FFmpegResult{videoSize=993000, audioSize=0, subtitleSize=0, otherStreamsSize=0, globalHeadersSize=0, muxingOverheadRatio=0.00129356}
Process finished with exit code 0
The text was updated successfully, but these errors were encountered:
As requested in #88 (comment) , here is sample code and output demonstrating exceptions being thrown when stopping ffmpeg input with different methods.
Context: this is with the CAPTURE_INPUT branch, up-to-date as of today.
Basically:
stopForcefully()
, and stacktraces appear on the console forstopWithException()
andstopWithInterruption()
.stopGracefully()
is OK.Probably the output should be hidden or at least not propagated up.
Regarding the resulting files:
I think this is perfectly acceptable, as graceful stop is the normal way of stopping a capture, and all others are "brutal".
Here is the test code;
And here is the console output :
The text was updated successfully, but these errors were encountered: