mirror of
				https://github.com/blakeblackshear/frigate.git
				synced 2025-10-27 10:52:11 +01:00 
			
		
		
		
	Remove rtmp (#8941)
* remove rtmp from python * remove rtmp from nginx * remove rtmp from docs * fix test for missing role
This commit is contained in:
		
							parent
							
								
									696434b36d
								
							
						
					
					
						commit
						d2d1278a4d
					
				| @ -5,7 +5,6 @@ set -euxo pipefail | |||||||
| NGINX_VERSION="1.25.3" | NGINX_VERSION="1.25.3" | ||||||
| VOD_MODULE_VERSION="1.31" | VOD_MODULE_VERSION="1.31" | ||||||
| SECURE_TOKEN_MODULE_VERSION="1.5" | SECURE_TOKEN_MODULE_VERSION="1.5" | ||||||
| RTMP_MODULE_VERSION="1.2.2" |  | ||||||
| 
 | 
 | ||||||
| cp /etc/apt/sources.list /etc/apt/sources.list.d/sources-src.list | cp /etc/apt/sources.list /etc/apt/sources.list.d/sources-src.list | ||||||
| sed -i 's|deb http|deb-src http|g' /etc/apt/sources.list.d/sources-src.list | sed -i 's|deb http|deb-src http|g' /etc/apt/sources.list.d/sources-src.list | ||||||
| @ -49,10 +48,6 @@ mkdir /tmp/nginx-secure-token-module | |||||||
| wget https://github.com/kaltura/nginx-secure-token-module/archive/refs/tags/${SECURE_TOKEN_MODULE_VERSION}.tar.gz | wget https://github.com/kaltura/nginx-secure-token-module/archive/refs/tags/${SECURE_TOKEN_MODULE_VERSION}.tar.gz | ||||||
| tar -zxf ${SECURE_TOKEN_MODULE_VERSION}.tar.gz -C /tmp/nginx-secure-token-module --strip-components=1 | tar -zxf ${SECURE_TOKEN_MODULE_VERSION}.tar.gz -C /tmp/nginx-secure-token-module --strip-components=1 | ||||||
| rm ${SECURE_TOKEN_MODULE_VERSION}.tar.gz | rm ${SECURE_TOKEN_MODULE_VERSION}.tar.gz | ||||||
| mkdir /tmp/nginx-rtmp-module |  | ||||||
| wget -nv https://github.com/arut/nginx-rtmp-module/archive/refs/tags/v${RTMP_MODULE_VERSION}.tar.gz |  | ||||||
| tar -zxf v${RTMP_MODULE_VERSION}.tar.gz -C /tmp/nginx-rtmp-module --strip-components=1 |  | ||||||
| rm v${RTMP_MODULE_VERSION}.tar.gz |  | ||||||
| 
 | 
 | ||||||
| cd /tmp/nginx | cd /tmp/nginx | ||||||
| 
 | 
 | ||||||
| @ -63,7 +58,6 @@ cd /tmp/nginx | |||||||
|     --with-threads \ |     --with-threads \ | ||||||
|     --add-module=../nginx-vod-module \ |     --add-module=../nginx-vod-module \ | ||||||
|     --add-module=../nginx-secure-token-module \ |     --add-module=../nginx-secure-token-module \ | ||||||
|     --add-module=../nginx-rtmp-module \ |  | ||||||
|     --with-cc-opt="-O3 -Wno-error=implicit-fallthrough" |     --with-cc-opt="-O3 -Wno-error=implicit-fallthrough" | ||||||
| 
 | 
 | ||||||
| make CC="ccache gcc" -j$(nproc) && make install | make CC="ccache gcc" -j$(nproc) && make install | ||||||
|  | |||||||
| @ -275,18 +275,3 @@ http { | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 |  | ||||||
| rtmp { |  | ||||||
|     server { |  | ||||||
|         listen 1935; |  | ||||||
|         chunk_size 4096; |  | ||||||
|         allow publish 127.0.0.1; |  | ||||||
|         deny publish all; |  | ||||||
|         allow play all; |  | ||||||
|         application live { |  | ||||||
|             live on; |  | ||||||
|             record off; |  | ||||||
|             meta copy; |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| } |  | ||||||
|  | |||||||
| @ -69,16 +69,12 @@ cameras: | |||||||
|     ffmpeg: |     ffmpeg: | ||||||
|       output_args: |       output_args: | ||||||
|         record: -f segment -segment_time 10 -segment_format mp4 -reset_timestamps 1 -strftime 1 -c:v copy -tag:v hvc1 -bsf:v hevc_mp4toannexb -c:a aac |         record: -f segment -segment_time 10 -segment_format mp4 -reset_timestamps 1 -strftime 1 -c:v copy -tag:v hvc1 -bsf:v hevc_mp4toannexb -c:a aac | ||||||
|         rtmp: -c:v copy -c:a aac -f flv |  | ||||||
| 
 | 
 | ||||||
|       inputs: |       inputs: | ||||||
|         - path: rtsp://user:password@camera-ip:554/H264/ch1/main/av_stream # <----- Update for your camera |         - path: rtsp://user:password@camera-ip:554/H264/ch1/main/av_stream # <----- Update for your camera | ||||||
|           roles: |           roles: | ||||||
|             - detect |             - detect | ||||||
|             - record |             - record | ||||||
|             - rtmp |  | ||||||
|     rtmp: |  | ||||||
|       enabled: False # <-- RTMP should be disabled if your stream is not H264 |  | ||||||
|     detect: |     detect: | ||||||
|       width: # <- optional, by default Frigate tries to automatically detect resolution |       width: # <- optional, by default Frigate tries to automatically detect resolution | ||||||
|       height: # <- optional, by default Frigate tries to automatically detect resolution |       height: # <- optional, by default Frigate tries to automatically detect resolution | ||||||
| @ -181,13 +177,12 @@ go2rtc: | |||||||
| 
 | 
 | ||||||
| [See the go2rtc docs for more information](https://github.com/AlexxIT/go2rtc/tree/v1.8.4#source-rtsp) | [See the go2rtc docs for more information](https://github.com/AlexxIT/go2rtc/tree/v1.8.4#source-rtsp) | ||||||
| 
 | 
 | ||||||
| In the Unifi 2.0 update Unifi Protect Cameras had a change in audio sample rate which causes issues for ffmpeg. The input rate needs to be set for record and rtmp if used directly with unifi protect. | In the Unifi 2.0 update Unifi Protect Cameras had a change in audio sample rate which causes issues for ffmpeg. The input rate needs to be set for record if used directly with unifi protect. | ||||||
| 
 | 
 | ||||||
| ```yaml | ```yaml | ||||||
| ffmpeg: | ffmpeg: | ||||||
|   output_args: |   output_args: | ||||||
|     record: preset-record-ubiquiti |     record: preset-record-ubiquiti | ||||||
|     rtmp: preset-rtmp-ubiquiti # recommend using go2rtc instead |  | ||||||
| ``` | ``` | ||||||
| 
 | 
 | ||||||
| ### TP-Link VIGI Cameras | ### TP-Link VIGI Cameras | ||||||
|  | |||||||
| @ -16,7 +16,6 @@ Each role can only be assigned to one input per camera. The options for roles ar | |||||||
| | `detect` | Main feed for object detection. [docs](object_detectors.md)                              | | | `detect` | Main feed for object detection. [docs](object_detectors.md)                              | | ||||||
| | `record` | Saves segments of the video feed based on configuration settings. [docs](record.md)      | | | `record` | Saves segments of the video feed based on configuration settings. [docs](record.md)      | | ||||||
| | `audio`  | Feed for audio based detection. [docs](audio_detectors.md)                               | | | `audio`  | Feed for audio based detection. [docs](audio_detectors.md)                               | | ||||||
| | `rtmp`   | Deprecated: Broadcast as an RTMP feed for other services to consume. [docs](restream.md) | |  | ||||||
| 
 | 
 | ||||||
| ```yaml | ```yaml | ||||||
| mqtt: | mqtt: | ||||||
| @ -29,7 +28,6 @@ cameras: | |||||||
|         - path: rtsp://viewer:{FRIGATE_RTSP_PASSWORD}@10.0.10.10:554/cam/realmonitor?channel=1&subtype=2 |         - path: rtsp://viewer:{FRIGATE_RTSP_PASSWORD}@10.0.10.10:554/cam/realmonitor?channel=1&subtype=2 | ||||||
|           roles: |           roles: | ||||||
|             - detect |             - detect | ||||||
|             - rtmp # <- deprecated, recommend using restream instead |  | ||||||
|         - path: rtsp://viewer:{FRIGATE_RTSP_PASSWORD}@10.0.10.10:554/live |         - path: rtsp://viewer:{FRIGATE_RTSP_PASSWORD}@10.0.10.10:554/live | ||||||
|           roles: |           roles: | ||||||
|             - record |             - record | ||||||
|  | |||||||
| @ -162,8 +162,6 @@ ffmpeg: | |||||||
|     detect: -threads 2 -f rawvideo -pix_fmt yuv420p |     detect: -threads 2 -f rawvideo -pix_fmt yuv420p | ||||||
|     # Optional: output args for record streams (default: shown below) |     # Optional: output args for record streams (default: shown below) | ||||||
|     record: preset-record-generic |     record: preset-record-generic | ||||||
|     # Optional: output args for rtmp streams (default: shown below) |  | ||||||
|     rtmp: preset-rtmp-generic |  | ||||||
|   # Optional: Time in seconds to wait before ffmpeg retries connecting to the camera. (default: shown below) |   # Optional: Time in seconds to wait before ffmpeg retries connecting to the camera. (default: shown below) | ||||||
|   # If set too low, frigate will retry a connection to the camera's stream too frequently, using up the limited streams some cameras can allow at once |   # If set too low, frigate will retry a connection to the camera's stream too frequently, using up the limited streams some cameras can allow at once | ||||||
|   # If set too high, then if a ffmpeg crash or camera stream timeout occurs, you could potentially lose up to a maximum of retry_interval second(s) of footage |   # If set too high, then if a ffmpeg crash or camera stream timeout occurs, you could potentially lose up to a maximum of retry_interval second(s) of footage | ||||||
| @ -386,13 +384,6 @@ snapshots: | |||||||
|   # Optional: quality of the encoded jpeg, 0-100 (default: shown below) |   # Optional: quality of the encoded jpeg, 0-100 (default: shown below) | ||||||
|   quality: 70 |   quality: 70 | ||||||
| 
 | 
 | ||||||
| # Optional: RTMP configuration |  | ||||||
| # NOTE: RTMP is deprecated in favor of restream |  | ||||||
| # NOTE: Can be overridden at the camera level |  | ||||||
| rtmp: |  | ||||||
|   # Optional: Enable the RTMP stream (default: False) |  | ||||||
|   enabled: False |  | ||||||
| 
 |  | ||||||
| # Optional: Restream configuration | # Optional: Restream configuration | ||||||
| # Uses https://github.com/AlexxIT/go2rtc (v1.8.3) | # Uses https://github.com/AlexxIT/go2rtc (v1.8.3) | ||||||
| go2rtc: | go2rtc: | ||||||
| @ -449,14 +440,13 @@ cameras: | |||||||
|         # Required: the path to the stream |         # Required: the path to the stream | ||||||
|         # NOTE: path may include environment variables or docker secrets, which must begin with 'FRIGATE_' and be referenced in {} |         # NOTE: path may include environment variables or docker secrets, which must begin with 'FRIGATE_' and be referenced in {} | ||||||
|         - path: rtsp://viewer:{FRIGATE_RTSP_PASSWORD}@10.0.10.10:554/cam/realmonitor?channel=1&subtype=2 |         - path: rtsp://viewer:{FRIGATE_RTSP_PASSWORD}@10.0.10.10:554/cam/realmonitor?channel=1&subtype=2 | ||||||
|           # Required: list of roles for this stream. valid values are: audio,detect,record,rtmp |           # Required: list of roles for this stream. valid values are: audio,detect,record | ||||||
|           # NOTICE: In addition to assigning the audio, record, and rtmp roles, |           # NOTICE: In addition to assigning the audio, detect, and record roles | ||||||
|           # they must also be enabled in the camera config. |           # they must also be enabled in the camera config. | ||||||
|           roles: |           roles: | ||||||
|             - audio |             - audio | ||||||
|             - detect |             - detect | ||||||
|             - record |             - record | ||||||
|             - rtmp |  | ||||||
|           # Optional: stream specific global args (default: inherit) |           # Optional: stream specific global args (default: inherit) | ||||||
|           # global_args: |           # global_args: | ||||||
|           # Optional: stream specific hwaccel args (default: inherit) |           # Optional: stream specific hwaccel args (default: inherit) | ||||||
|  | |||||||
| @ -38,10 +38,6 @@ go2rtc: | |||||||
| 
 | 
 | ||||||
| **NOTE:** This does not apply to localhost requests, there is no need to provide credentials when using the restream as a source for frigate cameras. | **NOTE:** This does not apply to localhost requests, there is no need to provide credentials when using the restream as a source for frigate cameras. | ||||||
| 
 | 
 | ||||||
| ## RTMP (Deprecated) |  | ||||||
| 
 |  | ||||||
| In previous Frigate versions RTMP was used for re-streaming. RTMP has disadvantages however including being incompatible with H.265, high bitrates, and certain audio codecs. RTMP is deprecated and it is recommended use the built in go2rtc config for restreaming. |  | ||||||
| 
 |  | ||||||
| ## Reduce Connections To Camera | ## Reduce Connections To Camera | ||||||
| 
 | 
 | ||||||
| Some cameras only support one active connection or you may just want to have a single connection open to the camera. The RTSP restream allows this to be possible. | Some cameras only support one active connection or you may just want to have a single connection open to the camera. The RTSP restream allows this to be possible. | ||||||
|  | |||||||
| @ -9,7 +9,7 @@ Use of the bundled go2rtc is optional. You can still configure FFmpeg to connect | |||||||
| 
 | 
 | ||||||
| - WebRTC or MSE for live viewing with higher resolutions and frame rates than the jsmpeg stream which is limited to the detect stream | - WebRTC or MSE for live viewing with higher resolutions and frame rates than the jsmpeg stream which is limited to the detect stream | ||||||
| - Live stream support for cameras in Home Assistant Integration | - Live stream support for cameras in Home Assistant Integration | ||||||
| - RTSP (instead of RTMP) relay for use with other consumers to reduce the number of connections to your camera streams | - RTSP relay for use with other consumers to reduce the number of connections to your camera streams | ||||||
| 
 | 
 | ||||||
| # Setup a go2rtc stream | # Setup a go2rtc stream | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -124,10 +124,6 @@ https://HA_URL/api/frigate/notifications/<event-id>/clip.mp4 | |||||||
| 
 | 
 | ||||||
| <a name="streams"></a> | <a name="streams"></a> | ||||||
| 
 | 
 | ||||||
| ## RTMP stream |  | ||||||
| 
 |  | ||||||
| RTMP is deprecated and it is recommended to switch to use RTSP restreams. |  | ||||||
| 
 |  | ||||||
| ## RTSP stream | ## RTSP stream | ||||||
| 
 | 
 | ||||||
| In order for the live streams to function they need to be accessible on the RTSP | In order for the live streams to function they need to be accessible on the RTSP | ||||||
|  | |||||||
| @ -30,7 +30,6 @@ from frigate.ffmpeg_presets import ( | |||||||
|     parse_preset_hardware_acceleration_scale, |     parse_preset_hardware_acceleration_scale, | ||||||
|     parse_preset_input, |     parse_preset_input, | ||||||
|     parse_preset_output_record, |     parse_preset_output_record, | ||||||
|     parse_preset_output_rtmp, |  | ||||||
| ) | ) | ||||||
| from frigate.plus import PlusApi | from frigate.plus import PlusApi | ||||||
| from frigate.util.builtin import ( | from frigate.util.builtin import ( | ||||||
| @ -582,7 +581,6 @@ DETECT_FFMPEG_OUTPUT_ARGS_DEFAULT = [ | |||||||
|     "-pix_fmt", |     "-pix_fmt", | ||||||
|     "yuv420p", |     "yuv420p", | ||||||
| ] | ] | ||||||
| RTMP_FFMPEG_OUTPUT_ARGS_DEFAULT = "preset-rtmp-generic" |  | ||||||
| RECORD_FFMPEG_OUTPUT_ARGS_DEFAULT = "preset-record-generic" | RECORD_FFMPEG_OUTPUT_ARGS_DEFAULT = "preset-record-generic" | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| @ -595,10 +593,6 @@ class FfmpegOutputArgsConfig(FrigateBaseModel): | |||||||
|         default=RECORD_FFMPEG_OUTPUT_ARGS_DEFAULT, |         default=RECORD_FFMPEG_OUTPUT_ARGS_DEFAULT, | ||||||
|         title="Record role FFmpeg output arguments.", |         title="Record role FFmpeg output arguments.", | ||||||
|     ) |     ) | ||||||
|     rtmp: Union[str, List[str]] = Field( |  | ||||||
|         default=RTMP_FFMPEG_OUTPUT_ARGS_DEFAULT, |  | ||||||
|         title="RTMP role FFmpeg output arguments.", |  | ||||||
|     ) |  | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| class FfmpegConfig(FrigateBaseModel): | class FfmpegConfig(FrigateBaseModel): | ||||||
| @ -624,7 +618,6 @@ class FfmpegConfig(FrigateBaseModel): | |||||||
| class CameraRoleEnum(str, Enum): | class CameraRoleEnum(str, Enum): | ||||||
|     audio = "audio" |     audio = "audio" | ||||||
|     record = "record" |     record = "record" | ||||||
|     rtmp = "rtmp" |  | ||||||
|     detect = "detect" |     detect = "detect" | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| @ -733,10 +726,6 @@ class CameraMqttConfig(FrigateBaseModel): | |||||||
|     ) |     ) | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| class RtmpConfig(FrigateBaseModel): |  | ||||||
|     enabled: bool = Field(default=False, title="RTMP restreaming enabled.") |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| class CameraLiveConfig(FrigateBaseModel): | class CameraLiveConfig(FrigateBaseModel): | ||||||
|     stream_name: str = Field(default="", title="Name of restream to use as live view.") |     stream_name: str = Field(default="", title="Name of restream to use as live view.") | ||||||
|     height: int = Field(default=720, title="Live camera view height") |     height: int = Field(default=720, title="Live camera view height") | ||||||
| @ -772,9 +761,6 @@ class CameraConfig(FrigateBaseModel): | |||||||
|     record: RecordConfig = Field( |     record: RecordConfig = Field( | ||||||
|         default_factory=RecordConfig, title="Record configuration." |         default_factory=RecordConfig, title="Record configuration." | ||||||
|     ) |     ) | ||||||
|     rtmp: RtmpConfig = Field( |  | ||||||
|         default_factory=RtmpConfig, title="RTMP restreaming configuration." |  | ||||||
|     ) |  | ||||||
|     live: CameraLiveConfig = Field( |     live: CameraLiveConfig = Field( | ||||||
|         default_factory=CameraLiveConfig, title="Live playback settings." |         default_factory=CameraLiveConfig, title="Live playback settings." | ||||||
|     ) |     ) | ||||||
| @ -819,7 +805,6 @@ class CameraConfig(FrigateBaseModel): | |||||||
| 
 | 
 | ||||||
|         # add roles to the input if there is only one |         # add roles to the input if there is only one | ||||||
|         if len(config["ffmpeg"]["inputs"]) == 1: |         if len(config["ffmpeg"]["inputs"]) == 1: | ||||||
|             has_rtmp = "rtmp" in config["ffmpeg"]["inputs"][0].get("roles", []) |  | ||||||
|             has_audio = "audio" in config["ffmpeg"]["inputs"][0].get("roles", []) |             has_audio = "audio" in config["ffmpeg"]["inputs"][0].get("roles", []) | ||||||
| 
 | 
 | ||||||
|             config["ffmpeg"]["inputs"][0]["roles"] = [ |             config["ffmpeg"]["inputs"][0]["roles"] = [ | ||||||
| @ -830,9 +815,6 @@ class CameraConfig(FrigateBaseModel): | |||||||
|             if has_audio: |             if has_audio: | ||||||
|                 config["ffmpeg"]["inputs"][0]["roles"].append("audio") |                 config["ffmpeg"]["inputs"][0]["roles"].append("audio") | ||||||
| 
 | 
 | ||||||
|             if has_rtmp: |  | ||||||
|                 config["ffmpeg"]["inputs"][0]["roles"].append("rtmp") |  | ||||||
| 
 |  | ||||||
|         super().__init__(**config) |         super().__init__(**config) | ||||||
| 
 | 
 | ||||||
|     @property |     @property | ||||||
| @ -872,15 +854,7 @@ class CameraConfig(FrigateBaseModel): | |||||||
|             ) |             ) | ||||||
| 
 | 
 | ||||||
|             ffmpeg_output_args = scale_detect_args + ffmpeg_output_args + ["pipe:"] |             ffmpeg_output_args = scale_detect_args + ffmpeg_output_args + ["pipe:"] | ||||||
|         if "rtmp" in ffmpeg_input.roles and self.rtmp.enabled: |  | ||||||
|             rtmp_args = get_ffmpeg_arg_list( |  | ||||||
|                 parse_preset_output_rtmp(self.ffmpeg.output_args.rtmp) |  | ||||||
|                 or self.ffmpeg.output_args.rtmp |  | ||||||
|             ) |  | ||||||
| 
 | 
 | ||||||
|             ffmpeg_output_args = ( |  | ||||||
|                 rtmp_args + [f"rtmp://127.0.0.1/live/{self.name}"] + ffmpeg_output_args |  | ||||||
|             ) |  | ||||||
|         if "record" in ffmpeg_input.roles and self.record.enabled: |         if "record" in ffmpeg_input.roles and self.record.enabled: | ||||||
|             record_args = get_ffmpeg_arg_list( |             record_args = get_ffmpeg_arg_list( | ||||||
|                 parse_preset_output_record(self.ffmpeg.output_args.record) |                 parse_preset_output_record(self.ffmpeg.output_args.record) | ||||||
| @ -967,11 +941,6 @@ def verify_config_roles(camera_config: CameraConfig) -> None: | |||||||
|             f"Camera {camera_config.name} has record enabled, but record is not assigned to an input." |             f"Camera {camera_config.name} has record enabled, but record is not assigned to an input." | ||||||
|         ) |         ) | ||||||
| 
 | 
 | ||||||
|     if camera_config.rtmp.enabled and "rtmp" not in assigned_roles: |  | ||||||
|         raise ValueError( |  | ||||||
|             f"Camera {camera_config.name} has rtmp enabled, but rtmp is not assigned to an input." |  | ||||||
|         ) |  | ||||||
| 
 |  | ||||||
|     if camera_config.audio.enabled and "audio" not in assigned_roles: |     if camera_config.audio.enabled and "audio" not in assigned_roles: | ||||||
|         raise ValueError( |         raise ValueError( | ||||||
|             f"Camera {camera_config.name} has audio events enabled, but audio is not assigned to an input." |             f"Camera {camera_config.name} has audio events enabled, but audio is not assigned to an input." | ||||||
| @ -1082,9 +1051,6 @@ class FrigateConfig(FrigateBaseModel): | |||||||
|     snapshots: SnapshotsConfig = Field( |     snapshots: SnapshotsConfig = Field( | ||||||
|         default_factory=SnapshotsConfig, title="Global snapshots configuration." |         default_factory=SnapshotsConfig, title="Global snapshots configuration." | ||||||
|     ) |     ) | ||||||
|     rtmp: RtmpConfig = Field( |  | ||||||
|         default_factory=RtmpConfig, title="Global RTMP restreaming configuration." |  | ||||||
|     ) |  | ||||||
|     live: CameraLiveConfig = Field( |     live: CameraLiveConfig = Field( | ||||||
|         default_factory=CameraLiveConfig, title="Live playback settings." |         default_factory=CameraLiveConfig, title="Live playback settings." | ||||||
|     ) |     ) | ||||||
| @ -1138,7 +1104,6 @@ class FrigateConfig(FrigateBaseModel): | |||||||
|                 "birdseye": ..., |                 "birdseye": ..., | ||||||
|                 "record": ..., |                 "record": ..., | ||||||
|                 "snapshots": ..., |                 "snapshots": ..., | ||||||
|                 "rtmp": ..., |  | ||||||
|                 "live": ..., |                 "live": ..., | ||||||
|                 "objects": ..., |                 "objects": ..., | ||||||
|                 "motion": ..., |                 "motion": ..., | ||||||
| @ -1272,11 +1237,6 @@ class FrigateConfig(FrigateBaseModel): | |||||||
|             verify_zone_objects_are_tracked(camera_config) |             verify_zone_objects_are_tracked(camera_config) | ||||||
|             verify_autotrack_zones(camera_config) |             verify_autotrack_zones(camera_config) | ||||||
| 
 | 
 | ||||||
|             if camera_config.rtmp.enabled: |  | ||||||
|                 logger.warning( |  | ||||||
|                     "RTMP restream is deprecated in favor of the restream role, recommend disabling RTMP." |  | ||||||
|                 ) |  | ||||||
| 
 |  | ||||||
|             # generate the ffmpeg commands |             # generate the ffmpeg commands | ||||||
|             camera_config.create_ffmpeg_cmds() |             camera_config.create_ffmpeg_cmds() | ||||||
|             config.cameras[name] = camera_config |             config.cameras[name] = camera_config | ||||||
|  | |||||||
| @ -446,28 +446,3 @@ def parse_preset_output_record(arg: Any) -> list[str]: | |||||||
|         return None |         return None | ||||||
| 
 | 
 | ||||||
|     return PRESETS_RECORD_OUTPUT.get(arg, None) |     return PRESETS_RECORD_OUTPUT.get(arg, None) | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| PRESETS_RTMP_OUTPUT = { |  | ||||||
|     "preset-rtmp-generic": ["-c", "copy", "-f", "flv"], |  | ||||||
|     "preset-rtmp-mjpeg": ["-c:v", "libx264", "-an", "-f", "flv"], |  | ||||||
|     "preset-rtmp-jpeg": ["-c:v", "libx264", "-an", "-f", "flv"], |  | ||||||
|     "preset-rtmp-ubiquiti": [ |  | ||||||
|         "-c:v", |  | ||||||
|         "copy", |  | ||||||
|         "-f", |  | ||||||
|         "flv", |  | ||||||
|         "-ar", |  | ||||||
|         "44100", |  | ||||||
|         "-c:a", |  | ||||||
|         "aac", |  | ||||||
|     ], |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| def parse_preset_output_rtmp(arg: Any) -> list[str]: |  | ||||||
|     """Return the correct preset if in preset format otherwise return None.""" |  | ||||||
|     if not isinstance(arg, str): |  | ||||||
|         return None |  | ||||||
| 
 |  | ||||||
|     return PRESETS_RTMP_OUTPUT.get(arg, None) |  | ||||||
|  | |||||||
| @ -653,7 +653,7 @@ class TestConfig(unittest.TestCase): | |||||||
|                         "inputs": [ |                         "inputs": [ | ||||||
|                             { |                             { | ||||||
|                                 "path": "rtsp://10.0.0.1:554/video", |                                 "path": "rtsp://10.0.0.1:554/video", | ||||||
|                                 "roles": ["detect", "rtmp"], |                                 "roles": ["detect"], | ||||||
|                             }, |                             }, | ||||||
|                             {"path": "rtsp://10.0.0.1:554/record", "roles": ["record"]}, |                             {"path": "rtsp://10.0.0.1:554/record", "roles": ["record"]}, | ||||||
|                         ] |                         ] | ||||||
| @ -930,7 +930,7 @@ class TestConfig(unittest.TestCase): | |||||||
|                         "width": 1920, |                         "width": 1920, | ||||||
|                         "fps": 5, |                         "fps": 5, | ||||||
|                     }, |                     }, | ||||||
|                     "rtmp": {"enabled": True}, |                     "audio": {"enabled": True}, | ||||||
|                 } |                 } | ||||||
|             }, |             }, | ||||||
|         } |         } | ||||||
| @ -1167,122 +1167,6 @@ class TestConfig(unittest.TestCase): | |||||||
|         assert runtime_config.cameras["back"].snapshots.height == 150 |         assert runtime_config.cameras["back"].snapshots.height == 150 | ||||||
|         assert runtime_config.cameras["back"].snapshots.enabled |         assert runtime_config.cameras["back"].snapshots.enabled | ||||||
| 
 | 
 | ||||||
