about summary refs log tree commit diff
diff options
context:
space:
mode:
authorfleaz <mail@felixbreidenstein.de>2024-02-01 23:09:56 +0100
committerfleaz <mail@felixbreidenstein.de>2024-02-06 22:54:22 +0100
commit250078ceba19d576437e46f8e1c1d19acf5dfa78 (patch)
tree792f40aae66a290e7f1b8c0d2e2beedca25b16f2
parentb6eaf6269aa88a51cd6124add36afe99aa72af97 (diff)
downloadnixlib-250078ceba19d576437e46f8e1c1d19acf5dfa78.tar
nixlib-250078ceba19d576437e46f8e1c1d19acf5dfa78.tar.gz
nixlib-250078ceba19d576437e46f8e1c1d19acf5dfa78.tar.bz2
nixlib-250078ceba19d576437e46f8e1c1d19acf5dfa78.tar.lz
nixlib-250078ceba19d576437e46f8e1c1d19acf5dfa78.tar.xz
nixlib-250078ceba19d576437e46f8e1c1d19acf5dfa78.tar.zst
nixlib-250078ceba19d576437e46f8e1c1d19acf5dfa78.zip
frigate: 0.12.1 -> 0.13.1
Changelog:
https://github.com/blakeblackshear/frigate/releases/tag/v0.13.0
https://github.com/blakeblackshear/frigate/releases/tag/v0.13.1

Co-Authored-By: Martin Weinelt <hexa@darmstadt.ccc.de>
-rw-r--r--nixos/modules/services/video/frigate.nix135
-rw-r--r--nixos/tests/frigate.nix9
-rw-r--r--pkgs/applications/video/frigate/default.nix57
-rw-r--r--pkgs/applications/video/frigate/web.nix8
4 files changed, 136 insertions, 73 deletions
diff --git a/nixos/modules/services/video/frigate.nix b/nixos/modules/services/video/frigate.nix
index b7945282ba09..0c923a20c40c 100644
--- a/nixos/modules/services/video/frigate.nix
+++ b/nixos/modules/services/video/frigate.nix
@@ -17,7 +17,7 @@ let
 
   cfg = config.services.frigate;
 
-  format = pkgs.formats.yaml {};
+  format = pkgs.formats.yaml { };
 
   filteredConfig = lib.converge (lib.filterAttrsRecursive (_: v: ! lib.elem v [ null ])) cfg.settings;
 
@@ -112,7 +112,7 @@ in
           };
         };
       };
-      default = {};
+      default = { };
       description = mdDoc ''
         Frigate configuration as a nix attribute set.
 
