app container and config schema

This commit is contained in:
Blake Blackshear 2020-11-01 06:17:44 -06:00
parent cce82fe2a5
commit 180baeba50
8 changed files with 227 additions and 14 deletions

View File

@ -231,7 +231,7 @@ objects:
person: person:
# Optional: minimum width*height of the bounding box for the detected object (default: 0) # Optional: minimum width*height of the bounding box for the detected object (default: 0)
min_area: 5000 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 max_area: 100000
# Optional: minimum score for the object to initiate tracking (default: shown below) # Optional: minimum score for the object to initiate tracking (default: shown below)
min_score: 0.5 min_score: 0.5

View File

@ -33,7 +33,8 @@ RUN pip3 wheel --wheel-dir=/wheels \
PyYAML \ PyYAML \
matplotlib \ matplotlib \
click \ click \
tinydb peewee \
voluptuous
FROM scratch FROM scratch

View File

@ -43,7 +43,8 @@ RUN pip3 wheel --wheel-dir=/wheels \
PyYAML \ PyYAML \
matplotlib \ matplotlib \
click \ click \
tinydb peewee \
voluptuous
FROM scratch FROM scratch

0
frigate/__init__.py Normal file
View File

View 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 faulthandler; faulthandler.enable()
import os import os
import signal import signal
@ -37,6 +27,7 @@ from frigate.object_processing import TrackedObjectProcessor
from frigate.events import EventProcessor from frigate.events import EventProcessor
from frigate.util import EventsPerSecond from frigate.util import EventsPerSecond
from frigate.edgetpu import EdgeTPUProcess 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_')} FRIGATE_VARS = {k: v for k, v in os.environ.items() if k.startswith('FRIGATE_')}
@ -326,7 +317,6 @@ def main():
frigate_watchdog.start() frigate_watchdog.start()
def receiveSignal(signalNumber, frame): def receiveSignal(signalNumber, frame):
print('Received:', signalNumber)
stop_event.set() stop_event.set()
event_processor.join() event_processor.join()
object_processor.join() object_processor.join()
@ -477,6 +467,59 @@ def main():
object_processor.join() 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__': if __name__ == '__main__':
# register stop handler
init_db() init_db()
main() main()

142
frigate/config.py Normal file
View 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
View File

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