|     def test_global_rtmp_disabled(self): |  | ||||||
|         config = { |  | ||||||
|             "mqtt": {"host": "mqtt"}, |  | ||||||
|             "cameras": { |  | ||||||
|                 "back": { |  | ||||||
|                     "ffmpeg": { |  | ||||||
|                         "inputs": [ |  | ||||||
|                             { |  | ||||||
|                                 "path": "rtsp://10.0.0.1:554/video", |  | ||||||
|                                 "roles": ["detect"], |  | ||||||
|                             }, |  | ||||||
|                         ] |  | ||||||
|                     }, |  | ||||||
|                     "detect": { |  | ||||||
|                         "height": 1080, |  | ||||||
|                         "width": 1920, |  | ||||||
|                         "fps": 5, |  | ||||||
|                     }, |  | ||||||
|                 } |  | ||||||
|             }, |  | ||||||
|         } |  | ||||||
|         frigate_config = FrigateConfig(**config) |  | ||||||
|         assert config == frigate_config.dict(exclude_unset=True) |  | ||||||
| 
 |  | ||||||
|         runtime_config = frigate_config.runtime_config() |  | ||||||
|         assert not runtime_config.cameras["back"].rtmp.enabled |  | ||||||
| 
 |  | ||||||
|     def test_default_not_rtmp(self): |  | ||||||
|         config = { |  | ||||||
|             "mqtt": {"host": "mqtt"}, |  | ||||||
|             "cameras": { |  | ||||||
|                 "back": { |  | ||||||
|                     "ffmpeg": { |  | ||||||
|                         "inputs": [ |  | ||||||
|                             { |  | ||||||
|                                 "path": "rtsp://10.0.0.1:554/video", |  | ||||||
|                                 "roles": ["detect"], |  | ||||||
|                             }, |  | ||||||
|                         ] |  | ||||||
|                     }, |  | ||||||
|                     "detect": { |  | ||||||
|                         "height": 1080, |  | ||||||
|                         "width": 1920, |  | ||||||
|                         "fps": 5, |  | ||||||
|                     }, |  | ||||||
|                 } |  | ||||||
|             }, |  | ||||||
|         } |  | ||||||
|         frigate_config = FrigateConfig(**config) |  | ||||||
|         assert config == frigate_config.dict(exclude_unset=True) |  | ||||||
| 
 |  | ||||||