@@ -125,7 +125,7 @@ in
 
   config = mkIf cfg.enable {
     services.nginx = {
-      enable =true;
+      enable = true;
       additionalModules = with pkgs.nginxModules; [
         secure-token
         rtmp
@@ -133,31 +133,64 @@ in
       ];
       recommendedProxySettings = mkDefault true;
       recommendedGzipSettings = mkDefault true;
+      mapHashBucketSize = mkDefault 128;
       upstreams = {
         frigate-api.servers = {
-          "127.0.0.1:5001" = {};
+          "127.0.0.1:5001" = { };
         };
         frigate-mqtt-ws.servers = {
-          "127.0.0.1:5002" = {};
+          "127.0.0.1:5002" = { };
         };
         frigate-jsmpeg.servers = {
-          "127.0.0.1:8082" = {};
+          "127.0.0.1:8082" = { };
         };
         frigate-go2rtc.servers = {
-          "127.0.0.1:1984" = {};
+          "127.0.0.1:1984" = { };
         };
       };
-      # Based on https://github.com/blakeblackshear/frigate/blob/v0.12.0/docker/rootfs/usr/local/nginx/conf/nginx.conf
+      proxyCachePath."frigate" = {
+        enable = true;
+        keysZoneSize = "10m";
+        keysZoneName = "frigate_api_cache";
+        maxSize = "10m";
+        inactive = "1m";
+        levels = "1:2";
+      };
+      # Based on https://github.com/blakeblackshear/frigate/blob/v0.13.1/docker/main/rootfs/usr/local/nginx/conf/nginx.conf
       virtualHosts."${cfg.hostname}" = {
         locations = {
           "/api/" = {
             proxyPass = "http://frigate-api/";
+            extraConfig = ''
+              proxy_cache frigate_api_cache;
+              proxy_cache_lock on;
+              proxy_cache_use_stale updating;
+              proxy_cache_valid 200 5s;
+              proxy_cache_bypass $http_x_cache_bypass;
+              proxy_no_cache $should_not_cache;
+              add_header X-Cache-Status $upstream_cache_status;
+
+              location /api/vod/ {
+                  proxy_pass http://frigate-api/vod/;
+                  proxy_cache off;
+              }
+
+              location /api/stats {
+                  access_log off;
+                  rewrite ^/api/(.*)$ $1 break;
+                  proxy_pass http://frigate-api;
+              }
+
+              location /api/version {
+                  access_log off;
+                  rewrite ^/api/(.*)$ $1 break;
+                  proxy_pass http://frigate-api;
+              }
+            '';
           };
           "~* /api/.*\.(jpg|jpeg|png)$" = {
             proxyPass = "http://frigate-api";
             extraConfig = ''
-              add_header 'Access-Control-Allow-Origin' '*';
-              add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, OPTIONS';
               rewrite ^/api/(.*)$ $1 break;
             '';
           };
@@ -169,10 +202,6 @@ in
               secure_token $args;
               secure_token_types application/vnd.apple.mpegurl;
 
-              add_header Access-Control-Allow-Headers '*';
-              add_header Access-Control-Expose-Headers 'Server,range,Content-Length,Content-Range';
-              add_header Access-Control-Allow-Methods 'GET, HEAD, OPTIONS';
-              add_header Access-Control-Allow-Origin '*';
               add_header Cache-Control "no-store";
               expires off;
             '';
@@ -192,27 +221,64 @@ in
             proxyPass = "http://frigate-go2rtc/";
             proxyWebsockets = true;
           };
+          # frigate lovelace card uses this path
+          "/live/mse/api/ws" = {
+            proxyPass = "http://frigate-go2rtc/api/ws";
+            proxyWebsockets = true;
+            extraConfig = ''
+              limit_except GET {
+                  deny  all;
+              }
+            '';
+          };
           "/live/webrtc/" = {
             proxyPass = "http://frigate-go2rtc/";
             proxyWebsockets = true;
           };
+          "/live/webrtc/api/ws" = {
+            proxyPass = "http://frigate-go2rtc/api/ws";
+            proxyWebsockets = true;
+            extraConfig = ''
+              limit_except GET {
+                  deny  all;
+              }
+            '';
+          };
+          # pass through go2rtc player
+          "/live/webrtc/webrtc.html" = {
+            proxyPass = "http://frigate-go2rtc/webrtc.html";
+            proxyWebsockets = true;
+            extraConfig = ''
+              limit_except GET {
+                  deny  all;
+              }
+            '';
+          };
+          "/api/go2rtc/api" = {
+            proxyPass = "http://frigate-go2rtc/api";
+            proxyWebsockets = true;
+            extraConfig = ''
+              limit_except GET {
+                  deny  all;
+              }
+            '';
+          };
+          # integrationn uses this to add webrtc candidate
+          "/api/go2rtc/webrtc" = {
+            proxyPass = "http://frigate-go2rtc/api/webrtc";
+            proxyWebsockets = true;
+            extraConfig = ''
+              limit_except GET {
+                  deny  all;
+              }
+            '';
+          };
           "/cache/" = {
             alias = "/var/cache/frigate/";
           };
           "/clips/" = {
             root = "/var/lib/frigate";
             extraConfig = ''
-              add_header 'Access-Control-Allow-Origin' "$http_origin" always;
-              add_header 'Access-Control-Allow-Credentials' 'true';
-              add_header 'Access-Control-Expose-Headers' 'Content-Length';
-              if ($request_method = 'OPTIONS') {
-                  add_header 'Access-Control-Allow-Origin' "$http_origin";
-                  add_header 'Access-Control-Max-Age' 1728000;
-                  add_header 'Content-Type' 'text/plain charset=UTF-8';
-                  add_header 'Content-Length' 0;
-                  return 204;
-              }
-
               types {
                   video/mp4 mp4;
                   image/jpeg jpg;
@@ -224,17 +290,6 @@ in
           "/recordings/" = {
             root = "/var/lib/frigate";
             extraConfig = ''
-              add_header 'Access-Control-Allow-Origin' "$http_origin" always;
-              add_header 'Access-Control-Allow-Credentials' 'true';
-              add_header 'Access-Control-Expose-Headers' 'Content-Length';
-              if ($request_method = 'OPTIONS') {
-                  add_header 'Access-Control-Allow-Origin' "$http_origin";
-                  add_header 'Access-Control-Max-Age' 1728000;
-                  add_header 'Content-Type' 'text/plain charset=UTF-8';
-                  add_header 'Content-Length' 0;
-                  return 204;
-              }
-
               types {
                   video/mp4 mp4;
               }
@@ -315,6 +370,12 @@ in
             }
         }
       '';
+      appendHttpConfig = ''
+        map $sent_http_content_type $should_not_cache {
+          'application/json' 0;
+          default 1;
+        }
+      '';
     };
 
     systemd.services.nginx.serviceConfig.SupplementaryGroups = [
@@ -325,7 +386,7 @@ in
       isSystemUser = true;
       group = "frigate";
     };
-    users.groups.frigate = {};
+    users.groups.frigate = { };
 
     systemd.services.frigate = {
       after = [
diff --git a/nixos/tests/frigate.nix b/nixos/tests/frigate.nix
index 836fe0d063f8..03bd2b89611d 100644
--- a/nixos/tests/frigate.nix
+++ b/nixos/tests/frigate.nix
@@ -41,6 +41,7 @@ import ./make-test-python.nix ({ pkgs, lib, ...} :
         serviceConfig = {
           DynamicUser = true;
           ExecStart = "${lib.getBin pkgs.ffmpeg-headless}/bin/ffmpeg -re -f lavfi -i smptebars=size=800x600:rate=10 -f mpegts -listen 1 http://0.0.0.0:8080";
+          Restart = "always";
         };
       };
     };
@@ -51,10 +52,14 @@ import ./make-test-python.nix ({ pkgs, lib, ...} :
 
     machine.wait_for_unit("frigate.service")
 
+    # Frigate startup
     machine.wait_for_open_port(5001)
 
-    machine.succeed("curl http://localhost:5001")
+    # nginx startup
+    machine.wait_for_open_port(80)
 
-    machine.wait_for_file("/var/cache/frigate/test-*.mp4")
+    machine.succeed("curl http://localhost")
+
+    machine.wait_for_file("/var/cache/frigate/test@*.mp4")
   '';
 })
diff --git a/pkgs/applications/video/frigate/default.nix b/pkgs/applications/video/frigate/default.nix
index 81798df47f27..6a93401d985d 100644
--- a/pkgs/applications/video/frigate/default.nix
+++ b/pkgs/applications/video/frigate/default.nix
@@ -3,20 +3,19 @@
 , python3
 , fetchFromGitHub
 , fetchurl
-, fetchpatch
 , frigate
 , nixosTests
 }:
 
 let
-  version = "0.12.1";
+  version = "0.13.1";
 
   src = fetchFromGitHub {
     #name = "frigate-${version}-source";
     owner = "blakeblackshear";
     repo = "frigate";
     rev = "refs/tags/v${version}";
-    hash = "sha256-kNvYsHoObi6b9KT/LYhTGK4uJ/uAHnYhyoQkiXIA/s8=";
+    hash = "sha256-2J7DhnYDX9ubbsk0qhji/vIKDouy9IqQztzbdPj2kxo=";
   };
 
   frigate-web = callPackage ./web.nix {
@@ -35,7 +34,7 @@ let
   };
 
   # Tensorflow Lite models
-  # https://github.com/blakeblackshear/frigate/blob/v0.12.0/Dockerfile#L88-L91
+  # https://github.com/blakeblackshear/frigate/blob/v0.13.0/docker/main/Dockerfile#L96-L97
   tflite_cpu_model = fetchurl {
     url = "https://github.com/google-coral/test_data/raw/release-frogfish/ssdlite_mobiledet_coco_qat_postprocess.tflite";
     hash = "sha256-kLszpjTgQZFMwYGapd+ZgY5sOWxNLblSwP16nP/Eck8=";
@@ -46,7 +45,7 @@ let
   };
 
   # OpenVino models
-  # https://github.com/blakeblackshear/frigate/blob/v0.12.0/Dockerfile#L92-L95
+  # https://github.com/blakeblackshear/frigate/blob/v0.13.0/docker/main/Dockerfile#L101
   openvino_model = fetchurl {
     url = "https://github.com/openvinotoolkit/open_model_zoo/raw/master/data/dataset_classes/coco_91cl_bkgr.txt";
     hash = "sha256-5Cj2vEiWR8Z9d2xBmVoLZuNRv4UOuxHSGZQWTJorXUQ=";
@@ -59,14 +58,6 @@ python.pkgs.buildPythonApplication rec {
 
   inherit src;
 
-  patches = [
-    (fetchpatch {
-      # numpy 1.24 compat
-      url = "https://github.com/blakeblackshear/frigate/commit/cb73d0cd392990448811c7212bc5f09be411fc69.patch";
-      hash = "sha256-Spt7eRosmTN8zyJ2uVme5HPVy2TKgBtvbQ6tp6PaNac=";
-    })
-  ];
-
   postPatch = ''
     echo 'VERSION = "${version}"' > frigate/version.py
 
@@ -75,58 +66,59 @@ python.pkgs.buildPythonApplication rec {
 
     substituteInPlace frigate/const.py \
       --replace "/media/frigate" "/var/lib/frigate" \
-      --replace "/tmp/cache" "/var/cache/frigate/"
+      --replace "/tmp/cache" "/var/cache/frigate" \
+      --replace "/config" "/var/lib/frigate" \
+      --replace "{CONFIG_DIR}/model_cache" "/var/cache/frigate/model_cache"
 
     substituteInPlace frigate/http.py \
-      --replace "/opt/frigate" "${placeholder "out"}/${python.sitePackages}" \
-      --replace "/tmp/cache/" "/var/cache/frigate/"
+      --replace "/opt/frigate" "${placeholder "out"}/${python.sitePackages}"
 
     substituteInPlace frigate/output.py \
       --replace "/opt/frigate" "${placeholder "out"}/${python.sitePackages}"
 
-    substituteInPlace frigate/record.py \
-      --replace "/tmp/cache" "/var/cache/frigate"
-
     substituteInPlace frigate/detectors/detector_config.py \
       --replace "/labelmap.txt" "${placeholder "out"}/share/frigate/labelmap.txt"
 
-    substituteInPlace frigate/detectors/plugins/edgetpu_tfl.py \
+    substituteInPlace frigate/config.py \
+      --replace "/cpu_model.tflite" "${tflite_cpu_model}" \
       --replace "/edgetpu_model.tflite" "${tflite_edgetpu_model}"
 
-    substituteInPlace frigate/detectors/plugins/cpu_tfl.py \
-      --replace "/cpu_model.tflite" "${tflite_cpu_model}"
-
-    substituteInPlace frigate/ffmpeg_presets.py --replace \
-       '"-timeout" if os.path.exists(BTBN_PATH) else "-stimeout"' \
-       '"-timeout"'
+    substituteInPlace frigate/test/test_config.py \
+      --replace "(MODEL_CACHE_DIR" "('/build/model_cache'" \
+      --replace "/config/model_cache" "/build/model_cache"
   '';
 
   dontBuild = true;
 
   propagatedBuildInputs = with python.pkgs; [
-    # requirements.txt
+    # docker/main/requirements.txt
     scikit-build
-    # requirements-wheel.txt
+    # docker/main/requirements-wheel.txt
     click
     flask
     imutils
     matplotlib
+    norfair
     numpy
+    onvif-zeep
     opencv4
     openvino
     paho-mqtt
     peewee
     peewee-migrate
     psutil
+    py3nvml
     pydantic
+    pytz
     pyyaml
     requests
+    ruamel-yaml
     scipy
     setproctitle
     tensorflow
     tzlocal
+    unidecode
     ws4py
-    zeroconf
   ];
 
   installPhase = ''
@@ -144,10 +136,15 @@ python.pkgs.buildPythonApplication rec {
     runHook postInstall
   '';
 
-  checkInputs = with python.pkgs; [
+  nativeCheckInputs = with python.pkgs; [
     pytestCheckHook
   ];
 
+  disabledTests = [
+    # Test needs network access
+    "test_plus_labelmap"
+  ];
+
   passthru = {
     web = frigate-web;
     inherit python;
diff --git a/pkgs/applications/video/frigate/web.nix b/pkgs/applications/video/frigate/web.nix
index 01a3e70b436f..be530c5c3637 100644
--- a/pkgs/applications/video/frigate/web.nix
+++ b/pkgs/applications/video/frigate/web.nix
@@ -11,14 +11,14 @@ buildNpmPackage {
 
   postPatch = ''
     substituteInPlace package.json \
-      --replace "--base=/BASE_PATH/" ""
+      --replace-fail "--base=/BASE_PATH/" ""
 
     substituteInPlace src/routes/Storage.jsx \
-      --replace "/media/frigate" "/var/lib/frigate" \
-      --replace "/tmp/cache" "/var/cache/frigate"
+      --replace-fail "/media/frigate" "/var/lib/frigate" \
+      --replace-fail "/tmp/cache" "/var/cache/frigate"
   '';
 
-  npmDepsHash = "sha256-fvRxpQjSEzd2CnoEOVgQcB6MJJ4dcjN8bOaacHjCdwU=";
+  npmDepsHash = "sha256-+36quezGArqIM9dM+UihwcIgmE3EVmJQThuicLgDW4A=";
 
   installPhase = ''
     cp -rv dist/ $out