def event_clip(id): download = request.args.get("download", type=bool) try: event: Event = Event.get(Event.id == id) except DoesNotExist: return "Event not found.", 404 if not event.has_clip: return "Clip not available", 404 file_name = f"{event.camera}-{id}.mp4" clip_path = os.path.join(CLIPS_DIR, file_name) if not os.path.isfile(clip_path): end_ts = (datetime.now().timestamp() if event.end_time is None else event.end_time) return recording_clip(event.camera, event.start_time, end_ts) response = make_response() response.headers["Content-Description"] = "File Transfer" response.headers["Cache-Control"] = "no-cache" response.headers["Content-Type"] = "video/mp4" if download: response.headers[ "Content-Disposition"] = "attachment; filename=%s" % file_name response.headers["Content-Length"] = os.path.getsize(clip_path) response.headers[ "X-Accel-Redirect"] = f"/clips/{file_name}" # nginx: http://wiki.nginx.org/NginxXSendfile return response
def event_snapshot(id): jpg_bytes = None try: event = Event.get(Event.id == id) if not event.has_snapshot: return "Snapshot not available", 404 # read snapshot from disk with open(os.path.join(CLIPS_DIR, f"{event.camera}-{id}.jpg"), "rb") as image_file: jpg_bytes = image_file.read() except DoesNotExist: # 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 not tracked_obj is None: jpg_bytes = tracked_obj.get_jpg_bytes( timestamp=request.args.get("timestamp", type=int), bounding_box=request.args.get("bbox", type=int), crop=request.args.get("crop", type=int), height=request.args.get("h", type=int), ) except: return "Event not found", 404 except: return "Event not found", 404 response = make_response(jpg_bytes) response.headers["Content-Type"] = "image/jpg" return response
def delete_event(id): try: event = Event.get(Event.id == id) except DoesNotExist: return make_response( jsonify({ "success": False, "message": "Event" + id + " not found" }), 404) media_name = f"{event.camera}-{event.id}" if event.has_snapshot: media = Path(f"{os.path.join(CLIPS_DIR, media_name)}.jpg") media.unlink(missing_ok=True) media = Path(f"{os.path.join(CLIPS_DIR, media_name)}-clean.png") media.unlink(missing_ok=True) if event.has_clip: media = Path(f"{os.path.join(CLIPS_DIR, media_name)}.mp4") media.unlink(missing_ok=True) event.delete_instance() return make_response( jsonify({ "success": True, "message": "Event" + id + " deleted" }), 200)
def event_thumbnail(id): format = request.args.get('format', 'ios') thumbnail_bytes = None try: event = Event.get(Event.id == id) thumbnail_bytes = base64.b64decode(event.thumbnail) except DoesNotExist: # see if the object is currently being tracked try: for camera_state in current_app.detected_frames_processor.camera_states.values( ): if id in camera_state.tracked_objects: tracked_obj = camera_state.tracked_objects.get(id) if not tracked_obj is None: thumbnail_bytes = tracked_obj.get_thumbnail() except: return "Event not found", 404 if thumbnail_bytes is None: return "Event not found", 404 # android notifications prefer a 2:1 ratio if format == 'android': jpg_as_np = np.frombuffer(thumbnail_bytes, dtype=np.uint8) img = cv2.imdecode(jpg_as_np, flags=1) thumbnail = cv2.copyMakeBorder(img, 0, 0, int(img.shape[1] * 0.5), int(img.shape[1] * 0.5), cv2.BORDER_CONSTANT, (0, 0, 0)) ret, jpg = cv2.imencode('.jpg', thumbnail, [int(cv2.IMWRITE_JPEG_QUALITY), 70]) thumbnail_bytes = jpg.tobytes() response = make_response(thumbnail_bytes) response.headers['Content-Type'] = 'image/jpg' return response
def vod_event(id): try: event: Event = Event.get(Event.id == id) except DoesNotExist: return "Event not found.", 404 if not event.has_clip: return "Clip not available", 404 clip_path = os.path.join(CLIPS_DIR, f"{event.camera}-{id}.mp4") if not os.path.isfile(clip_path): return vod_ts(event.camera, event.start_time, event.end_time) duration = int((event.end_time - event.start_time) * 1000) return jsonify( { "cache": True, "discontinuity": False, "durations": [duration], "sequences": [{"clips": [{"type": "source", "path": clip_path}]}], } )
def vod_event(id): try: event: Event = Event.get(Event.id == id) except DoesNotExist: logger.error(f"Event not found: {id}") return "Event not found.", 404 if not event.has_clip: logger.error(f"Event does not have recordings: {id}") return "Recordings not available", 404 clip_path = os.path.join(CLIPS_DIR, f"{event.camera}-{id}.mp4") if not os.path.isfile(clip_path): end_ts = (datetime.now().timestamp() if event.end_time is None else event.end_time) vod_response = vod_ts(event.camera, event.start_time, end_ts) # If the recordings are not found, set has_clip to false if (type(vod_response) == tuple and len(vod_response) == 2 and vod_response[1] == 404): Event.update(has_clip=False).where(Event.id == id).execute() return vod_response duration = int((event.end_time - event.start_time) * 1000) return jsonify({ "cache": True, "discontinuity": False, "durations": [duration], "sequences": [{ "clips": [{ "type": "source", "path": clip_path }] }], })
def event(id): try: return model_to_dict(Event.get(Event.id == id)) except DoesNotExist: return "Event not found", 404