mirror of
https://github.com/blakeblackshear/frigate.git
synced 2026-07-08 21:11:25 +03:00
make audio maintainer respond to dynamic config updates
This commit is contained in:
parent
9731f8687f
commit
f391406a94
@ -428,18 +428,11 @@ class FrigateApp:
|
|||||||
self.camera_maintainer.start()
|
self.camera_maintainer.start()
|
||||||
|
|
||||||
def start_audio_processor(self) -> None:
|
def start_audio_processor(self) -> None:
|
||||||
audio_cameras = [
|
self.audio_process = AudioProcessor(
|
||||||
c
|
self.config, self.camera_metrics, self.stop_event
|
||||||
for c in self.config.cameras.values()
|
)
|
||||||
if c.enabled and c.audio.enabled_in_config
|
self.audio_process.start()
|
||||||
]
|
self.processes["audio_detector"] = self.audio_process.pid or 0
|
||||||
|
|
||||||
if audio_cameras:
|
|
||||||
self.audio_process = AudioProcessor(
|
|
||||||
self.config, audio_cameras, self.camera_metrics, self.stop_event
|
|
||||||
)
|
|
||||||
self.audio_process.start()
|
|
||||||
self.processes["audio_detector"] = self.audio_process.pid or 0
|
|
||||||
|
|
||||||
def start_timeline_processor(self) -> None:
|
def start_timeline_processor(self) -> None:
|
||||||
self.timeline_processor = TimelineProcessor(
|
self.timeline_processor = TimelineProcessor(
|
||||||
|
|||||||
@ -84,7 +84,6 @@ class AudioProcessor(FrigateProcess):
|
|||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
config: FrigateConfig,
|
config: FrigateConfig,
|
||||||
cameras: list[CameraConfig],
|
|
||||||
camera_metrics: DictProxy,
|
camera_metrics: DictProxy,
|
||||||
stop_event: MpEvent,
|
stop_event: MpEvent,
|
||||||
):
|
):
|
||||||
@ -93,12 +92,11 @@ class AudioProcessor(FrigateProcess):
|
|||||||
)
|
)
|
||||||
|
|
||||||
self.camera_metrics = camera_metrics
|
self.camera_metrics = camera_metrics
|
||||||
self.cameras = cameras
|
|
||||||
self.config = config
|
self.config = config
|
||||||
|
|
||||||
def run(self) -> None:
|
def run(self) -> None:
|
||||||
self.pre_run_setup(self.config.logger)
|
self.pre_run_setup(self.config.logger)
|
||||||
audio_threads: list[AudioEventMaintainer] = []
|
audio_threads: dict[str, AudioEventMaintainer] = {}
|
||||||
|
|
||||||
threading.current_thread().name = "process:audio_manager"
|
threading.current_thread().name = "process:audio_manager"
|
||||||
|
|
||||||
@ -112,32 +110,55 @@ class AudioProcessor(FrigateProcess):
|
|||||||
else:
|
else:
|
||||||
self.transcription_model_runner = None
|
self.transcription_model_runner = None
|
||||||
|
|
||||||
if len(self.cameras) == 0:
|
config_subscriber = CameraConfigUpdateSubscriber(
|
||||||
return
|
self.config,
|
||||||
|
self.config.cameras,
|
||||||
|
[
|
||||||
|
CameraConfigUpdateEnum.add,
|
||||||
|
CameraConfigUpdateEnum.audio,
|
||||||
|
CameraConfigUpdateEnum.ffmpeg,
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
for camera in self.cameras:
|
def spawn_if_needed(camera: CameraConfig) -> None:
|
||||||
audio_thread = AudioEventMaintainer(
|
if camera.name in audio_threads:
|
||||||
|
return
|
||||||
|
if not camera.enabled or not camera.audio.enabled:
|
||||||
|
return
|
||||||
|
# ffmpeg update may not have arrived yet; wait for next poll
|
||||||
|
if not any("audio" in i.roles for i in camera.ffmpeg.inputs):
|
||||||
|
return
|
||||||
|
thread = AudioEventMaintainer(
|
||||||
camera,
|
camera,
|
||||||
self.config,
|
self.config,
|
||||||
self.camera_metrics,
|
self.camera_metrics,
|
||||||
self.transcription_model_runner,
|
self.transcription_model_runner,
|
||||||
self.stop_event, # type: ignore[arg-type]
|
self.stop_event, # type: ignore[arg-type]
|
||||||
)
|
)
|
||||||
audio_threads.append(audio_thread)
|
audio_threads[camera.name] = thread
|
||||||
audio_thread.start()
|
thread.start()
|
||||||
|
self.logger.info(f"Audio maintainer started for {camera.name}")
|
||||||
|
|
||||||
|
for camera in self.config.cameras.values():
|
||||||
|
spawn_if_needed(camera)
|
||||||
|
|
||||||
self.logger.info(f"Audio processor started (pid: {self.pid})")
|
self.logger.info(f"Audio processor started (pid: {self.pid})")
|
||||||
|
|
||||||
while not self.stop_event.wait():
|
# poll for newly added cameras or cameras flipped to audio.enabled at runtime
|
||||||
pass
|
while not self.stop_event.wait(timeout=1.0):
|
||||||
|
config_subscriber.check_for_updates()
|
||||||
|
for camera in self.config.cameras.values():
|
||||||
|
spawn_if_needed(camera)
|
||||||
|
|
||||||
for thread in audio_threads:
|
config_subscriber.stop()
|
||||||
|
|
||||||
|
for thread in audio_threads.values():
|
||||||
thread.join(1)
|
thread.join(1)
|
||||||
if thread.is_alive():
|
if thread.is_alive():
|
||||||
self.logger.info(f"Waiting for thread {thread.name:s} to exit")
|
self.logger.info(f"Waiting for thread {thread.name:s} to exit")
|
||||||
thread.join(10)
|
thread.join(10)
|
||||||
|
|
||||||
for thread in audio_threads:
|
for thread in audio_threads.values():
|
||||||
if thread.is_alive():
|
if thread.is_alive():
|
||||||
self.logger.warning(f"Thread {thread.name} is still alive")
|
self.logger.warning(f"Thread {thread.name} is still alive")
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user