* Pin ruff
* Add python upgrade fixes
This enables python upgrade checks in ruff to look for deprecated types and patterns. This namely fixes:
- usage of deprecated `Typing` which is now built in
- some specific exceptions which are caught and have new aliases
Some specific UP checks were also ignored as they are stylistic / unimportant and likely to cause bugs
* Remove async blocking calls
Use asyncio.to_thread on two remaining blocking calls to fix hanging event thread loop. Enable this specific rule to block it in the future.
* Use proper logging mechanism
* Correctly format logs
* Raise with context
When raising an exception include the from context to improve debugging
* Cleanup
* add optional onClick to EmptyCard
* show EmptyCard in face rec when face library is empty
* add loading indicator
* add description to camera management pane
* Cleanup when use snapshot but can't load snapshot
* Migrate files
* fix birdseye color distortion when configured aspect ratio is unsupported
* Skip processing end for object descriptions
* don't crash if stats is null
* fix genai roles in migration
* frigate+ pane updates
- allow users to select a plus model from the select even when one was not previously loaded
- always show model summary card
- add model filter popover
- add restart button totast
* fix frigate+ pane layout and buttons to match other settings panes
* match button layout in go2rtc settings view
* make audio maintainer respond to dynamic config updates
* check correct zone name in publish state
* fix nested translation extraction for Optional dict and list fields
* mypy
---------
Co-authored-by: Nicolas Mowen <nickmowen213@gmail.com>
The idle heartbeat check in BirdsEyeOutputProcess.update() compares
time.monotonic() (seconds since an arbitrary point, typically boot)
against last_output_time which is set from datetime.datetime.now().timestamp()
(Unix epoch seconds).
These are completely different time bases. The subtraction produces a
large negative number, so the idle heartbeat condition can never be
satisfied. This means birdseye stops sending frames when all cameras
go idle, instead of continuing at the configured idle_heartbeat_fps.
Use datetime.datetime.now().timestamp() consistently for both the
heartbeat check and the output time tracking.
* only send monitoring notifications to users with camera access
* check access to similarity search event id camera
* require admin role for storage usage endpoint
* check camera access for jsmpeg and birdseye cameras
* tests
* formatting
cv2.imread with IMREAD_UNCHANGED loads the image as-is, but the code
unconditionally indexes channel 3 (birdseye_logo[:, :, 3]) assuming
RGBA format. This crashes with IndexError for:
- Grayscale PNGs (2D array, no channel dimension)
- RGB PNGs without alpha (3 channels, no index 3)
- Fully transparent PNGs saved as grayscale+alpha (2 channels)
Handle all image formats:
- 2D (grayscale): use directly as luminance
- 4+ channels (RGBA): extract alpha channel (existing behavior)
- 3 channels (RGB/BGR): convert to grayscale
Also fixes the shape[0]/shape[1] swap in the array slice that breaks
non-square images (related to #6802, #7863).
In BirdsEyeFrameManager.update(), the exception handler on line 756
resets self.active_cameras to [] (a list), but it is initialized as
set() and compared as a set throughout the rest of the code.
Since set() \!= [] evaluates to True even though both are empty, the
next call to update_frame() will incorrectly detect a layout change
and trigger an unnecessary frame rebuild after every exception.
* face recognition dynamic config
* lpr dynamic config
* safe changes for birdseye dynamic config
* bird classification dynamic config
* always assign new config to stats emitter to make telemetry fields dynamic
* add wildcard support for camera config updates in config_set
* update restart required fields for global sections
* add test
* fix rebase issue
* collapsible settings sidebar
use the preexisting control available with shadcn's sidebar (cmd/ctrl-B) to give users more space to set masks/zones on smaller screens
* dynamic ffmpeg
* ensure previews dir exists
when ffmpeg processes restart, there's a brief window where the preview frame generation pipeline is torn down and restarted. before these changes, ffmpeg only restarted on crash/stall recovery or full Frigate restart. Now that ffmpeg restarts happen on-demand via config changes, there's a higher chance a frontend request hits the preview_mp4 or preview_gif endpoints during that brief restart window when the directory might not exist yet. The existing os.listdir() call would throw FileNotFoundError without a directory existence check. this fix just checks if the directory exists and returns 404 if not, exactly how preview_thumbnail already handles the same scenario a few lines below
* global ffmpeg section
* clean up
* tweak
* fix test
* debug replay implementation
* fix masks after dev rebase
* fix squash merge issues
* fix
* fix
* fix
* no need to write debug replay camera to config
* camera and filter button and dropdown
* add filters
* add ability to edit motion and object config for debug replay
* add debug draw overlay to debug replay
* add guard to prevent crash when camera is no longer in camera_states
* fix overflow due to radix absolutely positioned elements
* increase number of messages
* ensure deep_merge replaces existing list values when override is true
* add back button
* add debug replay to explore and review menus
* clean up
* clean up
* update instructions to prevent exposing exception info
* fix typing
* refactor output logic
* refactor with helper function
* move init to function for consistency
* Add optional idle heartbeat for Birdseye (periodic frame emission when idle)
birdseye: add optional idle heartbeat and FFmpeg tuning envs (default off)
This adds an optional configuration field `birdseye.idle_heartbeat_fps` to
enable a lightweight idle heartbeat mechanism in Birdseye. When set to a value
greater than 0, Birdseye periodically re-sends the last composed frame during
idle periods (no motion or active updates).
This helps downstream consumers such as go2rtc, Alexa, or Scrypted to attach
faster and maintain a low-latency RTSP stream when the system is idle.
Key details:
- Config-based (`birdseye.idle_heartbeat_fps`), default `0` (disabled).
- Uses existing Birdseye rendering pipeline; minimal performance impact.
- Does not alter behavior when unset.
Documentation: added tip section in docs/configuration/restream.md.
* Update docs/docs/configuration/restream.md
Co-authored-by: Nicolas Mowen <nickmowen213@gmail.com>
* Update docs/docs/configuration/reference.md
Co-authored-by: Nicolas Mowen <nickmowen213@gmail.com>
* Refactors Birdseye idle frame broadcasting
Simplifies the idle frame broadcasting logic by removing the dedicated thread.
The idle frame is now resent directly within the main loop,
improving efficiency and reducing complexity. Also, limits the idle
heartbeat FPS to a maximum of 10 since the framebuffer is limited to 10 anyway
* ruff fix
---------
Co-authored-by: Nicolas Mowen <nickmowen213@gmail.com>
Co-authored-by: Francesco Durighetto <francesco.durighetto@subbyx.com>
Co-authored-by: duri <duri@homelabubuntu.durihome.unifi>
* Fix the `Any` typing hint treewide
There has been confusion between the Any type[1] and the any function[2]
in typing hints.
[1] https://docs.python.org/3/library/typing.html#typing.Any
[2] https://docs.python.org/3/library/functions.html#any
* Fix typing for various frame_shape members
Frame shapes are most likely defined by height and width, so a single int
cannot express that.
* Wrap gpu stats functions in Optional[]
These can return `None`, so they need to be `Type | None`, which is what
`Optional` expresses very nicely.
* Fix return type in get_latest_segment_datetime
Returns a datetime object, not an integer.
* Make the return type of FrameManager.write optional
This is necessary since the SharedMemoryFrameManager.write function can
return None.
* Fix total_seconds() return type in get_tz_modifiers
The function returns a float, not an int.
https://docs.python.org/3/library/datetime.html#datetime.timedelta.total_seconds
* Account for floating point results in to_relative_box
Because the function uses division the return types may either be int or
float.
* Resolve ruff deprecation warning
The config has been split into formatter and linter, and the global
options are deprecated.
* Monitor if camera is disabled for review items
* Simplify multi camera disabled check
* Cleanup birdseye config handling
* Cleanup
* Remove old listeners
* Fix live cameras not showing on refresh
* Fix live dashboard when birdseye is added
* Handle cameras that are offline / disabled
* Use black instead of green frame
* Fix missing mqtt topics
* config options
* metrics
* stop and restart ffmpeg processes
* dispatcher
* frontend websocket
* buttons for testing
* don't recreate log pipe
* add/remove cam from birdseye when enabling/disabling
* end all objects and send empty camera activity
* enable/disable switch in ui
* disable buttons when camera is disabled
* use enabled_in_config for some frontend checks
* tweaks
* handle settings pane with disabled cameras
* frontend tweaks
* change to debug log
* mqtt docs
* tweak
* ensure all ffmpeg processes are initially started
* clean up
* use zmq
* remove camera metrics
* remove camera metrics
* tweaks
* frontend tweaks
* Install multiple ffmpeg versions and add config to make it configurable
* Update docs
* Run ffprobe too
* Cleanup
* Apply config to go2rtc as well
* Fix ffmpeg bin
* Docs
* Restore path
* Cleanup env var
* Fix ffmpeg path for encoding
* Fix export
* Formatting
* Restrict nginx to 4 processes if more are available
* Fix bash
* Different sed structure
* Limit ffmpeg thread counts for secondary ffmpeg processes
* Add up / down keyboard shortcut
* Add config pub / sub pattern
* remove recording from feature metrics
* remove audio and feature metrics
* Check for updates from all cameras
* remove birdseye from camera metrics
* remove motion and detection camera metrics
* Ensure that all processes are stopped
* Stop communicators
* Detections
* Cleanup video output queue
* Use select for time sensitive polls
* Use ipc instead of tcp
* Generate low res low fps previews for recordings viewer
* Make sure previews end on the hour
* Fix durations and decrase keyframe interval to ensure smooth scrubbing
* Ensure minimized resolution is compatible with yuv
* Add ability to configure preview quality
* Fix
* Clean up previews more efficiently
* Use iterator