Skip to content

Commit 5adac30

Browse files
authored
Merge pull request #37 from hawkeye217/streaming-options
fixes
2 parents 5221c75 + 43b53f3 commit 5adac30

18 files changed

+820
-74
lines changed

docs/docs/configuration/live.md

+29-4
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ id: live
33
title: Live View
44
---
55

6-
Frigate intelligently displays your camera streams on the Live view dashboard. Your camera images update once per minute when no detectable activity is occurring to conserve bandwidth and resources. As soon as any motion is detected, cameras seamlessly switch to a live stream.
6+
Frigate intelligently displays your camera streams on the Live view dashboard. By default, Frigate employs "smart streaming" where camera images update once per minute when no detectable activity is occurring to conserve bandwidth and resources. As soon as any motion or objects are detected, cameras seamlessly switch to a live stream.
77

88
## Live View technologies
99

@@ -51,9 +51,15 @@ go2rtc:
5151
- ffmpeg:rtsp://192.168.1.5:554/live0#video=copy
5252
```
5353
54-
### Setting Stream For Live UI
54+
### Setting Streams For Live UI
5555
56-
There may be some cameras that you would prefer to use the sub stream for live view, but the main stream for recording. This can be done via `live -> stream_name`.
56+
In Frigate 0.16 and later, you can edit your configuration to allow manual selection of the stream you want to view in the Live UI. For example, you may want to view your camera's substream on mobile devices, but the full resolution stream on desktop devices. Setting the `live -> streams` list will populate a dropdown in the UI's Live view that allows you to choose between the streams. This settings is _per device_ and is saved in your device's local storage.
57+
58+
Additionally, when creating and editing camera groups in the UI, you can choose the stream you want to use for your camera group's Live dashboard. The default dashboard ("All Cameras") will always use the first entry you've defined in `streams:` for streaming.
59+
60+
Configure the `streams` option with a "friendly name" for your stream followed by the go2rtc stream name.
61+
62+
Go2rtc is required to use this feature. You cannot specify paths in the `streams` list, only go2rtc stream names.
5763

5864
```yaml
5965
go2rtc:
@@ -80,7 +86,9 @@ cameras:
8086
roles:
8187
- detect
8288
live:
83-
stream_name: test_cam_sub
89+
streams: # <--- Multiple streams for Frigate 0.16 and later
90+
- Main Stream: test_cam
91+
- Sub Stream: test_cam_sub
8492
```
8593

8694
### WebRTC extra configuration:
@@ -138,3 +146,20 @@ services:
138146
:::
139147

140148
See [go2rtc WebRTC docs](https://github.com/AlexxIT/go2rtc/tree/v1.8.3#module-webrtc) for more information about this.
149+
150+
### Streaming options on camera group dashboards
151+
152+
Frigate 0.16 and later provides a dialog in the Camera Group Edit pane with several options for streaming on a camera group's dashboard. These settings are _per device_ and are saved in your device's local storage.
153+
154+
- Stream selection using the `live -> streams` configuration option (see _Setting Streams For Live UI_ above)
155+
- Streaming type:
156+
- _No streaming_: Camera images will only update once per minute and no live streaming will occur.
157+
- _Smart Streaming_ (default, recommended setting): Smart streaming will update your camera image once per minute when no detectable activity is occurring to conserve bandwidth and resources, since a static picture is the same as a streaming image with no motion or objects. When motion or objects are detected, the image seamlessly switches to a live stream.
158+
- _Continuous Streaming_: Camera image will always be a live stream when visible on the dashboard, even if no activity is being detected. Continuous streaming may cause high bandwidth usage and performance issues. **Use with caution.**
159+
- _Compatibility mode_: Enable this option only if your camera's live stream is displaying color artifacts and has a diagonal line on the right side of the image. Before enabling this, try setting your camera's `detect` width and height to a standard aspect ratio (for example: 640x352 becomes 640x360, and 800x443 becomes 800x450, 2688x1520 becomes 2688x1512, etc). Depending on your browser and device, more than a few cameras in compatibility mode may not be supported, so only use this option if changing your config fails to resolve the color artifacts and diagonal line.
160+
161+
:::note
162+
163+
The default dashboard ("All Cameras") will always use Smart Streaming and the first entry set in your `streams` configuration, if defined. Use a camera group if you need to change any of these settings from these defaults.
164+
165+
:::

docs/docs/configuration/reference.md

+3-2
Original file line numberDiff line numberDiff line change
@@ -551,10 +551,11 @@ go2rtc:
551551
# Optional: Live stream configuration for WebUI.
552552
# NOTE: Can be overridden at the camera level
553553
live:
554-
# Optional: Set the name of the stream configured in go2rtc
554+
# Optional: Set the streams configured in go2rtc
555555
# that should be used for live view in frigate WebUI. (default: name of camera)
556556
# NOTE: In most cases this should be set at the camera level only.
557-
stream_name: camera_name
557+
streams:
558+
- friendly_name: stream_name
558559
# Optional: Set the height of the jsmpeg stream. (default: 720)
559560
# This must be less than or equal to the height of the detect stream. Lower resolutions
560561
# reduce bandwidth required for viewing the jsmpeg stream. Width is computed to match known aspect ratio.

frigate/config/camera/live.py

+6-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
from typing import Dict
2+
13
from pydantic import Field
24

35
from ..base import FrigateBaseModel
@@ -6,6 +8,9 @@
68

79

810
class CameraLiveConfig(FrigateBaseModel):
9-
stream_name: str = Field(default="", title="Name of restream to use as live view.")
11+
streams: Dict[str, str] = Field(
12+
default_factory=list,
13+
title="Friendly names and restream names to use for live view.",
14+
)
1015
height: int = Field(default=720, title="Live camera view height")
1116
quality: int = Field(default=8, ge=1, le=31, title="Live camera view quality")

frigate/config/config.py

+12-11
Original file line numberDiff line numberDiff line change
@@ -176,17 +176,18 @@ def verify_config_roles(camera_config: CameraConfig) -> None:
176176
)
177177

178178

179-
def verify_valid_live_stream_name(
179+
def verify_valid_live_stream_names(
180180
frigate_config: FrigateConfig, camera_config: CameraConfig
181181
) -> ValueError | None:
182182
"""Verify that a restream exists to use for live view."""
183-
if (
184-
camera_config.live.stream_name
185-
not in frigate_config.go2rtc.model_dump().get("streams", {}).keys()
186-
):
187-
return ValueError(
188-
f"No restream with name {camera_config.live.stream_name} exists for camera {camera_config.name}."
189-
)
183+
for _, stream_name in camera_config.live.streams.items():
184+
if (
185+
stream_name
186+
not in frigate_config.go2rtc.model_dump().get("streams", {}).keys()
187+
):
188+
return ValueError(
189+
f"No restream with name {stream_name} exists for camera {camera_config.name}."
190+
)
190191

191192

192193
def verify_recording_retention(camera_config: CameraConfig) -> None:
@@ -562,15 +563,15 @@ def post_validation(self, info: ValidationInfo) -> Self:
562563
zone.generate_contour(camera_config.frame_shape)
563564

564565
# Set live view stream if none is set
565-
if not camera_config.live.stream_name:
566-
camera_config.live.stream_name = name
566+
if not camera_config.live.streams:
567+
camera_config.live.streams = {name: name}
567568

568569
# generate the ffmpeg commands
569570
camera_config.create_ffmpeg_cmds()
570571
self.cameras[name] = camera_config
571572

572573
verify_config_roles(camera_config)
573-
verify_valid_live_stream_name(self, camera_config)
574+
verify_valid_live_stream_names(self, camera_config)
574575
verify_recording_retention(camera_config)
575576
verify_recording_segments_setup_with_reasonable_time(camera_config)
576577
verify_zone_objects_are_tracked(camera_config)

frigate/util/config.py

+31-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313

1414
logger = logging.getLogger(__name__)
1515

16-
CURRENT_CONFIG_VERSION = "0.15-0"
16+
CURRENT_CONFIG_VERSION = "0.16-0"
1717
DEFAULT_CONFIG_FILE = "/config/config.yml"
1818

1919

@@ -77,6 +77,13 @@ def migrate_frigate_config(config_file: str):
7777
yaml.dump(new_config, f)
7878
previous_version = "0.15-0"
7979

80+
if previous_version < "0.16-0":
81+
logger.info(f"Migrating frigate config from {previous_version} to 0.16-0...")
82+
new_config = migrate_016_0(config)
83+
with open(config_file, "w") as f:
84+
yaml.dump(new_config, f)
85+
previous_version = "0.16-0"
86+
8087
logger.info("Finished frigate config migration...")
8188

8289

@@ -267,6 +274,29 @@ def migrate_015_0(config: dict[str, dict[str, any]]) -> dict[str, dict[str, any]
267274
return new_config
268275

269276

277+
def migrate_016_0(config: dict[str, dict[str, any]]) -> dict[str, dict[str, any]]:
278+
"""Handle migrating frigate config to 0.16-0"""
279+
new_config = config.copy()
280+
281+
for name, camera in config.get("cameras", {}).items():
282+
camera_config: dict[str, dict[str, any]] = camera.copy()
283+
284+
live_config = camera_config.get("live", {})
285+
if "stream_name" in live_config:
286+
# Migrate from live -> stream_name to live -> streams -> dict
287+
stream_name = live_config["stream_name"]
288+
live_config["streams"] = {stream_name: stream_name}
289+
290+
del live_config["stream_name"]
291+
292+
camera_config["live"] = live_config
293+
294+
new_config["cameras"][name] = camera_config
295+
296+
new_config["version"] = "0.16-0"
297+
return new_config
298+
299+
270300
def get_relative_coordinates(
271301
mask: Optional[Union[str, list]], frame_shape: tuple[int, int]
272302
) -> Union[str, list]:

0 commit comments

Comments
 (0)