Add audio detection process keypoints

This commit is contained in:
Nick Mowen 2023-06-17 17:14:43 -06:00
parent 2a83a3626c
commit 87a4d1d15b
3 changed files with 81 additions and 4 deletions

View File

@ -30,6 +30,8 @@ from frigate.const import (
MODEL_CACHE_DIR, MODEL_CACHE_DIR,
RECORD_DIR, RECORD_DIR,
) )
from frigate.detectors.plugins.audio_tfl import AudioDetectorConfig
from frigate.events.audio import AudioDetectProcess
from frigate.events.cleanup import EventCleanup from frigate.events.cleanup import EventCleanup
from frigate.events.external import ExternalEventProcessor from frigate.events.external import ExternalEventProcessor
from frigate.events.maintainer import EventProcessor from frigate.events.maintainer import EventProcessor
@ -60,6 +62,7 @@ class FrigateApp:
self.detectors: dict[str, ObjectDetectProcess] = {} self.detectors: dict[str, ObjectDetectProcess] = {}
self.detection_out_events: dict[str, MpEvent] = {} self.detection_out_events: dict[str, MpEvent] = {}
self.detection_shms: list[mp.shared_memory.SharedMemory] = [] self.detection_shms: list[mp.shared_memory.SharedMemory] = []
self.audio_queue: Queue = mp.Queue()
self.log_queue: Queue = mp.Queue() self.log_queue: Queue = mp.Queue()
self.plus_api = PlusApi() self.plus_api = PlusApi()
self.camera_metrics: dict[str, CameraMetricsTypes] = {} self.camera_metrics: dict[str, CameraMetricsTypes] = {}
@ -287,6 +290,8 @@ class FrigateApp:
) )
def start_detectors(self) -> None: def start_detectors(self) -> None:
audio_enabled = any(c.audio.enabled for c in self.config.cameras.items())
for name in self.config.cameras.keys(): for name in self.config.cameras.keys():
self.detection_out_events[name] = mp.Event() self.detection_out_events[name] = mp.Event()
@ -315,6 +320,33 @@ class FrigateApp:
self.detection_shms.append(shm_in) self.detection_shms.append(shm_in)
self.detection_shms.append(shm_out) self.detection_shms.append(shm_out)
if audio_enabled:
try:
shm_in_audio = mp.shared_memory.SharedMemory(
name=f"{name}-audio",
create=True,
size=int(
round(
self.config.audio_model.duration
* self.config.audio_model.sample_rate
)
)
* 4, # stored as float32, so 4 bytes per sample
)
except FileExistsError:
shm_in_audio = mp.shared_memory.SharedMemory(name=f"{name}-audio")
try:
shm_out_audio = mp.shared_memory.SharedMemory(
name=f"out-{name}-audio", create=True, size=20 * 6 * 4
)
except FileExistsError:
shm_out_audio = mp.shared_memory.SharedMemory(
name=f"out-{name}-audio"
)
for name, detector_config in self.config.detectors.items(): for name, detector_config in self.config.detectors.items():
self.detectors[name] = ObjectDetectProcess( self.detectors[name] = ObjectDetectProcess(
name, name,
@ -323,10 +355,12 @@ class FrigateApp:
detector_config, detector_config,
) )
if any(c.audio.enabled for c in self.config.cameras.items()): if audio_enabled:
self.detectors[AUDIO_DETECTOR] = ObjectDetectProcess( self.detectors[AUDIO_DETECTOR] = AudioDetectProcess(
AUDIO_DETECTOR, AUDIO_DETECTOR,
self.audio_queue,
self.detection_out_events,
AudioDetectorConfig
) )
def start_detected_frames_processor(self) -> None: def start_detected_frames_processor(self) -> None:

View File

@ -22,7 +22,7 @@ class AudioDetectorConfig(BaseDetectorConfig):
type: Literal[DETECTOR_KEY] type: Literal[DETECTOR_KEY]
class CpuTfl(DetectionApi): class AudioTfl(DetectionApi):
type_key = DETECTOR_KEY type_key = DETECTOR_KEY
def __init__(self, detector_config: AudioDetectorConfig): def __init__(self, detector_config: AudioDetectorConfig):

View File

@ -36,6 +36,49 @@ def listen_to_audio(config: FrigateConfig, event_queue: mp.Queue) -> None:
AudioEventMaintainer(camera, stop_event) AudioEventMaintainer(camera, stop_event)
class AudioDetectProcess:
def __init__(
self,
name,
detection_queue,
out_events,
):
self.name = name
self.out_events = out_events
self.detection_queue = detection_queue
self.detect_process = None
self.start_or_restart()
def stop(self):
# if the process has already exited on its own, just return
if self.detect_process and self.detect_process.exitcode:
return
self.detect_process.terminate()
logging.info("Waiting for detection process to exit gracefully...")
self.detect_process.join(timeout=30)
if self.detect_process.exitcode is None:
logging.info("Detection process didnt exit. Force killing...")
self.detect_process.kill()
self.detect_process.join()
logging.info("Detection process has exited...")
def start_or_restart(self):
self.detection_start.value = 0.0
if (self.detect_process is not None) and self.detect_process.is_alive():
self.stop()
self.detect_process = mp.Process(
target=run_detector,
name=f"detector:{self.name}",
args=(
self.name,
self.detection_queue,
self.out_events,
),
)
self.detect_process.daemon = True
self.detect_process.start()
class AudioEventMaintainer(threading.Thread): class AudioEventMaintainer(threading.Thread):
def __init__(self, camera: CameraConfig, stop_event: mp.Event) -> None: def __init__(self, camera: CameraConfig, stop_event: mp.Event) -> None:
threading.Thread.__init__(self) threading.Thread.__init__(self)