From e5cd4b5b58649d2f51562f968758ab9fc052f54f Mon Sep 17 00:00:00 2001 From: David Plowman Date: Thu, 19 Oct 2023 10:02:22 +0100 Subject: [PATCH] FfmpegOutput was not stopping when there was an audio stream ffmpeg.wait() hangs indefinitely if there's an audio stream because no one is stopping it. Instead, give the video a few moments to flush itself out and then use ffmpeg.terminate(). Signed-off-by: David Plowman --- picamera2/outputs/ffmpegoutput.py | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/picamera2/outputs/ffmpegoutput.py b/picamera2/outputs/ffmpegoutput.py index 17df8eb7..d782984f 100644 --- a/picamera2/outputs/ffmpegoutput.py +++ b/picamera2/outputs/ffmpegoutput.py @@ -43,6 +43,9 @@ def __init__(self, output_filename, audio=False, audio_device="default", audio_s self.audio_samplerate = audio_samplerate self.audio_codec = audio_codec self.audio_bitrate = audio_bitrate + # If we run an audio stream, FFmpeg won't stop so we'll give the video stream a + # moment or two to flush stuff out, and then we'll have to terminate the process. + self.timeout = 1 if audio else None def start(self): general_options = ['-loglevel', 'warning', @@ -76,7 +79,15 @@ def stop(self): super().stop() if self.ffmpeg is not None: self.ffmpeg.stdin.close() # FFmpeg needs this to shut down tidily - self.ffmpeg.wait() + try: + # Give it a moment to flush out video frames, but after that make sure we terminate it. + self.ffmpeg.wait(timeout=self.timeout) + except subprocess.TimeoutExpired: + # We'll always end up here when there was an audio strema. Ignore any further errors. + try: + self.ffmpeg.terminate() + except Exception: + pass self.ffmpeg = None def outputframe(self, frame, keyframe=True, timestamp=None):