Add option to have cameras sorted inside the Birdseye stream (#5450)

* Add option to sort cameras inside Birdseye

* Make default order to be sorted alphabetically

* Add docs for sorting cameras

* Update index.md for cameras

* Remove irelevant comments
This commit is contained in:
Alin Balutoiu 2023-04-27 02:29:01 +02:00 committed by GitHub
parent e451f44ced
commit 83006eeb65
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 53 additions and 1 deletions

View File

@ -33,3 +33,25 @@ cameras:
birdseye: birdseye:
enabled: False enabled: False
``` ```
### Sorting cameras in the Birdseye view
It is possible to override the order of cameras that are being shown in the Birdseye view.
The order needs to be set at the camera level.
```yaml
# Include all cameras by default in Birdseye view
birdseye:
enabled: True
mode: continuous
cameras:
front:
birdseye:
order: 1
back:
birdseye:
order: 2
```
*Note*: Cameras are sorted by default using their name to ensure a constant view inside Birdseye.

View File

@ -518,6 +518,12 @@ cameras:
# Optional: password for login. # Optional: password for login.
password: admin password: admin
# Optional: Configuration for how to sort the cameras in the Birdseye view.
birdseye:
# Optional: Adjust sort order of cameras in the Birdseye view. Larger numbers come later (default: shown below)
# By default the cameras are sorted alphabetically.
order: 0
# Optional # Optional
ui: ui:
# Optional: Set the default live mode for cameras in the UI (default: shown below) # Optional: Set the default live mode for cameras in the UI (default: shown below)

View File

@ -396,6 +396,7 @@ class BirdseyeConfig(FrigateBaseModel):
# uses BaseModel because some global attributes are not available at the camera level # uses BaseModel because some global attributes are not available at the camera level
class BirdseyeCameraConfig(BaseModel): class BirdseyeCameraConfig(BaseModel):
enabled: bool = Field(default=True, title="Enable birdseye view for camera.") enabled: bool = Field(default=True, title="Enable birdseye view for camera.")
order: int = Field(default=0, title="Position of the camera in the birdseye view.")
mode: BirdseyeModeEnum = Field( mode: BirdseyeModeEnum = Field(
default=BirdseyeModeEnum.objects, title="Tracking mode for camera." default=BirdseyeModeEnum.objects, title="Tracking mode for camera."
) )

View File

@ -4,6 +4,7 @@ import logging
import math import math
import multiprocessing as mp import multiprocessing as mp
import os import os
import operator
import queue import queue
import signal import signal
import subprocess as sp import subprocess as sp
@ -292,8 +293,16 @@ class BirdsEyeFrameManager:
# calculate layout dimensions # calculate layout dimensions
layout_dim = math.ceil(math.sqrt(len(active_cameras))) layout_dim = math.ceil(math.sqrt(len(active_cameras)))
# check if we need to reset the layout because there are new cameras to add
reset_layout = (
True if len(active_cameras.difference(self.active_cameras)) > 0 else False
)
# reset the layout if it needs to be different # reset the layout if it needs to be different
if layout_dim != self.layout_dim: if layout_dim != self.layout_dim or reset_layout:
if reset_layout:
logger.debug(f"Added new cameras, resetting layout...")
logger.debug(f"Changing layout size from {self.layout_dim} to {layout_dim}") logger.debug(f"Changing layout size from {self.layout_dim} to {layout_dim}")
self.layout_dim = layout_dim self.layout_dim = layout_dim
@ -327,6 +336,20 @@ class BirdsEyeFrameManager:
self.active_cameras = active_cameras self.active_cameras = active_cameras
# this also converts added_cameras from a set to a list since we need
# to pop elements in order
added_cameras = sorted(
added_cameras,
# sort cameras by order and by name if the order is the same
key=lambda added_camera: (
self.config.cameras[added_camera].birdseye.order,
added_camera,
),
# we're popping out elements from the end, so this needs to be reverse
# as we want the last element to be the first
reverse=True,
)
# update each position in the layout # update each position in the layout
for position, camera in enumerate(self.camera_layout, start=0): for position, camera in enumerate(self.camera_layout, start=0):
# if this camera was removed, replace it or clear it # if this camera was removed, replace it or clear it