mirror of
				https://github.com/blakeblackshear/frigate.git
				synced 2025-10-27 10:52:11 +01:00 
			
		
		
		
	app container and config schema
This commit is contained in:
		
							parent
							
								
									732e91ee42
								
							
						
					
					
						commit
						a8964dcc1f
					
				@ -231,7 +231,7 @@ objects:
 | 
			
		||||
    person:
 | 
			
		||||
      # Optional: minimum width*height of the bounding box for the detected object (default: 0)
 | 
			
		||||
      min_area: 5000
 | 
			
		||||
      # Optional: maximum width*height of the bounding box for the detected object (default: max_int)
 | 
			
		||||
      # Optional: maximum width*height of the bounding box for the detected object (default: 24000000)
 | 
			
		||||
      max_area: 100000
 | 
			
		||||
      # Optional: minimum score for the object to initiate tracking (default: shown below)
 | 
			
		||||
      min_score: 0.5
 | 
			
		||||
 | 
			
		||||
@ -33,7 +33,8 @@ RUN pip3 wheel --wheel-dir=/wheels \
 | 
			
		||||
    PyYAML \
 | 
			
		||||
    matplotlib \
 | 
			
		||||
    click \
 | 
			
		||||
    tinydb
 | 
			
		||||
    peewee \
 | 
			
		||||
    voluptuous
 | 
			
		||||
 | 
			
		||||
FROM scratch
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -43,7 +43,8 @@ RUN pip3 wheel --wheel-dir=/wheels \
 | 
			
		||||
    PyYAML \
 | 
			
		||||
    matplotlib \
 | 
			
		||||
    click \
 | 
			
		||||
    tinydb
 | 
			
		||||
    peewee \
 | 
			
		||||
    voluptuous
 | 
			
		||||
 | 
			
		||||
FROM scratch
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										0
									
								
								frigate/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								frigate/__init__.py
									
									
									
									
									
										Normal file
									
								
							@ -1,13 +1,3 @@
 | 
			
		||||
# load config
 | 
			
		||||
# init database
 | 
			
		||||
# connect to mqtt
 | 
			
		||||
# start detection processes
 | 
			
		||||
# start frame processor
 | 
			
		||||
# start camera processes
 | 
			
		||||
# start event processor
 | 
			
		||||
# start capture processes
 | 
			
		||||
# start web app
 | 
			
		||||
 | 
			
		||||
import faulthandler; faulthandler.enable()
 | 
			
		||||
import os
 | 
			
		||||
import signal
 | 
			
		||||
@ -37,6 +27,7 @@ from frigate.object_processing import TrackedObjectProcessor
 | 
			
		||||
from frigate.events import EventProcessor
 | 
			
		||||
from frigate.util import EventsPerSecond
 | 
			
		||||
from frigate.edgetpu import EdgeTPUProcess
 | 
			
		||||
from frigate.config import FRIGATE_CONFIG_SCHEMA
 | 
			
		||||
 | 
			
		||||
FRIGATE_VARS = {k: v for k, v in os.environ.items() if k.startswith('FRIGATE_')}
 | 
			
		||||
 | 
			
		||||
@ -326,7 +317,6 @@ def main():
 | 
			
		||||
    frigate_watchdog.start()
 | 
			
		||||
 | 
			
		||||
    def receiveSignal(signalNumber, frame):
 | 
			
		||||
        print('Received:', signalNumber)
 | 
			
		||||
        stop_event.set()
 | 
			
		||||
        event_processor.join()
 | 
			
		||||
        object_processor.join()
 | 
			
		||||
@ -477,6 +467,59 @@ def main():
 | 
			
		||||
 | 
			
		||||
    object_processor.join()
 | 
			
		||||
 | 
			
		||||
class FrigateApp():
 | 
			
		||||
    def __init__(self, stop: mp.Event):
 | 
			
		||||
        self.stop = stop
 | 
			
		||||
        self.config = None
 | 
			
		||||
    
 | 
			
		||||
    def init_config(self):
 | 
			
		||||
        config_file = os.environ.get('CONFIG_FILE', '/config/config.yml')
 | 
			
		||||
 | 
			
		||||
        if config_file.endswith(".yml"):
 | 
			
		||||
            with open(config_file) as f:
 | 
			
		||||
                config = yaml.safe_load(f)
 | 
			
		||||
        elif config_file.endswith(".json"):
 | 
			
		||||
            with open(config_file) as f:
 | 
			
		||||
                config = json.load(f)
 | 
			
		||||
        
 | 
			
		||||
        self.config = FRIGATE_CONFIG_SCHEMA(config)
 | 
			
		||||
 | 
			
		||||
    def init_web_server(self):
 | 
			
		||||
        pass
 | 
			
		||||
 | 
			
		||||
    def init_database(self):
 | 
			
		||||
        pass
 | 
			
		||||
 | 
			
		||||
    def init_mqtt(self):
 | 
			
		||||
        pass
 | 
			
		||||
 | 
			
		||||
    def start_detectors(self):
 | 
			
		||||
        pass
 | 
			
		||||
 | 
			
		||||
    def start_detection_processor(self):
 | 
			
		||||
        pass
 | 
			
		||||
 | 
			
		||||
    def start_frame_processors(self):
 | 
			
		||||
        pass
 | 
			
		||||
 | 
			
		||||
    def start_camera_capture_processes(self):
 | 
			
		||||
        pass
 | 
			
		||||
 | 
			
		||||
    def start_watchdog(self):
 | 
			
		||||
        pass
 | 
			
		||||
 | 
			
		||||
    def start(self):
 | 
			
		||||
        self.init_config()
 | 
			
		||||
        self.init_web_server()
 | 
			
		||||
        self.init_database()
 | 
			
		||||
        self.init_mqtt()
 | 
			
		||||
        self.start_detectors()
 | 
			
		||||
        self.start_detection_processor()
 | 
			
		||||
        self.start_frame_processors()
 | 
			
		||||
        self.start_camera_capture_processes()
 | 
			
		||||
        self.start_watchdog()
 | 
			
		||||
 | 
			
		||||
