mirror of
https://github.com/blakeblackshear/frigate.git
synced 2026-02-11 05:35:25 +03:00
Update review maintainer to save events when ongoing
This commit is contained in:
parent
3d43c5e811
commit
befc00d44a
@ -27,10 +27,18 @@ def review():
|
|||||||
|
|
||||||
before = request.args.get("before", type=float, default=datetime.now().timestamp())
|
before = request.args.get("before", type=float, default=datetime.now().timestamp())
|
||||||
after = request.args.get(
|
after = request.args.get(
|
||||||
"after", type=float, default=(datetime.now() - timedelta(hours=18)).timestamp()
|
"after", type=float, default=(datetime.now() - timedelta(hours=24)).timestamp()
|
||||||
)
|
)
|
||||||
|
|
||||||
clauses = [((ReviewSegment.start_time > after) & (ReviewSegment.end_time < before))]
|
clauses = [
|
||||||
|
(
|
||||||
|
(ReviewSegment.start_time > after)
|
||||||
|
& (
|
||||||
|
(ReviewSegment.end_time.is_null(True))
|
||||||
|
| (ReviewSegment.end_time < before)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
]
|
||||||
|
|
||||||
if cameras != "all":
|
if cameras != "all":
|
||||||
camera_list = cameras.split(",")
|
camera_list = cameras.split(",")
|
||||||
@ -45,6 +53,7 @@ def review():
|
|||||||
for label in filtered_labels:
|
for label in filtered_labels:
|
||||||
label_clauses.append(
|
label_clauses.append(
|
||||||
(ReviewSegment.data["objects"].cast("text") % f'*"{label}"*')
|
(ReviewSegment.data["objects"].cast("text") % f'*"{label}"*')
|
||||||
|
| ((ReviewSegment.data["audio"].cast("text") % f'*"{label}"*'))
|
||||||
)
|
)
|
||||||
|
|
||||||
label_clause = reduce(operator.or_, label_clauses)
|
label_clause = reduce(operator.or_, label_clauses)
|
||||||
@ -94,6 +103,7 @@ def review_summary():
|
|||||||
for label in filtered_labels:
|
for label in filtered_labels:
|
||||||
label_clauses.append(
|
label_clauses.append(
|
||||||
(ReviewSegment.data["objects"].cast("text") % f'*"{label}"*')
|
(ReviewSegment.data["objects"].cast("text") % f'*"{label}"*')
|
||||||
|
| ((ReviewSegment.data["audio"].cast("text") % f'*"{label}"*'))
|
||||||
)
|
)
|
||||||
|
|
||||||
label_clause = reduce(operator.or_, label_clauses)
|
label_clause = reduce(operator.or_, label_clauses)
|
||||||
|
|||||||
@ -66,6 +66,7 @@ class PendingReviewSegment:
|
|||||||
# thumbnail
|
# thumbnail
|
||||||
self.frame = np.zeros((THUMB_HEIGHT * 3 // 2, THUMB_WIDTH), np.uint8)
|
self.frame = np.zeros((THUMB_HEIGHT * 3 // 2, THUMB_WIDTH), np.uint8)
|
||||||
self.frame_active_count = 0
|
self.frame_active_count = 0
|
||||||
|
self.frame_path = os.path.join(CLIPS_DIR, f"thumb-{self.camera}-{self.id}.jpg")
|
||||||
|
|
||||||
def update_frame(
|
def update_frame(
|
||||||
self, camera_config: CameraConfig, frame, objects: list[TrackedObject]
|
self, camera_config: CameraConfig, frame, objects: list[TrackedObject]
|
||||||
@ -98,19 +99,19 @@ class PendingReviewSegment:
|
|||||||
color_frame, dsize=(width, THUMB_HEIGHT), interpolation=cv2.INTER_AREA
|
color_frame, dsize=(width, THUMB_HEIGHT), interpolation=cv2.INTER_AREA
|
||||||
)
|
)
|
||||||
|
|
||||||
def end(self) -> dict:
|
|
||||||
path = os.path.join(CLIPS_DIR, f"thumb-{self.camera}-{self.id}.jpg")
|
|
||||||
|
|
||||||
if self.frame is not None:
|
if self.frame is not None:
|
||||||
cv2.imwrite(path, self.frame, [int(cv2.IMWRITE_WEBP_QUALITY), 60])
|
cv2.imwrite(
|
||||||
|
self.frame_path, self.frame, [int(cv2.IMWRITE_WEBP_QUALITY), 60]
|
||||||
|
)
|
||||||
|
|
||||||
|
def get_data(self, ended: bool) -> dict:
|
||||||
return {
|
return {
|
||||||
ReviewSegment.id: self.id,
|
ReviewSegment.id: self.id,
|
||||||
ReviewSegment.camera: self.camera,
|
ReviewSegment.camera: self.camera,
|
||||||
ReviewSegment.start_time: self.start_time,
|
ReviewSegment.start_time: self.start_time,
|
||||||
ReviewSegment.end_time: self.last_update,
|
ReviewSegment.end_time: self.last_update if ended else None,
|
||||||
ReviewSegment.severity: self.severity.value,
|
ReviewSegment.severity: self.severity.value,
|
||||||
ReviewSegment.thumb_path: path,
|
ReviewSegment.thumb_path: self.frame_path,
|
||||||
ReviewSegment.data: {
|
ReviewSegment.data: {
|
||||||
"detections": list(set(self.detections.keys())),
|
"detections": list(set(self.detections.keys())),
|
||||||
"objects": list(set(self.detections.values())),
|
"objects": list(set(self.detections.values())),
|
||||||
@ -141,9 +142,20 @@ class ReviewSegmentMaintainer(threading.Thread):
|
|||||||
|
|
||||||
self.stop_event = stop_event
|
self.stop_event = stop_event
|
||||||
|
|
||||||
|
def update_segment(self, segment: PendingReviewSegment) -> None:
|
||||||
|
"""Update segment."""
|
||||||
|
seg_data = segment.get_data(ended=False)
|
||||||
|
self.requestor.send_data(UPSERT_REVIEW_SEGMENT, seg_data)
|
||||||
|
self.requestor.send_data(
|
||||||
|
"reviews",
|
||||||
|
json.dumps(
|
||||||
|
{"type": "update", "review": {k.name: v for k, v in seg_data.items()}}
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
def end_segment(self, segment: PendingReviewSegment) -> None:
|
def end_segment(self, segment: PendingReviewSegment) -> None:
|
||||||
"""End segment."""
|
"""End segment."""
|
||||||
seg_data = segment.end()
|
seg_data = segment.get_data(ended=True)
|
||||||
self.requestor.send_data(UPSERT_REVIEW_SEGMENT, seg_data)
|
self.requestor.send_data(UPSERT_REVIEW_SEGMENT, seg_data)
|
||||||
self.requestor.send_data(
|
self.requestor.send_data(
|
||||||
"reviews",
|
"reviews",
|
||||||
@ -179,6 +191,7 @@ class ReviewSegmentMaintainer(threading.Thread):
|
|||||||
)
|
)
|
||||||
segment.update_frame(camera_config, yuv_frame, active_objects)
|
segment.update_frame(camera_config, yuv_frame, active_objects)
|
||||||
self.frame_manager.close(frame_id)
|
self.frame_manager.close(frame_id)
|
||||||
|
self.update_segment(segment)
|
||||||
|
|
||||||
for object in active_objects:
|
for object in active_objects:
|
||||||
if not object["sub_label"]:
|
if not object["sub_label"]:
|
||||||
@ -263,6 +276,7 @@ class ReviewSegmentMaintainer(threading.Thread):
|
|||||||
camera_config, yuv_frame, active_objects
|
camera_config, yuv_frame, active_objects
|
||||||
)
|
)
|
||||||
self.frame_manager.close(frame_id)
|
self.frame_manager.close(frame_id)
|
||||||
|
self.update_segment(self.active_review_segments[camera])
|
||||||
elif len(motion) >= 20:
|
elif len(motion) >= 20:
|
||||||
self.active_review_segments[camera] = PendingReviewSegment(
|
self.active_review_segments[camera] = PendingReviewSegment(
|
||||||
camera,
|
camera,
|
||||||
@ -398,6 +412,11 @@ class ReviewSegmentMaintainer(threading.Thread):
|
|||||||
"end_time"
|
"end_time"
|
||||||
]
|
]
|
||||||
|
|
||||||
|
self.config_subscriber.stop()
|
||||||
|
self.requestor.stop()
|
||||||
|
self.detection_subscriber.stop()
|
||||||
|
logger.info("Exiting review maintainer...")
|
||||||
|
|
||||||
|
|
||||||
def get_active_objects(
|
def get_active_objects(
|
||||||
frame_time: float, camera_config: CameraConfig, all_objects: list[TrackedObject]
|
frame_time: float, camera_config: CameraConfig, all_objects: list[TrackedObject]
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user