mirror of
https://github.com/blakeblackshear/frigate.git
synced 2026-02-14 15:15:22 +03:00
Handle case where camera is offline when generating previews
This commit is contained in:
parent
6a0b5c3a3f
commit
91abf99370
@ -64,6 +64,8 @@ def output_frames(
|
|||||||
jsmpeg_cameras: dict[str, JsmpegCamera] = {}
|
jsmpeg_cameras: dict[str, JsmpegCamera] = {}
|
||||||
birdseye: Optional[Birdseye] = None
|
birdseye: Optional[Birdseye] = None
|
||||||
preview_recorders: dict[str, PreviewRecorder] = {}
|
preview_recorders: dict[str, PreviewRecorder] = {}
|
||||||
|
preview_write_times: dict[str, float] = {}
|
||||||
|
frame_time: float = 0
|
||||||
|
|
||||||
move_preview_frames("cache")
|
move_preview_frames("cache")
|
||||||
|
|
||||||
@ -73,6 +75,7 @@ def output_frames(
|
|||||||
|
|
||||||
jsmpeg_cameras[camera] = JsmpegCamera(cam_config, stop_event, websocket_server)
|
jsmpeg_cameras[camera] = JsmpegCamera(cam_config, stop_event, websocket_server)
|
||||||
preview_recorders[camera] = PreviewRecorder(cam_config)
|
preview_recorders[camera] = PreviewRecorder(cam_config)
|
||||||
|
preview_write_times[camera] = 0
|
||||||
|
|
||||||
if config.birdseye.enabled:
|
if config.birdseye.enabled:
|
||||||
birdseye = Birdseye(config, frame_manager, stop_event, websocket_server)
|
birdseye = Birdseye(config, frame_manager, stop_event, websocket_server)
|
||||||
@ -83,6 +86,13 @@ def output_frames(
|
|||||||
(topic, data) = detection_subscriber.check_for_update(timeout=1)
|
(topic, data) = detection_subscriber.check_for_update(timeout=1)
|
||||||
|
|
||||||
if not topic:
|
if not topic:
|
||||||
|
# all queued images have been written,
|
||||||
|
# check if any cameras have stale frames
|
||||||
|
|
||||||
|
for camera, time in preview_write_times.items():
|
||||||
|
if time != 0 and frame_time - time > 10:
|
||||||
|
preview_recorders[camera].flag_offline(frame_time)
|
||||||
|
|
||||||
continue
|
continue
|
||||||
|
|
||||||
(
|
(
|
||||||
|
|||||||
@ -3,6 +3,7 @@
|
|||||||
import datetime
|
import datetime
|
||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
|
import shutil
|
||||||
import subprocess as sp
|
import subprocess as sp
|
||||||
import threading
|
import threading
|
||||||
import time
|
import time
|
||||||
@ -326,7 +327,7 @@ class PreviewRecorder:
|
|||||||
)
|
)
|
||||||
self.start_time = frame_time
|
self.start_time = frame_time
|
||||||
self.last_output_time = frame_time
|
self.last_output_time = frame_time
|
||||||
self.output_frames = []
|
self.output_frames: list[float] = []
|
||||||
|
|
||||||
# include first frame to ensure consistent duration
|
# include first frame to ensure consistent duration
|
||||||
self.output_frames.append(frame_time)
|
self.output_frames.append(frame_time)
|
||||||
@ -335,6 +336,35 @@ class PreviewRecorder:
|
|||||||
self.output_frames.append(frame_time)
|
self.output_frames.append(frame_time)
|
||||||
self.write_frame_to_cache(frame_time, frame)
|
self.write_frame_to_cache(frame_time, frame)
|
||||||
|
|
||||||
|
def flag_offline(self, frame_time: float) -> None:
|
||||||
|
# check if PREVIEW clip should be generated and cached frames reset
|
||||||
|
if frame_time >= self.segment_end:
|
||||||
|
if len(self.output_frames) == 0:
|
||||||
|
return
|
||||||
|
|
||||||
|
old_frame_path = get_cache_image_name(self.config.name, self.output_frames[-1])
|
||||||
|
new_frame_path = get_cache_image_name(self.config.name, frame_time)
|
||||||
|
shutil.copy(old_frame_path, new_frame_path)
|
||||||
|
|
||||||
|
# save last frame to ensure consistent duration
|
||||||
|
self.output_frames.append(frame_time)
|
||||||
|
FFMpegConverter(
|
||||||
|
self.config,
|
||||||
|
self.output_frames,
|
||||||
|
self.requestor,
|
||||||
|
).start()
|
||||||
|
|
||||||
|
# reset frame cache
|
||||||
|
self.segment_end = (
|
||||||
|
(datetime.datetime.now() + datetime.timedelta(hours=1))
|
||||||
|
.astimezone(datetime.timezone.utc)
|
||||||
|
.replace(minute=0, second=0, microsecond=0)
|
||||||
|
.timestamp()
|
||||||
|
)
|
||||||
|
self.start_time = frame_time
|
||||||
|
self.last_output_time = frame_time
|
||||||
|
self.output_frames = []
|
||||||
|
|
||||||
def stop(self) -> None:
|
def stop(self) -> None:
|
||||||
self.requestor.stop()
|
self.requestor.stop()
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user