mirror of
https://github.com/blakeblackshear/frigate.git
synced 2026-07-03 18:41:14 +03:00
optimize recordings/unavailable gap detection and drop empty motion activity buckets
This commit is contained in:
parent
373fdad7f4
commit
51770e6922
@ -299,22 +299,36 @@ async def no_recordings(
|
|||||||
.iterator()
|
.iterator()
|
||||||
)
|
)
|
||||||
|
|
||||||
# Convert recordings to list of (start, end) tuples
|
# Convert recordings to list of (start, end) tuples, ordered by start_time
|
||||||
recordings = [(r["start_time"], r["end_time"]) for r in data]
|
recordings = [(r["start_time"], r["end_time"]) for r in data]
|
||||||
|
|
||||||
|
# Merge overlapping/adjacent recordings into covered intervals. The query
|
||||||
|
# orders by start_time, so a single pass merges them
|
||||||
|
covered: list[tuple[float, float]] = []
|
||||||
|
for rec_start, rec_end in recordings:
|
||||||
|
if covered and rec_start <= covered[-1][1]:
|
||||||
|
covered[-1] = (covered[-1][0], max(covered[-1][1], rec_end))
|
||||||
|
else:
|
||||||
|
covered.append((rec_start, rec_end))
|
||||||
|
|
||||||
# Iterate through time segments and check if each has any recording
|
# Iterate through time segments and check if each has any recording
|
||||||
no_recording_segments = []
|
no_recording_segments = []
|
||||||
current = after
|
current = after
|
||||||
current_gap_start = None
|
current_gap_start = None
|
||||||
|
idx = 0
|
||||||
|
covered_count = len(covered)
|
||||||
|
|
||||||
while current < before:
|
while current < before:
|
||||||
segment_end = min(current + scale, before)
|
segment_end = min(current + scale, before)
|
||||||
|
|
||||||
# Check if this segment overlaps with any recording
|
# Advance past covered intervals that end before this segment begins;
|
||||||
has_recording = any(
|
# they cannot overlap this or any later segment.
|
||||||
rec_start < segment_end and rec_end > current
|
while idx < covered_count and covered[idx][1] <= current:
|
||||||
for rec_start, rec_end in recordings
|
idx += 1
|
||||||
)
|
|
||||||
|
# A covered interval overlaps the segment when it starts before the
|
||||||
|
# segment ends (its end is already known to be > current).
|
||||||
|
has_recording = idx < covered_count and covered[idx][0] < segment_end
|
||||||
|
|
||||||
if not has_recording:
|
if not has_recording:
|
||||||
# This segment has no recordings
|
# This segment has no recordings
|
||||||
|
|||||||
@ -658,6 +658,11 @@ def motion_activity(
|
|||||||
else:
|
else:
|
||||||
df.iloc[i : i + chunk, 0] = 0.0
|
df.iloc[i : i + chunk, 0] = 0.0
|
||||||
|
|
||||||
|
# Drop resample gap-fill buckets. The resample above emits a row for every
|
||||||
|
# {scale}s bucket spanning the range, and buckets with no recording get a
|
||||||
|
# motion of 0 (from fillna) and an empty camera (from joining an empty set).
|
||||||
|
df = df[df["camera"] != ""]
|
||||||
|
|
||||||
# change types for output
|
# change types for output
|
||||||
df.index = df.index.astype(int) // (10**9)
|
df.index = df.index.astype(int) // (10**9)
|
||||||
normalized = df.reset_index().to_dict("records")
|
normalized = df.reset_index().to_dict("records")
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user