Ver código fonte

cleanup save_Clips/clips inconsistency

Blake Blackshear 4 anos atrás
pai
commit
80a5a7b129
5 arquivos alterados com 46 adições e 46 exclusões
  1. 3 3
      README.md
  2. 5 5
      frigate/app.py
  3. 20 20
      frigate/config.py
  4. 7 7
      frigate/events.py
  5. 11 11
      frigate/test/test_config.py

+ 3 - 3
README.md

@@ -33,7 +33,7 @@ Use of a [Google Coral Accelerator](https://coral.ai/products/) is optional, but
 - [Object Filters](#object-filters)
 - [Masks](#masks)
 - [Zones](#zones)
-- [Recording Clips (save_clips)](#recording-clips)
+- [Recording Clips (clips)](#recording-clips)
 - [Snapshots (snapshots)](#snapshots)
 - [24/7 Recordings (record)](#247-recordings)
 - [RTMP Streams (rtmp)](#rtmp-streams)
@@ -238,7 +238,7 @@ mqtt:
   password: password
 
 # Optional: Global configuration for saving clips
-save_clips:
+clips:
   # Optional: Maximum length of time to retain video during long events. (default: shown below)
   # NOTE: If an object is being tracked for longer than this amount of time, the cache
   #       will begin to expire and the resulting clip will be the last x seconds of the event.
@@ -399,7 +399,7 @@ cameras:
     # NOTE: This feature does not work if you have added "-vsync drop" in your input params. 
     #       This will only work for camera feeds that can be copied into the mp4 container format without
     #       encoding such as h264. It may not work for some types of streams.
-    save_clips:
+    clips:
       # Required: enables clips for the camera (default: shown below)
       enabled: False
       # Optional: Number of seconds before the event to include in the clips (default: shown below)

+ 5 - 5
frigate/app.py

@@ -45,7 +45,7 @@ class FrigateApp():
             else:
                 logger.debug(f"Skipping directory: {d}")
 
-        tmpfs_size = self.config.save_clips.tmpfs_cache_size
+        tmpfs_size = self.config.clips.tmpfs_cache_size
         if tmpfs_size:
              logger.info(f"Creating tmpfs of size {tmpfs_size}")
              rc = os.system(f"mount -t tmpfs -o size={tmpfs_size} tmpfs {CACHE_DIR}")
@@ -78,10 +78,10 @@ class FrigateApp():
     def check_config(self):
         for name, camera in self.config.cameras.items():
             assigned_roles = list(set([r for i in camera.ffmpeg.inputs for r in i.roles]))
-            if not camera.save_clips.enabled and 'clips' in assigned_roles:
-                logger.warning(f"Camera {name} has clips assigned to an input, but save_clips is not enabled.")
-            elif camera.save_clips.enabled and not 'clips' in assigned_roles:
-                logger.warning(f"Camera {name} has save_clips enabled, but clips is not assigned to an input.")
+            if not camera.clips.enabled and 'clips' in assigned_roles:
+                logger.warning(f"Camera {name} has clips assigned to an input, but clips is not enabled.")
+            elif camera.clips.enabled and not 'clips' in assigned_roles:
+                logger.warning(f"Camera {name} has clips enabled, but clips is not assigned to an input.")
 
             if not camera.record.enabled and 'record' in assigned_roles:
                 logger.warning(f"Camera {name} has record assigned to an input, but record is not enabled.")

+ 20 - 20
frigate/config.py

@@ -42,7 +42,7 @@ MQTT_SCHEMA = vol.Schema(
     }
 )
 
-SAVE_CLIPS_RETAIN_SCHEMA = vol.Schema(
+CLIPS_RETAIN_SCHEMA = vol.Schema(
     {
         vol.Required('default',default=10): int,
         'objects': {
@@ -51,11 +51,11 @@ SAVE_CLIPS_RETAIN_SCHEMA = vol.Schema(
     }
 )
 
-SAVE_CLIPS_SCHEMA = vol.Schema(
+CLIPS_SCHEMA = vol.Schema(
     {
         vol.Optional('max_seconds', default=300): int,
         'tmpfs_cache_size': str,
-        vol.Optional('retain', default={}): SAVE_CLIPS_RETAIN_SCHEMA
+        vol.Optional('retain', default={}): CLIPS_RETAIN_SCHEMA
     }
 )
 
@@ -177,12 +177,12 @@ CAMERAS_SCHEMA = vol.Schema(vol.All(
                     vol.Optional('filters', default={}): FILTER_SCHEMA
                 }
             },
-            vol.Optional('save_clips', default={}): {
+            vol.Optional('clips', default={}): {
                 vol.Optional('enabled', default=False): bool,
                 vol.Optional('pre_capture', default=5): int,
                 vol.Optional('post_capture', default=5): int,
                 'objects': [str],
-                vol.Optional('retain', default={}): SAVE_CLIPS_RETAIN_SCHEMA,
+                vol.Optional('retain', default={}): CLIPS_RETAIN_SCHEMA,
             },
             vol.Optional('record', default={}): {
                 'enabled': bool,
@@ -227,7 +227,7 @@ FRIGATE_CONFIG_SCHEMA = vol.Schema(
             vol.Optional('default', default='info'): vol.In(['info', 'debug', 'warning', 'error', 'critical']),
             vol.Optional('logs', default={}): {str: vol.In(['info', 'debug', 'warning', 'error', 'critical']) }
         },
-        vol.Optional('save_clips', default={}): SAVE_CLIPS_SCHEMA,
+        vol.Optional('clips', default={}): CLIPS_SCHEMA,
         vol.Optional('record', default={}): {
             vol.Optional('enabled', default=False): bool,
             vol.Optional('retain_days', default=30): int,
@@ -399,7 +399,7 @@ class CameraFfmpegConfig():
     def output_args(self):
         return {k: v if isinstance(v, list) else v.split(' ') for k, v in self._output_args.items()}
 
-class SaveClipsRetainConfig():
+class ClipsRetainConfig():
     def __init__(self, global_config, config):
         self._default = config.get('default', global_config.get('default'))
         self._objects = config.get('objects', global_config.get('objects', {}))
@@ -418,11 +418,11 @@ class SaveClipsRetainConfig():
             'objects': self.objects
         }
 
-class SaveClipsConfig():
+class ClipsConfig():
     def __init__(self, config):
         self._max_seconds = config['max_seconds']
         self._tmpfs_cache_size = config.get('tmpfs_cache_size', '').strip()
-        self._retain = SaveClipsRetainConfig(config['retain'], config['retain'])
+        self._retain = ClipsRetainConfig(config['retain'], config['retain'])
     
     @property
     def max_seconds(self):
@@ -589,13 +589,13 @@ class CameraMqttConfig():
             'height': self.height
         }
 
-class CameraSaveClipsConfig():
+class CameraClipsConfig():
     def __init__(self, global_config, config):
         self._enabled = config['enabled']
         self._pre_capture = config['pre_capture']
         self._post_capture = config['post_capture']
         self._objects = config.get('objects', global_config['objects']['track'])
-        self._retain = SaveClipsRetainConfig(global_config['save_clips']['retain'], config['retain'])
+        self._retain = ClipsRetainConfig(global_config['clips']['retain'], config['retain'])
     
     @property
     def enabled(self):
@@ -748,7 +748,7 @@ class CameraConfig():
         self._mask = self._create_mask(config.get('mask'))
         self._best_image_timeout = config['best_image_timeout']
         self._zones = { name: ZoneConfig(name, z) for name, z in config['zones'].items() }
-        self._save_clips = CameraSaveClipsConfig(global_config, config['save_clips'])
+        self._clips = CameraClipsConfig(global_config, config['clips'])
         self._record = RecordConfig(global_config['record'], config['record'])
         self._rtmp = CameraRtmpConfig(global_config, config['rtmp'])
         self._snapshots = CameraSnapshotsConfig(config['snapshots'])
@@ -806,7 +806,7 @@ class CameraConfig():
             ffmpeg_output_args = self.ffmpeg.output_args['rtmp'] + [
                 f"rtmp://127.0.0.1/live/{self.name}"
             ] + ffmpeg_output_args
-        if 'clips' in ffmpeg_input.roles and self.save_clips.enabled:
+        if 'clips' in ffmpeg_input.roles and self.clips.enabled:
             ffmpeg_output_args = self.ffmpeg.output_args['clips'] + [
                 f"{os.path.join(CACHE_DIR, self.name)}-%Y%m%d%H%M%S.mp4"
             ] + ffmpeg_output_args
@@ -872,8 +872,8 @@ class CameraConfig():
         return self._zones
     
     @property
-    def save_clips(self):
-        return self._save_clips
+    def clips(self):
+        return self._clips
     
     @property
     def record(self):
@@ -923,7 +923,7 @@ class CameraConfig():
             'fps': self.fps,
             'best_image_timeout': self.best_image_timeout,
             'zones': {k: z.to_dict() for k, z in self.zones.items()},
-            'save_clips': self.save_clips.to_dict(),
+            'clips': self.clips.to_dict(),
             'record': self.record.to_dict(),
             'rtmp': self.rtmp.to_dict(),
             'snapshots': self.snapshots.to_dict(),
@@ -951,7 +951,7 @@ class FrigateConfig():
         self._model = ModelConfig(config['model'])
         self._detectors = { name: DetectorConfig(d) for name, d in config['detectors'].items() }
         self._mqtt = MqttConfig(config['mqtt'])
-        self._save_clips = SaveClipsConfig(config['save_clips'])
+        self._clips = ClipsConfig(config['clips'])
         self._cameras = { name: CameraConfig(name, c, config) for name, c in config['cameras'].items() }
         self._logger = LoggerConfig(config['logger'])
 
@@ -984,7 +984,7 @@ class FrigateConfig():
             'model': self.model.to_dict(),
             'detectors': {k: d.to_dict() for k, d in self.detectors.items()},
             'mqtt': self.mqtt.to_dict(),
-            'save_clips': self.save_clips.to_dict(),
+            'clips': self.clips.to_dict(),
             'cameras': {k: c.to_dict() for k, c in self.cameras.items()},
             'logger': self.logger.to_dict()
         }
@@ -1010,8 +1010,8 @@ class FrigateConfig():
         return self._mqtt
     
     @property
-    def save_clips(self):
-        return self._save_clips
+    def clips(self):
+        return self._clips
 
     @property
     def cameras(self) -> Dict[str, CameraConfig]:

+ 7 - 7
frigate/events.py

@@ -88,7 +88,7 @@ class EventProcessor(threading.Thread):
             earliest_event = datetime.datetime.now().timestamp()
 
         # if the earliest event exceeds the max seconds, cap it
-        max_seconds = self.config.save_clips.max_seconds
+        max_seconds = self.config.clips.max_seconds
         if datetime.datetime.now().timestamp()-earliest_event > max_seconds:
             earliest_event = datetime.datetime.now().timestamp()-max_seconds
         
@@ -164,16 +164,16 @@ class EventProcessor(threading.Thread):
 
             self.refresh_cache()
 
-            save_clips_config = self.config.cameras[camera].save_clips
+            clips_config = self.config.cameras[camera].clips
 
             # if save clips is not enabled for this camera, just continue
-            if not save_clips_config.enabled:
+            if not clips_config.enabled:
                 if event_type == 'end':
                     self.event_processed_queue.put((event_data['id'], camera))
                 continue
 
             # if specific objects are listed for this camera, only save clips for them
-            if not event_data['label'] in save_clips_config.objects:
+            if not event_data['label'] in clips_config.objects:
                 if event_type == 'end':
                     self.event_processed_queue.put((event_data['id'], camera))
                 continue
@@ -183,7 +183,7 @@ class EventProcessor(threading.Thread):
 
             if event_type == 'end':
                 if len(self.cached_clips) > 0 and not event_data['false_positive']:
-                    self.create_clip(camera, event_data, save_clips_config.pre_capture, save_clips_config.post_capture)
+                    self.create_clip(camera, event_data, clips_config.pre_capture, clips_config.post_capture)
                     Event.create(
                         id=event_data['id'],
                         label=event_data['label'],
@@ -222,7 +222,7 @@ class EventCleanup(threading.Thread):
             camera_keys = list(self.config.cameras.keys())
 
             # Expire events from unlisted cameras based on the global config
-            retain_config = self.config.save_clips.retain
+            retain_config = self.config.clips.retain
             
             distinct_labels = (Event.select(Event.label)
                         .where(Event.camera.not_in(camera_keys))
@@ -256,7 +256,7 @@ class EventCleanup(threading.Thread):
 
             # Expire events from cameras based on the camera config
             for name, camera in self.config.cameras.items():
-                retain_config = camera.save_clips.retain
+                retain_config = camera.clips.retain
                 # get distinct objects in database for this camera
                 distinct_labels = (Event.select(Event.label)
                         .where(Event.camera == name)

+ 11 - 11
frigate/test/test_config.py

@@ -191,12 +191,12 @@ class TestConfig(TestCase):
         frigate_config = FrigateConfig(config=config)
         assert('-re' in frigate_config.cameras['back'].ffmpeg_cmds[0]['cmd'])
     
-    def test_inherit_save_clips_retention(self):
+    def test_inherit_clips_retention(self):
         config = {
             'mqtt': {
                 'host': 'mqtt'
             },
-            'save_clips': {
+            'clips': {
                 'retain': {
                     'default': 20,
                     'objects': {
@@ -217,14 +217,14 @@ class TestConfig(TestCase):
             }
         }
         frigate_config = FrigateConfig(config=config)
-        assert(frigate_config.cameras['back'].save_clips.retain.objects['person'] == 30)
+        assert(frigate_config.cameras['back'].clips.retain.objects['person'] == 30)
     
     def test_roles_listed_twice_throws_error(self):
         config = {
             'mqtt': {
                 'host': 'mqtt'
             },
-            'save_clips': {
+            'clips': {
                 'retain': {
                     'default': 20,
                     'objects': {
@@ -252,7 +252,7 @@ class TestConfig(TestCase):
             'mqtt': {
                 'host': 'mqtt'
             },
-            'save_clips': {
+            'clips': {
                 'retain': {
                     'default': 20,
                     'objects': {
@@ -279,12 +279,12 @@ class TestConfig(TestCase):
         }
         self.assertRaises(vol.MultipleInvalid, lambda: FrigateConfig(config=config))
     
-    def test_save_clips_should_default_to_global_objects(self):
+    def test_clips_should_default_to_global_objects(self):
         config = {
             'mqtt': {
                 'host': 'mqtt'
             },
-            'save_clips': {
+            'clips': {
                 'retain': {
                     'default': 20,
                     'objects': {
@@ -304,16 +304,16 @@ class TestConfig(TestCase):
                     },
                     'height': 1080,
                     'width': 1920,
-                    'save_clips': {
+                    'clips': {
                         'enabled': True
                     }
                 }
             }
         }
         config = FrigateConfig(config=config)
-        assert(len(config.cameras['back'].save_clips.objects) == 2)
-        assert('dog' in config.cameras['back'].save_clips.objects)
-        assert('person' in config.cameras['back'].save_clips.objects)
+        assert(len(config.cameras['back'].clips.objects) == 2)
+        assert('dog' in config.cameras['back'].clips.objects)
+        assert('person' in config.cameras['back'].clips.objects)
     
     def test_role_assigned_but_not_enabled(self):
         json_config = {