From 22df6f0b4549e3b98b679242a985e74cd575cf27 Mon Sep 17 00:00:00 2001 From: Mike Lang Date: Wed, 2 Jan 2019 07:13:27 -0800 Subject: [PATCH] cutter: Fix bugs that meant things wouldn't actually be cut The calculations were backwards, so instead of cutting a video by, say, 2 seconds, it would cut by -2 seconds, which was clamped to 0. So it would never actually cut, it would always use the closest segment. Also, once we were actually cutting, we hit an issue where ffmpeg would finish and close its input early, because we'd reached the end of the cut video, but not all input had been written yet. This resulted in an EPIPE error (write to closed pipe) in the input feeder. We now ignore that. --- restreamer/restreamer/main.py | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/restreamer/restreamer/main.py b/restreamer/restreamer/main.py index 657a926..7fba30b 100644 --- a/restreamer/restreamer/main.py +++ b/restreamer/restreamer/main.py @@ -226,11 +226,11 @@ def cut(stream, variant): return "We have no content available within the requested time range.", 406 # how far into the first segment to begin - cut_start = max(0, (segments[0].start - start).total_seconds()) + cut_start = max(0, (start - segments[0].start).total_seconds()) # calculate full uncut duration of content, ie. without holes. full_duration = sum(segment.duration.total_seconds() for segment in segments) # calculate how much of final segment should be cut off - cut_end = max(0, (end - segments[-1].end).total_seconds()) + cut_end = max(0, (segments[-1].end - end).total_seconds()) # finally, calculate actual output duration, which is what ffmpeg will use duration = full_duration - cut_start - cut_end @@ -243,7 +243,12 @@ def cut(stream, variant): # pass each segment into ffmpeg's stdin in order, while outputing everything on stdout. for segment in segments: with open(segment.path) as f: - shutil.copyfileobj(f, pipe) + try: + shutil.copyfileobj(f, pipe) + except OSError as e: + # ignore EPIPE, as this just means the end cut meant we didn't need all input + if e.errno != errno.EPIPE: + raise pipe.close() def _cut():