From 2be2050d57956892fb53b104d8efb70c4851e02d Mon Sep 17 00:00:00 2001 From: Nicolas Mowen Date: Sat, 17 Jun 2023 08:56:00 -0600 Subject: [PATCH] Don't fail to save segment when cv2 fails (#6823) * Don't fail when cv2 fails * Clean up exception handling --- frigate/util.py | 68 +++++++++++++++++++++++++++++-------------------- 1 file changed, 41 insertions(+), 27 deletions(-) diff --git a/frigate/util.py b/frigate/util.py index f18d3279e..bf0e9172c 100755 --- a/frigate/util.py +++ b/frigate/util.py @@ -1147,35 +1147,19 @@ def to_relative_box( def get_video_properties(url, get_duration=False): - width = height = 0 - # Open the video stream - video = cv2.VideoCapture(url) + def calculate_duration(video: Optional[any]) -> float: + duration = None - # Check if the video stream was opened successfully - if not video.isOpened(): - logger.debug(f"Error opening video stream {url}.") - return None + if video is not None: + # Get the frames per second (fps) of the video stream + fps = video.get(cv2.CAP_PROP_FPS) + total_frames = int(video.get(cv2.CAP_PROP_FRAME_COUNT)) - # Get the width of frames in the video stream - width = video.get(cv2.CAP_PROP_FRAME_WIDTH) + if fps and total_frames: + duration = total_frames / fps - # Get the height of frames in the video stream - height = video.get(cv2.CAP_PROP_FRAME_HEIGHT) - - # Release the video stream - video.release() - - result = {"width": round(width), "height": round(height)} - - if get_duration: - # Get the frames per second (fps) of the video stream - fps = video.get(cv2.CAP_PROP_FPS) - total_frames = int(video.get(cv2.CAP_PROP_FRAME_COUNT)) - - if fps and total_frames: - duration = total_frames / fps - else: - # if cv2 failed need to use ffprobe + # if cv2 failed need to use ffprobe + if duration is None: ffprobe_cmd = [ "ffprobe", "-v", @@ -1187,11 +1171,41 @@ def get_video_properties(url, get_duration=False): f"{url}", ] p = sp.run(ffprobe_cmd, capture_output=True) + if p.returncode == 0 and p.stdout.decode(): duration = float(p.stdout.decode().strip()) else: duration = -1 - result["duration"] = duration + return duration + + width = height = 0 + + try: + # Open the video stream + video = cv2.VideoCapture(url) + + # Check if the video stream was opened successfully + if not video.isOpened(): + video = None + except Exception: + video = None + + result = {} + + if get_duration: + result["duration"] = calculate_duration(video) + + if video is not None: + # Get the width of frames in the video stream + width = video.get(cv2.CAP_PROP_FRAME_WIDTH) + + # Get the height of frames in the video stream + height = video.get(cv2.CAP_PROP_FRAME_HEIGHT) + + # Release the video stream + video.release() + + result = {"width": round(width), "height": round(height)} return result