if __name__ == '__main__':
 | 
			
		||||
    # register stop handler
 | 
			
		||||
    init_db()
 | 
			
		||||
    main()
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										142
									
								
								frigate/config.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										142
									
								
								frigate/config.py
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,142 @@
 | 
			
		||||
import voluptuous as vol
 | 
			
		||||
 | 
			
		||||
DETECTORS_SCHEMA = vol.Schema(
 | 
			
		||||
    {
 | 
			
		||||
        vol.Required(str): {
 | 
			
		||||
            vol.Required('type', default='edgetpu'): vol.In(['cpu', 'edgetpu']), 
 | 
			
		||||
            vol.Optional('device', default='usb'): str
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
DEFAULT_DETECTORS = {
 | 
			
		||||
    'coral': {
 | 
			
		||||
        'type': 'edgetpu',
 | 
			
		||||
        'device': 'usb'
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
MQTT_SCHEMA = vol.Schema(
 | 
			
		||||
    {
 | 
			
		||||
        vol.Required('host'): str,
 | 
			
		||||
        vol.Optional('port', default=1883): int,
 | 
			
		||||
        vol.Optional('topic_prefix', default='frigate'): str,
 | 
			
		||||
        vol.Optional('client_id', default='frigate'): str,
 | 
			
		||||
        'user': str,
 | 
			
		||||
        'password': str
 | 
			
		||||
    }
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
SAVE_CLIPS_SCHEMA = vol.Schema(
 | 
			
		||||
    {
 | 
			
		||||
        vol.Optional('max_seconds', default=300): int,
 | 
			
		||||
        vol.Optional('clips_dir', default='/clips'): str,
 | 
			
		||||
        vol.Optional('cache_dir', default='/cache'): str
 | 
			
		||||
    }
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
FFMPEG_GLOBAL_ARGS_DEFAULT = ['-hide_banner','-loglevel','panic']
 | 
			
		||||
FFMPEG_INPUT_ARGS_DEFAULT = ['-avoid_negative_ts', 'make_zero',
 | 
			
		||||
    '-fflags', 'nobuffer',
 | 
			
		||||
    '-flags', 'low_delay',
 | 
			
		||||
    '-strict', 'experimental',
 | 
			
		||||
    '-fflags', '+genpts+discardcorrupt',
 | 
			
		||||
    '-rtsp_transport', 'tcp',
 | 
			
		||||
    '-stimeout', '5000000',
 | 
			
		||||
    '-use_wallclock_as_timestamps', '1']
 | 
			
		||||
FFMPEG_OUTPUT_ARGS_DEFAULT = ['-f', 'rawvideo',
 | 
			
		||||
    '-pix_fmt', 'yuv420p']
 | 
			
		||||
 | 
			
		||||
GLOBAL_FFMPEG_SCHEMA = vol.Schema(
 | 
			
		||||
    { 
 | 
			
		||||
        vol.Optional('global_args', default=FFMPEG_GLOBAL_ARGS_DEFAULT):  [str],
 | 
			
		||||
        vol.Optional('hwaccel_args', default=[]): [str],
 | 
			
		||||
        vol.Optional('input_args', default=FFMPEG_INPUT_ARGS_DEFAULT): [str],
 | 
			
		||||
        vol.Optional('output_args', default=FFMPEG_OUTPUT_ARGS_DEFAULT): [str]
 | 
			
		||||
    }
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
FILTER_SCHEMA = vol.Schema(
 | 
			
		||||
    { 
 | 
			
		||||
        str: {
 | 
			
		||||
                vol.Optional('min_area', default=0): int,
 | 
			
		||||
                vol.Optional('max_area', default=24000000): int,
 | 
			
		||||
                vol.Optional('threshold', default=0.85): float
 | 
			
		||||
            }
 | 
			
		||||
    }
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
OBJECTS_SCHEMA = vol.Schema(
 | 
			
		||||
    {
 | 
			
		||||
        vol.Optional('track', default=['person']): [str],
 | 
			
		||||
        'filters': FILTER_SCHEMA.extend({vol.Optional('min_score', default=0.5): float})
 | 
			
		||||
    }
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
DEFAULT_CAMERA_MQTT = {
 | 
			
		||||
    'crop_to_region': True
 | 
			
		||||
}
 | 
			
		||||
DEFAULT_CAMERA_SAVE_CLIPS = {
 | 
			
		||||
    'enabled': False
 | 
			
		||||
}
 | 
			
		||||
DEFAULT_CAMERA_SNAPSHOTS = {
 | 
			
		||||
    'show_timestamp': True,
 | 
			
		||||
    'draw_zones': False,
 | 
			
		||||
    'draw_bounding_boxes': True
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
CAMERA_FFMPEG_SCHEMA = vol.Schema(
 | 
			
		||||
    { 
 | 
			
		||||
        vol.Required('input'): str, 
 | 
			
		||||
        'global_args':  [str],
 | 
			
		||||
        'hwaccel_args': [str],
 | 
			
		||||
        'input_args': [str],
 | 
			
		||||
        'output_args': [str]
 | 
			
		||||
    }
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
CAMERAS_SCHEMA = vol.Schema(
 | 
			
		||||
    {
 | 
			
		||||
        str: {
 | 
			
		||||
            vol.Required('ffmpeg'): CAMERA_FFMPEG_SCHEMA,
 | 
			
		||||
            'height': int,
 | 
			
		||||
            'width': int,
 | 
			
		||||
            'fps': int,
 | 
			
		||||
            'mask': str,
 | 
			
		||||
            vol.Optional('best_image_timeout', default=60): int,
 | 
			
		||||
            vol.Optional('mqtt', default=DEFAULT_CAMERA_MQTT): {
 | 
			
		||||
                vol.Optional('crop_to_region', default=True): bool,
 | 
			
		||||
                'snapshot_height': int
 | 
			
		||||
            },
 | 
			
		||||
            vol.Optional('zones', default={}):  {
 | 
			
		||||
                str: {
 | 
			
		||||
                    vol.Required('coordinates'): vol.Any(str, [str]),
 | 
			
		||||
                    'filters': FILTER_SCHEMA
 | 
			
		||||
                }
 | 
			
		||||
             },
 | 
			
		||||
             vol.Optional('save_clips', default=DEFAULT_CAMERA_SAVE_CLIPS): {
 | 
			
		||||
                vol.Optional('enabled', default=False): bool,
 | 
			
		||||
                vol.Optional('pre_capture', default=30): int,
 | 
			
		||||
                'objects': [str],
 | 
			
		||||
             },
 | 
			
		||||
             vol.Optional('snapshots', default=DEFAULT_CAMERA_SNAPSHOTS): {
 | 
			
		||||
                vol.Optional('show_timestamp', default=True): bool,
 | 
			
		||||
                vol.Optional('draw_zones', default=False): bool,
 | 
			
		||||
                vol.Optional('draw_bounding_boxes', default=True): bool
 | 
			
		||||
             },
 | 
			
		||||
             'objects': OBJECTS_SCHEMA
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
FRIGATE_CONFIG_SCHEMA = vol.Schema(
 | 
			
		||||
    {
 | 
			
		||||
        vol.Optional('web_port', default=5000): int,
 | 
			
		||||
        vol.Optional('detectors', default=DEFAULT_DETECTORS): DETECTORS_SCHEMA,
 | 
			
		||||
        'mqtt': MQTT_SCHEMA,
 | 
			
		||||
        vol.Optional('save_clips', default={}): SAVE_CLIPS_SCHEMA,
 | 
			
		||||
        vol.Optional('ffmpeg', default={}): GLOBAL_FFMPEG_SCHEMA,
 | 
			
		||||
        vol.Optional('objects', default={}): OBJECTS_SCHEMA,
 | 
			
		||||
        vol.Required('cameras', default={}): CAMERAS_SCHEMA
 | 
			
		||||
    }
 | 
			
		||||
)
 | 
			
		||||
							
								
								
									
										0
									
								
								frigate/test/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								frigate/test/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										26
									
								
								frigate/test/test_config.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								frigate/test/test_config.py
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,26 @@
 | 
			
		||||
import json
 | 
			
		||||
from unittest import TestCase, main
 | 
			
		||||
import voluptuous as vol
 | 
			
		||||
from frigate.config import FRIGATE_CONFIG_SCHEMA
 | 
			
		||||
 | 
			
		||||
class TestConfig(TestCase):
 | 
			
		||||
    def test_empty(self):
 | 
			
		||||
        FRIGATE_CONFIG_SCHEMA({})
 | 
			
		||||
 | 
			
		||||
    def test_minimal(self):
 | 
			
		||||
        minimal = {
 | 
			
		||||
            'mqtt': {
 | 
			
		||||
                'host': 'mqtt'
 | 
			
		||||
            },
 | 
			
		||||
            'cameras': {
 | 
			
		||||
                'back': {
 | 
			
		||||
                    'ffmpeg': {
 | 
			
		||||
                        'input': 'rtsp://10.0.0.1:554/video'
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        FRIGATE_CONFIG_SCHEMA(minimal)
 | 
			
		||||
 | 
			
		||||
if __name__ == '__main__':
 | 
			
		||||
    main(verbosity=2)
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user