Skip to content

Commit a8bfe50

Browse files
committed
Merge branch 'dev' of github.com:blakeblackshear/frigate into testing
2 parents 1763b05 + a75f694 commit a8bfe50

File tree

274 files changed

+8494
-1081
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

274 files changed

+8494
-1081
lines changed

.github/copilot-instructions.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
1-
Never write strings in the frontend directly, always write to and reference the relevant translations file.
2-
Always conform new and refactored code to the existing coding style in the project.
1+
- For Frigate NVR, never write strings in the frontend directly. Since the project uses `react-i18next`, use `t()` and write the English string in the relevant translations file in `web/public/locales/en`.
2+
- Always conform new and refactored code to the existing coding style in the project.
3+
- Always have a way to test your work and confirm your changes. When running backend tests, use `python3 -u -m unittest`.

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ Please see our [Trademark Policy](TRADEMARK.md) for details on acceptable use of
6767
### Built-in mask and zone editor
6868

6969
<div>
70-
<img width="800" alt="Multi-camera scrubbing" src="https://github.com/blakeblackshear/frigate/assets/569905/d7885fc3-bfe6-452f-b7d0-d957cb3e31f5">
70+
<img width="800" alt="Built-in mask and zone editor" src="https://github.com/blakeblackshear/frigate/assets/569905/d7885fc3-bfe6-452f-b7d0-d957cb3e31f5">
7171
</div>
7272

7373
## Translations

docker/main/requirements-wheels.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,8 @@ onnxruntime == 1.22.*
4747
# Embeddings
4848
transformers == 4.45.*
4949
# Generative AI
50-
google-generativeai == 0.8.*
51-
ollama == 0.5.*
50+
google-genai == 1.58.*
51+
ollama == 0.6.*
5252
openai == 1.65.*
5353
# push notifications
5454
py-vapid == 1.9.*

