Compare commits

..
4 Commits
Author SHA1 Message Date
Josh Hawkins 10686e5e07 delete references to required_zones when a zone is deleted
cover all cases in review alerts/detections, genai, snapshots, mqtt

autotracking will fail backend validation if the user tries to delete the required zone, so they will just need to reassign the zone before deleting
2026-07-13 21:59:15 -05:00
Josh Hawkins eecc0e0b57 disable ID if zone is used anywhere in config required_zones 2026-07-13 21:42:25 -05:00
Josh Hawkins 390287dc6a tweak recordings language 2026-07-13 16:03:18 -05:00
Josh Hawkins 2dee1d37f8 debug replay docs clarity 2026-07-13 15:45:37 -05:00
5 changed files with 65 additions and 5 deletions
+3 -1
View File
@@ -39,7 +39,9 @@ The per-clip variation is typically quite low and is mostly an artifact of keyfr
Debug Replay lets you re-run Frigate's detection pipeline against a section of recorded video without manually configuring a dummy camera. It automatically extracts the recording, creates a temporary camera with the same detection settings as the original, and loops the clip through the pipeline so you can observe detections in real time.
Debug Replay isn't intended to be a one-stop pane for all Frigate diagnostics or a comprehensive debugging environment for every Frigate feature. It merely makes it easier to spin up a "dummy camera" and perform some common adjustments in real-time. You'll still need to use the normal tools (logs, an MQTT client, etc) to debug your feature.
The replay camera behaves like a live camera feed rather than History's video player: it loops the clip continuously as Frigate analyzes it and has no playback controls, so you cannot pause, scrub, or step through it frame by frame.
Debug Replay isn't intended to be a one-stop pane for all Frigate diagnostics or a comprehensive debugging environment for every Frigate feature. It merely makes it easier to spin up a "dummy camera" and perform some common adjustments in real time. You'll still need to use the normal tools (logs, an MQTT client, etc) to debug your feature.
### When to use
+1 -1
View File
@@ -126,7 +126,7 @@ The same recording playing perfectly in VLC, decoding cleanly with `ffprobe`/`ff
#### Step 1: Confirm it is a browser issue
Open the same recording in **Firefox**. Firefox uses a different (Gecko) media engine and cannot produce `PIPELINE_ERROR_DECODE`, so if playback works there you have confirmed a client-side codec or decoder problem rather than a bad recording. Switching browsers is a workaround, not a fix; the remaining steps address the root cause so that Chromium browsers work too.
Open the same recording in **Firefox** or **Safari**. Firefox and Safari both use a different media engine and cannot produce `PIPELINE_ERROR_DECODE`, so if playback works there you have confirmed a client-side codec or decoder problem rather than a bad recording. Switching browsers is a workaround, not a fix; the remaining steps address the root cause so that Chromium browsers work too.
#### Step 2: Rule out H.265 / HEVC
+26 -2
View File
@@ -27,7 +27,7 @@ import axios from "axios";
import { toast } from "sonner";
import useSWR from "swr";
import { FrigateConfig } from "@/types/frigateConfig";
import { reviewQueries } from "@/utils/zoneEdutUtil";
import { removeRequiredZoneQuery, reviewQueries } from "@/utils/zoneEdutUtil";
import IconWrapper from "../ui/icon-wrapper";
import { buttonVariants } from "@/components/ui/button";
import { Trans, useTranslation } from "react-i18next";
@@ -153,6 +153,30 @@ export default function PolygonItem({
cameraConfig?.review.alerts.required_zones || [],
cameraConfig?.review.detections.required_zones || [],
);
const genaiQueries = removeRequiredZoneQuery(
polygon.name,
polygon.camera,
"objects.genai",
cameraConfig?.objects.genai.required_zones || [],
);
const snapshotQueries = removeRequiredZoneQuery(
polygon.name,
polygon.camera,
"snapshots",
cameraConfig?.snapshots.required_zones || [],
);
const mqttQueries = removeRequiredZoneQuery(
polygon.name,
polygon.camera,
"mqtt",
cameraConfig?.mqtt.required_zones || [],
);
const autotrackQueries = removeRequiredZoneQuery(
polygon.name,
polygon.camera,
"onvif.autotracking",
cameraConfig?.onvif.autotracking.required_zones || [],
);
// Also delete from profiles that have overrides for this zone
let profileQueries = "";
if (allProfileNames && cameraConfig) {
@@ -165,7 +189,7 @@ export default function PolygonItem({
}
}
}
url = `cameras.${polygon.camera}.zones.${polygon.name}${alertQueries}${detectionQueries}${profileQueries}`;
url = `cameras.${polygon.camera}.zones.${polygon.name}${alertQueries}${detectionQueries}${genaiQueries}${snapshotQueries}${mqttQueries}${autotrackQueries}${profileQueries}`;
}
await axios
+5 -1
View File
@@ -108,7 +108,11 @@ export default function ZoneEditPane({
}
const inRequiredZones =
cam.review.alerts.required_zones.includes(polygon.name) ||
cam.review.detections.required_zones.includes(polygon.name);
cam.review.detections.required_zones.includes(polygon.name) ||
cam.objects.genai.required_zones.includes(polygon.name) ||
cam.snapshots.required_zones.includes(polygon.name) ||
cam.mqtt.required_zones.includes(polygon.name) ||
cam.onvif.autotracking.required_zones.includes(polygon.name);
const hasProfileOverride = Object.values(cam.profiles ?? {}).some(
(profile) => profile?.zones && polygon.name in profile.zones,
);
+30
View File
@@ -1,3 +1,33 @@
// Build a config/set query fragment that removes `name` from a
// required_zones list on the given camera section (e.g. "snapshots",
// "mqtt", "objects.genai", "onvif.autotracking"), rebuilding the
// remaining entries. When removing the name empties the list, the
// required_zones key itself is deleted so the field reverts to its
// default instead of retaining the now-stale zone name. Returns an empty
// string when `name` is not present so unrelated sections are untouched.
export const removeRequiredZoneQuery = (
name: string,
camera: string,
section: string,
zones: string[],
) => {
const remaining = new Set<string>(zones || []);
if (!remaining.has(name)) {
return "";
}
remaining.delete(name);
const key = `cameras.${camera}.${section}.required_zones`;
if (remaining.size === 0) {
return `&${key}`;
}
return [...remaining].map((zone) => `&${key}=${zone}`).join("");
};
export const reviewQueries = (
name: string,
review_alerts: boolean,