Compare commits

..

No commits in common. "c4a53ae9ae15ee7fb0710652b6b678b1dda18395" and "6159604b35de5a8db3e5c7653f7f654f4e376e33" have entirely different histories.

4 changed files with 36 additions and 52 deletions

View File

@ -291,9 +291,11 @@ class CameraState:
new_obj.thumbnail_data = thumbnail_data new_obj.thumbnail_data = thumbnail_data
tracked_objects[id].thumbnail_data = thumbnail_data tracked_objects[id].thumbnail_data = thumbnail_data
object_type = new_obj.obj_data["label"] object_type = new_obj.obj_data["label"]
self.best_objects[object_type] = new_obj
# call event handlers # call event handlers
self.send_mqtt_snapshot(new_obj, object_type) for c in self.callbacks["snapshot"]:
c(self.name, self.best_objects[object_type], frame_name)
for c in self.callbacks["start"]: for c in self.callbacks["start"]:
c(self.name, new_obj, frame_name) c(self.name, new_obj, frame_name)
@ -415,9 +417,13 @@ class CameraState:
or (now - current_best.thumbnail_data["frame_time"]) or (now - current_best.thumbnail_data["frame_time"])
> self.camera_config.best_image_timeout > self.camera_config.best_image_timeout
): ):
self.send_mqtt_snapshot(obj, object_type) self.best_objects[object_type] = obj
for c in self.callbacks["snapshot"]:
c(self.name, self.best_objects[object_type], frame_name)
else: else:
self.send_mqtt_snapshot(obj, object_type) self.best_objects[object_type] = obj
for c in self.callbacks["snapshot"]:
c(self.name, self.best_objects[object_type], frame_name)
for c in self.callbacks["camera_activity"]: for c in self.callbacks["camera_activity"]:
c(self.name, camera_activity) c(self.name, camera_activity)
@ -466,20 +472,6 @@ class CameraState:
self.previous_frame_id = frame_name self.previous_frame_id = frame_name
def send_mqtt_snapshot(self, new_obj: TrackedObject, object_type: str) -> None:
for c in self.callbacks["snapshot"]:
updated = c(self.name, new_obj)
# if the snapshot was not updated, then this object is not a best object
# but all new objects should be considered the next best object
# so we remove the label from the best objects
if updated:
self.best_objects[object_type] = new_obj
else:
if object_type in self.best_objects:
self.best_objects.pop(object_type)
break
def save_manual_event_image( def save_manual_event_image(
self, self,
frame: np.ndarray | None, frame: np.ndarray | None,

View File

@ -792,10 +792,6 @@ class OnvifController:
) )
return return
logger.debug(
f"{camera_name}: Pan/tilt status: {pan_tilt_status}, Zoom status: {zoom_status}"
)
if pan_tilt_status == "IDLE" and (zoom_status is None or zoom_status == "IDLE"): if pan_tilt_status == "IDLE" and (zoom_status is None or zoom_status == "IDLE"):
self.cams[camera_name]["active"] = False self.cams[camera_name]["active"] = False
if not self.ptz_metrics[camera_name].motor_stopped.is_set(): if not self.ptz_metrics[camera_name].motor_stopped.is_set():

View File

@ -156,7 +156,7 @@ class TrackedObjectProcessor(threading.Thread):
) )
) )
def snapshot(camera: str, obj: TrackedObject) -> bool: def snapshot(camera, obj: TrackedObject, frame_name: str):
mqtt_config: CameraMqttConfig = self.config.cameras[camera].mqtt mqtt_config: CameraMqttConfig = self.config.cameras[camera].mqtt
if mqtt_config.enabled and self.should_mqtt_snapshot(camera, obj): if mqtt_config.enabled and self.should_mqtt_snapshot(camera, obj):
jpg_bytes = obj.get_img_bytes( jpg_bytes = obj.get_img_bytes(
@ -189,10 +189,6 @@ class TrackedObjectProcessor(threading.Thread):
retain=True, retain=True,
) )
return True
return False
def camera_activity(camera, activity): def camera_activity(camera, activity):
last_activity = self.camera_activity.get(camera) last_activity = self.camera_activity.get(camera)

View File

@ -1242,13 +1242,13 @@ export function VideoTab({ search }: VideoTabProps) {
<> <>
<span tabIndex={0} className="sr-only" /> <span tabIndex={0} className="sr-only" />
<GenericVideoPlayer source={source}> <GenericVideoPlayer source={source}>
<div {reviewItem && (
className={cn( <div
"absolute top-2 z-10 flex items-center gap-2", className={cn(
isIOS ? "right-8" : "right-2", "absolute top-2 z-10 flex items-center gap-2",
)} isIOS ? "right-8" : "right-2",
> )}
{reviewItem && ( >
<Tooltip> <Tooltip>
<TooltipTrigger> <TooltipTrigger>
<Chip <Chip
@ -1271,25 +1271,25 @@ export function VideoTab({ search }: VideoTabProps) {
</TooltipContent> </TooltipContent>
</TooltipPortal> </TooltipPortal>
</Tooltip> </Tooltip>
)} <Tooltip>
<Tooltip> <TooltipTrigger asChild>
<TooltipTrigger asChild> <a
<a download
download href={`${baseUrl}api/${search.camera}/${clipTimeRange}/clip.mp4`}
href={`${baseUrl}api/${search.camera}/${clipTimeRange}/clip.mp4`} >
> <Chip className="cursor-pointer rounded-md bg-gray-500 bg-gradient-to-br from-gray-400 to-gray-500">
<Chip className="cursor-pointer rounded-md bg-gray-500 bg-gradient-to-br from-gray-400 to-gray-500"> <FaDownload className="size-4 text-white" />
<FaDownload className="size-4 text-white" /> </Chip>
</Chip> </a>
</a> </TooltipTrigger>
</TooltipTrigger> <TooltipPortal>
<TooltipPortal> <TooltipContent>
<TooltipContent> {t("button.download", { ns: "common" })}
{t("button.download", { ns: "common" })} </TooltipContent>
</TooltipContent> </TooltipPortal>
</TooltipPortal> </Tooltip>
</Tooltip> </div>
</div> )}
</GenericVideoPlayer> </GenericVideoPlayer>
</> </>
); );