Compare commits

..

7 Commits

Author SHA1 Message Date
Nicolas Mowen
889835a59b Always show recording link even if recordings are currently disabled (#2787)
* Always show recording link even if recordings are currently disabled

* Fix test to consider all cameras to have recording link
2022-02-12 13:51:28 -06:00
Blake Blackshear
ee01396b36 update birdseye to handle stationary objects 2022-02-12 06:59:10 -06:00
Blake Blackshear
334e28fe54 use second stream in docs example 2022-02-12 06:43:46 -06:00
Blake Blackshear
6b2bae040c stop forcing detection all the way to stationary_threshold 2022-02-11 07:34:42 -06:00
Blake Blackshear
95ab22d411 bump default stationary_threshold to 10s 2022-02-11 07:30:47 -06:00
Blake Blackshear
4e52461aa9 set stationary_threshold default to 5x fps 2022-02-11 07:12:51 -06:00
Blake Blackshear
7934f8699f fix the bounding box calculation position at 10 2022-02-11 06:54:42 -06:00
10 changed files with 25 additions and 20 deletions

View File

@@ -162,8 +162,8 @@ detect:
# Optional: Frequency for running detection on stationary objects (default: shown below)
# When set to 0, object detection will never be run on stationary objects. If set to 10, it will be run on every 10th frame.
stationary_interval: 0
# Optional: Number of frames without a position change for an object to be considered stationary (default: shown below)
stationary_threshold: 10
# Optional: Number of frames without a position change for an object to be considered stationary (default: 10x the frame rate or 10s)
stationary_threshold: 50
# Optional: Object configuration
# NOTE: Can be overridden at the camera level

View File

@@ -167,13 +167,17 @@ cameras:
roles:
- detect
- rtmp
- record # <----- Add role
- path: rtsp://10.0.10.10:554/high_res_stream # <----- Add high res stream
roles:
- record
detect: ...
record: # <----- Enable recording
enabled: True
motion: ...
```
If you don't have separate streams for detect and record, you would just add the record role to the list on the first input.
By default, Frigate will retain video of all events for 10 days. The full set of options for recording can be found [here](/configuration/index#full-configuration-reference).
### Step 8: Enable snapshots (optional)

View File

@@ -56,6 +56,7 @@ Message published for each changed event. The first message is published when th
"thumbnail": null,
"has_snapshot": false,
"has_clip": false,
"stationary": false, // whether or not the object is considered stationary
"motionless_count": 0, // number of frames the object has been motionless
"position_changes": 2 // number of times the object has moved from a stationary position
},
@@ -78,6 +79,7 @@ Message published for each changed event. The first message is published when th
"thumbnail": null,
"has_snapshot": false,
"has_clip": false,
"stationary": false, // whether or not the object is considered stationary
"motionless_count": 0, // number of frames the object has been motionless
"position_changes": 2 // number of times the object has changed position
}

View File

@@ -178,7 +178,6 @@ class DetectConfig(FrigateBaseModel):
ge=0,
)
stationary_threshold: Optional[int] = Field(
default=10,
title="Number of frames without a position change for an object to be considered stationary",
ge=1,
)
@@ -771,6 +770,11 @@ class FrigateConfig(FrigateBaseModel):
if camera_config.detect.max_disappeared is None:
camera_config.detect.max_disappeared = max_disappeared
# Default stationary_threshold configuration
stationary_threshold = camera_config.detect.fps * 10
if camera_config.detect.stationary_threshold is None:
camera_config.detect.stationary_threshold = stationary_threshold
# FFMPEG input substitution
for input in camera_config.ffmpeg.inputs:
input.path = input.path.format(**FRIGATE_ENV_VARS)

View File

@@ -193,6 +193,8 @@ class TrackedObject:
"box": self.obj_data["box"],
"area": self.obj_data["area"],
"region": self.obj_data["region"],
"stationary": self.obj_data["motionless_count"]
> self.camera_config.detect.stationary_threshold,
"motionless_count": self.obj_data["motionless_count"],
"position_changes": self.obj_data["position_changes"],
"current_zones": self.current_zones.copy(),

View File

@@ -78,9 +78,9 @@ class ObjectTracker:
}
return False
# if there are less than stationary_threshold entries for the position, add the bounding box
# if there are less than 10 entries for the position, add the bounding box
# and recompute the position box
if len(position["xmins"]) < self.detect_config.stationary_threshold:
if len(position["xmins"]) < 10:
position["xmins"].append(xmin)
position["ymins"].append(ymin)
position["xmaxs"].append(xmax)

View File

@@ -184,10 +184,7 @@ class BirdsEyeFrameManager:
if self.mode == BirdseyeModeEnum.continuous:
return True
if (
self.mode == BirdseyeModeEnum.motion
and object_box_count + motion_box_count > 0
):
if self.mode == BirdseyeModeEnum.motion and motion_box_count > 0:
return True
if self.mode == BirdseyeModeEnum.objects and object_box_count > 0:
@@ -418,7 +415,7 @@ def output_frames(config: FrigateConfig, video_output_queue):
):
if birdseye_manager.update(
camera,
len(current_tracked_objects),
len([o for o in current_tracked_objects if not o["stationary"]]),
len(motion_boxes),
frame_time,
frame,

View File

@@ -507,8 +507,8 @@ def process_frames(
stationary_object_ids = [
obj["id"]
for obj in object_tracker.tracked_objects.values()
# if there hasn't been motion for N frames
if obj["motionless_count"] >= detect_config.stationary_threshold
# if there hasn't been motion for 10 frames
if obj["motionless_count"] >= 10
# and it isn't due for a periodic check
and (
detect_config.stationary_interval == 0

View File

@@ -29,12 +29,8 @@ function Camera({ name, conf }) {
const { payload: snapshotValue, send: sendSnapshots } = useSnapshotsState(name);
const href = `/cameras/${name}`;
const buttons = useMemo(() => {
const result = [{ name: 'Events', href: `/events?camera=${name}` }];
if (conf.record.enabled) {
result.push({ name: 'Recordings', href: `/recording/${name}` });
}
return result;
}, [name, conf.record.enabled]);
return [{ name: 'Events', href: `/events?camera=${name}` }, { name: 'Recordings', href: `/recording/${name}` }];
}, [name]);
const icons = useMemo(
() => [
{

View File

@@ -46,7 +46,7 @@ describe('Cameras Route', () => {
expect(screen.queryByLabelText('Loading…')).not.toBeInTheDocument();
expect(screen.queryAllByText('Recordings')).toHaveLength(1);
expect(screen.queryAllByText('Recordings')).toHaveLength(2);
});
test('buttons toggle detect, clips, and snapshots', async () => {