* Add option to not trim clip

* Improve API

* Update snapshot for new best objects

* Fix missing strings

* Convert to separate key

* Always include bounding box on snapshots

* improve autotracking relative zooming time calculation

* update proxy docs to note the need for comma separated header roles

* Add count translation

* tracked object lifecycle i18n fix

* update speed estimation docs

* clarity

* Re-initialize onvif information when toggling camera on live view

* Move time ago to card info and add face area

* Clarify face recognition docs

* Increase minimum face recognition area

* use clipFrom to in vod module endpoint to start at the correct time

* Cleanup media api

* Don't change duration

* Use search detail dialog for face library

* Move to segment based

* Cleanup

* Add back duration modification

* clean up docs

---------

Co-authored-by: Josh Hawkins <32435876+hawkeye217@users.noreply.github.com>
This commit is contained in:
Nicolas Mowen
2025-05-14 16:44:06 -06:00
committed by GitHub
co-authored by Josh Hawkins
parent 1fa7ce5486
commit d3d05fa397
17 changed files with 121 additions and 121 deletions
+19 -7
View File
@@ -593,10 +593,12 @@ def recording_clip(
clip: Recordings
for clip in recordings:
file.write(f"file '{clip.path}'\n")
# if this is the starting clip, add an inpoint
if clip.start_time < start_ts:
file.write(f"inpoint {int(start_ts - clip.start_time)}\n")
# if this is the ending clip, add an outpoint
# if this is the ending clip and end trim is enabled, add an outpoint
if clip.end_time > end_ts:
file.write(f"outpoint {int(end_ts - clip.start_time)}\n")
@@ -641,7 +643,12 @@ def recording_clip(
@router.get("/vod/{camera_name}/start/{start_ts}/end/{end_ts}")
def vod_ts(camera_name: str, start_ts: float, end_ts: float):
recordings = (
Recordings.select(Recordings.path, Recordings.duration, Recordings.end_time)
Recordings.select(
Recordings.path,
Recordings.duration,
Recordings.end_time,
Recordings.start_time,
)
.where(
Recordings.start_time.between(start_ts, end_ts)
| Recordings.end_time.between(start_ts, end_ts)
@@ -661,14 +668,19 @@ def vod_ts(camera_name: str, start_ts: float, end_ts: float):
clip = {"type": "source", "path": recording.path}
duration = int(recording.duration * 1000)
# Determine if we need to end the last clip early
# adjust start offset if start_ts is after recording.start_time
if start_ts > recording.start_time:
inpoint = int((start_ts - recording.start_time) * 1000)
clip["clipFrom"] = inpoint
duration -= inpoint
# adjust end if recording.end_time is after end_ts
if recording.end_time > end_ts:
duration -= int((recording.end_time - end_ts) * 1000)
if duration == 0:
# this means the segment starts right at the end of the requested time range
# and it does not need to be included
continue
if duration <= 0:
# skip if the clip has no valid duration
continue
if 0 < duration < max_duration_ms:
clip["keyFrameDurations"] = [duration]
+5 -1
View File
@@ -282,9 +282,13 @@ class CameraState:
}
new_obj.thumbnail_data = thumbnail_data
tracked_objects[id].thumbnail_data = thumbnail_data
self.best_objects[new_obj.obj_data["label"]] = new_obj
object_type = new_obj.obj_data["label"]
self.best_objects[object_type] = new_obj
# call event handlers
for c in self.callbacks["snapshot"]:
c(self.name, self.best_objects[object_type], frame_name)
for c in self.callbacks["start"]:
c(self.name, new_obj, frame_name)
+2 -2
View File
@@ -78,7 +78,7 @@ class FaceRecognitionConfig(FrigateBaseModel):
le=1.0,
)
min_area: int = Field(
default=500, title="Min area of face box to consider running face recognition."
default=750, title="Min area of face box to consider running face recognition."
)
save_attempts: int = Field(
default=100, ge=0, title="Number of face attempts to save in the train tab."
@@ -91,7 +91,7 @@ class FaceRecognitionConfig(FrigateBaseModel):
class CameraFaceRecognitionConfig(FrigateBaseModel):
enabled: bool = Field(default=False, title="Enable face recognition.")
min_area: int = Field(
default=500, title="Min area of face box to consider running face recognition."
default=750, title="Min area of face box to consider running face recognition."
)
model_config = ConfigDict(extra="forbid", protected_namespaces=())
+15 -2
View File
@@ -1171,7 +1171,20 @@ class PtzAutoTracker:
zoom_predicted_movement_time = 0
if np.any(average_velocity):
zoom_predicted_movement_time = abs(zoom) * self.zoom_time[camera]
# Calculate the intended change in zoom level
zoom_change = (1 - abs(zoom)) * (1 if zoom >= 0 else -1)
# Calculate new zoom level and clamp to [0, 1]
new_zoom = max(
0, min(1, self.ptz_metrics[camera].zoom_level.value + zoom_change)
)
# Calculate the actual zoom distance
zoom_distance = abs(
new_zoom - self.ptz_metrics[camera].zoom_level.value
)
zoom_predicted_movement_time = zoom_distance * self.zoom_time[camera]
zoom_predicted_box = (
predicted_box
@@ -1188,7 +1201,7 @@ class PtzAutoTracker:
tilt = (0.5 - (centroid_y / camera_height)) * 2
logger.debug(
f"{camera}: Zoom amount: {zoom}, zoom predicted time: {zoom_predicted_movement_time}, zoom predicted box: {tuple(zoom_predicted_box)}"
f"{camera}: Zoom amount: {zoom}, zoom distance: {zoom_distance}, zoom predicted time: {zoom_predicted_movement_time}, zoom predicted box: {tuple(zoom_predicted_box)}"
)
self._enqueue_move(camera, obj.obj_data["frame_time"], pan, tilt, zoom)