Skip to content

Commit

Permalink
cleanup save_Clips/clips inconsistency
Browse files Browse the repository at this point in the history
  • Loading branch information
blakeblackshear committed Jan 27, 2021
1 parent 9dc97d4 commit 80a5a7b
Show file tree
Hide file tree
Showing 5 changed files with 46 additions and 46 deletions.
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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)
Expand Down
10 changes: 5 additions & 5 deletions frigate/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ def ensure_dirs(self):
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}")
Expand Down Expand Up @@ -78,10 +78,10 @@ def init_config(self):
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.")
Expand Down
40 changes: 20 additions & 20 deletions frigate/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@
}
)

SAVE_CLIPS_RETAIN_SCHEMA = vol.Schema(
CLIPS_RETAIN_SCHEMA = vol.Schema(
{
vol.Required('default',default=10): int,
'objects': {
Expand All @@ -51,11 +51,11 @@
}
)

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
}
)

Expand Down Expand Up @@ -177,12 +177,12 @@ def ensure_zones_and_cameras_have_different_names(cameras):
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,
Expand Down Expand Up @@ -227,7 +227,7 @@ def ensure_zones_and_cameras_have_different_names(cameras):
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,
Expand Down Expand Up @@ -399,7 +399,7 @@ def inputs(self):
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', {}))
Expand All @@ -418,11 +418,11 @@ def to_dict(self):
'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):
Expand Down Expand Up @@ -589,13 +589,13 @@ def to_dict(self):
'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):
Expand Down Expand Up @@ -748,7 +748,7 @@ def __init__(self, name, config, global_config):
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'])
Expand Down Expand Up @@ -806,7 +806,7 @@ def _get_ffmpeg_cmd(self, ffmpeg_input):
ffmpeg_output_args = self.ffmpeg.output_args['rtmp'] + [
f"rtmp:https://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
Expand Down Expand Up @@ -872,8 +872,8 @@ def zones(self)-> Dict[str, ZoneConfig]:
return self._zones

@property
def save_clips(self):
return self._save_clips
def clips(self):
return self._clips

@property
def record(self):
Expand Down Expand Up @@ -923,7 +923,7 @@ def to_dict(self):
'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(),
Expand Down Expand Up @@ -951,7 +951,7 @@ def __init__(self, config_file=None, config=None):
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'])

Expand Down Expand Up @@ -984,7 +984,7 @@ def to_dict(self):
'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()
}
Expand All @@ -1010,8 +1010,8 @@ def mqtt(self):
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]:
Expand Down
14 changes: 7 additions & 7 deletions frigate/events.py
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ def refresh_cache(self):
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

Expand Down Expand Up @@ -164,16 +164,16 @@ def run(self):

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
Expand All @@ -183,7 +183,7 @@ def run(self):

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'],
Expand Down Expand Up @@ -222,7 +222,7 @@ def run(self):
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))
Expand Down Expand Up @@ -256,7 +256,7 @@ def run(self):

# 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)
Expand Down
22 changes: 11 additions & 11 deletions frigate/test/test_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -191,12 +191,12 @@ def test_ffmpeg_params(self):
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': {
Expand All @@ -217,14 +217,14 @@ def test_inherit_save_clips_retention(self):
}
}
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': {
Expand Down Expand Up @@ -252,7 +252,7 @@ def test_zone_matching_camera_name_throws_error(self):
'mqtt': {
'host': 'mqtt'
},
'save_clips': {
'clips': {
'retain': {
'default': 20,
'objects': {
Expand All @@ -279,12 +279,12 @@ def test_zone_matching_camera_name_throws_error(self):
}
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': {
Expand All @@ -304,16 +304,16 @@ def test_save_clips_should_default_to_global_objects(self):
},
'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 = {
Expand Down

0 comments on commit 80a5a7b

Please sign in to comment.