Add snapshot-clean.png API endpoint (#10510)

* Add snapshot-clean.png API endpoint

* fix lint

* enable on inprogress event
This commit is contained in:
Alex Yao 2024-03-19 07:54:25 -04:00 committed by GitHub
parent 3bd0ad63b4
commit 5c3925ab50
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 84 additions and 0 deletions

View File

@ -290,6 +290,14 @@ Returns a thumbnail for the event id optimized for notifications. Works while th
Returns the clip for the event id. Works after the event has ended. Returns the clip for the event id. Works after the event has ended.
### `GET /api/events/<id>/snapshot-clean.png`
Returns the clean snapshot image for the event id. Only works if `snapshots` and `clean_copy` are enabled in the config.
| param | Type | Description |
| ---------- | ---- | ------------------ |
| `download` | bool | Download the image |
### `GET /api/events/<id>/snapshot.jpg` ### `GET /api/events/<id>/snapshot.jpg`
Returns the snapshot image for the event id. Works while the event is in progress and after completion. Returns the snapshot image for the event id. Works while the event is in progress and after completion.
@ -303,6 +311,7 @@ Accepts the following query string parameters, but they are only applied when an
| `timestamp` | int | Print the timestamp in the upper left (0 or 1) | | `timestamp` | int | Print the timestamp in the upper left (0 or 1) |
| `crop` | int | Crop the snapshot to the (0 or 1) | | `crop` | int | Crop the snapshot to the (0 or 1) |
| `quality` | int | Jpeg encoding quality (0-100). Defaults to 70. | | `quality` | int | Jpeg encoding quality (0-100). Defaults to 70. |
| `download` | bool | Download the image |
### `POST /api/events/<camera_name>/<label>/create` ### `POST /api/events/<camera_name>/<label>/create`

View File

@ -935,6 +935,81 @@ def grid_snapshot(camera_name):
) )
@MediaBp.route("/events/<id>/snapshot-clean.png")
def event_snapshot_clean(id):
download = request.args.get("download", type=bool)
png_bytes = None
try:
event = Event.get(Event.id == id)
snapshot_config = current_app.frigate_config.cameras[event.camera].snapshots
if not (snapshot_config.enabled and event.has_snapshot):
return make_response(
jsonify(
{
"success": False,
"message": "Snapshots and clean_copy must be enabled in the config",
}
),
404,
)
if event.end_time is None:
# see if the object is currently being tracked
try:
camera_states = (
current_app.detected_frames_processor.camera_states.values()
)
for camera_state in camera_states:
if id in camera_state.tracked_objects:
tracked_obj = camera_state.tracked_objects.get(id)
if tracked_obj is not None:
png_bytes = tracked_obj.get_clean_png()
break
except Exception:
return make_response(
jsonify({"success": False, "message": "Event not found"}), 404
)
elif not event.has_snapshot:
return make_response(
jsonify({"success": False, "message": "Snapshot not available"}), 404
)
except DoesNotExist:
return make_response(
jsonify({"success": False, "message": "Event not found"}), 404
)
if png_bytes is None:
try:
clean_snapshot_path = os.path.join(
CLIPS_DIR, f"{event.camera}-{event.id}-clean.png"
)
if not os.path.exists(clean_snapshot_path):
return make_response(
jsonify(
{"success": False, "message": "Clean snapshot not available"}
),
404,
)
with open(
os.path.join(CLIPS_DIR, f"{event.camera}-{event.id}-clean.png"), "rb"
) as image_file:
png_bytes = image_file.read()
except Exception:
logger.error(f"Unable to load clean png for event: {event.id}")
return make_response(
jsonify(
{"success": False, "message": "Unable to load clean png for event"}
),
400,
)
response = make_response(png_bytes)
response.headers["Content-Type"] = "image/png"
response.headers["Cache-Control"] = "private, max-age=31536000"
if download:
response.headers["Content-Disposition"] = (
f"attachment; filename=snapshot-{id}-clean.png"
)
return response
@MediaBp.route("/events/<id>/snapshot.jpg") @MediaBp.route("/events/<id>/snapshot.jpg")
def event_snapshot(id): def event_snapshot(id):
download = request.args.get("download", type=bool) download = request.args.get("download", type=bool)