mirror of
https://github.com/blakeblackshear/frigate.git
synced 2024-11-21 19:07:46 +01:00
Add RTMP and timestamp style to global config (#1674)
* 📝✅🔧 - Make RTMP config global Fixes #1671 * 📝✅🔧 - Make timestamp style config global Fixes #1656 * fix test function names * formatter Co-authored-by: Blake Blackshear <blakeb@blakeshome.com>
This commit is contained in:
parent
6c28613def
commit
65855e23d9
@ -215,6 +215,12 @@ Frigate can re-stream your video feed as a RTMP feed for other applications such
|
|||||||
|
|
||||||
Some video feeds are not compatible with RTMP. If you are experiencing issues, check to make sure your camera feed is h264 with AAC audio. If your camera doesn't support a compatible format for RTMP, you can use the ffmpeg args to re-encode it on the fly at the expense of increased CPU utilization.
|
Some video feeds are not compatible with RTMP. If you are experiencing issues, check to make sure your camera feed is h264 with AAC audio. If your camera doesn't support a compatible format for RTMP, you can use the ffmpeg args to re-encode it on the fly at the expense of increased CPU utilization.
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
rtmp:
|
||||||
|
# Optional: Enable the RTMP stream (default: True)
|
||||||
|
enabled: True
|
||||||
|
```
|
||||||
|
|
||||||
## Timestamp style configuration
|
## Timestamp style configuration
|
||||||
|
|
||||||
For the debug view and snapshots it is possible to embed a timestamp in the feed. In some instances the default position obstructs important space, visibility or contrast is too low because of color or the datetime format does not match ones desire.
|
For the debug view and snapshots it is possible to embed a timestamp in the feed. In some instances the default position obstructs important space, visibility or contrast is too low because of color or the datetime format does not match ones desire.
|
||||||
@ -357,7 +363,7 @@ cameras:
|
|||||||
|
|
||||||
# Optional: RTMP re-stream configuration
|
# Optional: RTMP re-stream configuration
|
||||||
rtmp:
|
rtmp:
|
||||||
# Required: Enable the RTMP stream (default: True)
|
# Optional: Enable the RTMP stream (default: True)
|
||||||
enabled: True
|
enabled: True
|
||||||
|
|
||||||
# Optional: Live stream configuration for WebUI
|
# Optional: Live stream configuration for WebUI
|
||||||
|
@ -233,3 +233,44 @@ birdseye:
|
|||||||
# continuous - all cameras are included always
|
# continuous - all cameras are included always
|
||||||
mode: objects
|
mode: objects
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### `rtmp`
|
||||||
|
|
||||||
|
Can be overridden at the camera level. See the [cameras configuration page](cameras.md) for more information about RTMP streaming.
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
rtmp:
|
||||||
|
# Optional: Enable the RTMP stream (default: True)
|
||||||
|
enabled: True
|
||||||
|
```
|
||||||
|
|
||||||
|
## `timestamp_style`
|
||||||
|
|
||||||
|
Can be overridden at the camera level. See the [cameras configuration page](cameras.md) for more information about timestamp styling.
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
# Optional: in-feed timestamp style configuration
|
||||||
|
timestamp_style:
|
||||||
|
# Optional: Position of the timestamp (default: shown below)
|
||||||
|
# "tl" (top left), "tr" (top right), "bl" (bottom left), "br" (bottom right)
|
||||||
|
position: "tl"
|
||||||
|
# Optional: Format specifier conform to the Python package "datetime" (default: shown below)
|
||||||
|
# Additional Examples:
|
||||||
|
# german: "%d.%m.%Y %H:%M:%S"
|
||||||
|
format: "%m/%d/%Y %H:%M:%S"
|
||||||
|
# Optional: Color of font
|
||||||
|
color:
|
||||||
|
# All Required when color is specified (default: shown below)
|
||||||
|
red: 255
|
||||||
|
green: 255
|
||||||
|
blue: 255
|
||||||
|
# Optional: Scale factor for font (default: shown below)
|
||||||
|
scale: 1.0
|
||||||
|
# Optional: Line thickness of font (default: shown below)
|
||||||
|
thickness: 2
|
||||||
|
# Optional: Effect of lettering (default: shown below)
|
||||||
|
# None (No effect),
|
||||||
|
# "solid" (solid background in inverse color of font)
|
||||||
|
# "shadow" (shadow for font)
|
||||||
|
effect: None
|
||||||
|
```
|
@ -432,7 +432,7 @@ class CameraMqttConfig(BaseModel):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
class CameraRtmpConfig(BaseModel):
|
class RtmpConfig(BaseModel):
|
||||||
enabled: bool = Field(default=True, title="RTMP restreaming enabled.")
|
enabled: bool = Field(default=True, title="RTMP restreaming enabled.")
|
||||||
|
|
||||||
|
|
||||||
@ -454,8 +454,8 @@ class CameraConfig(BaseModel):
|
|||||||
record: RecordConfig = Field(
|
record: RecordConfig = Field(
|
||||||
default_factory=RecordConfig, title="Record configuration."
|
default_factory=RecordConfig, title="Record configuration."
|
||||||
)
|
)
|
||||||
rtmp: CameraRtmpConfig = Field(
|
rtmp: RtmpConfig = Field(
|
||||||
default_factory=CameraRtmpConfig, title="RTMP restreaming configuration."
|
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."
|
||||||
@ -656,6 +656,9 @@ class FrigateConfig(BaseModel):
|
|||||||
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."
|
||||||
|
)
|
||||||
birdseye: BirdseyeConfig = Field(
|
birdseye: BirdseyeConfig = Field(
|
||||||
default_factory=BirdseyeConfig, title="Birdseye configuration."
|
default_factory=BirdseyeConfig, title="Birdseye configuration."
|
||||||
)
|
)
|
||||||
@ -672,6 +675,10 @@ class FrigateConfig(BaseModel):
|
|||||||
default_factory=DetectConfig, title="Global object tracking configuration."
|
default_factory=DetectConfig, title="Global object tracking configuration."
|
||||||
)
|
)
|
||||||
cameras: Dict[str, CameraConfig] = Field(title="Camera configuration.")
|
cameras: Dict[str, CameraConfig] = Field(title="Camera configuration.")
|
||||||
|
timestamp_style: TimestampStyleConfig = Field(
|
||||||
|
default_factory=TimestampStyleConfig,
|
||||||
|
title="Global timestamp style configuration.",
|
||||||
|
)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def runtime_config(self) -> FrigateConfig:
|
def runtime_config(self) -> FrigateConfig:
|
||||||
@ -687,10 +694,12 @@ class FrigateConfig(BaseModel):
|
|||||||
include={
|
include={
|
||||||
"record": ...,
|
"record": ...,
|
||||||
"snapshots": ...,
|
"snapshots": ...,
|
||||||
|
"rtmp": ...,
|
||||||
"objects": ...,
|
"objects": ...,
|
||||||
"motion": ...,
|
"motion": ...,
|
||||||
"detect": ...,
|
"detect": ...,
|
||||||
"ffmpeg": ...,
|
"ffmpeg": ...,
|
||||||
|
"timestamp_style": ...,
|
||||||
},
|
},
|
||||||
exclude_unset=True,
|
exclude_unset=True,
|
||||||
)
|
)
|
||||||
|
@ -884,6 +884,156 @@ 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(self):
|
||||||
|
|
||||||
|
config = {
|
||||||
|
"mqtt": {"host": "mqtt"},
|
||||||
|
"rtmp": {"enabled": True},
|
||||||
|
"cameras": {
|
||||||
|
"back": {
|
||||||
|
"ffmpeg": {
|
||||||
|
"inputs": [
|
||||||
|
{
|
||||||
|
"path": "rtsp://10.0.0.1:554/video",
|
||||||
|
"roles": ["detect"],
|
||||||
|
},
|
||||||
|
]
|
||||||
|
},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
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_default_rtmp(self):
|
||||||
|
|
||||||
|
config = {
|
||||||
|
"mqtt": {"host": "mqtt"},
|
||||||
|
"cameras": {
|
||||||
|
"back": {
|
||||||
|
"ffmpeg": {
|
||||||
|
"inputs": [
|
||||||
|
{
|
||||||
|
"path": "rtsp://10.0.0.1:554/video",
|
||||||
|
"roles": ["detect"],
|
||||||
|
},
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
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_merge(self):
|
||||||
|
|
||||||
|
config = {
|
||||||
|
"mqtt": {"host": "mqtt"},
|
||||||
|
"rtmp": {"enabled": False},
|
||||||
|
"cameras": {
|
||||||
|
"back": {
|
||||||
|
"ffmpeg": {
|
||||||
|
"inputs": [
|
||||||
|
{
|
||||||
|
"path": "rtsp://10.0.0.1:554/video",
|
||||||
|
"roles": ["detect"],
|
||||||
|
},
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"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_timestamp_style(self):
|
||||||
|
|
||||||
|
config = {
|
||||||
|
"mqtt": {"host": "mqtt"},
|
||||||
|
"timestamp_style": {"position": "bl", "scale": 1.5},
|
||||||
|
"cameras": {
|
||||||
|
"back": {
|
||||||
|
"ffmpeg": {
|
||||||
|
"inputs": [
|
||||||
|
{
|
||||||
|
"path": "rtsp://10.0.0.1:554/video",
|
||||||
|
"roles": ["detect"],
|
||||||
|
},
|
||||||
|
]
|
||||||
|
},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
frigate_config = FrigateConfig(**config)
|
||||||
|
assert config == frigate_config.dict(exclude_unset=True)
|
||||||
|
|
||||||
|
runtime_config = frigate_config.runtime_config
|
||||||
|
assert runtime_config.cameras["back"].timestamp_style.position == "bl"
|
||||||
|
assert runtime_config.cameras["back"].timestamp_style.scale == 1.5
|
||||||
|
|
||||||
|
def test_default_timestamp_style(self):
|
||||||
|
|
||||||
|
config = {
|
||||||
|
"mqtt": {"host": "mqtt"},
|
||||||
|
"cameras": {
|
||||||
|
"back": {
|
||||||
|
"ffmpeg": {
|
||||||
|
"inputs": [
|
||||||
|
{
|
||||||
|
"path": "rtsp://10.0.0.1:554/video",
|
||||||
|
"roles": ["detect"],
|
||||||
|
},
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
frigate_config = FrigateConfig(**config)
|
||||||
|
assert config == frigate_config.dict(exclude_unset=True)
|
||||||
|
|
||||||
|
runtime_config = frigate_config.runtime_config
|
||||||
|
assert runtime_config.cameras["back"].timestamp_style.position == "tl"
|
||||||
|
assert runtime_config.cameras["back"].timestamp_style.scale == 1.0
|
||||||
|
|
||||||
|
def test_global_timestamp_style_merge(self):
|
||||||
|
|
||||||
|
config = {
|
||||||
|
"mqtt": {"host": "mqtt"},
|
||||||
|
"rtmp": {"enabled": False},
|
||||||
|
"timestamp_style": {"position": "br", "scale": 2.0},
|
||||||
|
"cameras": {
|
||||||
|
"back": {
|
||||||
|
"ffmpeg": {
|
||||||
|
"inputs": [
|
||||||
|
{
|
||||||
|
"path": "rtsp://10.0.0.1:554/video",
|
||||||
|
"roles": ["detect"],
|
||||||
|
},
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"timestamp_style": {"position": "bl", "scale": 1.5},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
frigate_config = FrigateConfig(**config)
|
||||||
|
assert config == frigate_config.dict(exclude_unset=True)
|
||||||
|
|
||||||
|
runtime_config = frigate_config.runtime_config
|
||||||
|
assert runtime_config.cameras["back"].timestamp_style.position == "bl"
|
||||||
|
assert runtime_config.cameras["back"].timestamp_style.scale == 1.5
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
unittest.main(verbosity=2)
|
unittest.main(verbosity=2)
|
||||||
|
Loading…
Reference in New Issue
Block a user