mirror of
https://github.com/blakeblackshear/frigate.git
synced 2026-06-21 03:41:55 +03:00
add validation and messages for detect settings
This commit is contained in:
parent
c92c514997
commit
c82474e360
@ -28,5 +28,8 @@
|
||||
"detectRequired": "At least one input stream must be assigned the 'detect' role.",
|
||||
"hwaccelDetectOnly": "Only the input stream with the detect role can define hardware acceleration arguments."
|
||||
}
|
||||
},
|
||||
"detect": {
|
||||
"dimensionMustBeEven": "Must be an even number."
|
||||
}
|
||||
}
|
||||
|
||||
@ -1794,7 +1794,9 @@
|
||||
},
|
||||
"detect": {
|
||||
"fpsGreaterThanFive": "Setting the detect FPS higher than 5 is not recommended. Higher values may cause performance issues and will not provide any benefit.",
|
||||
"disabled": "Object detection is disabled. Snapshots, review items, and enrichments such as face recognition, license plate recognition, and Generative AI will not function."
|
||||
"disabled": "Object detection is disabled. Snapshots, review items, and enrichments such as face recognition, license plate recognition, and Generative AI will not function.",
|
||||
"resolutionShouldBeMultipleOfFour": "For best results, detect width and height should be multiples of 4. Other even values may produce visual artifacts or slight distortion in the detect stream.",
|
||||
"aspectRatioMismatch": "The width and height you've entered don't match the aspect ratio of your current detect resolution. This may produce a stretched or distorted image."
|
||||
},
|
||||
"objects": {
|
||||
"genaiNoDescriptionsProvider": "You must configure a GenAI provider with the 'descriptions' role for descriptions to be generated."
|
||||
|
||||
@ -11,6 +11,50 @@ const detect: SectionConfigOverrides = {
|
||||
condition: (ctx) =>
|
||||
ctx.level === "camera" && ctx.formData?.enabled === false,
|
||||
},
|
||||
{
|
||||
key: "detect-resolution-not-multiple-of-four",
|
||||
messageKey: "configMessages.detect.resolutionShouldBeMultipleOfFour",
|
||||
severity: "warning",
|
||||
condition: (ctx) => {
|
||||
const width = ctx.formData?.width as number | null | undefined;
|
||||
const height = ctx.formData?.height as number | null | undefined;
|
||||
const isEvenButNotFour = (v: unknown) =>
|
||||
typeof v === "number" && v % 2 === 0 && v % 4 !== 0;
|
||||
return isEvenButNotFour(width) || isEvenButNotFour(height);
|
||||
},
|
||||
},
|
||||
{
|
||||
key: "detect-aspect-ratio-mismatch",
|
||||
messageKey: "configMessages.detect.aspectRatioMismatch",
|
||||
severity: "warning",
|
||||
condition: (ctx) => {
|
||||
const newWidth = ctx.formData?.width as number | null | undefined;
|
||||
const newHeight = ctx.formData?.height as number | null | undefined;
|
||||
if (typeof newWidth !== "number" || typeof newHeight !== "number") {
|
||||
return false;
|
||||
}
|
||||
const saved =
|
||||
ctx.level === "camera"
|
||||
? ctx.fullCameraConfig?.detect
|
||||
: ctx.fullConfig?.detect;
|
||||
const savedWidth = saved?.width;
|
||||
const savedHeight = saved?.height;
|
||||
if (
|
||||
typeof savedWidth !== "number" ||
|
||||
typeof savedHeight !== "number" ||
|
||||
savedWidth <= 0 ||
|
||||
savedHeight <= 0
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
if (newWidth === savedWidth && newHeight === savedHeight) {
|
||||
return false;
|
||||
}
|
||||
const newRatio = newWidth / newHeight;
|
||||
const savedRatio = savedWidth / savedHeight;
|
||||
return Math.abs(newRatio - savedRatio) > 0.01;
|
||||
},
|
||||
},
|
||||
],
|
||||
fieldMessages: [
|
||||
{
|
||||
|
||||
36
web/src/components/config-form/section-validations/detect.ts
Normal file
36
web/src/components/config-form/section-validations/detect.ts
Normal file
@ -0,0 +1,36 @@
|
||||
import type { FormValidation } from "@rjsf/utils";
|
||||
import type { TFunction } from "i18next";
|
||||
import { isJsonObject } from "@/lib/utils";
|
||||
import type { JsonObject } from "@/types/configForm";
|
||||
|
||||
export function validateDetectDimensions(
|
||||
formData: unknown,
|
||||
errors: FormValidation,
|
||||
t: TFunction,
|
||||
): FormValidation {
|
||||
if (!isJsonObject(formData as JsonObject)) {
|
||||
return errors;
|
||||
}
|
||||
|
||||
const data = formData as JsonObject;
|
||||
const width = data.width;
|
||||
const height = data.height;
|
||||
|
||||
const widthErrors = errors.width as
|
||||
| { addError?: (message: string) => void }
|
||||
| undefined;
|
||||
const heightErrors = errors.height as
|
||||
| { addError?: (message: string) => void }
|
||||
| undefined;
|
||||
|
||||
const message = t("detect.dimensionMustBeEven", { ns: "config/validation" });
|
||||
|
||||
if (typeof width === "number" && width % 2 !== 0) {
|
||||
widthErrors?.addError?.(message);
|
||||
}
|
||||
if (typeof height === "number" && height % 2 !== 0) {
|
||||
heightErrors?.addError?.(message);
|
||||
}
|
||||
|
||||
return errors;
|
||||
}
|
||||
@ -1,5 +1,6 @@
|
||||
import type { FormValidation } from "@rjsf/utils";
|
||||
import type { TFunction } from "i18next";
|
||||
import { validateDetectDimensions } from "./detect";
|
||||
import { validateFfmpegInputRoles } from "./ffmpeg";
|
||||
import { validateProxyRoleHeader } from "./proxy";
|
||||
|
||||
@ -19,6 +20,10 @@ export function getSectionValidation({
|
||||
level,
|
||||
t,
|
||||
}: SectionValidationOptions): SectionValidation | undefined {
|
||||
if (sectionPath === "detect") {
|
||||
return (formData, errors) => validateDetectDimensions(formData, errors, t);
|
||||
}
|
||||
|
||||
if (sectionPath === "ffmpeg" && level === "camera") {
|
||||
return (formData, errors) => validateFfmpegInputRoles(formData, errors, t);
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user