mirror of
https://github.com/blakeblackshear/frigate.git
synced 2026-02-05 02:35:22 +03:00
Add option to sort cameras inside Birdseye
This commit is contained in:
parent
cdd8e6fd4e
commit
a5855ab428
@ -372,6 +372,9 @@ class BirdseyeModeEnum(str, Enum):
|
|||||||
class BirdseyeConfig(FrigateBaseModel):
|
class BirdseyeConfig(FrigateBaseModel):
|
||||||
enabled: bool = Field(default=True, title="Enable birdseye view.")
|
enabled: bool = Field(default=True, title="Enable birdseye view.")
|
||||||
restream: bool = Field(default=False, title="Restream birdseye via RTSP.")
|
restream: bool = Field(default=False, title="Restream birdseye via RTSP.")
|
||||||
|
sort_cameras: bool = Field(
|
||||||
|
default=False, title="Sort cameras by position and name."
|
||||||
|
)
|
||||||
width: int = Field(default=1280, title="Birdseye width.")
|
width: int = Field(default=1280, title="Birdseye width.")
|
||||||
height: int = Field(default=720, title="Birdseye height.")
|
height: int = Field(default=720, title="Birdseye height.")
|
||||||
quality: int = Field(
|
quality: int = Field(
|
||||||
@ -388,6 +391,9 @@ 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.")
|
||||||
|
position: 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."
|
||||||
)
|
)
|
||||||
|
|||||||
@ -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,21 @@ 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 sorting is enabled and there are new cameras to add
|
||||||
|
reset_layout = (
|
||||||
|
True
|
||||||
|
if self.config.birdseye.sort_cameras
|
||||||
|
and 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 and Birdseye sorting is enabled, 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 +341,21 @@ class BirdsEyeFrameManager:
|
|||||||
|
|
||||||
self.active_cameras = active_cameras
|
self.active_cameras = active_cameras
|
||||||
|
|
||||||
|
if self.config.birdseye.sort_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 the position and by name if the position is the same
|
||||||
|
key=lambda added_camera: (
|
||||||
|
self.config.cameras[added_camera].birdseye.position,
|
||||||
|
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
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user