diff --git a/.gitignore b/.gitignore index 8456d9be0..392cd815c 100644 --- a/.gitignore +++ b/.gitignore @@ -11,11 +11,12 @@ models *.mp4 *.db *.csv -frigate/version.py +# frigate/version.py web/build web/node_modules web/coverage core !/web/**/*.ts .idea/* -.ipynb_checkpoints \ No newline at end of file +.ipynb_checkpoints +media/* \ No newline at end of file diff --git a/benchmark.py b/benchmark.py index 7db09a5d7..ce8843112 100755 --- a/benchmark.py +++ b/benchmark.py @@ -13,7 +13,7 @@ from frigate.object_detection import ( ) my_frame = np.expand_dims(np.full((300, 300, 3), 1, np.uint8), axis=0) -labels = load_labels("/labelmap.txt") +labels = load_labels("./labelmap.txt") ###### # Minimal same process runner diff --git a/cpu_model.tflite b/cpu_model.tflite new file mode 100644 index 000000000..66f6f3a54 Binary files /dev/null and b/cpu_model.tflite differ diff --git a/cspell.json b/cspell.json index 132e51532..9c0ce9570 100644 --- a/cspell.json +++ b/cspell.json @@ -8,7 +8,7 @@ "node_modules", "__pycache__", "dist", - "/audio-labelmap.txt" + "./audio-labelmap.txt" ], "language": "en", "dictionaryDefinitions": [ diff --git a/docker/main/rootfs/usr/local/ffmpeg/get_ffmpeg_path.py b/docker/main/rootfs/usr/local/ffmpeg/get_ffmpeg_path.py index 27034bff9..7c6ba505f 100644 --- a/docker/main/rootfs/usr/local/ffmpeg/get_ffmpeg_path.py +++ b/docker/main/rootfs/usr/local/ffmpeg/get_ffmpeg_path.py @@ -15,7 +15,7 @@ sys.path.remove("/opt/frigate") yaml = YAML() -config_file = os.environ.get("CONFIG_FILE", "/config/config.yml") +config_file = os.environ.get("CONFIG_FILE", "./config/config.yml") # Check if we can use .yaml instead of .yml config_file_yaml = config_file.replace(".yml", ".yaml") diff --git a/docker/main/rootfs/usr/local/go2rtc/create_config.py b/docker/main/rootfs/usr/local/go2rtc/create_config.py index 1038af64c..e34d58fe4 100644 --- a/docker/main/rootfs/usr/local/go2rtc/create_config.py +++ b/docker/main/rootfs/usr/local/go2rtc/create_config.py @@ -29,7 +29,7 @@ if os.path.isdir("/run/secrets"): Path(os.path.join("/run/secrets", secret_file)).read_text().strip() ) -config_file = os.environ.get("CONFIG_FILE", "/config/config.yml") +config_file = os.environ.get("CONFIG_FILE", "./config/config.yml") # Check if we can use .yaml instead of .yml config_file_yaml = config_file.replace(".yml", ".yaml") diff --git a/docker/main/rootfs/usr/local/nginx/conf/nginx.conf b/docker/main/rootfs/usr/local/nginx/conf/nginx.conf index 75527bf53..7368a8f23 100644 --- a/docker/main/rootfs/usr/local/nginx/conf/nginx.conf +++ b/docker/main/rootfs/usr/local/nginx/conf/nginx.conf @@ -1,8 +1,8 @@ -daemon off; +# daemon off; user root; worker_processes auto; -error_log /dev/stdout warn; +# error_log /dev/stdout warn; pid /var/run/nginx.pid; events { @@ -19,7 +19,7 @@ http { '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"'; - access_log /dev/stdout main; + # access_log /dev/stdout main; # send headers in one piece, it is better than sending them one by one tcp_nopush on; diff --git a/docker/main/rootfs/usr/local/nginx/get_tls_settings.py b/docker/main/rootfs/usr/local/nginx/get_tls_settings.py index f1a4c85de..327c20891 100644 --- a/docker/main/rootfs/usr/local/nginx/get_tls_settings.py +++ b/docker/main/rootfs/usr/local/nginx/get_tls_settings.py @@ -7,7 +7,7 @@ from ruamel.yaml import YAML yaml = YAML() -config_file = os.environ.get("CONFIG_FILE", "/config/config.yml") +config_file = os.environ.get("CONFIG_FILE", "./config/config.yml") # Check if we can use .yaml instead of .yml config_file_yaml = config_file.replace(".yml", ".yaml") diff --git a/frigate/app.py b/frigate/app.py index 02955b6c9..ef3902636 100644 --- a/frigate/app.py +++ b/frigate/app.py @@ -7,7 +7,8 @@ import shutil from multiprocessing import Queue from multiprocessing.synchronize import Event as MpEvent from typing import Optional - +import subprocess +import sys import psutil import uvicorn from peewee_migrate import Router @@ -94,7 +95,38 @@ class FrigateApp: self.region_grids: dict[str, list[list[dict[str, int]]]] = {} self.frame_manager = SharedMemoryFrameManager() self.config = config + self.go2rtc_process = self.run_go2rtc() + # self.nginx_process = self.run_nginx() + def run_go2rtc(self, config_path="./config/cam.yaml"): + """ + Hàm chạy Frigate cùng với go2rtc trong một tiến trình nền. + + Args: + config_path (str): Đường dẫn đến file cấu hình của go2rtc (mặc định: config/cam.yaml) + """ + # Khởi động go2rtc trong một tiến trình nền + + go2rtc_process = subprocess.Popen( + ["go2rtc", "-c", config_path], + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + text=True # Để dễ đọc output dưới dạng chuỗi + ) + print(f"Đã khởi động go2rtc với PID: {go2rtc_process.pid}") + return go2rtc_process + + def run_nginx(self): + nginx_path = shutil.which("nginx") + nginx_process = subprocess.Popen( + ["sudo", nginx_path], + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + text=True + ) + print(f"Đã khởi động Nginx với PID: {nginx_process.pid}") + return nginx_process + def ensure_dirs(self) -> None: for d in [ CONFIG_DIR, @@ -583,7 +615,6 @@ class FrigateApp: def start(self) -> None: logger.info(f"Starting Frigate ({VERSION})") - # Ensure global state. self.ensure_dirs() @@ -642,7 +673,13 @@ class FrigateApp: def stop(self) -> None: logger.info("Stopping...") - + + self.go2rtc_process.terminate() + logger.info("Exiting go2rtc...") + + # self.nginx_process.terminate() + # logger.info("Exiting Nginx...") + self.stop_event.set() # set an end_time on entries without an end_time before exiting diff --git a/frigate/config/camera/ffmpeg.py b/frigate/config/camera/ffmpeg.py index 4750a950f..63f4e72dd 100644 --- a/frigate/config/camera/ffmpeg.py +++ b/frigate/config/camera/ffmpeg.py @@ -67,27 +67,29 @@ class FfmpegConfig(FrigateBaseModel): @property def ffmpeg_path(self) -> str: - if self.path == "default": - if shutil.which("ffmpeg") is None: - return f"/usr/lib/ffmpeg/{DEFAULT_FFMPEG_VERSION}/bin/ffmpeg" - else: - return "ffmpeg" - elif self.path in INCLUDED_FFMPEG_VERSIONS: - return f"/usr/lib/ffmpeg/{self.path}/bin/ffmpeg" - else: - return f"{self.path}/bin/ffmpeg" + # if self.path == "default": + # if shutil.which("ffmpeg") is None: + # return f"/usr/lib/ffmpeg/{DEFAULT_FFMPEG_VERSION}/bin/ffmpeg" + # else: + # return "ffmpeg" + # elif self.path in INCLUDED_FFMPEG_VERSIONS: + # return f"/usr/lib/ffmpeg/{self.path}/bin/ffmpeg" + # else: + # return f"{self.path}/bin/ffmpeg" + return shutil.which("ffmpeg") @property def ffprobe_path(self) -> str: - if self.path == "default": - if shutil.which("ffprobe") is None: - return f"/usr/lib/ffmpeg/{DEFAULT_FFMPEG_VERSION}/bin/ffprobe" - else: - return "ffprobe" - elif self.path in INCLUDED_FFMPEG_VERSIONS: - return f"/usr/lib/ffmpeg/{self.path}/bin/ffprobe" - else: - return f"{self.path}/bin/ffprobe" + # if self.path == "default": + # if shutil.which("ffprobe") is None: + # return f"/usr/lib/ffmpeg/{DEFAULT_FFMPEG_VERSION}/bin/ffprobe" + # else: + # return "ffprobe" + # elif self.path in INCLUDED_FFMPEG_VERSIONS: + # return f"/usr/lib/ffmpeg/{self.path}/bin/ffprobe" + # else: + # return f"{self.path}/bin/ffprobe" + return shutil.which("ffprobe") class CameraRoleEnum(str, Enum): diff --git a/frigate/config/config.py b/frigate/config/config.py index 43db89b4f..efa82f079 100644 --- a/frigate/config/config.py +++ b/frigate/config/config.py @@ -607,9 +607,9 @@ class FrigateConfig(FrigateBaseModel): if "path" not in model_config: if detector_config.type == "cpu": - model_config["path"] = "/cpu_model.tflite" + model_config["path"] = "./cpu_model.tflite" elif detector_config.type == "edgetpu": - model_config["path"] = "/edgetpu_model.tflite" + model_config["path"] = "./edgetpu_model.tflite" model = ModelConfig.model_validate(model_config) model.check_and_load_plus_model(self.plus_api, detector_config.type) diff --git a/frigate/const.py b/frigate/const.py index 5976f47b1..860437407 100644 --- a/frigate/const.py +++ b/frigate/const.py @@ -1,9 +1,9 @@ import re -CONFIG_DIR = "/config" +CONFIG_DIR = "./config" DEFAULT_DB_PATH = f"{CONFIG_DIR}/frigate.db" MODEL_CACHE_DIR = f"{CONFIG_DIR}/model_cache" -BASE_DIR = "/media/frigate" +BASE_DIR = "./media/frigate" CLIPS_DIR = f"{BASE_DIR}/clips" RECORD_DIR = f"{BASE_DIR}/recordings" EXPORT_DIR = f"{BASE_DIR}/exports" diff --git a/frigate/detectors/detector_config.py b/frigate/detectors/detector_config.py index 452f1feed..014a26244 100644 --- a/frigate/detectors/detector_config.py +++ b/frigate/detectors/detector_config.py @@ -94,7 +94,7 @@ class ModelConfig(BaseModel): super().__init__(**config) self._merged_labelmap = { - **load_labels(config.get("labelmap_path", "/labelmap.txt")), + **load_labels(config.get("labelmap_path", "./labelmap.txt")), **config.get("labelmap", {}), } self._colormap = {} @@ -117,7 +117,7 @@ class ModelConfig(BaseModel): return model_id = self.path[7:] - self.path = f"/config/model_cache/{model_id}" + self.path = f"./config/model_cache/{model_id}" model_info_path = f"{self.path}.json" # download the model if it doesn't exist diff --git a/frigate/detectors/plugins/hailo8l.py b/frigate/detectors/plugins/hailo8l.py index b66d78bd6..e1a64f1a1 100644 --- a/frigate/detectors/plugins/hailo8l.py +++ b/frigate/detectors/plugins/hailo8l.py @@ -57,7 +57,7 @@ class HailoDetector(DetectionApi): self.h8l_tensor_format = detector_config.model.input_tensor self.h8l_pixel_format = detector_config.model.input_pixel_format self.model_url = "https://hailo-model-zoo.s3.eu-west-2.amazonaws.com/ModelZoo/Compiled/v2.11.0/hailo8l/ssd_mobilenet_v1.hef" - self.cache_dir = "/config/model_cache/h8l_cache" + self.cache_dir = "./config/model_cache/h8l_cache" self.expected_model_filename = "ssd_mobilenet_v1.hef" output_type = "FLOAT32" diff --git a/frigate/detectors/plugins/openvino.py b/frigate/detectors/plugins/openvino.py index 51e48530b..13a497a35 100644 --- a/frigate/detectors/plugins/openvino.py +++ b/frigate/detectors/plugins/openvino.py @@ -35,8 +35,8 @@ class OvDetector(DetectionApi): logger.error(f"OpenVino model file {detector_config.model.path} not found.") raise FileNotFoundError - os.makedirs("/config/model_cache/openvino", exist_ok=True) - self.ov_core.set_property({props.cache_dir: "/config/model_cache/openvino"}) + os.makedirs("./config/model_cache/openvino", exist_ok=True) + self.ov_core.set_property({props.cache_dir: "./config/model_cache/openvino"}) self.interpreter = self.ov_core.compile_model( model=detector_config.model.path, device_name=detector_config.device ) diff --git a/frigate/detectors/plugins/rknn.py b/frigate/detectors/plugins/rknn.py index df94d7b62..58bf44e06 100644 --- a/frigate/detectors/plugins/rknn.py +++ b/frigate/detectors/plugins/rknn.py @@ -17,7 +17,7 @@ supported_socs = ["rk3562", "rk3566", "rk3568", "rk3576", "rk3588"] supported_models = {ModelTypeEnum.yolonas: "^deci-fp16-yolonas_[sml]$"} -model_cache_dir = "/config/model_cache/rknn_cache/" +model_cache_dir = "./config/model_cache/rknn_cache/" class RknnDetectorConfig(BaseDetectorConfig): diff --git a/frigate/detectors/plugins/rocm.py b/frigate/detectors/plugins/rocm.py index 60118d129..e8fe9a807 100644 --- a/frigate/detectors/plugins/rocm.py +++ b/frigate/detectors/plugins/rocm.py @@ -116,7 +116,7 @@ class ROCmDetector(DetectionApi): logger.info(f"AMD/ROCm: saving parsed model into {mxr_path}") - os.makedirs("/config/model_cache/rocm", exist_ok=True) + os.makedirs("./config/model_cache/rocm", exist_ok=True) migraphx.save(self.model, mxr_path) logger.info("AMD/ROCm: model loaded") diff --git a/frigate/events/audio.py b/frigate/events/audio.py index 7675f821b..fdaae2369 100644 --- a/frigate/events/audio.py +++ b/frigate/events/audio.py @@ -309,7 +309,7 @@ class AudioTfl: def __init__(self, stop_event: threading.Event, num_threads=2): self.stop_event = stop_event self.num_threads = num_threads - self.labels = load_labels("/audio-labelmap.txt", prefill=521) + self.labels = load_labels("./audio-labelmap.txt", prefill=521) self.interpreter = Interpreter( model_path="/cpu_audio_model.tflite", num_threads=self.num_threads, diff --git a/frigate/test/test_config.py b/frigate/test/test_config.py index e6cb1274e..4f2a512b6 100644 --- a/frigate/test/test_config.py +++ b/frigate/test/test_config.py @@ -75,11 +75,11 @@ class TestConfig(unittest.TestCase): "detectors": { "cpu": { "type": "cpu", - "model_path": "/cpu_model.tflite", + "model_path": "./cpu_model.tflite", }, "edgetpu": { "type": "edgetpu", - "model_path": "/edgetpu_model.tflite", + "model_path": "./edgetpu_model.tflite", }, "openvino": { "type": "openvino", @@ -854,9 +854,9 @@ class TestConfig(unittest.TestCase): assert frigate_config.model.merged_labelmap[0] == "person" def test_plus_labelmap(self): - with open("/config/model_cache/test", "w") as f: + with open("./config/model_cache/test", "w") as f: json.dump(self.plus_model_info, f) - with open("/config/model_cache/test.json", "w") as f: + with open("./config/model_cache/test.json", "w") as f: json.dump(self.plus_model_info, f) config = { diff --git a/frigate/test/test_http.py b/frigate/test/test_http.py index 8c89e0433..551e7f4b0 100644 --- a/frigate/test/test_http.py +++ b/frigate/test/test_http.py @@ -316,7 +316,7 @@ class TestHttp(unittest.TestCase): ) with TestClient(app) as client: - config = client.get("/config").json() + config = client.get("./config").json() assert config assert config["cameras"]["front_door"] diff --git a/frigate/util/config.py b/frigate/util/config.py index d456c7557..041c7837e 100644 --- a/frigate/util/config.py +++ b/frigate/util/config.py @@ -14,7 +14,7 @@ from frigate.util.services import get_video_properties logger = logging.getLogger(__name__) CURRENT_CONFIG_VERSION = "0.15-1" -DEFAULT_CONFIG_FILE = "/config/config.yml" +DEFAULT_CONFIG_FILE = "./config/config.yml" def find_config_file() -> str: diff --git a/frigate/util/model.py b/frigate/util/model.py index ce2c9538c..2c58dcbce 100644 --- a/frigate/util/model.py +++ b/frigate/util/model.py @@ -46,7 +46,7 @@ def get_ort_providers( # so it is not enabled by default if device == "Tensorrt": os.makedirs( - "/config/model_cache/tensorrt/ort/trt-engines", exist_ok=True + "./config/model_cache/tensorrt/ort/trt-engines", exist_ok=True ) device_id = 0 if not device.isdigit() else int(device) providers.append(provider) @@ -57,19 +57,19 @@ def get_ort_providers( and os.environ.get("USE_FP_16", "True") != "False", "trt_timing_cache_enable": True, "trt_engine_cache_enable": True, - "trt_timing_cache_path": "/config/model_cache/tensorrt/ort", - "trt_engine_cache_path": "/config/model_cache/tensorrt/ort/trt-engines", + "trt_timing_cache_path": "./config/model_cache/tensorrt/ort", + "trt_engine_cache_path": "./config/model_cache/tensorrt/ort/trt-engines", } ) else: continue elif provider == "OpenVINOExecutionProvider": - os.makedirs("/config/model_cache/openvino/ort", exist_ok=True) + os.makedirs("./config/model_cache/openvino/ort", exist_ok=True) providers.append(provider) options.append( { "arena_extend_strategy": "kSameAsRequested", - "cache_dir": "/config/model_cache/openvino/ort", + "cache_dir": "./config/model_cache/openvino/ort", "device_type": device, } ) @@ -103,7 +103,7 @@ class ONNXModelRunner: self.type = "ov" self.ov = ov.Core() self.ov.set_property( - {ov.properties.cache_dir: "/config/model_cache/openvino"} + {ov.properties.cache_dir: "./config/model_cache/openvino"} ) self.interpreter = self.ov.compile_model( model=model_path, device_name=device diff --git a/frigate/version.py b/frigate/version.py new file mode 100644 index 000000000..7376d84f5 --- /dev/null +++ b/frigate/version.py @@ -0,0 +1 @@ +VERSION = "0.15.0" diff --git a/process_clip.py b/process_clip.py index 7ef9f4c75..722fd8f18 100644 --- a/process_clip.py +++ b/process_clip.py @@ -266,7 +266,7 @@ def process(path, label, output, debug_path): }, } - object_detector = LocalObjectDetector(labels="/labelmap.txt") + object_detector = LocalObjectDetector(labels="./labelmap.txt") results = [] for c in clips: