mirror of
https://github.com/blakeblackshear/frigate.git
synced 2026-02-03 17:55:21 +03:00
Merge branch 'dev' of https://github.com/blakeblackshear/frigate into migrate-db-path
This commit is contained in:
commit
8cc1727da7
@ -27,7 +27,7 @@ RUN --mount=type=tmpfs,target=/tmp --mount=type=tmpfs,target=/var/cache/apt \
|
|||||||
FROM wget AS go2rtc
|
FROM wget AS go2rtc
|
||||||
ARG TARGETARCH
|
ARG TARGETARCH
|
||||||
WORKDIR /rootfs/usr/local/go2rtc/bin
|
WORKDIR /rootfs/usr/local/go2rtc/bin
|
||||||
RUN wget -qO go2rtc "https://github.com/AlexxIT/go2rtc/releases/download/v1.0.0/go2rtc_linux_${TARGETARCH}" \
|
RUN wget -qO go2rtc "https://github.com/AlexxIT/go2rtc/releases/download/v1.0.1/go2rtc_linux_${TARGETARCH}" \
|
||||||
&& chmod +x go2rtc
|
&& chmod +x go2rtc
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -10,7 +10,7 @@ s6-svc -O .
|
|||||||
function get_ip_and_port_from_supervisor() {
|
function get_ip_and_port_from_supervisor() {
|
||||||
local ip_address
|
local ip_address
|
||||||
# Example: 192.168.1.10/24
|
# Example: 192.168.1.10/24
|
||||||
local ip_regex='^([0-9]{1,3}\.{3}[0-9]{1,3})/[0-9]{1,2}$'
|
local ip_regex='^([0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3})/[0-9]{1,2}$'
|
||||||
if ip_address=$(
|
if ip_address=$(
|
||||||
curl -fsSL \
|
curl -fsSL \
|
||||||
-H "Authorization: Bearer ${SUPERVISOR_TOKEN}" \
|
-H "Authorization: Bearer ${SUPERVISOR_TOKEN}" \
|
||||||
@ -32,7 +32,7 @@ function get_ip_and_port_from_supervisor() {
|
|||||||
-H "Authorization: Bearer ${SUPERVISOR_TOKEN}" \
|
-H "Authorization: Bearer ${SUPERVISOR_TOKEN}" \
|
||||||
-H "Content-Type: application/json" \
|
-H "Content-Type: application/json" \
|
||||||
http://supervisor/addons/self/info |
|
http://supervisor/addons/self/info |
|
||||||
jq --exit-status --raw-output '.data.network["22/tcp"]'
|
jq --exit-status --raw-output '.data.network["8555/tcp"]'
|
||||||
) && [[ "${webrtc_port}" =~ ${port_regex} ]]; then
|
) && [[ "${webrtc_port}" =~ ${port_regex} ]]; then
|
||||||
webrtc_port="${BASH_REMATCH[1]}"
|
webrtc_port="${BASH_REMATCH[1]}"
|
||||||
echo "[INFO] Got WebRTC port from supervisor: ${ip_address}" >&2
|
echo "[INFO] Got WebRTC port from supervisor: ${ip_address}" >&2
|
||||||
|
|||||||
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
import json
|
import json
|
||||||
import os
|
import os
|
||||||
|
import sys
|
||||||
import yaml
|
import yaml
|
||||||
|
|
||||||
|
|
||||||
@ -40,6 +41,8 @@ if not go2rtc_config.get("webrtc", {}).get("candidates", []):
|
|||||||
default_candidates.append("stun:8555")
|
default_candidates.append("stun:8555")
|
||||||
|
|
||||||
go2rtc_config["webrtc"] = {"candidates": default_candidates}
|
go2rtc_config["webrtc"] = {"candidates": default_candidates}
|
||||||
|
else:
|
||||||
|
print("[INFO] Not injecting WebRTC candidates into go2rtc config as it has been set manually", file=sys.stderr)
|
||||||
|
|
||||||
# need to replace ffmpeg command when using ffmpeg4
|
# need to replace ffmpeg command when using ffmpeg4
|
||||||
if not os.path.exists(BTBN_PATH):
|
if not os.path.exists(BTBN_PATH):
|
||||||
|
|||||||
@ -108,8 +108,11 @@ According to [this discussion](https://github.com/blakeblackshear/frigate/issues
|
|||||||
```yaml
|
```yaml
|
||||||
go2rtc:
|
go2rtc:
|
||||||
streams:
|
streams:
|
||||||
reolink: ffmpeg:http://reolink_ip/flv?port=1935&app=bcs&stream=channel0_main.bcs&user=username&password=password#video=copy#audio=copy#audio=opus
|
reolink:
|
||||||
reolink_sub: ffmpeg:http://reolink_ip/flv?port=1935&app=bcs&stream=channel0_ext.bcs&user=username&password=password
|
- http://reolink_ip/flv?port=1935&app=bcs&stream=channel0_main.bcs&user=username&password=password
|
||||||
|
- ffmpeg:reolink#audio=opus
|
||||||
|
reolink_sub:
|
||||||
|
- http://reolink_ip/flv?port=1935&app=bcs&stream=channel0_ext.bcs&user=username&password=password
|
||||||
|
|
||||||
cameras:
|
cameras:
|
||||||
reolink:
|
reolink:
|
||||||
@ -119,7 +122,7 @@ cameras:
|
|||||||
input_args: preset-rtsp-restream
|
input_args: preset-rtsp-restream
|
||||||
roles:
|
roles:
|
||||||
- record
|
- record
|
||||||
- path: rtsp://127.0.0.1:8554/reolink?video=copy
|
- path: rtsp://127.0.0.1:8554/reolink_sub?video=copy
|
||||||
input_args: preset-rtsp-restream
|
input_args: preset-rtsp-restream
|
||||||
roles:
|
roles:
|
||||||
- detect
|
- detect
|
||||||
|
|||||||
@ -355,7 +355,7 @@ rtmp:
|
|||||||
enabled: False
|
enabled: False
|
||||||
|
|
||||||
# Optional: Restream configuration
|
# Optional: Restream configuration
|
||||||
# Uses https://github.com/AlexxIT/go2rtc (v1.0.0)
|
# Uses https://github.com/AlexxIT/go2rtc (v1.0.1)
|
||||||
go2rtc:
|
go2rtc:
|
||||||
|
|
||||||
# Optional: jsmpeg stream configuration for WebUI
|
# Optional: jsmpeg stream configuration for WebUI
|
||||||
@ -491,4 +491,10 @@ ui:
|
|||||||
timezone: None
|
timezone: None
|
||||||
# Optional: Use an experimental recordings / camera view UI (default: shown below)
|
# Optional: Use an experimental recordings / camera view UI (default: shown below)
|
||||||
experimental_ui: False
|
experimental_ui: False
|
||||||
|
|
||||||
|
# Optional: Telemetry configuration
|
||||||
|
telemetry:
|
||||||
|
# Optional: Enable the latest version outbound check (default: shown below)
|
||||||
|
# NOTE: If you use the HomeAssistant integration, disabling this will prevent it from reporting new versions
|
||||||
|
version_check: True
|
||||||
```
|
```
|
||||||
|
|||||||
@ -31,8 +31,9 @@ go2rtc:
|
|||||||
rtsp_cam: # <- for RTSP streams
|
rtsp_cam: # <- for RTSP streams
|
||||||
- rtsp://192.168.1.5:554/live0 # <- stream which supports video & aac audio
|
- rtsp://192.168.1.5:554/live0 # <- stream which supports video & aac audio
|
||||||
- ffmpeg:rtsp_cam#audio=opus # <- copy of the stream which transcodes audio to the missing codec (usually will be opus)
|
- ffmpeg:rtsp_cam#audio=opus # <- copy of the stream which transcodes audio to the missing codec (usually will be opus)
|
||||||
http_cam: # <- for http streams
|
http_cam: # <- for other streams
|
||||||
- "ffmpeg:http://192.168.50.155/flv?port=1935&app=bcs&stream=channel0_main.bcs&user=user&password=password#video=copy#audio=copy#audio=opus" # <- http streams must use ffmpeg to set all types
|
- http://192.168.50.155/flv?port=1935&app=bcs&stream=channel0_main.bcs&user=user&password=password # <- stream which supports video & aac audio
|
||||||
|
- ffmpeg:http_cam#audio=opus # <- copy of the stream which transcodes audio to the missing codec (usually will be opus)
|
||||||
|
|
||||||
cameras:
|
cameras:
|
||||||
rtsp_cam:
|
rtsp_cam:
|
||||||
@ -71,9 +72,11 @@ go2rtc:
|
|||||||
- rtsp://192.168.1.5:554/substream # <- stream which supports video & aac audio. This is only supported for rtsp streams, http must use ffmpeg
|
- rtsp://192.168.1.5:554/substream # <- stream which supports video & aac audio. This is only supported for rtsp streams, http must use ffmpeg
|
||||||
- ffmpeg:rtsp_cam_sub#audio=opus # <- copy of the stream which transcodes audio to opus
|
- ffmpeg:rtsp_cam_sub#audio=opus # <- copy of the stream which transcodes audio to opus
|
||||||
http_cam:
|
http_cam:
|
||||||
- "ffmpeg:http://192.168.50.155/flv?port=1935&app=bcs&stream=channel0_main.bcs&user=user&password=password#video=copy#audio=copy#audio=opus" # <- http streams must use ffmpeg to set all types
|
- http://192.168.50.155/flv?port=1935&app=bcs&stream=channel0_main.bcs&user=user&password=password # <- stream which supports video & aac audio. This is only supported for rtsp streams, http must use ffmpeg
|
||||||
|
- ffmpeg:http_cam#audio=opus # <- copy of the stream which transcodes audio to opus
|
||||||
http_cam_sub:
|
http_cam_sub:
|
||||||
- "ffmpeg:http://192.168.50.155/flv?port=1935&app=bcs&stream=channel0_ext.bcs&user=user&password=password#video=copy#audio=copy#audio=opus" # <- http streams must use ffmpeg to set all types
|
- http://192.168.50.155/flv?port=1935&app=bcs&stream=channel0_ext.bcs&user=user&password=password # <- stream which supports video & aac audio. This is only supported for rtsp streams, http must use ffmpeg
|
||||||
|
- ffmpeg:http_cam_sub#audio=opus # <- copy of the stream which transcodes audio to opus
|
||||||
|
|
||||||
cameras:
|
cameras:
|
||||||
rtsp_cam:
|
rtsp_cam:
|
||||||
@ -115,3 +118,15 @@ go2rtc:
|
|||||||
streams:
|
streams:
|
||||||
stream1: exec:ffmpeg -hide_banner -re -stream_loop -1 -i /media/BigBuckBunny.mp4 -c copy -rtsp_transport tcp -f rtsp {{output}}
|
stream1: exec:ffmpeg -hide_banner -re -stream_loop -1 -i /media/BigBuckBunny.mp4 -c copy -rtsp_transport tcp -f rtsp {{output}}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Go2rtc Exec
|
||||||
|
|
||||||
|
Go2rtc offers the ability to [run a full command with exec](https://github.com/AlexxIT/go2rtc#source-exec) and calls for `{output}` at the end of the stream. Due to frigate's handling of templates, the output will need to be passed as `{{output}}`.
|
||||||
|
|
||||||
|
ex:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
go2rtc:
|
||||||
|
streams:
|
||||||
|
test: exec:ffmpeg -hide_banner -re -stream_loop -1 -i /media/BigBuckBunny.mp4 -c copy -rtsp_transport tcp -f rtsp {{output}}
|
||||||
|
```
|
||||||
|
|||||||
@ -155,7 +155,9 @@ class FrigateApp:
|
|||||||
self.db.bind(models)
|
self.db.bind(models)
|
||||||
|
|
||||||
def init_stats(self) -> None:
|
def init_stats(self) -> None:
|
||||||
self.stats_tracking = stats_init(self.camera_metrics, self.detectors)
|
self.stats_tracking = stats_init(
|
||||||
|
self.config, self.camera_metrics, self.detectors
|
||||||
|
)
|
||||||
|
|
||||||
def init_web_server(self) -> None:
|
def init_web_server(self) -> None:
|
||||||
self.flask_app = create_app(
|
self.flask_app = create_app(
|
||||||
|
|||||||
@ -74,6 +74,10 @@ class UIConfig(FrigateBaseModel):
|
|||||||
use_experimental: bool = Field(default=False, title="Experimental UI")
|
use_experimental: bool = Field(default=False, title="Experimental UI")
|
||||||
|
|
||||||
|
|
||||||
|
class TelemetryConfig(FrigateBaseModel):
|
||||||
|
version_check: bool = Field(default=True, title="Enable latest version check.")
|
||||||
|
|
||||||
|
|
||||||
class MqttConfig(FrigateBaseModel):
|
class MqttConfig(FrigateBaseModel):
|
||||||
enabled: bool = Field(title="Enable MQTT Communication.", default=True)
|
enabled: bool = Field(title="Enable MQTT Communication.", default=True)
|
||||||
host: str = Field(default="", title="MQTT Host")
|
host: str = Field(default="", title="MQTT Host")
|
||||||
@ -816,6 +820,9 @@ class FrigateConfig(FrigateBaseModel):
|
|||||||
default_factory=dict, title="Frigate environment variables."
|
default_factory=dict, title="Frigate environment variables."
|
||||||
)
|
)
|
||||||
ui: UIConfig = Field(default_factory=UIConfig, title="UI configuration.")
|
ui: UIConfig = Field(default_factory=UIConfig, title="UI configuration.")
|
||||||
|
telemetry: TelemetryConfig = Field(
|
||||||
|
default_factory=TelemetryConfig, title="Telemetry configuration."
|
||||||
|
)
|
||||||
model: ModelConfig = Field(
|
model: ModelConfig = Field(
|
||||||
default_factory=ModelConfig, title="Detection model configuration."
|
default_factory=ModelConfig, title="Detection model configuration."
|
||||||
)
|
)
|
||||||
|
|||||||
@ -82,14 +82,14 @@ PRESETS_HW_ACCEL_DECODE = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
PRESETS_HW_ACCEL_SCALE = {
|
PRESETS_HW_ACCEL_SCALE = {
|
||||||
"preset-rpi-32-h264": "-r {} -s {}x{} -f rawvideo -pix_fmt yuv420p",
|
"preset-rpi-32-h264": "-r {0} -s {1}x{2} -f rawvideo -pix_fmt yuv420p",
|
||||||
"preset-rpi-64-h264": "-r {} -s {}x{} -f rawvideo -pix_fmt yuv420p",
|
"preset-rpi-64-h264": "-r {0} -s {1}x{2} -f rawvideo -pix_fmt yuv420p",
|
||||||
"preset-vaapi": "-vf fps={},scale_vaapi=w={}:h={},hwdownload,format=yuv420p -f rawvideo",
|
"preset-vaapi": "-r {0} -vf fps={0},scale_vaapi=w={1}:h={2},hwdownload,format=yuv420p -f rawvideo",
|
||||||
"preset-intel-qsv-h264": "-r {} -vf vpp_qsv=w={}:h={}:format=nv12,hwdownload,format=nv12,format=yuv420p -f rawvideo",
|
"preset-intel-qsv-h264": "-r {0} -vf vpp_qsv=framerate={0}:w={1}:h={2}:format=nv12,hwdownload,format=nv12,format=yuv420p -f rawvideo",
|
||||||
"preset-intel-qsv-h265": "-r {} -vf vpp_qsv=w={}:h={}:format=nv12,hwdownload,format=nv12,format=yuv420p -f rawvideo",
|
"preset-intel-qsv-h265": "-r {0} -vf vpp_qsv=framerate={0}:w={1}:h={2}:format=nv12,hwdownload,format=nv12,format=yuv420p -f rawvideo",
|
||||||
"preset-nvidia-h264": "-vf fps={},scale_cuda=w={}:h={}:format=nv12,hwdownload,format=nv12,format=yuv420p -f rawvideo",
|
"preset-nvidia-h264": "-r {0} -vf fps={0},scale_cuda=w={1}:h={2}:format=nv12,hwdownload,format=nv12,format=yuv420p -f rawvideo",
|
||||||
"preset-nvidia-h265": "-vf fps={},scale_cuda=w={}:h={}:format=nv12,hwdownload,format=nv12,format=yuv420p -f rawvideo",
|
"preset-nvidia-h265": "-r {0} -vf fps={0},scale_cuda=w={1}:h={2}:format=nv12,hwdownload,format=nv12,format=yuv420p -f rawvideo",
|
||||||
"default": "-r {} -s {}x{}",
|
"default": "-r {0} -s {1}x{2}",
|
||||||
}
|
}
|
||||||
|
|
||||||
PRESETS_HW_ACCEL_ENCODE = {
|
PRESETS_HW_ACCEL_ENCODE = {
|
||||||
@ -236,6 +236,10 @@ PRESETS_INPUT = {
|
|||||||
"tcp",
|
"tcp",
|
||||||
TIMEOUT_PARAM,
|
TIMEOUT_PARAM,
|
||||||
"5000000",
|
"5000000",
|
||||||
|
"-fflags",
|
||||||
|
"nobuffer",
|
||||||
|
"-flags",
|
||||||
|
"low_delay",
|
||||||
],
|
],
|
||||||
"preset-rtsp-udp": _user_agent_args
|
"preset-rtsp-udp": _user_agent_args
|
||||||
+ [
|
+ [
|
||||||
|
|||||||
@ -22,7 +22,11 @@ from frigate.object_detection import ObjectDetectProcess
|
|||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
def get_latest_version() -> str:
|
def get_latest_version(config: FrigateConfig) -> str:
|
||||||
|
|
||||||
|
if not config.telemetry.version_check:
|
||||||
|
return "disabled"
|
||||||
|
|
||||||
try:
|
try:
|
||||||
request = requests.get(
|
request = requests.get(
|
||||||
"https://api.github.com/repos/blakeblackshear/frigate/releases/latest",
|
"https://api.github.com/repos/blakeblackshear/frigate/releases/latest",
|
||||||
@ -40,6 +44,7 @@ def get_latest_version() -> str:
|
|||||||
|
|
||||||
|
|
||||||
def stats_init(
|
def stats_init(
|
||||||
|
config: FrigateConfig,
|
||||||
camera_metrics: dict[str, CameraMetricsTypes],
|
camera_metrics: dict[str, CameraMetricsTypes],
|
||||||
detectors: dict[str, ObjectDetectProcess],
|
detectors: dict[str, ObjectDetectProcess],
|
||||||
) -> StatsTrackingTypes:
|
) -> StatsTrackingTypes:
|
||||||
@ -47,7 +52,7 @@ def stats_init(
|
|||||||
"camera_metrics": camera_metrics,
|
"camera_metrics": camera_metrics,
|
||||||
"detectors": detectors,
|
"detectors": detectors,
|
||||||
"started": int(time.time()),
|
"started": int(time.time()),
|
||||||
"latest_frigate_version": get_latest_version(),
|
"latest_frigate_version": get_latest_version(config),
|
||||||
}
|
}
|
||||||
return stats_tracking
|
return stats_tracking
|
||||||
|
|
||||||
|
|||||||
@ -628,8 +628,13 @@ def clipped(obj, frame_shape):
|
|||||||
|
|
||||||
|
|
||||||
def restart_frigate():
|
def restart_frigate():
|
||||||
# S6 overlay is configured to exit once the Frigate process exits
|
proc = psutil.Process(1)
|
||||||
os.kill(os.getpid(), signal.SIGTERM)
|
# if this is running via s6, sigterm pid 1
|
||||||
|
if proc.name() == "s6-svscan":
|
||||||
|
proc.terminate()
|
||||||
|
# otherwise, just try and exit frigate
|
||||||
|
else:
|
||||||
|
os.kill(os.getpid(), signal.SIGTERM)
|
||||||
|
|
||||||
|
|
||||||
class EventsPerSecond:
|
class EventsPerSecond:
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user