mirror of
https://github.com/blakeblackshear/frigate.git
synced 2026-05-07 05:55:27 +03:00
Compare commits
5 Commits
4a167c21f7
...
c2beda98ad
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c2beda98ad | ||
|
|
704ee9667c | ||
|
|
76a1230885 | ||
|
|
52a3301726 | ||
|
|
4359aca5bf |
@ -287,6 +287,9 @@ RUN --mount=type=bind,source=docker/main/install_memryx.sh,target=/deps/install_
|
|||||||
|
|
||||||
COPY --from=deps-rootfs / /
|
COPY --from=deps-rootfs / /
|
||||||
|
|
||||||
|
RUN mkdir -p /etc/letsencrypt/www /etc/letsencrypt/live/frigate /usr/local/nginx/logs /config /run /tmp/cache /media/frigate \
|
||||||
|
&& chmod -R a+rwX /etc/letsencrypt /usr/local/nginx /config /run /tmp/cache /media/frigate
|
||||||
|
|
||||||
RUN ldconfig
|
RUN ldconfig
|
||||||
|
|
||||||
EXPOSE 5000
|
EXPOSE 5000
|
||||||
@ -297,6 +300,8 @@ EXPOSE 8555/tcp 8555/udp
|
|||||||
ENV S6_LOGGING_SCRIPT="T 1 n0 s10000000 T"
|
ENV S6_LOGGING_SCRIPT="T 1 n0 s10000000 T"
|
||||||
# Do not fail on long-running download scripts
|
# Do not fail on long-running download scripts
|
||||||
ENV S6_CMD_WAIT_FOR_SERVICES_MAXTIME=0
|
ENV S6_CMD_WAIT_FOR_SERVICES_MAXTIME=0
|
||||||
|
# Set HOME to cache directory so rootless users can cache downloaded models
|
||||||
|
ENV HOME=/tmp/cache
|
||||||
|
|
||||||
ENTRYPOINT ["/init"]
|
ENTRYPOINT ["/init"]
|
||||||
CMD []
|
CMD []
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
#!/command/with-contenv bash
|
#!/command/with-contenv bash
|
||||||
# shellcheck shell=bash
|
# shellcheck shell=bash
|
||||||
|
|
||||||
exec logutil-service /dev/shm/logs/certsync
|
exec /usr/local/bin/logutil /dev/shm/logs/certsync/
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
#!/command/with-contenv bash
|
#!/command/with-contenv bash
|
||||||
# shellcheck shell=bash
|
# shellcheck shell=bash
|
||||||
|
|
||||||
exec logutil-service /dev/shm/logs/frigate
|
exec /usr/local/bin/logutil /dev/shm/logs/frigate/
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
#!/command/with-contenv bash
|
#!/command/with-contenv bash
|
||||||
# shellcheck shell=bash
|
# shellcheck shell=bash
|
||||||
|
|
||||||
exec logutil-service /dev/shm/logs/go2rtc
|
exec /usr/local/bin/logutil /dev/shm/logs/go2rtc/
|
||||||
|
|||||||
@ -7,5 +7,7 @@ set -o errexit -o nounset -o pipefail
|
|||||||
dirs=(/dev/shm/logs/frigate /dev/shm/logs/go2rtc /dev/shm/logs/nginx /dev/shm/logs/certsync)
|
dirs=(/dev/shm/logs/frigate /dev/shm/logs/go2rtc /dev/shm/logs/nginx /dev/shm/logs/certsync)
|
||||||
|
|
||||||
mkdir -p "${dirs[@]}"
|
mkdir -p "${dirs[@]}"
|
||||||
|
if [ "$(id -u)" = "0" ]; then
|
||||||
chown nobody:nogroup "${dirs[@]}"
|
chown nobody:nogroup "${dirs[@]}"
|
||||||
|
fi
|
||||||
chmod 02755 "${dirs[@]}"
|
chmod 02755 "${dirs[@]}"
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
#!/command/with-contenv bash
|
#!/command/with-contenv bash
|
||||||
# shellcheck shell=bash
|
# shellcheck shell=bash
|
||||||
|
|
||||||
exec logutil-service /dev/shm/logs/nginx
|
exec /usr/local/bin/logutil /dev/shm/logs/nginx/
|
||||||
|
|||||||
@ -65,6 +65,11 @@ function set_worker_processes() {
|
|||||||
|
|
||||||
set_worker_processes
|
set_worker_processes
|
||||||
|
|
||||||
|
# NGINX cannot switch users if running rootless; strip the directive
|
||||||
|
if [ "$(id -u)" != "0" ]; then
|
||||||
|
sed -i '/^user root;/d' /usr/local/nginx/conf/nginx.conf || true
|
||||||
|
fi
|
||||||
|
|
||||||
# ensure the directory for ACME challenges exists
|
# ensure the directory for ACME challenges exists
|
||||||
mkdir -p /etc/letsencrypt/www
|
mkdir -p /etc/letsencrypt/www
|
||||||
|
|
||||||
|
|||||||
17
docker/main/rootfs/usr/local/bin/logutil
Executable file
17
docker/main/rootfs/usr/local/bin/logutil
Executable file
@ -0,0 +1,17 @@
|
|||||||
|
#!/command/with-contenv bash
|
||||||
|
# shellcheck shell=bash
|
||||||
|
|
||||||
|
LOG_DIR=$1
|
||||||
|
|
||||||
|
if [ -z "$LOG_DIR" ]; then
|
||||||
|
echo "Usage: $0 <log-dir>"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
CMD=(s6-log -b -- ${S6_LOGGING_SCRIPT:-n20 s1000000 T} "$LOG_DIR")
|
||||||
|
|
||||||
|
if [ "$(id -u)" = "0" ]; then
|
||||||
|
exec /command/s6-envuidgid nobody /command/s6-applyuidgid -U -- "${CMD[@]}"
|
||||||
|
else
|
||||||
|
exec "${CMD[@]}"
|
||||||
|
fi
|
||||||
@ -13,7 +13,7 @@ ARG ROCM
|
|||||||
|
|
||||||
RUN apt update -qq && \
|
RUN apt update -qq && \
|
||||||
apt install -y wget gpg && \
|
apt install -y wget gpg && \
|
||||||
wget -O rocm.deb https://repo.radeon.com/amdgpu-install/7.2/ubuntu/jammy/amdgpu-install_7.2.70200-1_all.deb && \
|
wget -O rocm.deb https://repo.radeon.com/amdgpu-install/7.2.3/ubuntu/jammy/amdgpu-install_7.2.3.70203-1_all.deb && \
|
||||||
apt install -y ./rocm.deb && \
|
apt install -y ./rocm.deb && \
|
||||||
apt update && \
|
apt update && \
|
||||||
apt install -qq -y rocm
|
apt install -qq -y rocm
|
||||||
@ -78,6 +78,10 @@ ENV MIGRAPHX_DISABLE_MIOPEN_FUSION=1
|
|||||||
ENV MIGRAPHX_DISABLE_SCHEDULE_PASS=1
|
ENV MIGRAPHX_DISABLE_SCHEDULE_PASS=1
|
||||||
ENV MIGRAPHX_DISABLE_REDUCE_FUSION=1
|
ENV MIGRAPHX_DISABLE_REDUCE_FUSION=1
|
||||||
ENV MIGRAPHX_ENABLE_HIPRTC_WORKAROUNDS=1
|
ENV MIGRAPHX_ENABLE_HIPRTC_WORKAROUNDS=1
|
||||||
|
ENV MIOPEN_CUSTOM_CACHE_DIR=/config/model_cache/migraphx
|
||||||
|
ENV MIOPEN_USER_DB_PATH=/config/model_cache/migraphx
|
||||||
|
ENV AMD_COMGR_CACHE=1
|
||||||
|
ENV AMD_COMGR_CACHE_DIR=/config/model_cache/migraphx
|
||||||
|
|
||||||
COPY --from=rocm-dist / /
|
COPY --from=rocm-dist / /
|
||||||
|
|
||||||
|
|||||||
@ -1 +1 @@
|
|||||||
onnxruntime-migraphx @ https://github.com/NickM-27/frigate-onnxruntime-rocm/releases/download/v7.2.0/onnxruntime_migraphx-1.23.1-cp311-cp311-linux_x86_64.whl
|
onnxruntime-migraphx @ https://github.com/NickM-27/frigate-onnxruntime-rocm/releases/download/v7.2.3-1/onnxruntime_migraphx-1.24.4-cp311-cp311-linux_x86_64.whl
|
||||||
@ -1,5 +1,5 @@
|
|||||||
variable "ROCM" {
|
variable "ROCM" {
|
||||||
default = "7.2.0"
|
default = "7.2.3"
|
||||||
}
|
}
|
||||||
variable "HSA_OVERRIDE_GFX_VERSION" {
|
variable "HSA_OVERRIDE_GFX_VERSION" {
|
||||||
default = ""
|
default = ""
|
||||||
|
|||||||
@ -1023,9 +1023,9 @@ detectors:
|
|||||||
### ONNX Supported Models
|
### ONNX Supported Models
|
||||||
|
|
||||||
| Model | Nvidia GPU | AMD GPU | Notes |
|
| Model | Nvidia GPU | AMD GPU | Notes |
|
||||||
| ----------------------------- | ---------- | ------- | --------------------------------------------------- |
|
| ------------------------------------ | ---------- | ------- | --------------------------------------------------- |
|
||||||
| [YOLOv9](#yolo-v3-v4-v7-v9-2) | ✅ | ✅ | Supports CUDA Graphs for optimal Nvidia performance |
|
| [YOLOv9](#yolo-v3-v4-v7-v9-2) | ✅ | ✅ | Supports CUDA Graphs for optimal Nvidia performance |
|
||||||
| [RF-DETR](#rf-detr) | ✅ | ❌ | Supports CUDA Graphs for optimal Nvidia performance |
|
| [RF-DETR](#rf-detr) | ✅ | ⚠️ | Supports CUDA Graphs for optimal Nvidia performance |
|
||||||
| [YOLO-NAS](#yolo-nas-1) | ⚠️ | ⚠️ | Not supported by CUDA Graphs |
|
| [YOLO-NAS](#yolo-nas-1) | ⚠️ | ⚠️ | Not supported by CUDA Graphs |
|
||||||
| [YOLOX](#yolox-1) | ✅ | ✅ | Supports CUDA Graphs for optimal Nvidia performance |
|
| [YOLOX](#yolox-1) | ✅ | ✅ | Supports CUDA Graphs for optimal Nvidia performance |
|
||||||
| [D-FINE / DEIMv2](#d-fine--deimv2-1) | ⚠️ | ❌ | Not supported by CUDA Graphs |
|
| [D-FINE / DEIMv2](#d-fine--deimv2-1) | ⚠️ | ❌ | Not supported by CUDA Graphs |
|
||||||
|
|||||||
@ -223,10 +223,11 @@ Apple Silicon can not run within a container, so a ZMQ proxy is utilized to comm
|
|||||||
|
|
||||||
With the [ROCm](../configuration/object_detectors.md#amdrocm-gpu-detector) detector Frigate can take advantage of many discrete AMD GPUs.
|
With the [ROCm](../configuration/object_detectors.md#amdrocm-gpu-detector) detector Frigate can take advantage of many discrete AMD GPUs.
|
||||||
|
|
||||||
| Name | YOLOv9 Inference Time | YOLO-NAS Inference Time |
|
| Name | YOLOv9 Inference Time | YOLO-NAS Inference Time | RF-DETR Inference Time |
|
||||||
| --------- | --------------------------- | ------------------------- |
|
| -------------- | --------------------------- | ------------------------- | ---------------------- |
|
||||||
| AMD 780M | t-320: ~ 14 ms s-320: 20 ms | 320: ~ 25 ms 640: ~ 50 ms |
|
| AMD 780M | t-320: ~ 14 ms s-320: 20 ms | 320: ~ 25 ms 640: ~ 50 ms | |
|
||||||
| AMD 8700G | | 320: ~ 20 ms 640: ~ 40 ms |
|
| AMD 8700G | | 320: ~ 20 ms 640: ~ 40 ms | |
|
||||||
|
| AMD 9060XT 16G | t-320: ~ 4 ms s-320: 5 ms | 320: ~ 6 ms | Nano-320: ~ 90 ms |
|
||||||
|
|
||||||
## Community Supported Detectors
|
## Community Supported Detectors
|
||||||
|
|
||||||
|
|||||||
@ -812,6 +812,11 @@ limiter = Limiter(key_func=get_remote_addr)
|
|||||||
)
|
)
|
||||||
@limiter.limit(limit_value=rateLimiter.get_limit)
|
@limiter.limit(limit_value=rateLimiter.get_limit)
|
||||||
def login(request: Request, body: AppPostLoginBody):
|
def login(request: Request, body: AppPostLoginBody):
|
||||||
|
if not request.app.frigate_config.auth.enabled:
|
||||||
|
return JSONResponse(
|
||||||
|
content={"message": "Authentication is disabled"}, status_code=404
|
||||||
|
)
|
||||||
|
|
||||||
JWT_COOKIE_NAME = request.app.frigate_config.auth.cookie_name
|
JWT_COOKIE_NAME = request.app.frigate_config.auth.cookie_name
|
||||||
JWT_COOKIE_SECURE = request.app.frigate_config.auth.cookie_secure
|
JWT_COOKIE_SECURE = request.app.frigate_config.auth.cookie_secure
|
||||||
JWT_SESSION_LENGTH = request.app.frigate_config.auth.session_length
|
JWT_SESSION_LENGTH = request.app.frigate_config.auth.session_length
|
||||||
|
|||||||
@ -229,9 +229,10 @@ class FaceRealTimeProcessor(RealTimeProcessorApi):
|
|||||||
logger.debug(f"No person box available for {id}")
|
logger.debug(f"No person box available for {id}")
|
||||||
return
|
return
|
||||||
|
|
||||||
rgb = cv2.cvtColor(frame, cv2.COLOR_YUV2RGB_I420)
|
# YuNet (cv2.FaceDetectorYN) is trained on BGR
|
||||||
|
bgr = cv2.cvtColor(frame, cv2.COLOR_YUV2BGR_I420)
|
||||||
left, top, right, bottom = person_box
|
left, top, right, bottom = person_box
|
||||||
person = rgb[top:bottom, left:right]
|
person = bgr[top:bottom, left:right]
|
||||||
face_box = self.__detect_face(person, self.face_config.detection_threshold)
|
face_box = self.__detect_face(person, self.face_config.detection_threshold)
|
||||||
|
|
||||||
if not face_box:
|
if not face_box:
|
||||||
@ -250,11 +251,6 @@ class FaceRealTimeProcessor(RealTimeProcessorApi):
|
|||||||
)
|
)
|
||||||
return
|
return
|
||||||
|
|
||||||
try:
|
|
||||||
face_frame = cv2.cvtColor(face_frame, cv2.COLOR_RGB2BGR)
|
|
||||||
except Exception as e:
|
|
||||||
logger.debug(f"Failed to convert face frame color for {id}: {e}")
|
|
||||||
return
|
|
||||||
else:
|
else:
|
||||||
# don't run for object without attributes
|
# don't run for object without attributes
|
||||||
if not obj_data.get("current_attributes"):
|
if not obj_data.get("current_attributes"):
|
||||||
|
|||||||
@ -132,7 +132,6 @@ class ONNXModelRunner(BaseModelRunner):
|
|||||||
return model_type in [
|
return model_type in [
|
||||||
EnrichmentModelTypeEnum.paddleocr.value,
|
EnrichmentModelTypeEnum.paddleocr.value,
|
||||||
EnrichmentModelTypeEnum.jina_v2.value,
|
EnrichmentModelTypeEnum.jina_v2.value,
|
||||||
EnrichmentModelTypeEnum.arcface.value,
|
|
||||||
ModelTypeEnum.rfdetr.value,
|
ModelTypeEnum.rfdetr.value,
|
||||||
ModelTypeEnum.dfine.value,
|
ModelTypeEnum.dfine.value,
|
||||||
]
|
]
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
import { WidgetProps } from "@rjsf/utils";
|
import { WidgetProps } from "@rjsf/utils";
|
||||||
import { SwitchesWidget } from "./SwitchesWidget";
|
import { SwitchesWidget } from "./SwitchesWidget";
|
||||||
import { FormContext } from "./SwitchesWidget";
|
import { FormContext } from "./SwitchesWidget";
|
||||||
import { getTranslatedLabel } from "@/utils/i18n";
|
import i18n, { getTranslatedLabel } from "@/utils/i18n";
|
||||||
import { FrigateConfig } from "@/types/frigateConfig";
|
import { FrigateConfig } from "@/types/frigateConfig";
|
||||||
import { JsonObject } from "@/types/configForm";
|
import { JsonObject } from "@/types/configForm";
|
||||||
|
|
||||||
@ -76,7 +76,12 @@ function getObjectLabels(context: FormContext): string[] {
|
|||||||
...sourceLabels,
|
...sourceLabels,
|
||||||
...formDataLabels,
|
...formDataLabels,
|
||||||
]);
|
]);
|
||||||
return [...combinedLabels].sort();
|
return [...combinedLabels].sort((a, b) =>
|
||||||
|
getObjectLabelDisplayName(a).localeCompare(
|
||||||
|
getObjectLabelDisplayName(b),
|
||||||
|
i18n.language,
|
||||||
|
),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getObjectLabelDisplayName(label: string): string {
|
function getObjectLabelDisplayName(label: string): string {
|
||||||
@ -94,6 +99,7 @@ export function ObjectLabelSwitchesWidget(props: WidgetProps) {
|
|||||||
i18nKey: "objectLabels",
|
i18nKey: "objectLabels",
|
||||||
listClassName:
|
listClassName:
|
||||||
"relative max-h-none overflow-visible md:max-h-64 md:overflow-y-auto md:overscroll-contain md:scrollbar-container",
|
"relative max-h-none overflow-visible md:max-h-64 md:overflow-y-auto md:overscroll-contain md:scrollbar-container",
|
||||||
|
enableSearch: true,
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|||||||
@ -7,13 +7,20 @@ import useSWR from "swr";
|
|||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
import { toast } from "sonner";
|
import { toast } from "sonner";
|
||||||
import { Pencil, Trash2 } from "lucide-react";
|
import { Pencil, Trash2 } from "lucide-react";
|
||||||
import { LuChevronDown, LuChevronRight, LuPlus } from "react-icons/lu";
|
import {
|
||||||
|
LuChevronDown,
|
||||||
|
LuChevronRight,
|
||||||
|
LuExternalLink,
|
||||||
|
LuPlus,
|
||||||
|
} from "react-icons/lu";
|
||||||
|
import { Link } from "react-router-dom";
|
||||||
import type { FrigateConfig } from "@/types/frigateConfig";
|
import type { FrigateConfig } from "@/types/frigateConfig";
|
||||||
import type { JsonObject } from "@/types/configForm";
|
import type { JsonObject } from "@/types/configForm";
|
||||||
import type { ProfileState, ProfilesApiResponse } from "@/types/profile";
|
import type { ProfileState, ProfilesApiResponse } from "@/types/profile";
|
||||||
import { getProfileColor } from "@/utils/profileColors";
|
import { getProfileColor } from "@/utils/profileColors";
|
||||||
import { PROFILE_ELIGIBLE_SECTIONS } from "@/utils/configUtil";
|
import { PROFILE_ELIGIBLE_SECTIONS } from "@/utils/configUtil";
|
||||||
import { resolveCameraName } from "@/hooks/use-camera-friendly-name";
|
import { resolveCameraName } from "@/hooks/use-camera-friendly-name";
|
||||||
|
import { useDocDomain } from "@/hooks/use-doc-domain";
|
||||||
import { cn } from "@/lib/utils";
|
import { cn } from "@/lib/utils";
|
||||||
import Heading from "@/components/ui/heading";
|
import Heading from "@/components/ui/heading";
|
||||||
import { Button } from "@/components/ui/button";
|
import { Button } from "@/components/ui/button";
|
||||||
@ -66,6 +73,7 @@ export default function ProfilesView({
|
|||||||
setProfilesUIEnabled,
|
setProfilesUIEnabled,
|
||||||
}: ProfilesViewProps) {
|
}: ProfilesViewProps) {
|
||||||
const { t } = useTranslation(["views/settings", "common"]);
|
const { t } = useTranslation(["views/settings", "common"]);
|
||||||
|
const { getLocaleDocUrl } = useDocDomain();
|
||||||
const { data: config, mutate: updateConfig } =
|
const { data: config, mutate: updateConfig } =
|
||||||
useSWR<FrigateConfig>("config");
|
useSWR<FrigateConfig>("config");
|
||||||
const { data: profilesData, mutate: updateProfiles } =
|
const { data: profilesData, mutate: updateProfiles } =
|
||||||
@ -360,6 +368,17 @@ export default function ProfilesView({
|
|||||||
<div className="my-1 text-sm text-muted-foreground">
|
<div className="my-1 text-sm text-muted-foreground">
|
||||||
{t("profiles.disabledDescription", { ns: "views/settings" })}
|
{t("profiles.disabledDescription", { ns: "views/settings" })}
|
||||||
</div>
|
</div>
|
||||||
|
<div className="flex items-center text-sm text-primary-variant">
|
||||||
|
<Link
|
||||||
|
to={getLocaleDocUrl("configuration/profiles")}
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener noreferrer"
|
||||||
|
className="inline"
|
||||||
|
>
|
||||||
|
{t("readTheDocumentation", { ns: "common" })}
|
||||||
|
<LuExternalLink className="ml-2 inline-flex size-3" />
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
|
|
||||||
{/* Enable Profiles Toggle — shown only when no profiles exist */}
|
{/* Enable Profiles Toggle — shown only when no profiles exist */}
|
||||||
{!hasProfiles && setProfilesUIEnabled && (
|
{!hasProfiles && setProfilesUIEnabled && (
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user