diff --git a/frigate/output/preview.py b/frigate/output/preview.py index 8570ea5d4..cece66cfa 100644 --- a/frigate/output/preview.py +++ b/frigate/output/preview.py @@ -1,5 +1,6 @@ """Handle outputting low res / fps preview segments from decoded frames.""" +import datetime import logging import multiprocessing as mp import os @@ -144,6 +145,13 @@ class PreviewRecorder: "v2": v2, } + # end segment at end of hour + self.segment_end = ( + (datetime.datetime.now() + datetime.timedelta(hours=1)) + .replace(minute=0, second=0, microsecond=0) + .timestamp() + ) + Path(os.path.join(CACHE_DIR, "preview_frames")).mkdir(exist_ok=True) Path(os.path.join(CLIPS_DIR, f"previews/{config.name}")).mkdir( parents=True, exist_ok=True @@ -216,7 +224,7 @@ class PreviewRecorder: self.write_frame_to_cache(frame_time, frame) # check if PREVIEW clip should be generated and cached frames reset - if frame_time - self.start_time >= PREVIEW_SEGMENT_DURATION: + if frame_time >= self.segment_end: # save last frame to ensure consistent duration self.output_frames.append(frame_time) self.write_frame_to_cache(frame_time, frame) @@ -227,6 +235,11 @@ class PreviewRecorder: ).start() # reset frame cache + self.segment_end = ( + (datetime.datetime.now() + datetime.timedelta(hours=1)) + .replace(minute=0, second=0, microsecond=0) + .timestamp() + ) self.start_time = frame_time self.last_output_time = frame_time self.output_frames = [] diff --git a/frigate/util/image.py b/frigate/util/image.py index 9585aabf8..d7cf9426b 100644 --- a/frigate/util/image.py +++ b/frigate/util/image.py @@ -312,14 +312,17 @@ def yuv_crop_and_resize(frame, region, height=None): # copy u2 yuv_cropped_frame[ size + uv_channel_y_offset : size + uv_channel_y_offset + uv_crop_height, - size // 2 + uv_channel_x_offset : size // 2 + size // 2 + + uv_channel_x_offset : size // 2 + uv_channel_x_offset + uv_crop_width, ] = frame[u2[1] : u2[3], u2[0] : u2[2]] # copy v1 yuv_cropped_frame[ - size + size // 4 + uv_channel_y_offset : size + size + + size // 4 + + uv_channel_y_offset : size + size // 4 + uv_channel_y_offset + uv_crop_height, @@ -328,11 +331,14 @@ def yuv_crop_and_resize(frame, region, height=None): # copy v2 yuv_cropped_frame[ - size + size // 4 + uv_channel_y_offset : size + size + + size // 4 + + uv_channel_y_offset : size + size // 4 + uv_channel_y_offset + uv_crop_height, - size // 2 + uv_channel_x_offset : size // 2 + size // 2 + + uv_channel_x_offset : size // 2 + uv_channel_x_offset + uv_crop_width, ] = frame[v2[1] : v2[3], v2[0] : v2[2]] @@ -387,7 +393,7 @@ def copy_yuv_to_position( destination_shape, source_frame=None, source_channel_dim=None, - interpolation = cv2.INTER_LINEAR, + interpolation=cv2.INTER_LINEAR, ): # get the coordinates of the channels for this position in the layout y, u1, u2, v1, v2 = get_yuv_crop(