mirror of
https://github.com/blakeblackshear/frigate.git
synced 2026-04-21 06:21:53 +03:00
create audio activity manager
move publishing logic out of audio detector
This commit is contained in:
parent
5af8fbac51
commit
12e4f4b9cd
@ -1,10 +1,21 @@
|
|||||||
"""Manage camera activity and updating listeners."""
|
"""Manage camera activity and updating listeners."""
|
||||||
|
|
||||||
|
import datetime
|
||||||
|
import json
|
||||||
|
import logging
|
||||||
|
import random
|
||||||
|
import string
|
||||||
from collections import Counter
|
from collections import Counter
|
||||||
from typing import Any, Callable
|
from typing import Any, Callable
|
||||||
|
|
||||||
|
from frigate.comms.event_metadata_updater import (
|
||||||
|
EventMetadataPublisher,
|
||||||
|
EventMetadataTypeEnum,
|
||||||
|
)
|
||||||
from frigate.config import CameraConfig, FrigateConfig
|
from frigate.config import CameraConfig, FrigateConfig
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
class CameraActivityManager:
|
class CameraActivityManager:
|
||||||
def __init__(
|
def __init__(
|
||||||
@ -139,3 +150,106 @@ class CameraActivityManager:
|
|||||||
if any_changed:
|
if any_changed:
|
||||||
self.publish(f"{camera}/all", sum(list(all_objects.values())))
|
self.publish(f"{camera}/all", sum(list(all_objects.values())))
|
||||||
self.publish(f"{camera}/all/active", sum(list(active_objects.values())))
|
self.publish(f"{camera}/all/active", sum(list(active_objects.values())))
|
||||||
|
|
||||||
|
|
||||||
|
class AudioActivityManager:
|
||||||
|
def __init__(
|
||||||
|
self, config: FrigateConfig, publish: Callable[[str, Any], None]
|
||||||
|
) -> None:
|
||||||
|
self.config = config
|
||||||
|
self.publish = publish
|
||||||
|
self.current_audio_detections: dict[str, dict[str, dict[str, Any]]] = {}
|
||||||
|
self.event_metadata_publisher = EventMetadataPublisher()
|
||||||
|
|
||||||
|
for camera_config in config.cameras.values():
|
||||||
|
if not camera_config.audio.enabled_in_config:
|
||||||
|
continue
|
||||||
|
|
||||||
|
self.__init_camera(camera_config)
|
||||||
|
|
||||||
|
def __init_camera(self, camera_config: CameraConfig) -> None:
|
||||||
|
self.current_audio_detections[camera_config.name] = {}
|
||||||
|
|
||||||
|
def update_activity(self, new_activity: dict[str, dict[str, Any]]) -> None:
|
||||||
|
now = datetime.datetime.now().timestamp()
|
||||||
|
|
||||||
|
for camera in new_activity.keys():
|
||||||
|
# handle cameras that were added dynamically
|
||||||
|
if camera not in self.current_audio_detections:
|
||||||
|
self.__init_camera(self.config.cameras[camera])
|
||||||
|
|
||||||
|
new_detections = new_activity[camera].get("detections", [])
|
||||||
|
if self.compare_audio_activity(camera, new_detections, now):
|
||||||
|
logger.info(f"audio detections {camera}, {new_activity}")
|
||||||
|
self.publish(
|
||||||
|
"audio_detections",
|
||||||
|
json.dumps(self.current_audio_detections),
|
||||||
|
)
|
||||||
|
|
||||||
|
def compare_audio_activity(
|
||||||
|
self, camera: str, new_detections: list[tuple[str, float]], now: float
|
||||||
|
) -> None:
|
||||||
|
max_not_heard = self.config.cameras[camera].audio.max_not_heard
|
||||||
|
current = self.current_audio_detections[camera]
|
||||||
|
|
||||||
|
any_changed = False
|
||||||
|
|
||||||
|
for label, score in new_detections:
|
||||||
|
any_changed = True
|
||||||
|
if label in current:
|
||||||
|
current[label]["last_detection"] = now
|
||||||
|
current[label]["score"] = score
|
||||||
|
else:
|
||||||
|
rand_id = "".join(
|
||||||
|
random.choices(string.ascii_lowercase + string.digits, k=6)
|
||||||
|
)
|
||||||
|
event_id = f"{now}-{rand_id}"
|
||||||
|
self.publish(f"{camera}/audio/{label}", "ON")
|
||||||
|
|
||||||
|
self.event_metadata_publisher.publish(
|
||||||
|
(
|
||||||
|
now,
|
||||||
|
camera,
|
||||||
|
label,
|
||||||
|
event_id,
|
||||||
|
True,
|
||||||
|
score,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
"audio",
|
||||||
|
{},
|
||||||
|
),
|
||||||
|
EventMetadataTypeEnum.manual_event_create.value,
|
||||||
|
)
|
||||||
|
current[label] = {
|
||||||
|
"id": event_id,
|
||||||
|
"score": score,
|
||||||
|
"last_detection": now,
|
||||||
|
}
|
||||||
|
|
||||||
|
# expire detections
|
||||||
|
for label in list(current.keys()):
|
||||||
|
if now - current[label]["last_detection"] > max_not_heard:
|
||||||
|
any_changed = True
|
||||||
|
self.publish(f"{camera}/audio/{label}", "OFF")
|
||||||
|
|
||||||
|
self.event_metadata_publisher.publish(
|
||||||
|
(current[label]["id"], now),
|
||||||
|
EventMetadataTypeEnum.manual_event_end.value,
|
||||||
|
)
|
||||||
|
del current[label]
|
||||||
|
|
||||||
|
return any_changed
|
||||||
|
|
||||||
|
def expire_all(self, camera: str) -> None:
|
||||||
|
now = datetime.datetime.now().timestamp()
|
||||||
|
current = self.current_audio_detections.get(camera, {})
|
||||||
|
|
||||||
|
for label in list(current.keys()):
|
||||||
|
self.publish(f"{camera}/audio/{label}", "OFF")
|
||||||
|
|
||||||
|
self.event_metadata_publisher.publish(
|
||||||
|
(current[label]["id"], now),
|
||||||
|
EventMetadataTypeEnum.manual_event_end.value,
|
||||||
|
)
|
||||||
|
del current[label]
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user