This commit is contained in:
Nicolas Mowen 2024-02-17 11:46:03 -07:00
parent a3b43471a9
commit 26f8552b1c
2 changed files with 52 additions and 17 deletions

View File

@ -45,7 +45,7 @@ from frigate.const import (
RECORD_DIR, RECORD_DIR,
) )
from frigate.events.external import ExternalEventProcessor from frigate.events.external import ExternalEventProcessor
from frigate.models import Event, Previews, Recordings, Regions, Timeline from frigate.models import Event, Previews, Recordings, Regions, ReviewSegment, Timeline
from frigate.object_processing import TrackedObject from frigate.object_processing import TrackedObject
from frigate.plus import PlusApi from frigate.plus import PlusApi
from frigate.ptz.onvif import OnvifController from frigate.ptz.onvif import OnvifController
@ -1056,9 +1056,9 @@ def event_snapshot(id):
else: else:
response.headers["Cache-Control"] = "no-store" response.headers["Cache-Control"] = "no-store"
if download: if download:
response.headers[ response.headers["Content-Disposition"] = (
"Content-Disposition" f"attachment; filename=snapshot-{id}.jpg"
] = f"attachment; filename=snapshot-{id}.jpg" )
return response return response
@ -1245,9 +1245,9 @@ def event_clip(id):
if download: if download:
response.headers["Content-Disposition"] = "attachment; filename=%s" % file_name response.headers["Content-Disposition"] = "attachment; filename=%s" % file_name
response.headers["Content-Length"] = os.path.getsize(clip_path) response.headers["Content-Length"] = os.path.getsize(clip_path)
response.headers[ response.headers["X-Accel-Redirect"] = (
"X-Accel-Redirect" f"/clips/{file_name}" # nginx: https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_ignore_headers
] = f"/clips/{file_name}" # nginx: https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_ignore_headers )
return response return response
@ -1952,9 +1952,9 @@ def get_recordings_storage_usage():
total_mb = recording_stats["total"] total_mb = recording_stats["total"]
camera_usages: dict[ camera_usages: dict[str, dict] = (
str, dict current_app.storage_maintainer.calculate_camera_usages()
] = current_app.storage_maintainer.calculate_camera_usages() )
for camera_name in camera_usages.keys(): for camera_name in camera_usages.keys():
if camera_usages.get(camera_name, {}).get("usage"): if camera_usages.get(camera_name, {}).get("usage"):
@ -2142,9 +2142,9 @@ def recording_clip(camera_name, start_ts, end_ts):
if download: if download:
response.headers["Content-Disposition"] = "attachment; filename=%s" % file_name response.headers["Content-Disposition"] = "attachment; filename=%s" % file_name
response.headers["Content-Length"] = os.path.getsize(path) response.headers["Content-Length"] = os.path.getsize(path)
response.headers[ response.headers["X-Accel-Redirect"] = (
"X-Accel-Redirect" f"/cache/{file_name}" # nginx: https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_ignore_headers
] = f"/cache/{file_name}" # nginx: https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_ignore_headers )
return response return response
@ -2390,6 +2390,36 @@ def vod_event(id):
) )
@bp.route("/review")
def review():
camera = request.args.get("camera", "all")
limit = request.args.get("limit", 100)
severity = request.args.get("severity", None)
before = request.args.get("before", type=float, default=datetime.now().timestamp())
after = request.args.get(
"after", type=float, default=(datetime.now() - timedelta(hours=18)).timestamp()
)
clauses = [((ReviewSegment.start_time > after) & (ReviewSegment.end_time < before))]
if camera != "all":
clauses.append((ReviewSegment.camera == camera))
if severity:
clauses.append((ReviewSegment.severity == severity))
review = (
ReviewSegment.select()
.where(reduce(operator.and_, clauses))
.order_by(ReviewSegment.start_time.desc())
.limit(limit)
.dicts()
)
return jsonify([r for r in review])
@bp.route( @bp.route(
"/export/<camera_name>/start/<int:start_time>/end/<int:end_time>", methods=["POST"] "/export/<camera_name>/start/<int:start_time>/end/<int:end_time>", methods=["POST"]
) )

View File

@ -113,11 +113,15 @@ class ReviewSegmentMaintainer(threading.Thread):
segment.detections.add(object["id"]) segment.detections.add(object["id"])
segment.objects.add(object["label"]) segment.objects.add(object["label"])
if segment.severity == SeverityEnum.detection and object["has_clip"]: if object["has_clip"]:
segment.severity = SeverityEnum.alert segment.severity = SeverityEnum.alert
if object["current_zones"]: if len(object["current_zones"]) > 0:
segment.zones.update(object) segment.zones.update(object["current_zones"])
elif (
segment.severity == SeverityEnum.signification_motion and len(motion) >= 20
):
segment.last_update = frame_time
elif frame_time > ( elif frame_time > (
segment.last_update segment.last_update
+ (camera_config.detect.max_disappeared / camera_config.detect.fps) + (camera_config.detect.max_disappeared / camera_config.detect.fps)
@ -215,7 +219,8 @@ class ReviewSegmentMaintainer(threading.Thread):
current_tracked_objects, current_tracked_objects,
motion_boxes, motion_boxes,
) )
elif topic == DetectionTypeEnum.audio: elif topic == DetectionTypeEnum.audio and len(audio_detections) > 0:
current_segment.last_update = frame_time
current_segment.audio.update(audio_detections) current_segment.audio.update(audio_detections)
else: else:
if topic == DetectionTypeEnum.video: if topic == DetectionTypeEnum.video: