From d78f96fef6a5c9aa5a11d8f1f184ab7b17e60c3d Mon Sep 17 00:00:00 2001 From: 0xboobface <0xboobface@gmail.com> Date: Sat, 25 Apr 2020 15:15:03 +0200 Subject: [PATCH] Improve handling of recording termination This change hopefully helps to terminate FFmpeg reliably once a recording terminates. --- .../download/hls/MergedFfmpegHlsDownload.java | 23 ++++++++++++------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/common/src/main/java/ctbrec/recorder/download/hls/MergedFfmpegHlsDownload.java b/common/src/main/java/ctbrec/recorder/download/hls/MergedFfmpegHlsDownload.java index cc151b01..2ef55394 100644 --- a/common/src/main/java/ctbrec/recorder/download/hls/MergedFfmpegHlsDownload.java +++ b/common/src/main/java/ctbrec/recorder/download/hls/MergedFfmpegHlsDownload.java @@ -42,6 +42,7 @@ import okhttp3.Response; public class MergedFfmpegHlsDownload extends AbstractHlsDownload { + private static final long serialVersionUID = 1L; private static final Logger LOG = LoggerFactory.getLogger(MergedFfmpegHlsDownload.class); private static final boolean IGNORE_CACHE = true; private ZonedDateTime splitRecStartTime; @@ -95,7 +96,7 @@ public class MergedFfmpegHlsDownload extends AbstractHlsDownload { // end of playlist reached LOG.debug("Reached end of playlist for model {}", model); } catch (Exception e) { - throw new IOException("Couldn't download segment", e); + throw new IOException("Exception while downloading segments", e); } finally { internalStop(); downloadThreadPool.shutdown(); @@ -133,6 +134,7 @@ public class MergedFfmpegHlsDownload extends AbstractHlsDownload { stdout.start(); stderr.start(); exitCode = ffmpeg.waitFor(); + LOG.debug("FFmpeg exited with code {}", exitCode); stdout.join(); stderr.join(); mergeLogStream.flush(); @@ -142,15 +144,18 @@ public class MergedFfmpegHlsDownload extends AbstractHlsDownload { Files.delete(ffmpegLog.toPath()); } } else { - LOG.info("FFmpeg exit code was {}. Logfile: {}", exitCode, ffmpegLog.getAbsolutePath()); - throw new ProcessExitedUncleanException("FFmpeg exit code was " + exitCode); + if (running) { + LOG.info("FFmpeg exit code was {}. Logfile: {}", exitCode, ffmpegLog.getAbsolutePath()); + throw new ProcessExitedUncleanException("FFmpeg exit code was " + exitCode); + } } } catch (IOException | ProcessExitedUncleanException e) { LOG.error("Error in FFMpeg thread", e); } catch (InterruptedException e) { Thread.currentThread().interrupt(); - LOG.info("Interrupted while waiting for ffmpeg", e); - // maybe kill / terminate ffmpeg here?!? + if (running) { + LOG.info("Interrupted while waiting for ffmpeg", e); + } } }); ffmpegThread.setName("FFmpeg"); @@ -209,7 +214,7 @@ public class MergedFfmpegHlsDownload extends AbstractHlsDownload { running = false; } } - internalStop(); + ffmpegThread.interrupt(); } private void downloadRecording(SegmentPlaylist lsp) throws IOException { @@ -365,10 +370,12 @@ public class MergedFfmpegHlsDownload extends AbstractHlsDownload { ffmpegStdIn.close(); } catch (IOException e) { LOG.error("Couldn't terminate FFmpeg by closing stdin", e); - } finally { - ffmpeg.destroy(); } } + if (ffmpeg != null && ffmpeg.isAlive()) { + ffmpeg.destroyForcibly(); + ffmpeg = null; + } } private class SegmentDownload implements Callable {