mirror of
				https://github.com/blakeblackshear/frigate.git
				synced 2025-10-27 10:52:11 +01:00 
			
		
		
		
	Improve review mqtt topic (#11072)
* Don't request preview for current hour and fix content type * Send before / after on messages * Send before / after for end * Handle specific cases * remove log * Fix update type
This commit is contained in:
		
							parent
							
								
									d6e93d039d
								
							
						
					
					
						commit
						2d71cd7fe2
					
				@ -1351,6 +1351,6 @@ def preview_thumbnail(file_name: str):
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
    response = make_response(jpg_bytes)
 | 
			
		||||
    response.headers["Content-Type"] = "image/jpeg"
 | 
			
		||||
    response.headers["Content-Type"] = "image/webp"
 | 
			
		||||
    response.headers["Cache-Control"] = "private, max-age=31536000"
 | 
			
		||||
    return response
 | 
			
		||||
 | 
			
		||||
@ -146,25 +146,61 @@ class ReviewSegmentMaintainer(threading.Thread):
 | 
			
		||||
 | 
			
		||||
        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)
 | 
			
		||||
    def new_segment(
 | 
			
		||||
        self,
 | 
			
		||||
        segment: PendingReviewSegment,
 | 
			
		||||
    ) -> None:
 | 
			
		||||
        """New segment."""
 | 
			
		||||
        new_data = segment.get_data(ended=False)
 | 
			
		||||
        self.requestor.send_data(UPSERT_REVIEW_SEGMENT, new_data)
 | 
			
		||||
        start_data = {k.name: v for k, v in new_data.items()}
 | 
			
		||||
        self.requestor.send_data(
 | 
			
		||||
            "reviews",
 | 
			
		||||
            json.dumps(
 | 
			
		||||
                {"type": "update", "review": {k.name: v for k, v in seg_data.items()}}
 | 
			
		||||
                {
 | 
			
		||||
                    "type": "new",
 | 
			
		||||
                    "before": start_data,
 | 
			
		||||
                    "after": start_data,
 | 
			
		||||
                }
 | 
			
		||||
            ),
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
    def update_segment(
 | 
			
		||||
        self,
 | 
			
		||||
        segment: PendingReviewSegment,
 | 
			
		||||
        camera_config: CameraConfig,
 | 
			
		||||
        frame,
 | 
			
		||||
        objects: list[TrackedObject],
 | 
			
		||||
    ) -> None:
 | 
			
		||||
        """Update segment."""
 | 
			
		||||
        prev_data = segment.get_data(ended=False)
 | 
			
		||||
        segment.update_frame(camera_config, frame, objects)
 | 
			
		||||
        new_data = segment.get_data(ended=False)
 | 
			
		||||
        self.requestor.send_data(UPSERT_REVIEW_SEGMENT, new_data)
 | 
			
		||||
        self.requestor.send_data(
 | 
			
		||||
            "reviews",
 | 
			
		||||
            json.dumps(
 | 
			
		||||
                {
 | 
			
		||||
                    "type": "update",
 | 
			
		||||
                    "before": {k.name: v for k, v in prev_data.items()},
 | 
			
		||||
                    "after": {k.name: v for k, v in new_data.items()},
 | 
			
		||||
                }
 | 
			
		||||
            ),
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
    def end_segment(self, segment: PendingReviewSegment) -> None:
 | 
			
		||||
        """End segment."""
 | 
			
		||||
        seg_data = segment.get_data(ended=True)
 | 
			
		||||
        self.requestor.send_data(UPSERT_REVIEW_SEGMENT, seg_data)
 | 
			
		||||
        final_data = segment.get_data(ended=True)
 | 
			
		||||
        self.requestor.send_data(UPSERT_REVIEW_SEGMENT, final_data)
 | 
			
		||||
        end_data = {k.name: v for k, v in final_data.items()}
 | 
			
		||||
        self.requestor.send_data(
 | 
			
		||||
            "reviews",
 | 
			
		||||
            json.dumps(
 | 
			
		||||
                {"type": "end", "review": {k.name: v for k, v in seg_data.items()}}
 | 
			
		||||
                {
 | 
			
		||||
                    "type": "end",
 | 
			
		||||
                    "before": end_data,
 | 
			
		||||
                    "after": end_data,
 | 
			
		||||
                }
 | 
			
		||||
            ),
 | 
			
		||||
        )
 | 
			
		||||
        self.active_review_segments[segment.camera] = None
 | 
			
		||||
@ -219,9 +255,10 @@ class ReviewSegmentMaintainer(threading.Thread):
 | 
			
		||||
                    yuv_frame = self.frame_manager.get(
 | 
			
		||||
                        frame_id, camera_config.frame_shape_yuv
 | 
			
		||||
                    )
 | 
			
		||||
                    segment.update_frame(camera_config, yuv_frame, active_objects)
 | 
			
		||||
                    self.update_segment(
 | 
			
		||||
                        segment, camera_config, yuv_frame, active_objects
 | 
			
		||||
                    )
 | 
			
		||||
                    self.frame_manager.close(frame_id)
 | 
			
		||||
                    self.update_segment(segment)
 | 
			
		||||
                except FileNotFoundError:
 | 
			
		||||
                    return
 | 
			
		||||
        else:
 | 
			
		||||
@ -317,7 +354,7 @@ class ReviewSegmentMaintainer(threading.Thread):
 | 
			
		||||
                        camera_config, yuv_frame, active_objects
 | 
			
		||||
                    )
 | 
			
		||||
                    self.frame_manager.close(frame_id)
 | 
			
		||||
                    self.update_segment(self.active_review_segments[camera])
 | 
			
		||||
                    self.new_segment(self.active_review_segments[camera])
 | 
			
		||||
                except FileNotFoundError:
 | 
			
		||||
                    return
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -12,6 +12,7 @@ import {
 | 
			
		||||
  InProgressPreview,
 | 
			
		||||
  VideoPreview,
 | 
			
		||||
} from "../player/PreviewThumbnailPlayer";
 | 
			
		||||
import { isCurrentHour } from "@/utils/dateUtil";
 | 
			
		||||
 | 
			
		||||
type AnimatedEventCardProps = {
 | 
			
		||||
  event: ReviewSegment;
 | 
			
		||||
@ -19,10 +20,14 @@ type AnimatedEventCardProps = {
 | 
			
		||||
export function AnimatedEventCard({ event }: AnimatedEventCardProps) {
 | 
			
		||||
  const { data: config } = useSWR<FrigateConfig>("config");
 | 
			
		||||
 | 
			
		||||
  const currentHour = useMemo(() => isCurrentHour(event.start_time), [event]);
 | 
			
		||||
 | 
			
		||||
  // preview
 | 
			
		||||
 | 
			
		||||
  const { data: previews } = useSWR<Preview[]>(
 | 
			
		||||
    `/preview/${event.camera}/start/${Math.round(event.start_time)}/end/${Math.round(event.end_time || event.start_time + 20)}`,
 | 
			
		||||
    currentHour
 | 
			
		||||
      ? null
 | 
			
		||||
      : `/preview/${event.camera}/start/${Math.round(event.start_time)}/end/${Math.round(event.end_time || event.start_time + 20)}`,
 | 
			
		||||
  );
 | 
			
		||||
 | 
			
		||||
  // interaction
 | 
			
		||||
 | 
			
		||||
@ -31,7 +31,8 @@ type FrigateObjectState = {
 | 
			
		||||
 | 
			
		||||
export interface FrigateReview {
 | 
			
		||||
  type: "new" | "update" | "end";
 | 
			
		||||
  review: ReviewSegment;
 | 
			
		||||
  before: ReviewSegment;
 | 
			
		||||
  after: ReviewSegment;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export interface FrigateEvent {
 | 
			
		||||
 | 
			
		||||
@ -47,8 +47,19 @@ export default function LiveDashboardView({
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // if event is ended and was saved, update events list
 | 
			
		||||
    if (eventUpdate.review.severity == "alert") {
 | 
			
		||||
      setTimeout(() => updateEvents(), eventUpdate.type == "end" ? 1000 : 6000);
 | 
			
		||||
    if (eventUpdate.after.severity == "alert") {
 | 
			
		||||
      if (eventUpdate.type == "end" || eventUpdate.type == "new") {
 | 
			
		||||
        setTimeout(
 | 
			
		||||
          () => updateEvents(),
 | 
			
		||||
          eventUpdate.type == "end" ? 1000 : 6000,
 | 
			
		||||
        );
 | 
			
		||||
      } else if (
 | 
			
		||||
        eventUpdate.before.data.objects.length <
 | 
			
		||||
        eventUpdate.after.data.objects.length
 | 
			
		||||
      ) {
 | 
			
		||||
        setTimeout(() => updateEvents(), 5000);
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
  }, [eventUpdate, updateEvents]);
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user