mirror of
https://github.com/blakeblackshear/frigate.git
synced 2024-11-21 19:07:46 +01:00
use a queue for logging
This commit is contained in:
parent
af303cbf2a
commit
4c3fea25a5
@ -1,9 +1,12 @@
|
|||||||
import faulthandler; faulthandler.enable()
|
import faulthandler; faulthandler.enable()
|
||||||
import os
|
import os
|
||||||
import json
|
import json
|
||||||
|
import logging
|
||||||
import yaml
|
import yaml
|
||||||
import multiprocessing as mp
|
import multiprocessing as mp
|
||||||
|
import sys
|
||||||
|
|
||||||
|
from logging.handlers import QueueHandler
|
||||||
from playhouse.sqlite_ext import SqliteExtDatabase
|
from playhouse.sqlite_ext import SqliteExtDatabase
|
||||||
from typing import Dict, List
|
from typing import Dict, List
|
||||||
|
|
||||||
@ -11,12 +14,18 @@ from frigate.config import FrigateConfig
|
|||||||
from frigate.edgetpu import EdgeTPUProcess
|
from frigate.edgetpu import EdgeTPUProcess
|
||||||
from frigate.events import EventProcessor
|
from frigate.events import EventProcessor
|
||||||
from frigate.http import create_app
|
from frigate.http import create_app
|
||||||
|
from frigate.log import root_configurer, log_process
|
||||||
from frigate.models import Event
|
from frigate.models import Event
|
||||||
from frigate.mqtt import create_mqtt_client
|
from frigate.mqtt import create_mqtt_client
|
||||||
from frigate.object_processing import TrackedObjectProcessor
|
from frigate.object_processing import TrackedObjectProcessor
|
||||||
from frigate.video import track_camera, capture_camera
|
from frigate.video import track_camera, capture_camera
|
||||||
from frigate.watchdog import FrigateWatchdog
|
from frigate.watchdog import FrigateWatchdog
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
cli = sys.modules['flask.cli']
|
||||||
|
cli.show_server_banner = lambda *x: None
|
||||||
|
|
||||||
class FrigateApp():
|
class FrigateApp():
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.stop_event = mp.Event()
|
self.stop_event = mp.Event()
|
||||||
@ -25,8 +34,14 @@ class FrigateApp():
|
|||||||
self.detectors: Dict[str, EdgeTPUProcess] = {}
|
self.detectors: Dict[str, EdgeTPUProcess] = {}
|
||||||
self.detection_out_events: Dict[str, mp.Event] = {}
|
self.detection_out_events: Dict[str, mp.Event] = {}
|
||||||
self.detection_shms: List[mp.shared_memory.SharedMemory] = []
|
self.detection_shms: List[mp.shared_memory.SharedMemory] = []
|
||||||
|
self.log_queue = mp.Queue()
|
||||||
self.camera_metrics = {}
|
self.camera_metrics = {}
|
||||||
|
|
||||||
|
def init_logger(self):
|
||||||
|
self.log_process = mp.Process(target=log_process, args=(self.log_queue,))
|
||||||
|
self.log_process.start()
|
||||||
|
root_configurer(self.log_queue)
|
||||||
|
|
||||||
def init_config(self):
|
def init_config(self):
|
||||||
config_file = os.environ.get('CONFIG_FILE', '/config/config.yml')
|
config_file = os.environ.get('CONFIG_FILE', '/config/config.yml')
|
||||||
self.config = FrigateConfig(config_file=config_file)
|
self.config = FrigateConfig(config_file=config_file)
|
||||||
@ -90,7 +105,7 @@ class FrigateApp():
|
|||||||
camera_process.daemon = True
|
camera_process.daemon = True
|
||||||
self.camera_metrics[name]['process'] = camera_process
|
self.camera_metrics[name]['process'] = camera_process
|
||||||
camera_process.start()
|
camera_process.start()
|
||||||
print(f"Camera processor started for {name}: {camera_process.pid}")
|
logger.info(f"Camera processor started for {name}: {camera_process.pid}")
|
||||||
|
|
||||||
def start_camera_capture_processes(self):
|
def start_camera_capture_processes(self):
|
||||||
for name, config in self.config.cameras.items():
|
for name, config in self.config.cameras.items():
|
||||||
@ -99,7 +114,7 @@ class FrigateApp():
|
|||||||
capture_process.daemon = True
|
capture_process.daemon = True
|
||||||
self.camera_metrics[name]['capture_process'] = capture_process
|
self.camera_metrics[name]['capture_process'] = capture_process
|
||||||
capture_process.start()
|
capture_process.start()
|
||||||
print(f"Capture process started for {name}: {capture_process.pid}")
|
logger.info(f"Capture process started for {name}: {capture_process.pid}")
|
||||||
|
|
||||||
def start_event_processor(self):
|
def start_event_processor(self):
|
||||||
self.event_processor = EventProcessor(self.config, self.camera_metrics, self.event_queue, self.stop_event)
|
self.event_processor = EventProcessor(self.config, self.camera_metrics, self.event_queue, self.stop_event)
|
||||||
@ -110,6 +125,7 @@ class FrigateApp():
|
|||||||
self.frigate_watchdog.start()
|
self.frigate_watchdog.start()
|
||||||
|
|
||||||
def start(self):
|
def start(self):
|
||||||
|
self.init_logger()
|
||||||
self.init_config()
|
self.init_config()
|
||||||
self.init_queues()
|
self.init_queues()
|
||||||
self.init_database()
|
self.init_database()
|
||||||
@ -125,7 +141,7 @@ class FrigateApp():
|
|||||||
self.stop()
|
self.stop()
|
||||||
|
|
||||||
def stop(self):
|
def stop(self):
|
||||||
print(f"Stopping...")
|
logger.info(f"Stopping...")
|
||||||
self.stop_event.set()
|
self.stop_event.set()
|
||||||
|
|
||||||
self.detected_frames_processor.join()
|
self.detected_frames_processor.join()
|
||||||
|
@ -10,8 +10,6 @@ import matplotlib.pyplot as plt
|
|||||||
import numpy as np
|
import numpy as np
|
||||||
import voluptuous as vol
|
import voluptuous as vol
|
||||||
|
|
||||||
from frigate.util import get_frame_shape
|
|
||||||
|
|
||||||
DETECTORS_SCHEMA = vol.Schema(
|
DETECTORS_SCHEMA = vol.Schema(
|
||||||
{
|
{
|
||||||
vol.Required(str): {
|
vol.Required(str): {
|
||||||
|
@ -3,6 +3,7 @@ import datetime
|
|||||||
import hashlib
|
import hashlib
|
||||||
import multiprocessing as mp
|
import multiprocessing as mp
|
||||||
import queue
|
import queue
|
||||||
|
import logging
|
||||||
from multiprocessing.connection import Connection
|
from multiprocessing.connection import Connection
|
||||||
from abc import ABC, abstractmethod
|
from abc import ABC, abstractmethod
|
||||||
from typing import Dict
|
from typing import Dict
|
||||||
@ -11,6 +12,8 @@ import tflite_runtime.interpreter as tflite
|
|||||||
from tflite_runtime.interpreter import load_delegate
|
from tflite_runtime.interpreter import load_delegate
|
||||||
from frigate.util import EventsPerSecond, listen, SharedMemoryFrameManager
|
from frigate.util import EventsPerSecond, listen, SharedMemoryFrameManager
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
def load_labels(path, encoding='utf-8'):
|
def load_labels(path, encoding='utf-8'):
|
||||||
"""Loads labels from file (with or without index numbers).
|
"""Loads labels from file (with or without index numbers).
|
||||||
Args:
|
Args:
|
||||||
@ -51,11 +54,11 @@ class LocalObjectDetector(ObjectDetector):
|
|||||||
|
|
||||||
if tf_device != 'cpu':
|
if tf_device != 'cpu':
|
||||||
try:
|
try:
|
||||||
print(f"Attempting to load TPU as {device_config['device']}")
|
logging.info(f"Attempting to load TPU as {device_config['device']}")
|
||||||
edge_tpu_delegate = load_delegate('libedgetpu.so.1.0', device_config)
|
edge_tpu_delegate = load_delegate('libedgetpu.so.1.0', device_config)
|
||||||
print("TPU found")
|
logging.info("TPU found")
|
||||||
except ValueError:
|
except ValueError:
|
||||||
print("No EdgeTPU detected. Falling back to CPU.")
|
logging.info("No EdgeTPU detected. Falling back to CPU.")
|
||||||
|
|
||||||
if edge_tpu_delegate is None:
|
if edge_tpu_delegate is None:
|
||||||
self.interpreter = tflite.Interpreter(
|
self.interpreter = tflite.Interpreter(
|
||||||
@ -100,7 +103,7 @@ class LocalObjectDetector(ObjectDetector):
|
|||||||
return detections
|
return detections
|
||||||
|
|
||||||
def run_detector(detection_queue: mp.Queue, out_events: Dict[str, mp.Event], avg_speed, start, tf_device):
|
def run_detector(detection_queue: mp.Queue, out_events: Dict[str, mp.Event], avg_speed, start, tf_device):
|
||||||
print(f"Starting detection process: {os.getpid()}")
|
logging.info(f"Starting detection process: {os.getpid()}")
|
||||||
listen()
|
listen()
|
||||||
frame_manager = SharedMemoryFrameManager()
|
frame_manager = SharedMemoryFrameManager()
|
||||||
object_detector = LocalObjectDetector(tf_device=tf_device)
|
object_detector = LocalObjectDetector(tf_device=tf_device)
|
||||||
@ -143,10 +146,10 @@ class EdgeTPUProcess():
|
|||||||
|
|
||||||
def stop(self):
|
def stop(self):
|
||||||
self.detect_process.terminate()
|
self.detect_process.terminate()
|
||||||
print("Waiting for detection process to exit gracefully...")
|
logging.info("Waiting for detection process to exit gracefully...")
|
||||||
self.detect_process.join(timeout=30)
|
self.detect_process.join(timeout=30)
|
||||||
if self.detect_process.exitcode is None:
|
if self.detect_process.exitcode is None:
|
||||||
print("Detection process didnt exit. Force killing...")
|
logging.info("Detection process didnt exit. Force killing...")
|
||||||
self.detect_process.kill()
|
self.detect_process.kill()
|
||||||
self.detect_process.join()
|
self.detect_process.join()
|
||||||
|
|
||||||
|
@ -2,6 +2,7 @@ import os
|
|||||||
import time
|
import time
|
||||||
import psutil
|
import psutil
|
||||||
import threading
|
import threading
|
||||||
|
import logging
|
||||||
from collections import defaultdict
|
from collections import defaultdict
|
||||||
import json
|
import json
|
||||||
import datetime
|
import datetime
|
||||||
@ -10,6 +11,8 @@ import queue
|
|||||||
|
|
||||||
from frigate.models import Event
|
from frigate.models import Event
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
class EventProcessor(threading.Thread):
|
class EventProcessor(threading.Thread):
|
||||||
def __init__(self, config, camera_processes, event_queue, stop_event):
|
def __init__(self, config, camera_processes, event_queue, stop_event):
|
||||||
threading.Thread.__init__(self)
|
threading.Thread.__init__(self)
|
||||||
@ -60,7 +63,7 @@ class EventProcessor(threading.Thread):
|
|||||||
if p_status == 0:
|
if p_status == 0:
|
||||||
duration = float(output.decode('utf-8').strip())
|
duration = float(output.decode('utf-8').strip())
|
||||||
else:
|
else:
|
||||||
print(f"bad file: {f}")
|
logger.info(f"bad file: {f}")
|
||||||
os.remove(os.path.join(self.cache_dir,f))
|
os.remove(os.path.join(self.cache_dir,f))
|
||||||
continue
|
continue
|
||||||
|
|
||||||
@ -133,7 +136,7 @@ class EventProcessor(threading.Thread):
|
|||||||
|
|
||||||
p = sp.run(ffmpeg_cmd, input="\n".join(playlist_lines), encoding='ascii', capture_output=True)
|
p = sp.run(ffmpeg_cmd, input="\n".join(playlist_lines), encoding='ascii', capture_output=True)
|
||||||
if p.returncode != 0:
|
if p.returncode != 0:
|
||||||
print(p.stderr)
|
logger.error(p.stderr)
|
||||||
return
|
return
|
||||||
|
|
||||||
with open(f"{os.path.join(self.clips_dir, clip_name)}.json", 'w') as outfile:
|
with open(f"{os.path.join(self.clips_dir, clip_name)}.json", 'w') as outfile:
|
||||||
@ -151,7 +154,7 @@ class EventProcessor(threading.Thread):
|
|||||||
def run(self):
|
def run(self):
|
||||||
while True:
|
while True:
|
||||||
if self.stop_event.is_set():
|
if self.stop_event.is_set():
|
||||||
print(f"Exiting event processor...")
|
logger.info(f"Exiting event processor...")
|
||||||
break
|
break
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
25
frigate/log.py
Normal file
25
frigate/log.py
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
# adapted from https://medium.com/@jonathonbao/python3-logging-with-multiprocessing-f51f460b8778
|
||||||
|
import logging
|
||||||
|
import threading
|
||||||
|
from logging import handlers
|
||||||
|
|
||||||
|
def listener_configurer():
|
||||||
|
root = logging.getLogger()
|
||||||
|
console_handler = logging.StreamHandler()
|
||||||
|
formatter = logging.Formatter('%(processName)-12s %(threadName)-12s %(name)-16s %(levelname)-8s: %(message)s')
|
||||||
|
console_handler.setFormatter(formatter)
|
||||||
|
root.addHandler(console_handler)
|
||||||
|
root.setLevel(logging.INFO)
|
||||||
|
|
||||||
|
def root_configurer(queue):
|
||||||
|
h = handlers.QueueHandler(queue)
|
||||||
|
root = logging.getLogger()
|
||||||
|
root.addHandler(h)
|
||||||
|
root.setLevel(logging.INFO)
|
||||||
|
|
||||||
|
def log_process(queue):
|
||||||
|
listener_configurer()
|
||||||
|
while True:
|
||||||
|
record = queue.get()
|
||||||
|
logger = logging.getLogger(record.name)
|
||||||
|
logger.handle(record)
|
@ -1,21 +1,24 @@
|
|||||||
|
import logging
|
||||||
import paho.mqtt.client as mqtt
|
import paho.mqtt.client as mqtt
|
||||||
|
|
||||||
from frigate.config import MqttConfig
|
from frigate.config import MqttConfig
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
def create_mqtt_client(config: MqttConfig):
|
def create_mqtt_client(config: MqttConfig):
|
||||||
client = mqtt.Client(client_id=config.client_id)
|
client = mqtt.Client(client_id=config.client_id)
|
||||||
def on_connect(client, userdata, flags, rc):
|
def on_connect(client, userdata, flags, rc):
|
||||||
# TODO: use logging library
|
# TODO: use logging library
|
||||||
print("On connect called")
|
logger.info("On connect called")
|
||||||
if rc != 0:
|
if rc != 0:
|
||||||
if rc == 3:
|
if rc == 3:
|
||||||
print ("MQTT Server unavailable")
|
logger.error("MQTT Server unavailable")
|
||||||
elif rc == 4:
|
elif rc == 4:
|
||||||
print ("MQTT Bad username or password")
|
logger.error("MQTT Bad username or password")
|
||||||
elif rc == 5:
|
elif rc == 5:
|
||||||
print ("MQTT Not authorized")
|
logger.error("MQTT Not authorized")
|
||||||
else:
|
else:
|
||||||
print ("Unable to connect to MQTT: Connection refused. Error code: " + str(rc))
|
logger.error("Unable to connect to MQTT: Connection refused. Error code: " + str(rc))
|
||||||
client.publish(config.topic_prefix+'/available', 'online', retain=True)
|
client.publish(config.topic_prefix+'/available', 'online', retain=True)
|
||||||
client.on_connect = on_connect
|
client.on_connect = on_connect
|
||||||
client.will_set(config.topic_prefix+'/available', payload='offline', qos=1, retain=True)
|
client.will_set(config.topic_prefix+'/available', payload='offline', qos=1, retain=True)
|
||||||
|
@ -5,6 +5,7 @@ import time
|
|||||||
import copy
|
import copy
|
||||||
import cv2
|
import cv2
|
||||||
import threading
|
import threading
|
||||||
|
import logging
|
||||||
import queue
|
import queue
|
||||||
import copy
|
import copy
|
||||||
import numpy as np
|
import numpy as np
|
||||||
@ -17,6 +18,8 @@ from frigate.config import CameraConfig
|
|||||||
from typing import Callable, Dict
|
from typing import Callable, Dict
|
||||||
from statistics import mean, median
|
from statistics import mean, median
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
PATH_TO_LABELS = '/labelmap.txt'
|
PATH_TO_LABELS = '/labelmap.txt'
|
||||||
|
|
||||||
LABELS = load_labels(PATH_TO_LABELS)
|
LABELS = load_labels(PATH_TO_LABELS)
|
||||||
@ -366,7 +369,7 @@ class TrackedObjectProcessor(threading.Thread):
|
|||||||
def run(self):
|
def run(self):
|
||||||
while True:
|
while True:
|
||||||
if self.stop_event.is_set():
|
if self.stop_event.is_set():
|
||||||
print(f"Exiting object processor...")
|
logger.info(f"Exiting object processor...")
|
||||||
break
|
break
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
@ -14,36 +14,6 @@ import hashlib
|
|||||||
from multiprocessing import shared_memory
|
from multiprocessing import shared_memory
|
||||||
from typing import AnyStr
|
from typing import AnyStr
|
||||||
|
|
||||||
def get_frame_shape(source):
|
|
||||||
ffprobe_cmd = " ".join([
|
|
||||||
'ffprobe',
|
|
||||||
'-v',
|
|
||||||
'panic',
|
|
||||||
'-show_error',
|
|
||||||
'-show_streams',
|
|
||||||
'-of',
|
|
||||||
'json',
|
|
||||||
'"'+source+'"'
|
|
||||||
])
|
|
||||||
print(ffprobe_cmd)
|
|
||||||
p = sp.Popen(ffprobe_cmd, stdout=sp.PIPE, shell=True)
|
|
||||||
(output, err) = p.communicate()
|
|
||||||
p_status = p.wait()
|
|
||||||
info = json.loads(output)
|
|
||||||
print(info)
|
|
||||||
|
|
||||||
video_info = [s for s in info['streams'] if s['codec_type'] == 'video'][0]
|
|
||||||
|
|
||||||
if video_info['height'] != 0 and video_info['width'] != 0:
|
|
||||||
return (video_info['height'], video_info['width'], 3)
|
|
||||||
|
|
||||||
# fallback to using opencv if ffprobe didnt succeed
|
|
||||||
video = cv2.VideoCapture(source)
|
|
||||||
ret, frame = video.read()
|
|
||||||
frame_shape = frame.shape
|
|
||||||
video.release()
|
|
||||||
return frame_shape
|
|
||||||
|
|
||||||
def draw_box_with_label(frame, x_min, y_min, x_max, y_max, label, info, thickness=2, color=None, position='ul'):
|
def draw_box_with_label(frame, x_min, y_min, x_max, y_max, label, info, thickness=2, color=None, position='ul'):
|
||||||
if color is None:
|
if color is None:
|
||||||
color = (0,0,255)
|
color = (0,0,255)
|
||||||
|
@ -4,6 +4,7 @@ import datetime
|
|||||||
import cv2
|
import cv2
|
||||||
import queue
|
import queue
|
||||||
import threading
|
import threading
|
||||||
|
import logging
|
||||||
import ctypes
|
import ctypes
|
||||||
import multiprocessing as mp
|
import multiprocessing as mp
|
||||||
import subprocess as sp
|
import subprocess as sp
|
||||||
@ -20,6 +21,8 @@ from frigate.objects import ObjectTracker
|
|||||||
from frigate.edgetpu import RemoteObjectDetector
|
from frigate.edgetpu import RemoteObjectDetector
|
||||||
from frigate.motion import MotionDetector
|
from frigate.motion import MotionDetector
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
def filtered(obj, objects_to_track, object_filters, mask=None):
|
def filtered(obj, objects_to_track, object_filters, mask=None):
|
||||||
object_name = obj[0]
|
object_name = obj[0]
|
||||||
|
|
||||||
@ -66,19 +69,19 @@ def create_tensor_input(frame, region):
|
|||||||
|
|
||||||
def start_or_restart_ffmpeg(ffmpeg_cmd, frame_size, ffmpeg_process=None):
|
def start_or_restart_ffmpeg(ffmpeg_cmd, frame_size, ffmpeg_process=None):
|
||||||
if not ffmpeg_process is None:
|
if not ffmpeg_process is None:
|
||||||
print("Terminating the existing ffmpeg process...")
|
logger.info("Terminating the existing ffmpeg process...")
|
||||||
ffmpeg_process.terminate()
|
ffmpeg_process.terminate()
|
||||||
try:
|
try:
|
||||||
print("Waiting for ffmpeg to exit gracefully...")
|
logger.info("Waiting for ffmpeg to exit gracefully...")
|
||||||
ffmpeg_process.communicate(timeout=30)
|
ffmpeg_process.communicate(timeout=30)
|
||||||
except sp.TimeoutExpired:
|
except sp.TimeoutExpired:
|
||||||
print("FFmpeg didnt exit. Force killing...")
|
logger.info("FFmpeg didnt exit. Force killing...")
|
||||||
ffmpeg_process.kill()
|
ffmpeg_process.kill()
|
||||||
ffmpeg_process.communicate()
|
ffmpeg_process.communicate()
|
||||||
ffmpeg_process = None
|
ffmpeg_process = None
|
||||||
|
|
||||||
print("Creating ffmpeg process...")
|
logger.info("Creating ffmpeg process...")
|
||||||
print(" ".join(ffmpeg_cmd))
|
logger.info(" ".join(ffmpeg_cmd))
|
||||||
process = sp.Popen(ffmpeg_cmd, stdout = sp.PIPE, stdin = sp.DEVNULL, bufsize=frame_size*10, start_new_session=True)
|
process = sp.Popen(ffmpeg_cmd, stdout = sp.PIPE, stdin = sp.DEVNULL, bufsize=frame_size*10, start_new_session=True)
|
||||||
return process
|
return process
|
||||||
|
|
||||||
@ -100,10 +103,10 @@ def capture_frames(ffmpeg_process, camera_name, frame_shape, frame_manager: Fram
|
|||||||
try:
|
try:
|
||||||
frame_buffer[:] = ffmpeg_process.stdout.read(frame_size)
|
frame_buffer[:] = ffmpeg_process.stdout.read(frame_size)
|
||||||
except:
|
except:
|
||||||
print(f"{camera_name}: ffmpeg sent a broken frame. something is wrong.")
|
logger.info(f"{camera_name}: ffmpeg sent a broken frame. something is wrong.")
|
||||||
|
|
||||||
if ffmpeg_process.poll() != None:
|
if ffmpeg_process.poll() != None:
|
||||||
print(f"{camera_name}: ffmpeg process is not running. exiting capture thread...")
|
logger.info(f"{camera_name}: ffmpeg process is not running. exiting capture thread...")
|
||||||
frame_manager.delete(frame_name)
|
frame_manager.delete(frame_name)
|
||||||
break
|
break
|
||||||
|
|
||||||
@ -145,13 +148,13 @@ class CameraWatchdog(threading.Thread):
|
|||||||
if not self.capture_thread.is_alive():
|
if not self.capture_thread.is_alive():
|
||||||
self.start_ffmpeg()
|
self.start_ffmpeg()
|
||||||
elif now - self.capture_thread.current_frame.value > 5:
|
elif now - self.capture_thread.current_frame.value > 5:
|
||||||
print(f"No frames received from {self.name} in 5 seconds. Exiting ffmpeg...")
|
logger.info(f"No frames received from {self.name} in 5 seconds. Exiting ffmpeg...")
|
||||||
self.ffmpeg_process.terminate()
|
self.ffmpeg_process.terminate()
|
||||||
try:
|
try:
|
||||||
print("Waiting for ffmpeg to exit gracefully...")
|
logger.info("Waiting for ffmpeg to exit gracefully...")
|
||||||
self.ffmpeg_process.communicate(timeout=30)
|
self.ffmpeg_process.communicate(timeout=30)
|
||||||
except sp.TimeoutExpired:
|
except sp.TimeoutExpired:
|
||||||
print("FFmpeg didnt exit. Force killing...")
|
logger.info("FFmpeg didnt exit. Force killing...")
|
||||||
self.ffmpeg_process.kill()
|
self.ffmpeg_process.kill()
|
||||||
self.ffmpeg_process.communicate()
|
self.ffmpeg_process.communicate()
|
||||||
|
|
||||||
@ -209,7 +212,7 @@ def track_camera(name, config: CameraConfig, detection_queue, result_connection,
|
|||||||
process_frames(name, frame_queue, frame_shape, frame_manager, motion_detector, object_detector,
|
process_frames(name, frame_queue, frame_shape, frame_manager, motion_detector, object_detector,
|
||||||
object_tracker, detected_objects_queue, process_info, objects_to_track, object_filters, mask)
|
object_tracker, detected_objects_queue, process_info, objects_to_track, object_filters, mask)
|
||||||
|
|
||||||
print(f"{name}: exiting subprocess")
|
logger.info(f"{name}: exiting subprocess")
|
||||||
|
|
||||||
def reduce_boxes(boxes):
|
def reduce_boxes(boxes):
|
||||||
if len(boxes) == 0:
|
if len(boxes) == 0:
|
||||||
@ -256,7 +259,7 @@ def process_frames(camera_name: str, frame_queue: mp.Queue, frame_shape,
|
|||||||
|
|
||||||
while True:
|
while True:
|
||||||
if exit_on_empty and frame_queue.empty():
|
if exit_on_empty and frame_queue.empty():
|
||||||
print(f"Exiting track_objects...")
|
logger.info(f"Exiting track_objects...")
|
||||||
break
|
break
|
||||||
|
|
||||||
try:
|
try:
|
||||||
@ -269,7 +272,7 @@ def process_frames(camera_name: str, frame_queue: mp.Queue, frame_shape,
|
|||||||
frame = frame_manager.get(f"{camera_name}{frame_time}", (frame_shape[0]*3//2, frame_shape[1]))
|
frame = frame_manager.get(f"{camera_name}{frame_time}", (frame_shape[0]*3//2, frame_shape[1]))
|
||||||
|
|
||||||
if frame is None:
|
if frame is None:
|
||||||
print(f"{camera_name}: frame {frame_time} is not in memory store.")
|
logger.info(f"{camera_name}: frame {frame_time} is not in memory store.")
|
||||||
continue
|
continue
|
||||||
|
|
||||||
# look for motion
|
# look for motion
|
||||||
|
@ -1,7 +1,10 @@
|
|||||||
import datetime
|
import datetime
|
||||||
|
import logging
|
||||||
import time
|
import time
|
||||||
import threading
|
import threading
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
class FrigateWatchdog(threading.Thread):
|
class FrigateWatchdog(threading.Thread):
|
||||||
def __init__(self, detectors, stop_event):
|
def __init__(self, detectors, stop_event):
|
||||||
threading.Thread.__init__(self)
|
threading.Thread.__init__(self)
|
||||||
@ -15,7 +18,7 @@ class FrigateWatchdog(threading.Thread):
|
|||||||
time.sleep(10)
|
time.sleep(10)
|
||||||
|
|
||||||
if self.stop_event.is_set():
|
if self.stop_event.is_set():
|
||||||
print(f"Exiting watchdog...")
|
logger.info(f"Exiting watchdog...")
|
||||||
break
|
break
|
||||||
|
|
||||||
now = datetime.datetime.now().timestamp()
|
now = datetime.datetime.now().timestamp()
|
||||||
@ -25,8 +28,8 @@ class FrigateWatchdog(threading.Thread):
|
|||||||
detection_start = detector.detection_start.value
|
detection_start = detector.detection_start.value
|
||||||
if (detection_start > 0.0 and
|
if (detection_start > 0.0 and
|
||||||
now - detection_start > 10):
|
now - detection_start > 10):
|
||||||
print("Detection appears to be stuck. Restarting detection process")
|
logger.info("Detection appears to be stuck. Restarting detection process")
|
||||||
detector.start_or_restart()
|
detector.start_or_restart()
|
||||||
elif not detector.detect_process.is_alive():
|
elif not detector.detect_process.is_alive():
|
||||||
print("Detection appears to have stopped. Restarting detection process")
|
logger.info("Detection appears to have stopped. Restarting detection process")
|
||||||
detector.start_or_restart()
|
detector.start_or_restart()
|
||||||
|
Loading…
Reference in New Issue
Block a user