Refactor frigate config to add a bunch of features
All checks were successful
Check Flake / check-flake (push) Successful in 2h20m26s
All checks were successful
Check Flake / check-flake (push) Successful in 2h20m26s
- Enable vaapi GPU video encode/decode support - Use go2rtc. This allows for watching high resolution camera feeds - Split nix config into pieces that are easier to understand - Add utilities for easily adding new cameras in the future - misc changes
This commit is contained in:
parent
91874b9d53
commit
66bfc62566
@ -3,105 +3,153 @@
|
|||||||
let
|
let
|
||||||
frigateHostname = "frigate.s0.neet.dev";
|
frigateHostname = "frigate.s0.neet.dev";
|
||||||
|
|
||||||
mkEsp32Cam = address: {
|
mkGo2RtcStream = name: url: withAudio: {
|
||||||
ffmpeg = {
|
${name} = [
|
||||||
input_args = "";
|
url
|
||||||
inputs = [{
|
"ffmpeg:${name}#video=copy${if withAudio then "#audio=copy" else ""}"
|
||||||
path = "http://${address}:8080";
|
];
|
||||||
roles = [ "detect" "record" ];
|
|
||||||
}];
|
|
||||||
|
|
||||||
output_args.record = "-f segment -pix_fmt yuv420p -segment_time 10 -segment_format mp4 -reset_timestamps 1 -strftime 1 -c:v libx264 -preset ultrafast -an ";
|
|
||||||
};
|
|
||||||
detect = {
|
|
||||||
enabled = true;
|
|
||||||
width = 800;
|
|
||||||
height = 600;
|
|
||||||
fps = 10;
|
|
||||||
};
|
|
||||||
objects = {
|
|
||||||
track = [ "person" ];
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
mkDahuaCam = address: {
|
# Assumes camera is set to output:
|
||||||
ffmpeg = {
|
# - rtsp
|
||||||
inputs = [
|
# - H.264 + AAC
|
||||||
{
|
# - a downscaled substream for detection
|
||||||
path = "rtsp://admin:{FRIGATE_RTSP_PASSWORD}@${address}/cam/realmonitor?channel=1&subtype=0";
|
mkCamera = name: primaryUrl: detectUrl: {
|
||||||
roles = [ "record" ];
|
# Reference https://docs.frigate.video/configuration/reference/
|
||||||
}
|
services.frigate.settings = {
|
||||||
{
|
cameras.${name} = {
|
||||||
path = "rtsp://admin:{FRIGATE_RTSP_PASSWORD}@${address}/cam/realmonitor?channel=1&subtype=1";
|
ffmpeg = {
|
||||||
roles = [ "detect" ];
|
# Camera feeds are relayed through go2rtc
|
||||||
}
|
inputs = [
|
||||||
];
|
{
|
||||||
};
|
path = "rtsp://127.0.0.1:8554/${name}";
|
||||||
detect.enabled = true;
|
# input_args = "preset-rtsp-restream";
|
||||||
objects = {
|
input_args = "preset-rtsp-restream-low-latency";
|
||||||
track = [ "person" "dog" ];
|
roles = [ "record" ];
|
||||||
};
|
}
|
||||||
};
|
{
|
||||||
in
|
path = detectUrl;
|
||||||
{
|
roles = [ "detect" ];
|
||||||
networking.firewall.allowedTCPPorts = [
|
}
|
||||||
# 1883 # mqtt
|
];
|
||||||
];
|
output_args = {
|
||||||
|
record = "preset-record-generic-audio-copy";
|
||||||
services.frigate = {
|
|
||||||
enable = true;
|
|
||||||
hostname = frigateHostname;
|
|
||||||
settings = {
|
|
||||||
mqtt = {
|
|
||||||
enabled = true;
|
|
||||||
host = "localhost:1883";
|
|
||||||
};
|
|
||||||
rtmp.enabled = false;
|
|
||||||
snapshots = {
|
|
||||||
enabled = true;
|
|
||||||
bounding_box = true;
|
|
||||||
};
|
|
||||||
record = {
|
|
||||||
enabled = true;
|
|
||||||
# sync_recordings = true; # detect if recordings were deleted outside of frigate
|
|
||||||
retain = {
|
|
||||||
days = 2; # Keep video for 2 days
|
|
||||||
mode = "motion";
|
|
||||||
};
|
|
||||||
events = {
|
|
||||||
retain = {
|
|
||||||
default = 10; # Keep video with detections for 10 days
|
|
||||||
mode = "motion";
|
|
||||||
# mode = "active_objects";
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
cameras = {
|
};
|
||||||
dahlia-cam = mkEsp32Cam "dahlia-cam.lan";
|
services.go2rtc.settings.streams = lib.mkMerge [
|
||||||
dog-cam = mkDahuaCam "192.168.10.31";
|
(mkGo2RtcStream name primaryUrl false)
|
||||||
};
|
|
||||||
# ffmpeg = {
|
# Sadly having the detection stream go through go2rpc too makes the stream unreadable by frigate for some reason.
|
||||||
# hwaccel_args = "preset-vaapi";
|
# It might need to be re-encoded to work. But I am not interested in wasting the processing power if only frigate
|
||||||
# };
|
# need the detection stream anyway. So just let frigate grab the stream directly since it works.
|
||||||
detectors.coral = {
|
# (mkGo2RtcStream detectName detectUrl false)
|
||||||
type = "edgetpu";
|
];
|
||||||
device = "pci";
|
};
|
||||||
|
|
||||||
|
mkDahuaCamera = name: address:
|
||||||
|
let
|
||||||
|
# go2rtc and frigate have a slightly different syntax for inserting env vars. So the URLs are not interchangable :(
|
||||||
|
# - go2rtc: ${VAR}
|
||||||
|
# - frigate: {VAR}
|
||||||
|
primaryUrl = "rtsp://admin:\${FRIGATE_RTSP_PASSWORD}@${address}/cam/realmonitor?channel=1&subtype=0";
|
||||||
|
detectUrl = "rtsp://admin:{FRIGATE_RTSP_PASSWORD}@${address}/cam/realmonitor?channel=1&subtype=1";
|
||||||
|
in
|
||||||
|
mkCamera name primaryUrl detectUrl;
|
||||||
|
|
||||||
|
mkEsp32Camera = name: address: {
|
||||||
|
services.frigate.settings.cameras.${name} = {
|
||||||
|
ffmpeg = {
|
||||||
|
input_args = "";
|
||||||
|
inputs = [{
|
||||||
|
path = "http://${address}:8080";
|
||||||
|
roles = [ "detect" "record" ];
|
||||||
|
}];
|
||||||
|
|
||||||
|
output_args.record = "-f segment -pix_fmt yuv420p -segment_time 10 -segment_format mp4 -reset_timestamps 1 -strftime 1 -c:v libx264 -preset ultrafast -an ";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
in
|
||||||
|
lib.mkMerge [
|
||||||
|
(mkDahuaCamera "dog-cam" "192.168.10.31")
|
||||||
|
# (mkEsp32Camera "dahlia-cam" "dahlia-cam.lan")
|
||||||
|
{
|
||||||
|
services.frigate = {
|
||||||
|
enable = true;
|
||||||
|
hostname = frigateHostname;
|
||||||
|
settings = {
|
||||||
|
mqtt = {
|
||||||
|
enabled = true;
|
||||||
|
host = "localhost:1883";
|
||||||
|
};
|
||||||
|
rtmp.enabled = false;
|
||||||
|
snapshots = {
|
||||||
|
enabled = true;
|
||||||
|
bounding_box = true;
|
||||||
|
};
|
||||||
|
record = {
|
||||||
|
enabled = true;
|
||||||
|
# sync_recordings = true; # detect if recordings were deleted outside of frigate (expensive)
|
||||||
|
retain = {
|
||||||
|
days = 2; # Keep video for 2 days
|
||||||
|
mode = "motion";
|
||||||
|
};
|
||||||
|
events = {
|
||||||
|
retain = {
|
||||||
|
default = 10; # Keep video with detections for 10 days
|
||||||
|
mode = "motion";
|
||||||
|
# mode = "active_objects";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
# Make frigate aware of the go2rtc streams
|
||||||
|
go2rtc.streams = config.services.go2rtc.settings.streams;
|
||||||
|
detect.enabled = true;
|
||||||
|
objects = {
|
||||||
|
track = [ "person" "dog" ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
# Pass in env file with secrets to frigate
|
services.go2rtc = {
|
||||||
systemd.services.frigate.serviceConfig.EnvironmentFile = "/run/agenix/frigate-credentials";
|
enable = true;
|
||||||
age.secrets.frigate-credentials.file = ../../../secrets/frigate-credentials.age;
|
settings = {
|
||||||
|
rtsp.listen = ":8554";
|
||||||
|
webrtc.listen = ":8555";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
# AMD GPU for vaapi
|
# Pass in env file with secrets to frigate/go2rtc
|
||||||
systemd.services.frigate.environment.LIBVA_DRIVER_NAME = "radeonsi";
|
systemd.services.frigate.serviceConfig.EnvironmentFile = "/run/agenix/frigate-credentials";
|
||||||
|
systemd.services.go2rtc.serviceConfig.EnvironmentFile = "/run/agenix/frigate-credentials";
|
||||||
|
age.secrets.frigate-credentials.file = ../../../secrets/frigate-credentials.age;
|
||||||
|
}
|
||||||
|
{
|
||||||
|
# hardware encode/decode with amdgpu vaapi
|
||||||
|
systemd.services.frigate = {
|
||||||
|
environment.LIBVA_DRIVER_NAME = "radeonsi";
|
||||||
|
serviceConfig = {
|
||||||
|
SupplementaryGroups = [ "render" "video" ]; # for access to dev/dri/*
|
||||||
|
AmbientCapabilities = "CAP_PERFMON";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
services.frigate.settings.ffmpeg.hwaccel_args = "preset-vaapi";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
# Coral TPU for frigate
|
||||||
|
services.udev.packages = [ pkgs.libedgetpu ];
|
||||||
|
users.groups.apex = { };
|
||||||
|
systemd.services.frigate.environment.LD_LIBRARY_PATH = "${pkgs.libedgetpu}/lib";
|
||||||
|
systemd.services.frigate.serviceConfig.SupplementaryGroups = [ "apex" ];
|
||||||
|
|
||||||
# Coral TPU for frigate
|
# Coral PCIe driver
|
||||||
services.udev.packages = [ pkgs.libedgetpu ];
|
kernel.enableGasketKernelModule = true;
|
||||||
users.groups.apex = { };
|
|
||||||
systemd.services.frigate.environment.LD_LIBRARY_PATH = "${pkgs.libedgetpu}/lib";
|
services.frigate.settings.detectors.coral = {
|
||||||
systemd.services.frigate.serviceConfig.SupplementaryGroups = "apex";
|
type = "edgetpu";
|
||||||
# Coral PCIe driver
|
device = "pci";
|
||||||
kernel.enableGasketKernelModule = true;
|
};
|
||||||
}
|
}
|
||||||
|
]
|
||||||
|
Loading…
x
Reference in New Issue
Block a user