mirror of
https://github.com/blakeblackshear/frigate.git
synced 2026-02-05 10:45:21 +03:00
Fix snapshot saving
This commit is contained in:
parent
c4aea4d1ca
commit
b64b0ac487
@ -1,7 +1,9 @@
|
|||||||
"""Handle external events created by the user."""
|
"""Handle external events created by the user."""
|
||||||
|
|
||||||
|
import cv2
|
||||||
import datetime
|
import datetime
|
||||||
import logging
|
import logging
|
||||||
|
import os
|
||||||
import random
|
import random
|
||||||
import string
|
import string
|
||||||
|
|
||||||
@ -9,9 +11,9 @@ from typing import Optional
|
|||||||
|
|
||||||
from multiprocessing.queues import Queue
|
from multiprocessing.queues import Queue
|
||||||
|
|
||||||
from frigate.config import FrigateConfig
|
from frigate.config import CameraConfig, FrigateConfig
|
||||||
|
from frigate.const import CLIPS_DIR
|
||||||
from frigate.events.maintainer import EventTypeEnum
|
from frigate.events.maintainer import EventTypeEnum
|
||||||
from frigate.models import Event
|
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
@ -28,6 +30,7 @@ class ExternalEventProcessor:
|
|||||||
sub_label: Optional[str],
|
sub_label: Optional[str],
|
||||||
duration: Optional[int],
|
duration: Optional[int],
|
||||||
include_recording: bool,
|
include_recording: bool,
|
||||||
|
snapshot_frame: any,
|
||||||
) -> str:
|
) -> str:
|
||||||
now = datetime.datetime.now().timestamp()
|
now = datetime.datetime.now().timestamp()
|
||||||
camera_config = self.config.cameras.get(camera)
|
camera_config = self.config.cameras.get(camera)
|
||||||
@ -36,6 +39,7 @@ class ExternalEventProcessor:
|
|||||||
rand_id = "".join(random.choices(string.ascii_lowercase + string.digits, k=6))
|
rand_id = "".join(random.choices(string.ascii_lowercase + string.digits, k=6))
|
||||||
event_id = f"{now}-{rand_id}"
|
event_id = f"{now}-{rand_id}"
|
||||||
|
|
||||||
|
self._write_snapshots(camera_config, event_id, snapshot_frame)
|
||||||
self.queue.put(
|
self.queue.put(
|
||||||
(
|
(
|
||||||
EventTypeEnum.api,
|
EventTypeEnum.api,
|
||||||
@ -50,16 +54,41 @@ class ExternalEventProcessor:
|
|||||||
"end_time": now + duration if duration is not None else None,
|
"end_time": now + duration if duration is not None else None,
|
||||||
"thumbnail": "", # TODO create thumbnail icon
|
"thumbnail": "", # TODO create thumbnail icon
|
||||||
"has_clip": camera_config.record.enabled and include_recording,
|
"has_clip": camera_config.record.enabled and include_recording,
|
||||||
"has_snapshot": False, # TODO get snapshot frame passed in
|
"has_snapshot": True,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
return event_id
|
return event_id
|
||||||
|
|
||||||
def finish_manual_event(self, event_id: str):
|
def finish_manual_event(self, event_id: str) -> None:
|
||||||
"""Finish external event with indeterminate duration."""
|
"""Finish external event with indeterminate duration."""
|
||||||
now = datetime.datetime.now().timestamp()
|
now = datetime.datetime.now().timestamp()
|
||||||
self.queue.put(
|
self.queue.put(
|
||||||
(EventTypeEnum.api, "end", None, {"id": event_id, "end_time": now})
|
(EventTypeEnum.api, "end", None, {"id": event_id, "end_time": now})
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def _write_snapshots(
|
||||||
|
self, camera_config: CameraConfig, event_id: str, img_bytes: any
|
||||||
|
) -> None:
|
||||||
|
# write jpg snapshot
|
||||||
|
ret, jpg = cv2.imencode(".jpg", img_bytes)
|
||||||
|
with open(
|
||||||
|
os.path.join(CLIPS_DIR, f"{camera_config.name}-{event_id}.jpg"),
|
||||||
|
"wb",
|
||||||
|
) as j:
|
||||||
|
j.write(jpg.tobytes())
|
||||||
|
|
||||||
|
# write clean snapshot if enabled
|
||||||
|
if camera_config.snapshots.clean_copy:
|
||||||
|
ret, png = cv2.imencode(".png", img_bytes)
|
||||||
|
|
||||||
|
if ret:
|
||||||
|
with open(
|
||||||
|
os.path.join(
|
||||||
|
CLIPS_DIR,
|
||||||
|
f"{camera_config.name}-{event_id}-clean.png",
|
||||||
|
),
|
||||||
|
"wb",
|
||||||
|
) as p:
|
||||||
|
p.write(png.tobytes())
|
||||||
|
|||||||
@ -859,16 +859,21 @@ def create_event(camera_name, label):
|
|||||||
json: dict[str, any] = request.get_json(silent=True) or {}
|
json: dict[str, any] = request.get_json(silent=True) or {}
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
frame = current_app.detected_frames_processor.get_current_frame(camera_name)
|
||||||
|
|
||||||
event_id = current_app.external_processor.create_manual_event(
|
event_id = current_app.external_processor.create_manual_event(
|
||||||
camera_name,
|
camera_name,
|
||||||
label,
|
label,
|
||||||
json.get("sub_label", None),
|
json.get("sub_label", None),
|
||||||
json.get("duration", 30),
|
json.get("duration", 30),
|
||||||
json.get("include_recording", True),
|
json.get("include_recording", True),
|
||||||
|
frame,
|
||||||
)
|
)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"The error is {e}")
|
logger.error(f"The error is {e}")
|
||||||
return jsonify({"success": False, "message": f"An unknown error occurred: {e}"}, 404)
|
return jsonify(
|
||||||
|
{"success": False, "message": f"An unknown error occurred: {e}"}, 404
|
||||||
|
)
|
||||||
|
|
||||||
return jsonify(
|
return jsonify(
|
||||||
{
|
{
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user