app/frigate: Add schema, templates for Frigate
[Frigate] is an open source network video recording software with advanced motion detection using machine learning object detection. It uses `ffmpeg` to stream video from one or more RTSP-capable IP video cameras and passes the images through an object detection process. To improve the performance of the machine learning model, it supports using a Coral EdgeTPU device, which requires special drivers: `gasket` and `apex`. Frigate is configured via a (rather compex) YAML document, some of the schema of which is modeled in `schema.cue` (the parts I need, anyway). [Frigate]: https://frigate.video/master
parent
c4dcb5a8de
commit
cd64b3bccb
|
@ -0,0 +1,132 @@
|
||||||
|
package schema
|
||||||
|
|
||||||
|
#Frigate: {
|
||||||
|
env?: [string]: string
|
||||||
|
|
||||||
|
config: #FrigateConfig
|
||||||
|
}
|
||||||
|
|
||||||
|
#FrigateConfig: {
|
||||||
|
ffmpeg?: #FfmpegConfig
|
||||||
|
cameras: [string]: #CameraConfig
|
||||||
|
go2rtc?: #Go2RtcConfig
|
||||||
|
detectors?: [string]: #DetectorConfig
|
||||||
|
birdseye?: #BirdseyeConfig
|
||||||
|
mqtt: #MqttConfig
|
||||||
|
}
|
||||||
|
|
||||||
|
#FfmpegConfig: {
|
||||||
|
hwaccel_args?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
#CameraConfig: {
|
||||||
|
detect?: {
|
||||||
|
height: int
|
||||||
|
width: int
|
||||||
|
}
|
||||||
|
ffmpeg: {
|
||||||
|
inputs: [...#FfmpegInput]
|
||||||
|
}
|
||||||
|
objects?: {
|
||||||
|
track: [...string]
|
||||||
|
filters?: [string]: #ObjectFilter
|
||||||
|
}
|
||||||
|
record?: #RecordConfig
|
||||||
|
rtmp?: {
|
||||||
|
enabled?: bool
|
||||||
|
}
|
||||||
|
snapshots?: #SnapshotsConfig
|
||||||
|
zones?: [string]: #ZoneConfig
|
||||||
|
motion?: {
|
||||||
|
mask: [...string]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#FfmpegInput: {
|
||||||
|
path: string
|
||||||
|
input_args?: string
|
||||||
|
roles: [...string]
|
||||||
|
}
|
||||||
|
|
||||||
|
#ObjectFilter: {
|
||||||
|
threshold?: float
|
||||||
|
}
|
||||||
|
|
||||||
|
#RecordConfig: {
|
||||||
|
enabled?: bool
|
||||||
|
retain?: {
|
||||||
|
days: int
|
||||||
|
mode?: #RetainMode
|
||||||
|
}
|
||||||
|
events: {
|
||||||
|
pre_capture?: int
|
||||||
|
post_capture?: int
|
||||||
|
objects?: [...string]
|
||||||
|
required_zones?: [...string]
|
||||||
|
retain?: {
|
||||||
|
default?: int
|
||||||
|
mode?: #RetainMode
|
||||||
|
objects?: [string]: int
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#SnapshotsConfig: {
|
||||||
|
enabled?: bool
|
||||||
|
required_zones?: [...string]
|
||||||
|
retain?: {
|
||||||
|
default?: int
|
||||||
|
objects?: [string]: int
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#RetainMode: "all" | "motion" | "active_objects"
|
||||||
|
|
||||||
|
#ZoneConfig: {
|
||||||
|
coordinates: string
|
||||||
|
inertia?: int
|
||||||
|
objects?: [...string]
|
||||||
|
filters?: [string]: {
|
||||||
|
min_area?: int
|
||||||
|
maax_area?: int
|
||||||
|
threshold?: float
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#Go2RtcConfig: {
|
||||||
|
streams: [string]: [...string]
|
||||||
|
}
|
||||||
|
|
||||||
|
#DetectorConfig: #CpuDetector | #EdgeTpuDetector
|
||||||
|
|
||||||
|
#CpuDetector: {
|
||||||
|
type: "cpu"
|
||||||
|
num_threads?: int
|
||||||
|
}
|
||||||
|
|
||||||
|
#EdgeTpuDetector: {
|
||||||
|
type: "edgetpu"
|
||||||
|
device: string
|
||||||
|
}
|
||||||
|
|
||||||
|
#BirdseyeConfig: {
|
||||||
|
enabled?: bool
|
||||||
|
restream?: bool
|
||||||
|
width?: int
|
||||||
|
height?: int
|
||||||
|
quality?: int
|
||||||
|
mode?: "objects" | "motion" | "continuous"
|
||||||
|
inactivity_threshold?: int
|
||||||
|
layout?: {
|
||||||
|
scaling_factor?: float
|
||||||
|
max_cameras?: int
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#MqttConfig: {
|
||||||
|
host: string
|
||||||
|
password?: string
|
||||||
|
port?: int
|
||||||
|
tls_ca_certs?: string
|
||||||
|
user?: string
|
||||||
|
}
|
|
@ -0,0 +1,68 @@
|
||||||
|
package frigate
|
||||||
|
|
||||||
|
import "du5t1n.me/cfg/base/schema/instructions"
|
||||||
|
|
||||||
|
templates: [...instructions.#RenderInstruction] & [
|
||||||
|
{
|
||||||
|
template: "frigate/frigate.sysusers"
|
||||||
|
dest: "/etc/sysusers.d/frigate.conf"
|
||||||
|
hooks: changed: [
|
||||||
|
{
|
||||||
|
run: "systemd-sysusers /etc/sysusers.d/frigate.conf"
|
||||||
|
immediate: true
|
||||||
|
},
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
template: "frigate/frigate.env"
|
||||||
|
dest: "/etc/frigate/environ"
|
||||||
|
mode: "u=rw,go="
|
||||||
|
hooks: {
|
||||||
|
changed: [{run: "systemctl restart frigate"}]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
template: "frigate/config.yml"
|
||||||
|
dest: "/etc/frigate/config.yml"
|
||||||
|
hooks: {
|
||||||
|
changed: [{run: "systemctl restart frigate"}]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
template: "frigate/65-apex.rules"
|
||||||
|
dest: "/etc/udev/rules.d/65-apex.rules"
|
||||||
|
hooks: {
|
||||||
|
changed: [{run: "udevadm control --reload", immediate: true}]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
template: "frigate/gasket-driver.container"
|
||||||
|
dest: "/etc/containers/systemd/gasket-driver.container"
|
||||||
|
hooks: {
|
||||||
|
changed: [
|
||||||
|
{run: "systemctl daemon-reload", immediate: true},
|
||||||
|
{run: "systemctl restart gasket-driver"},
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
template: "frigate/frigate.container"
|
||||||
|
dest: "/etc/containers/systemd/frigate.container"
|
||||||
|
hooks: {
|
||||||
|
changed: [
|
||||||
|
{run: "systemctl daemon-reload", immediate: true},
|
||||||
|
{run: "systemctl restart frigate"},
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
template: "frigate/frigate-watchdog.container"
|
||||||
|
dest: "/etc/containers/systemd/frigate-watchdog.container"
|
||||||
|
hooks: {
|
||||||
|
changed: [
|
||||||
|
{run: "systemctl daemon-reload", immediate: true},
|
||||||
|
{run: "systemctl restart frigate-watchdog"},
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
]
|
|
@ -0,0 +1,5 @@
|
||||||
|
# Add systemd tag to apex devices so systemd will create .device
|
||||||
|
# units for them. This allows Frigate to wait for the device to be
|
||||||
|
# available before starting, by adding an After= dependency on the
|
||||||
|
# .device unit.
|
||||||
|
SUBSYSTEM=="apex", MODE="0666", TAG+="systemd"
|
|
@ -0,0 +1 @@
|
||||||
|
{{ frigate.yaml -}}
|
|
@ -0,0 +1,18 @@
|
||||||
|
[Unit]
|
||||||
|
Description=Frigate watchdog
|
||||||
|
After=frigate.service
|
||||||
|
|
||||||
|
[Container]
|
||||||
|
Image=git.pyrocufflink.blue/containerimages/frigate-watchdog
|
||||||
|
Pull=newer
|
||||||
|
Exec=-u frigate
|
||||||
|
Volume=/run/log:/run/log:ro
|
||||||
|
Volume=/var/log:/var/log:ro
|
||||||
|
Volume=/etc/machine-id:/etc/machine-id:ro
|
||||||
|
ReadOnly=true
|
||||||
|
VolatileTmp=true
|
||||||
|
PodmanArgs=--privileged --uts=host --cgroupns=host --ipc=host --pid=host
|
||||||
|
Network=host
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=frigate.service
|
|
@ -0,0 +1,34 @@
|
||||||
|
[Unit]
|
||||||
|
Description=Frigate NVR
|
||||||
|
Wants=network-online.target
|
||||||
|
After=network-online.target
|
||||||
|
Requires=dev-apex_0.device
|
||||||
|
After=dev-apex_0.device
|
||||||
|
RequiresMountsFor=/var/lib/frigate
|
||||||
|
|
||||||
|
[Container]
|
||||||
|
Image=ghcr.io/blakeblackshear/frigate:0.12.1
|
||||||
|
PodmanArgs=--uidmap 0:209:1
|
||||||
|
PodmanArgs=--gidmap 0:209:1
|
||||||
|
PodmanArgs=--uidmap 1:6000001:65536
|
||||||
|
PodmanArgs=--gidmap 1:6000001:65536
|
||||||
|
PodmanArgs=--shm-size 256m
|
||||||
|
EnvironmentFile=/etc/frigate/environ
|
||||||
|
Volume=/var/lib/frigate/media:/media/frigate:rw,z,U
|
||||||
|
Volume=/var/lib/frigate/tmp:/tmp:rw,z,U
|
||||||
|
Volume=/etc/frigate/config.yml:/config/config.yml:ro
|
||||||
|
AddDevice=/dev/apex_0
|
||||||
|
AddDevice=/dev/dri/renderD128
|
||||||
|
AddCapability=CAP_PERFMON
|
||||||
|
Network=host
|
||||||
|
Annotation=org.systemd.property.KillMode='none'
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
UMask=0077
|
||||||
|
Restart=always
|
||||||
|
TimeoutStopSec=infinity
|
||||||
|
StateDirectory=%N/tmp
|
||||||
|
StateDirectory=%N/media
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
|
@ -0,0 +1,9 @@
|
||||||
|
{% if frigate.env is defined -%}
|
||||||
|
{% for k, v in frigate.env -%}
|
||||||
|
{% if v is starting_with("-----BEGIN AGE") -%}
|
||||||
|
{{ k }}={{ v | decrypt }}
|
||||||
|
{% else %}
|
||||||
|
{{ k }}={{ v }}
|
||||||
|
{% endif -%}
|
||||||
|
{% endfor -%}
|
||||||
|
{% endif -%}
|
|
@ -0,0 +1,2 @@
|
||||||
|
g frigate 209
|
||||||
|
u frigate 209:209 "Frigate" /var/lib/frigate /sbin/nologin
|
|
@ -0,0 +1,17 @@
|
||||||
|
[Unit]
|
||||||
|
Description=Install the gasket/apex kernel modules
|
||||||
|
Wants=network-online.target
|
||||||
|
After=network-online.target
|
||||||
|
|
||||||
|
[Container]
|
||||||
|
Image=git.pyrocufflink.net/containerimages/gasket-driver:%v
|
||||||
|
PodmanArgs=--privileged
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=oneshot
|
||||||
|
RemainAfterExit=true
|
||||||
|
ExecStop=/usr/sbin/rmmod apex
|
||||||
|
ExecStop=/usr/sbin/rmmod gasket
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
Loading…
Reference in New Issue