docker/main/rootfs/etc/s6-overlay/s6-rc.d/go2rtc/run

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,8 @@ function setup_homekit_config() {
5454
local config_path="$1"
5555

5656
if [[ ! -f "${config_path}" ]]; then
57-
echo "[INFO] Creating empty HomeKit config file..."
58-
echo 'homekit: {}' > "${config_path}"
57+
echo "[INFO] Creating empty config file for HomeKit..."
58+
echo '{}' > "${config_path}"
5959
fi
6060

6161
# Convert YAML to JSON for jq processing
@@ -69,15 +69,15 @@ function setup_homekit_config() {
6969
local cleaned_json="/tmp/cache/homekit_cleaned.json"
7070
jq '
7171
# Keep only the homekit section if it exists, otherwise empty object
72-
if has("homekit") then {homekit: .homekit} else {homekit: {}} end
72+
if has("homekit") then {homekit: .homekit} else {} end
7373
' "${temp_json}" > "${cleaned_json}" 2>/dev/null || {
74-
echo '{"homekit": {}}' > "${cleaned_json}"
74+
echo '{}' > "${cleaned_json}"
7575
}
7676

7777
# Convert back to YAML and write to the config file
7878
yq eval -P "${cleaned_json}" > "${config_path}" 2>/dev/null || {
7979
echo "[WARNING] Failed to convert cleaned config to YAML, creating minimal config"
80-
echo 'homekit: {}' > "${config_path}"
80+
echo '{}' > "${config_path}"
8181
}
8282

8383
# Clean up temp files

docker/main/rootfs/usr/local/go2rtc/create_config.py

Lines changed: 61 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,31 @@
2222

2323
yaml = YAML()
2424

25+
# Check if arbitrary exec sources are allowed (defaults to False for security)
26+
allow_arbitrary_exec = None
27+
if "GO2RTC_ALLOW_ARBITRARY_EXEC" in os.environ:
28+
allow_arbitrary_exec = os.environ.get("GO2RTC_ALLOW_ARBITRARY_EXEC")
29+
elif (
30+
os.path.isdir("/run/secrets")
31+
and os.access("/run/secrets", os.R_OK)
32+
and "GO2RTC_ALLOW_ARBITRARY_EXEC" in os.listdir("/run/secrets")
33+
):
34+
allow_arbitrary_exec = (
35+
Path(os.path.join("/run/secrets", "GO2RTC_ALLOW_ARBITRARY_EXEC"))
36+
.read_text()
37+
.strip()
38+
)
39+
# check for the add-on options file
40+
elif os.path.isfile("/data/options.json"):
41+
with open("/data/options.json") as f:
42+
raw_options = f.read()
43+
options = json.loads(raw_options)
44+
allow_arbitrary_exec = options.get("go2rtc_allow_arbitrary_exec")
45+
46+
ALLOW_ARBITRARY_EXEC = allow_arbitrary_exec is not None and str(
47+
allow_arbitrary_exec
48+
).lower() in ("true", "1", "yes")
49+
2550
FRIGATE_ENV_VARS = {k: v for k, v in os.environ.items() if k.startswith("FRIGATE_")}
2651
# read docker secret files as env vars too
2752
if os.path.isdir("/run/secrets"):
@@ -109,30 +134,60 @@
109134
elif go2rtc_config["ffmpeg"].get("rtsp") is None:
110135
go2rtc_config["ffmpeg"]["rtsp"] = rtsp_args
111136

112-
for name in go2rtc_config.get("streams", {}):
137+
138+
def is_restricted_source(stream_source: str) -> bool:
139+
"""Check if a stream source is restricted (echo, expr, or exec)."""
140+
return stream_source.strip().startswith(("echo:", "expr:", "exec:"))
141+
142+
143+
for name in list(go2rtc_config.get("streams", {})):
113144
stream = go2rtc_config["streams"][name]
114145

115146
if isinstance(stream, str):
116147
try:
117-
go2rtc_config["streams"][name] = go2rtc_config["streams"][name].format(
118-
**FRIGATE_ENV_VARS
119-
)
148+
formatted_stream = stream.format(**FRIGATE_ENV_VARS)
149+
if not ALLOW_ARBITRARY_EXEC and is_restricted_source(formatted_stream):
150+
print(
151+
f"[ERROR] Stream '{name}' uses a restricted source (echo/expr/exec) which is disabled by default for security. "
152+
f"Set GO2RTC_ALLOW_ARBITRARY_EXEC=true to enable arbitrary exec sources."
153+
)
154+
del go2rtc_config["streams"][name]
155+
continue
156+
go2rtc_config["streams"][name] = formatted_stream
120157
except KeyError as e:
121158
print(
122159
"[ERROR] Invalid substitution found, see https://docs.frigate.video/configuration/restream#advanced-restream-configurations for more info."
123160
)
124161
sys.exit(e)
125162

126163
elif isinstance(stream, list):
127-
for i, stream in enumerate(stream):
164+
filtered_streams = []
165+
for i, stream_item in enumerate(stream):
128166
try:
129-
go2rtc_config["streams"][name][i] = stream.format(**FRIGATE_ENV_VARS)
167+
formatted_stream = stream_item.format(**FRIGATE_ENV_VARS)
168+
if not ALLOW_ARBITRARY_EXEC and is_restricted_source(formatted_stream):
169+
print(
170+
f"[ERROR] Stream '{name}' item {i + 1} uses a restricted source (echo/expr/exec) which is disabled by default for security. "
171+
f"Set GO2RTC_ALLOW_ARBITRARY_EXEC=true to enable arbitrary exec sources."
172+
)
173+
continue
174+
175+
filtered_streams.append(formatted_stream)
130176
except KeyError as e:
131177
print(
132178
"[ERROR] Invalid substitution found, see https://docs.frigate.video/configuration/restream#advanced-restream-configurations for more info."
133179
)
134180
sys.exit(e)
135181

182+
if filtered_streams:
183+
go2rtc_config["streams"][name] = filtered_streams
184+
else:
185+
print(
186+
f"[ERROR] Stream '{name}' was removed because all sources were restricted (echo/expr/exec). "
187+
f"Set GO2RTC_ALLOW_ARBITRARY_EXEC=true to enable arbitrary exec sources."
188+
)
189+
del go2rtc_config["streams"][name]
190+
136191
# add birdseye restream stream if enabled
137192
if config.get("birdseye", {}).get("restream", False):
138193
birdseye: dict[str, Any] = config.get("birdseye")

docs/docs/configuration/audio_detectors.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ cameras:
5050

5151
### Configuring Minimum Volume
5252

53-
The audio detector uses volume levels in the same way that motion in a camera feed is used for object detection. This means that frigate will not run audio detection unless the audio volume is above the configured level in order to reduce resource usage. Audio levels can vary widely between camera models so it is important to run tests to see what volume levels are. The Debug view in the Frigate UI has an Audio tab for cameras that have the `audio` role assigned where a graph and the current levels are is displayed. The `min_volume` parameter should be set to the minimum the `RMS` level required to run audio detection.
53+
The audio detector uses volume levels in the same way that motion in a camera feed is used for object detection. This means that Frigate will not run audio detection unless the audio volume is above the configured level in order to reduce resource usage. Audio levels can vary widely between camera models so it is important to run tests to see what volume levels are. The Debug view in the Frigate UI has an Audio tab for cameras that have the `audio` role assigned where a graph and the current levels are is displayed. The `min_volume` parameter should be set to the minimum the `RMS` level required to run audio detection.
5454

5555
:::tip
5656

docs/docs/configuration/cameras.md

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,12 @@ cameras:
7979

8080
If the ONVIF connection is successful, PTZ controls will be available in the camera's WebUI.
8181

82+
:::note
83+
84+
Some cameras use a separate ONVIF/service account that is distinct from the device administrator credentials. If ONVIF authentication fails with the admin account, try creating or using an ONVIF/service user in the camera's firmware. Refer to your camera manufacturer's documentation for more.
85+
86+
:::
87+
8288
:::tip
8389

8490
If your ONVIF camera does not require authentication credentials, you may still need to specify an empty string for `user` and `password`, eg: `user: ""` and `password: ""`.
@@ -95,7 +101,7 @@ The FeatureList on the [ONVIF Conformant Products Database](https://www.onvif.or
95101

96102
| Brand or specific camera | PTZ Controls | Autotracking | Notes |
97103
| ---------------------------- | :----------: | :----------: | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
98-
| Amcrest | ✅ | ✅ | ⛔️ Generally, Amcrest should work, but some older models (like the common IP2M-841) don't support autotracking |
104+
| Amcrest | ✅ | ✅ | ⛔️ Generally, Amcrest should work, but some older models (like the common IP2M-841) don't support autotracking |
99105
| Amcrest ASH21 | ✅ | ❌ | ONVIF service port: 80 |
100106
| Amcrest IP4M-S2112EW-AI | ✅ | ❌ | FOV relative movement not supported. |
101107
| Amcrest IP5M-1190EW | ✅ | ❌ | ONVIF Port: 80. FOV relative movement not supported. |

0 commit comments

Comments
 (0)