|         runtime_config = frigate_config.runtime_config() |  | ||||||
|         assert not runtime_config.cameras["back"].rtmp.enabled |  | ||||||
| 
 |  | ||||||
|     def test_global_rtmp_merge(self): |  | ||||||
|         config = { |  | ||||||
|             "mqtt": {"host": "mqtt"}, |  | ||||||
|             "rtmp": {"enabled": False}, |  | ||||||
|             "cameras": { |  | ||||||
|                 "back": { |  | ||||||
|                     "ffmpeg": { |  | ||||||
|                         "inputs": [ |  | ||||||
|                             { |  | ||||||
|                                 "path": "rtsp://10.0.0.1:554/video", |  | ||||||
|                                 "roles": ["detect", "rtmp"], |  | ||||||
|                             }, |  | ||||||
|                         ] |  | ||||||
|                     }, |  | ||||||
|                     "detect": { |  | ||||||
|                         "height": 1080, |  | ||||||
|                         "width": 1920, |  | ||||||
|                         "fps": 5, |  | ||||||
|                     }, |  | ||||||
|                     "rtmp": { |  | ||||||
|                         "enabled": True, |  | ||||||
|                     }, |  | ||||||
|                 } |  | ||||||
|             }, |  | ||||||
|         } |  | ||||||
|         frigate_config = FrigateConfig(**config) |  | ||||||
|         assert config == frigate_config.dict(exclude_unset=True) |  | ||||||
| 
 |  | ||||||
