From 7d697c0015d973570d475393df3e3a10d7c155e8 Mon Sep 17 00:00:00 2001 From: Kyle Niewiada Date: Sat, 30 Nov 2019 10:23:41 -0500 Subject: [PATCH] Make streaming more friendly to additional protocols --- config/config.yml | 126 +++++++++++++++++++++++++++++----------------- frigate/video.py | 64 +++++++++-------------- 2 files changed, 104 insertions(+), 86 deletions(-) diff --git a/config/config.yml b/config/config.yml index 6afa0e888..6943e7f54 100644 --- a/config/config.yml +++ b/config/config.yml @@ -7,20 +7,90 @@ mqtt: # password: password # Optional -- Uncomment for use cameras: - back: + backyard: rtsp: + # The camera URL protocol is determined by the key (`rtsp`) above unless overridden by `urlformat` user: viewer host: 10.0.10.10 port: 554 # values that begin with a "$" will be replaced with environment variable password: $RTSP_PASSWORD path: /cam/realmonitor?channel=1&subtype=2 - - ################ - ## Optional URL format. Specifying this will override the default RTSP URL format. - ## Some cameras support the RTMP protocol which may give better performance. - ################ - # urlformat: rtmp://{host}:{port}{path}&user={user}&password={password} + regions: + - size: 350 + x_offset: 0 + y_offset: 300 + min_person_area: 5000 + threshold: 0.5 + - size: 400 + x_offset: 350 + y_offset: 250 + min_person_area: 2000 + threshold: 0.5 + - size: 400 + x_offset: 750 + y_offset: 250 + min_person_area: 2000 + threshold: 0.5 + front_yard: + rtmp: + user: viewer + host: 10.0.10.11 + port: 1935 + # values that begin with a "$" will be replaced with environment variable + password: $RTMP_PASSWORD + path: /cam/realmonitor?channel=1&subtype=2 + ffmpeg_input_args: + - -avoid_negative_ts + - make_zero + - -fflags + - nobuffer + - -flags + - low_delay + - -strict + - experimental + - -fflags + - +genpts+discardcorrupt + - -vsync + - drop + - -use_wallclock_as_timestamps + - '1' + regions: + - size: 350 + x_offset: 0 + y_offset: 300 + min_person_area: 5000 + threshold: 0.5 + garage: + rtmp: + user: viewer + host: 10.0.10.12 + port: 1935 + # values that begin with a "$" will be replaced with environment variable + password: $CUSTOM_PASSWORD + path: /cam/realmonitor?channel=1&subtype=2 + urlformat: rtmp://{host}:{port}{path}&user={user}&password={password} + ffmpeg_input_args: + - -avoid_negative_ts + - make_zero + - -fflags + - nobuffer + - -flags + - low_delay + - -strict + - experimental + - -fflags + - +genpts+discardcorrupt + - -vsync + - drop + - -use_wallclock_as_timestamps + - '1' + regions: + - size: 350 + x_offset: 0 + y_offset: 300 + min_person_area: 5000 + threshold: 0.5 ################ ## Optional mask. Must be the same dimensions as your video feed. @@ -37,7 +107,7 @@ cameras: # custom framerates. A value of 1 tells frigate to look at every frame, 2 every 2nd frame, # 3 every 3rd frame, etc. ################ - take_frame: 1 + # take_frame: 1 ################ # Optional hardware acceleration parameters for ffmpeg. If your hardware supports it, it can @@ -70,42 +140,8 @@ cameras: ################ # ffmpeg_output_args: [] - ################ - ## RTMP supports all RTSP arguments - ## The RTMP config uses different ffmpeg arguments to make it compatible with frigate. + ## Optional URL format. Specifying this will override the default protocol URL format. + ## Some cameras support the RTMP protocol which may give better performance. ################ - - rtmp: - user: viewer - host: 10.0.10.11 - port: 1935 - # values that begin with a "$" will be replaced with environment variable - password: $RTSP_PASSWORD - path: /cam/realmonitor?channel=1&subtype=2 - - rtmp: - user: viewer - host: 10.0.10.12 - port: 1935 - # values that begin with a "$" will be replaced with environment variable - password: $RTSP_PASSWORD - path: /cam/realmonitor?channel=1&subtype=2 - urlformat: rtmp://{host}:{port}{path}&user={user}&password={password} - - regions: - - size: 350 - x_offset: 0 - y_offset: 300 - min_person_area: 5000 - threshold: 0.5 - - size: 400 - x_offset: 350 - y_offset: 250 - min_person_area: 2000 - threshold: 0.5 - - size: 400 - x_offset: 750 - y_offset: 250 - min_person_area: 2000 - threshold: 0.5 + # urlformat: rtmp://{host}:{port}{path}&user={user}&password={password} diff --git a/frigate/video.py b/frigate/video.py index 44ec42910..d98dc8cde 100644 --- a/frigate/video.py +++ b/frigate/video.py @@ -55,19 +55,13 @@ def get_frame_shape(stream_url): video.release() return frame_shape -def get_rtsp_url(rtsp_config): - if (rtsp_config['password'].startswith('$')): - rtsp_config['password'] = os.getenv(rtsp_config['password'][1:]) - urlformat = rtsp_config.get('urlformat', 'rtsp://{user}:{password}@{host}:{port}{path}') - return urlformat.format(host=rtsp_config['host'], port=rtsp_config['port'], - path=rtsp_config['path'], user=rtsp_config['user'], password=rtsp_config['password']) - -def get_rtmp_url(rtmp_config): - if (rtmp_config['password'].startswith('$')): - rtmp_config['password'] = os.getenv(rtmp_config['password'][1:]) - urlformat = rtmp_config.get('urlformat', 'rtmp://{user}:{password}@{host}:{port}{path}') - return urlformat.format(host=rtmp_config['host'], port=rtmp_config['port'], - path=rtmp_config['path'], user=rtmp_config['user'], password=rtmp_config['password']) +def get_stream_url(stream_protocol, stream_config): + if (stream_config['password'].startswith('$')): + stream_config['password'] = os.getenv(stream_config['password'][1:]) + urlformat = stream_config.get('urlformat', '{urlProtocol}://{user}:{password}@{host}:{port}{path}') + return urlformat.format(host=stream_config['host'], port=stream_config['port'], + path=stream_config['path'], user=stream_config['user'], + password=stream_config['password'], urlProtocol=stream_protocol) class CameraWatchdog(threading.Thread): def __init__(self, camera): @@ -126,35 +120,23 @@ class Camera: self.config = config self.detected_objects = [] self.recent_frames = {} - if ('rtsp' in config): - print('Found rtsp camera config.') - self.stream_url = get_rtsp_url(self.config['rtsp']) - self.ffmpeg_input_args = self.config.get('ffmpeg_input_args', [ - '-avoid_negative_ts', 'make_zero', - '-fflags', 'nobuffer', - '-flags', 'low_delay', - '-strict', 'experimental', - '-fflags', '+genpts+discardcorrupt', - '-vsync', 'drop', - '-rtsp_transport', 'tcp', - '-stimeout', '5000000', - '-use_wallclock_as_timestamps', '1' - ]) - elif ('rtmp' in config): - print('Found rtmp camera config.') - self.stream_url = get_rtmp_url(self.config['rtmp']) - self.ffmpeg_input_args = self.config.get('ffmpeg_input_args', [ - '-avoid_negative_ts', 'make_zero', - '-fflags', 'nobuffer', - '-flags', 'low_delay', - '-strict', 'experimental', - '-fflags', '+genpts+discardcorrupt', - '-vsync', 'drop', - '-use_wallclock_as_timestamps', '1' - ]) - else: - print('No valid camera config found.') + self.stream_protocol = list(self.config.keys())[0] + self.stream_config = list(self.config.values())[0] + print('Found {} camera config.'.format(self.stream_protocol)) + self.stream_url = get_stream_url(self.stream_protocol, self.stream_config) + + self.ffmpeg_input_args = self.config.get('ffmpeg_input_args', [ + '-avoid_negative_ts', 'make_zero', + '-fflags', 'nobuffer', + '-flags', 'low_delay', + '-strict', 'experimental', + '-fflags', '+genpts+discardcorrupt', + '-vsync', 'drop', + '-rtsp_transport', 'tcp', + '-stimeout', '5000000', + '-use_wallclock_as_timestamps', '1' + ]) self.take_frame = self.config.get('take_frame', 1) self.ffmpeg_log_level = self.config.get('ffmpeg_log_level', 'panic') self.ffmpeg_hwaccel_args = self.config.get('ffmpeg_hwaccel_args', [])