Beispiel #1
0
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
            }]
        }],
    })
Beispiel #2
0
    def expire(self, media_type):
        ## Expire events from unlisted cameras based on the global config
        if media_type == 'clips':
            retain_config = self.config.clips.retain
            file_extension = "mp4"
            update_params = {"has_clip": False}
        else:
            retain_config = self.config.snapshots.retain
            file_extension = "jpg"
            update_params = {"has_snapshot": False}

        distinct_labels = (Event.select(Event.label).where(
            Event.camera.not_in(self.camera_keys)).distinct())

        # loop over object types in db
        for l in distinct_labels:
            # get expiration time for this label
            expire_days = retain_config.objects.get(l.label,
                                                    retain_config.default)
            expire_after = (datetime.datetime.now() -
                            datetime.timedelta(days=expire_days)).timestamp()
            # grab all events after specific time
            expired_events = Event.select().where(
                Event.camera.not_in(self.camera_keys),
                Event.start_time < expire_after,
                Event.label == l.label,
            )
            # delete the media from disk
            for event in expired_events:
                media_name = f"{event.camera}-{event.id}"
                media_path = Path(
                    f"{os.path.join(CLIPS_DIR, media_name)}.{file_extension}")
                media_path.unlink(missing_ok=True)
            # update the clips attribute for the db entry
            update_query = Event.update(update_params).where(
                Event.camera.not_in(self.camera_keys),
                Event.start_time < expire_after,
                Event.label == l.label,
            )
            update_query.execute()

        ## Expire events from cameras based on the camera config
        for name, camera in self.config.cameras.items():
            if media_type == 'clips':
                retain_config = camera.clips.retain
            else:
                retain_config = camera.snapshots.retain
            # get distinct objects in database for this camera
            distinct_labels = (Event.select(
                Event.label).where(Event.camera == name).distinct())

            # loop over object types in db
            for l in distinct_labels:
                # get expiration time for this label
                expire_days = retain_config.objects.get(
                    l.label, retain_config.default)
                expire_after = (
                    datetime.datetime.now() -
                    datetime.timedelta(days=expire_days)).timestamp()
                # grab all events after specific time
                expired_events = Event.select().where(
                    Event.camera == name,
                    Event.start_time < expire_after,
                    Event.label == l.label,
                )
                # delete the grabbed clips from disk
                for event in expired_events:
                    media_name = f"{event.camera}-{event.id}"
                    media_path = Path(
                        f"{os.path.join(CLIPS_DIR, media_name)}.{file_extension}"
                    )
                    media_path.unlink(missing_ok=True)
                # update the clips attribute for the db entry
                update_query = Event.update(update_params).where(
                    Event.camera == name,
                    Event.start_time < expire_after,
                    Event.label == l.label,
                )
                update_query.execute()
Beispiel #3
0
    def run(self):
        # set an end_time on events without an end_time on startup
        Event.update(end_time=Event.start_time +
                     30).where(Event.end_time == None).execute()

        while not self.stop_event.is_set():
            try:
                event_type, camera, event_data = self.event_queue.get(
                    timeout=10)
            except queue.Empty:
                continue

            logger.debug(
                f"Event received: {event_type} {camera} {event_data['id']}")

            event_config: EventsConfig = self.config.cameras[
                camera].record.events

            if event_type == "start":
                self.events_in_process[event_data["id"]] = event_data

            elif event_type == "update" and should_update_db(
                    self.events_in_process[event_data["id"]], event_data):
                self.events_in_process[event_data["id"]] = event_data
                # TODO: this will generate a lot of db activity possibly
                if event_data["has_clip"] or event_data["has_snapshot"]:
                    Event.replace(
                        id=event_data["id"],
                        label=event_data["label"],
                        camera=camera,
                        start_time=event_data["start_time"] -
                        event_config.pre_capture,
                        end_time=None,
                        top_score=event_data["top_score"],
                        false_positive=event_data["false_positive"],
                        zones=list(event_data["entered_zones"]),
                        thumbnail=event_data["thumbnail"],
                        region=event_data["region"],
                        box=event_data["box"],
                        area=event_data["area"],
                        has_clip=event_data["has_clip"],
                        has_snapshot=event_data["has_snapshot"],
                    ).execute()

            elif event_type == "end":
                if event_data["has_clip"] or event_data["has_snapshot"]:
                    Event.replace(
                        id=event_data["id"],
                        label=event_data["label"],
                        camera=camera,
                        start_time=event_data["start_time"] -
                        event_config.pre_capture,
                        end_time=event_data["end_time"] +
                        event_config.post_capture,
                        top_score=event_data["top_score"],
                        false_positive=event_data["false_positive"],
                        zones=list(event_data["entered_zones"]),
                        thumbnail=event_data["thumbnail"],
                        region=event_data["region"],
                        box=event_data["box"],
                        area=event_data["area"],
                        has_clip=event_data["has_clip"],
                        has_snapshot=event_data["has_snapshot"],
                    ).execute()

                del self.events_in_process[event_data["id"]]
                self.event_processed_queue.put((event_data["id"], camera))

        # set an end_time on events without an end_time before exiting
        Event.update(end_time=datetime.datetime.now().timestamp()).where(
            Event.end_time == None).execute()
        logger.info(f"Exiting event processor...")