|         runtime_config = frigate_config.runtime_config() |  | ||||||
|         assert runtime_config.cameras["back"].rtmp.enabled |  | ||||||
| 
 |  | ||||||
|     def test_global_rtmp_default(self): |  | ||||||
|         config = { |  | ||||||
|             "mqtt": {"host": "mqtt"}, |  | ||||||
|             "cameras": { |  | ||||||
|                 "back": { |  | ||||||
|                     "ffmpeg": { |  | ||||||
|                         "inputs": [ |  | ||||||
|                             { |  | ||||||
|                                 "path": "rtsp://10.0.0.1:554/video", |  | ||||||
|                                 "roles": ["detect"], |  | ||||||
|                             }, |  | ||||||
|                             { |  | ||||||
|                                 "path": "rtsp://10.0.0.1:554/video2", |  | ||||||
|                                 "roles": ["record"], |  | ||||||
|                             }, |  | ||||||
|                         ] |  | ||||||
|                     }, |  | ||||||
|                     "detect": { |  | ||||||
|                         "height": 1080, |  | ||||||
|                         "width": 1920, |  | ||||||
|                         "fps": 5, |  | ||||||
|                     }, |  | ||||||
|                 } |  | ||||||
|             }, |  | ||||||
|         } |  | ||||||
|         frigate_config = FrigateConfig(**config) |  | ||||||
|         assert config == frigate_config.dict(exclude_unset=True) |  | ||||||
| 
 |  | ||||||
