Commit Graph
23 Commits
Author SHA1 Message Date
Josh HawkinsandGitHub 64d6366ac4 Live streaming tech selection (#24374)
* allow users to select live streaming technology

* fix webrtc being downgraded to mse on load

`useUserPersistence` seeds state with the default and loads asynchronously, so the first render always used `mse` instead of the saved choice, and `useWebRTCGloballyAvailable` reports `checking` until the probe settles and re-enters that state on every consumer mount, so a saved `webrtc` was rewritten to `mse` even after the probe had already passed. On Safari the MSE player then timed out and latched the jsmpeg fallback. A pending probe now counts as available, the player waits on `autoLive` until the stored preferences load, and `handleError` gates on the mode in use since the fallback flag no longer implies webrtc is untried. A rejected IndexedDB read also resolves `loaded` now, so a blocked store can't leave the player waiting forever.

* add support for configurable ICE servers in WebRTC player

* add mic error state, fix dialog overwriting saved choice and dashboard ignoring stream

* tweaks
2026-09-16 09:12:06 -05:00
Josh HawkinsandGitHub caa6edecac Migrate web to ESLint 10 flat config (#24326)
* migrate web to eslint 10 flat config

ESLint 10 dropped `.eslintrc` support, so `.eslintrc.cjs` is replaced with `eslint.config.js` and the lint scripts no longer pass `--ext` or `--ignore-path`. typescript-eslint moves to 8, react-hooks to 7, and react-refresh to 0.5, and the unused jest and vitest-globals plugins are removed. Lint behaves as it did before: catch variables aren't checked, unused disable directives aren't reported, and rules newly added to the recommended sets are off until the code passes them. typescript-eslint 8 flags constants used only in `typeof`, so those are now exported, or replaced with a union type where the export would trip react-refresh.

* fix lint findings from the eslint 10 recommended rules

Remove the rule overrides from the flat config migration and fix what they were hiding. Unused catch bindings are dropped, 20 disable directives that suppressed nothing are removed (react-hooks 5.2 and 7.1.1 report identical exhaustive-deps findings with inline config ignored), dead initial values are dropped, short-circuit calls become if statements or optional calls, rethrown errors pass `cause`, and the disabled "No recordings" tooltip in `ReviewTimeline` is removed along with its memo and the `getRecordingAvailability` prop. The 3 react-refresh warnings for files that export contexts or classes are left for a later refactor.
2026-09-14 07:53:45 -06:00
ryzendigoandGitHub e80da2b297 fix: WebSocket connection leaked on WebRTC player cleanup (#22473)
The connect() function creates a WebSocket but never stores the
reference. The useEffect cleanup only closes the RTCPeerConnection
via pcRef, leaving the WebSocket open.

Each time the component re-renders with changed deps (camera switch,
playback toggle, microphone toggle), a new WebSocket is created
without closing the previous one. This leaks connections until the
browser garbage-collects them or the server times out.

Store the WebSocket in a ref and close it in the cleanup function.
2026-03-16 06:47:07 -06:00
Josh HawkinsandGitHub 2782931c72 Update frontend to React 19 (#22275)
* remove unused RecoilRoot and fix implicit ref callback

Remove the vestigial recoil dependency (zero consumers) and convert
the implicit-return ref callback in SearchView to block form to
prevent React 19 interpreting it as a cleanup function.

* replace react-transition-group with framer-motion in Chip

Replace CSSTransition with framer-motion AnimatePresence + motion.div
for React 19 compatibility (react-transition-group uses findDOMNode).
framer-motion is already a project dependency.

* migrate react-grid-layout v1 to v2

- Replace WidthProvider(Responsive) HOC with useContainerWidth hook
- Update types: Layout (single item) → LayoutItem, Layout[] → Layout
- Replace isDraggable/isResizable/resizeHandles with dragConfig/resizeConfig
- Update EventCallback signature for v2 API
- Remove @types/react-grid-layout (v2 includes its own types)

* upgrade vaul, next-themes, framer-motion, react-zoom-pan-pinch

- vaul: ^0.9.1 → ^1.1.2
- next-themes: ^0.3.0 → ^0.4.6
- framer-motion: ^11.5.4 → ^12.35.0 (React 19 native support)
- react-zoom-pan-pinch: 3.4.4 → latest

* upgrade to React 19, react-konva v19, eslint-plugin-react-hooks v5

Core React 19 upgrade with all necessary type fixes:
- Update RefObject types to accept T | null (React 19 refs always nullable)
- Add JSX namespace imports (no longer global in React 19)
- Add initial values to useRef calls (required in React 19)
- Fix ReactElement.props unknown type in config-form components
- Fix IconWrapper interface to use HTMLAttributes instead of index signature
- Add monaco-editor as dev dependency for type declarations
- Upgrade react-konva to v19, eslint-plugin-react-hooks to v5

* upgrade typescript to 5.9.3

* modernize Context.Provider to React 19 shorthand

Replace <Context.Provider value={...}> with <Context value={...}>
across all project-owned context providers. External library contexts
(react-icons IconContext, radix TooltipPrimitive) left unchanged.

* add runtime patches for React 19 compatibility

- Patch @radix-ui/react-compose-refs@1.1.2: stabilize useComposedRefs
  to prevent infinite render loops from unstable ref callbacks
  https://github.com/radix-ui/primitives/issues/3799
- Patch @radix-ui/react-slot@1.2.4: use useComposedRefs hook in
  SlotClone instead of inline composeRefs to prevent re-render cycles
  https://github.com/radix-ui/primitives/pull/3804
- Patch react-use-websocket@4.8.1: remove flushSync wrappers that
  cause "Maximum update depth exceeded" with React 19 auto-batching
  https://github.com/facebook/react/issues/27613
- Add npm overrides to ensure single hoisted copies of compose-refs
  and react-slot across all Radix packages
- Add postinstall script for patch-package
- Remove leftover react-transition-group dependency

* formatting

* use availableWidth instead of useContainerWidth for grid layout

The useContainerWidth hook from react-grid-layout v2 returns raw
container width without accounting for scrollbar width, causing the
grid to not fill the full available space. Use the existing
availableWidth value from useResizeObserver which already compensates
for scrollbar width, matching the working implementation.

* remove unused carousel component and fix React 19 peer deps

Remove embla-carousel-react and its unused Carousel UI component.
Upgrade sonner v1 → v2 for native React 19 support. Remove
@types/react-icons stub (react-icons bundles its own types).
These changes eliminate all peer dependency conflicts, so
npm install works without --legacy-peer-deps.

* fix React 19 infinite re-render loop on live dashboard

The "Maximum update depth exceeded" error was caused by two issues:

1. useDeferredStreamMetadata returned a new `{}` default on every render
   when SWR data was undefined, creating an unstable reference that
   triggered the useEffect in useCameraLiveMode on every render cycle.
   Fixed by using a stable module-level EMPTY_METADATA constant.

2. useResizeObserver's rest parameter `...refs` created a new array on
   every render, causing its useEffect to re-run and re-observe elements
   continuously. Fixed by stabilizing refs with useRef and only
   reconnecting the observer when actual DOM elements change.
2026-03-05 07:42:38 -07:00
815303922d Miscellaneous Fixes (#21005)
* update live view docs

* use swr as single source of truth for searchDetail

rather than maintaining a separate state, derive the selected item from swr cache. fixes websocket sync when regenerating descriptions or fetching transcriptions

* fix key warning in console

* don't try to fetch event from review item for audio events

* update audio transcription toast wording

* Add a community supported badge to specific detectors in the info summaries to better separate

* Make object classification publish to tracked object update and add examples for state classification

* Add item to advanced docs about tensorflow limiting

* Don't show submission for in progress objects

* fix for ios not reporting video dimensions on initial metadata load

in testing, polling with requestAnimationFrame finds the dimensions within 2 frames

* Catch jetson nvidia device tree

---------

Co-authored-by: Nicolas Mowen <nickmowen213@gmail.com>
2025-11-23 08:40:25 -07:00
Josh HawkinsandGitHub 658b0a064c Improve live view console errors (#20340)
* improve live view console errors

* more docs clarity
2025-10-03 06:37:18 -06:00
Josh HawkinsandGitHub 7f7eefef7f Live view improvements (#20177) 2025-09-22 21:21:51 -05:00
Josh HawkinsandGitHub 198e53bd42 Fix stream stats display (#19874)
* Fix stats calculations and labels

* fix linter from complaining

* fix mse calc

* label
2025-09-01 19:23:44 -05:00
Josh HawkinsandGitHub dd7820e4ee Improve live streaming (#16447)
* config file changes

* config migrator

* stream selection on single camera live view

* camera streaming settings dialog

* manage persistent group streaming settings

* apply streaming settings in camera groups

* add ability to clear all streaming settings from settings

* docs

* update reference config

* fixes

* clarify docs

* use first stream as default in dialog

* ensure still image is visible after switching stream type to none

* docs

* clarify docs

* add ability to continue playing stream in background

* fix props

* put stream selection inside dropdown on desktop

* add capabilities to live mode hook

* live context menu component

* resize observer: only return new dimensions if they've actually changed

* pass volume prop to players

* fix slider bug, https://github.com/shadcn-ui/ui/issues/1448

* update react-grid-layout

* prevent animated transitions on draggable grid layout

* add context menu to dashboards

* use provider

* streaming dialog from context menu

* docs

* add jsmpeg warning to context menu

* audio and two way talk indicators in single camera view

* add link to debug view

* don't use hook

* create manual events from live camera view

* maintain grow classes on grid items

* fix initial volume state on default dashboard

* fix pointer events causing context menu to end up underneath image on iOS

* mobile drawer tweaks

* stream stats

* show settings menu for non-restreamed cameras

* consistent settings icon

* tweaks

* optional stats to fix birdseye player

* add toaster to live camera view

* fix crash on initial save in streaming dialog

* don't require restreaming for context menu streaming settings

* add debug view to context menu

* stats fixes

* update docs

* always show stream info when restreamed

* update camera streaming dialog

* make note of no h265 support for webrtc

* docs clarity

* ensure docs show streams as a dict

* docs clarity

* fix css file

* tweaks
2025-02-10 09:42:35 -07:00
Nicolas MowenandGitHub e56ce993df UI Tweaks (#11931)
* Show number of items instead of dot

* Don't call error when connection has been closed on purpose

* Use motion icon for motion

* Show text on tablets as well
2024-06-13 09:45:07 -05:00
Josh HawkinsandGitHub 18d561da0e Live player fixes and improvements (#11855)
* Only set stalled error when player is visible

* Show activity indicator before live player starts playing

* remove comment

* keep gradients when still image is showing

* fix chips

* red dot and outline
2024-06-10 17:24:25 -06:00
Josh HawkinsandGitHub 3f0a954856 Try webrtc when mse fails with decoding error (#11745)
* Try webrtc if enabled and mse fails with decoding error

* default to jsmpeg if webrtc times out

* check for mic first
2024-06-04 09:11:32 -06:00
Nicolas MowenandGitHub 758df09da3 Handle error when live view stalls (#11665)
* Handle error when live view stalls

* Manually calculate buffer timeout

* Formatting
2024-05-31 08:52:42 -05:00
Nicolas MowenandGitHub 97f5ba0145 Update go2rtc and implement stream probe to only show 2 way talk when supported (#11407)
* Support two way talk validation

* Fix handling

* Use go2rtc stream info to infer audio output

* Update go2rtc

* Update bundle policy

* Formatting
2024-05-17 07:30:22 -06:00
Nicolas MowenandGitHub 4d8d3cd22e Live view improvements (#10781)
* Show frigate features in bottom sheet on mobile

* Use flex wrap on mobile so the ptz icons are not cutoff

* Support opening pip from live view

* Remove unused
2024-04-02 07:45:16 -05:00
Nicolas MowenandGitHub 380b15b286 WebUI Fixes (#10481)
* Update previews on the hour

* Allow tap to toggle controls so zooming still works

* Use hash location insteaad of state for live camera view

* Add typing
2024-03-15 13:46:17 -05:00
Nicolas MowenandGitHub 52ce6190ae Fix two way talk starting webrtc session (#10422)
* Fix two way talk starting webrtc session

* Remove logs
2024-03-13 09:04:11 -05:00
Nicolas MowenandGitHub 92255f771b Add micropohone button for two way talk (#10408) 2024-03-12 18:19:02 -05:00
Nicolas MowenandGitHub 5028a9632e Individual live view (#10178)
* Get live camera view working

* Get ptz working

* Add button for ptz presets

* Add camera feature buttons

* Add button for camera audio

* Cleanup

* Cleanup mobile live

* Only use landscape check on mobile
2024-03-01 18:43:02 -06:00
Nicolas MowenandGitHub 3bf2a496e1 Fix linter and fix lint issues (#10141) 2024-02-28 16:23:56 -06:00
Nicolas MowenandGitHub 8c4811ed69 Use webrtc for safari live view (#9839)
* Move safari function

* Use webrtc for safari

* Use taller aspect ratio for tall thumbnails

* Simplify thumbnail sizing

* Use correct aspect ratio on all devices
2024-02-14 18:19:55 -06:00
64988c9be0 Streamline live view (#9772)
* Break out live page

* Improving layouts and add chip component

* Improve default camera player sizing

* Improve live updating

* Cleanup and fit figma

* Use fixed height

* Masonry layout

* Fix stuff

* Don't force heights

* Adjust scaling

* Cleanup

* remove sidebar (#9731)

* remove sidebar

* keep sidebar on mobile for now and add icons

* Fix revalidation

* Cleanup

* Cleanup width

* Add chips for activity on cameras

* Remove dashboard from header

* Use Inter font (#9735)

* Show still image when no activity is occurring

* remove unused search params

* add playing check for webrtc

* Don't use grid at all for single column

* Fix height on mobile

* a few style updates to better match figma (#9745)

* Remove active objects when they become stationary

* Move to sidebar only and make settings separate component

* Fix layout

* Animate visibility of chips

* Sidebar is full screen

* Fix tall aspect ratio cameras

* Fix complicated aspect logic

* remove

* Adjust thumbnail aspect and add text

* margin on single column layout

* Smaller event thumb text

* Simplify basic image view

* Only show the red dot when camera is recording

* Improve typing for camera toggles

* animate chips with react-transition-group (#9763)

* don't flash when going to still image

* revalidate

* tooltips and active tracking outline (#9766)

* tooltips

* fix tooltip provider and add active tracking outline

* remove unused icon

* remove figma comment

* Get live mode working for jsmpeg

* add small gradient below timeago on event thumbnails (#9767)

* Create live mode hook and make sure jsmpeg can be used

* Enforce env var

* Use print

* Remove unstable

* Add tooltips to thumbnails

* Put back vite

* Format

* Update web/src/components/player/JSMpegPlayer.tsx

---------

Co-authored-by: Josh Hawkins <32435876+hawkeye217@users.noreply.github.com>
Co-authored-by: Blake Blackshear <blake@frigate.video>
2024-02-10 05:30:53 -07:00
Blake Blackshear bdebb99b5a Use new UI (#8983)
* fixup build

* swap frontends
2024-01-31 12:56:11 +00:00