|         runtime_config = frigate_config.runtime_config() |  | ||||||
|         assert not runtime_config.cameras["back"].rtmp.enabled |  | ||||||
| 
 |  | ||||||
|     def test_global_jsmpeg(self): |     def test_global_jsmpeg(self): | ||||||
|         config = { |         config = { | ||||||
|             "mqtt": {"host": "mqtt"}, |             "mqtt": {"host": "mqtt"}, | ||||||
| @ -1428,7 +1312,6 @@ class TestConfig(unittest.TestCase): | |||||||
|     def test_global_timestamp_style_merge(self): |     def test_global_timestamp_style_merge(self): | ||||||
|         config = { |         config = { | ||||||
|             "mqtt": {"host": "mqtt"}, |             "mqtt": {"host": "mqtt"}, | ||||||
|             "rtmp": {"enabled": False}, |  | ||||||
|             "timestamp_style": {"position": "br", "thickness": 2}, |             "timestamp_style": {"position": "br", "thickness": 2}, | ||||||
|             "cameras": { |             "cameras": { | ||||||
|                 "back": { |                 "back": { | ||||||
|  | |||||||
| @ -14,13 +14,12 @@ class TestFfmpegPresets(unittest.TestCase): | |||||||
|                         "inputs": [ |                         "inputs": [ | ||||||
|                             { |                             { | ||||||
|                                 "path": "rtsp://10.0.0.1:554/video", |                                 "path": "rtsp://10.0.0.1:554/video", | ||||||
|                                 "roles": ["detect", "rtmp"], |                                 "roles": ["detect"], | ||||||
|                             } |                             } | ||||||
|                         ], |                         ], | ||||||
|                         "output_args": { |                         "output_args": { | ||||||
|                             "detect": "-f rawvideo -pix_fmt yuv420p", |                             "detect": "-f rawvideo -pix_fmt yuv420p", | ||||||
|                             "record": "-f segment -segment_time 10 -segment_format mp4 -reset_timestamps 1 -strftime 1 -c copy -an", |                             "record": "-f segment -segment_time 10 -segment_format mp4 -reset_timestamps 1 -strftime 1 -c copy -an", | ||||||
|                             "rtmp": "-c copy -f flv", |  | ||||||
|                         }, |                         }, | ||||||
|                     }, |                     }, | ||||||
|                     "detect": { |                     "detect": { | ||||||
| @ -31,9 +30,6 @@ class TestFfmpegPresets(unittest.TestCase): | |||||||
|                     "record": { |                     "record": { | ||||||
|                         "enabled": True, |                         "enabled": True, | ||||||
|                     }, |                     }, | ||||||
|                     "rtmp": { |  | ||||||
|                         "enabled": True, |  | ||||||
|                     }, |  | ||||||
|                     "name": "back", |                     "name": "back", | ||||||
|                 } |                 } | ||||||
|             }, |             }, | ||||||
| @ -157,29 +153,6 @@ class TestFfmpegPresets(unittest.TestCase): | |||||||
|             " ".join(frigate_config.cameras["back"].ffmpeg_cmds[0]["cmd"]) |             " ".join(frigate_config.cameras["back"].ffmpeg_cmds[0]["cmd"]) | ||||||
|         ) |         ) | ||||||
| 
 | 
 | ||||||
|     def test_ffmpeg_output_rtmp_preset(self): |  | ||||||
|         self.default_ffmpeg["cameras"]["back"]["ffmpeg"]["output_args"][ |  | ||||||
|             "rtmp" |  | ||||||
|         ] = "preset-rtmp-jpeg" |  | ||||||
|         frigate_config = FrigateConfig(**self.default_ffmpeg) |  | ||||||
|         frigate_config.cameras["back"].create_ffmpeg_cmds() |  | ||||||
|         assert "preset-rtmp-jpeg" not in ( |  | ||||||
|             " ".join(frigate_config.cameras["back"].ffmpeg_cmds[0]["cmd"]) |  | ||||||
|         ) |  | ||||||
|         assert "-c:v libx264" in ( |  | ||||||
|             " ".join(frigate_config.cameras["back"].ffmpeg_cmds[0]["cmd"]) |  | ||||||
|         ) |  | ||||||
| 
 |  | ||||||
|     def test_ffmpeg_output_rtmp_not_preset(self): |  | ||||||
|         self.default_ffmpeg["cameras"]["back"]["ffmpeg"]["output_args"][ |  | ||||||
|             "rtmp" |  | ||||||
|         ] = "-some output" |  | ||||||
|         frigate_config = FrigateConfig(**self.default_ffmpeg) |  | ||||||
|         frigate_config.cameras["back"].create_ffmpeg_cmds() |  | ||||||
|         assert "-some output" in ( |  | ||||||
|             " ".join(frigate_config.cameras["back"].ffmpeg_cmds[0]["cmd"]) |  | ||||||
|         ) |  | ||||||
| 
 |  | ||||||
| 
 | 
 | ||||||
| if __name__ == "__main__": | if __name__ == "__main__": | ||||||
|     unittest.main(verbosity=2) |     unittest.main(verbosity=2) | ||||||
|  | |||||||
| @ -262,7 +262,6 @@ def process(path, label, output, debug_path): | |||||||
|                         } |                         } | ||||||
|                     ] |                     ] | ||||||
|                 }, |                 }, | ||||||
|                 "rtmp": {"enabled": False}, |  | ||||||
|                 "record": {"enabled": False}, |                 "record": {"enabled": False}, | ||||||
|             } |             } | ||||||
|         }, |         }, | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user