Documentation ¶
Index ¶
- Constants
- Variables
- func LoadStandardOntology(e *EventDB) error
- func Migrations(log log.Log) []migration.Migrator
- type BaseModel
- type EventDB
- func (e *EventDB) Count() (int64, error)
- func (e *EventDB) CreateOntology(spec *OntologyDefinition) (int64, error)
- func (e *EventDB) CreateRecording(parentID int64, rtype RecordType, origin RecordingOrigin, startTime time.Time, ...) (*Recording, error)
- func (e *EventDB) DeleteFilesOf(recordings []*Recording) error
- func (e *EventDB) DeleteRecordingComplete(id int64) error
- func (e *EventDB) DeleteRecordingDBRecord(id int64) error
- func (e *EventDB) FindLatestOntologyThatIsSupersetOf(spec *OntologyDefinition) (*Ontology, error)
- func (e *EventDB) FullPath(videoOrImagePath string) string
- func (e *EventDB) GetLatestOntology() (*Ontology, error)
- func (e *EventDB) GetOntologies() ([]Ontology, error)
- func (e *EventDB) GetOntology(id int64) (*Ontology, error)
- func (e *EventDB) GetPhysicalRecordsOf(rec *Recording) ([]*Recording, error)
- func (e *EventDB) GetRecording(id int64) (*Recording, error)
- func (e *EventDB) GetRecordings() ([]Recording, error)
- func (e *EventDB) GetRecordingsForTraining() ([]Recording, error)
- func (e *EventDB) IsOntologyUsed(id int64) (bool, error)
- func (e *EventDB) PruneUnusedOntologies(keep []int64) error
- func (e *EventDB) Save(origin RecordingOrigin, cameraID int64, startTime time.Time, ...) (*Recording, error)
- func (e *EventDB) SaveThumbnail(img *cimg.Image, targetFilename string) error
- func (e *EventDB) SetRecordingLabels(rec *Recording) error
- type Labels
- type Ontology
- type OntologyDefinition
- type OntologyLevel
- type OntologyTag
- type RecordType
- type Recording
- func (r *Recording) IsLogical() bool
- func (r *Recording) IsPhysical() bool
- func (r *Recording) IsSimple() bool
- func (r *Recording) SetFormatAndDimensions(res defs.Resolution, width, height int)
- func (r *Recording) ThumbnailFilename() string
- func (r *Recording) VideoContentType(res defs.Resolution) string
- func (r *Recording) VideoContentTypeHD() string
- func (r *Recording) VideoContentTypeLD() string
- func (r *Recording) VideoFilename(res defs.Resolution) string
- func (r *Recording) VideoFilenameHD() string
- func (r *Recording) VideoFilenameLD() string
- type RecordingOrigin
Constants ¶
const MaxThumbnailWidth = 320
Variables ¶
var (
ErrNotALogicalRecord = errors.New("Not a logical record")
)
Functions ¶
func LoadStandardOntology ¶
Types ¶
type BaseModel ¶
type BaseModel struct {
ID int64 `gorm:"primaryKey" json:"id"`
}
BaseModel is our base class for a GORM model. The default GORM Model uses int, but we prefer int64
type EventDB ¶
type EventDB struct { Root string // Where we store our videos (also directory where sqlite DB is stored) // contains filtered or unexported fields }
EventDB manages recordings. There are two EventDBs. One for recent recordings, which may or may not be of interest. One for permanent recordings, which form part of the training set (or a user wants to keep for whatever reason).
func NewEventDB ¶
Open or create an event DB
func (*EventDB) CreateOntology ¶
func (e *EventDB) CreateOntology(spec *OntologyDefinition) (int64, error)
Find an existing ontology that matches the given spec, or create a new one if necessary
func (*EventDB) CreateRecording ¶
func (e *EventDB) CreateRecording(parentID int64, rtype RecordType, origin RecordingOrigin, startTime time.Time, cameraID int64, res defs.Resolution, width, height int) (*Recording, error)
Create a new empty recording The idea is that you'll be building this recording's mp4 file bit by bit.
func (*EventDB) DeleteFilesOf ¶
Delete the video files (but not the DB record) of the given recordings The recording records should be Simple or Physical records
func (*EventDB) DeleteRecordingComplete ¶
Delete the DB record and the video files of a recording. If the recording does not exist, the function returns success.
func (*EventDB) DeleteRecordingDBRecord ¶
Delete the _DB record only_ of the recording If the record does not exist, return nil.
func (*EventDB) FindLatestOntologyThatIsSupersetOf ¶
func (e *EventDB) FindLatestOntologyThatIsSupersetOf(spec *OntologyDefinition) (*Ontology, error)
Find the latest ontology that is a superset of the given spec. Returns (nil, nil) if no such ontology exists.
func (*EventDB) FullPath ¶
Return the complete path to the specified video or image file For example, eventDB.FullPath(recording.VideoFilenameLD())
func (*EventDB) GetLatestOntology ¶
func (*EventDB) GetOntologies ¶
func (*EventDB) GetPhysicalRecordsOf ¶
Get all physical records for the given logical or simple recording object
func (*EventDB) GetRecordings ¶
func (*EventDB) GetRecordingsForTraining ¶
func (*EventDB) IsOntologyUsed ¶
Return true if there are any recordings that reference the given ontology
func (*EventDB) PruneUnusedOntologies ¶
Delete unused ontologies. The optional array 'keep' will prevent ontologies with those IDs from being deleted.
func (*EventDB) Save ¶
func (e *EventDB) Save(origin RecordingOrigin, cameraID int64, startTime time.Time, rawLD, rawHD *videox.PacketBuffer) (*Recording, error)
Save a new recording to disk. Returns the record of the new recording. Either rawLD or rawHD may be nil, but not both.
func (*EventDB) SaveThumbnail ¶
func (*EventDB) SetRecordingLabels ¶
type Labels ¶
type Labels struct { VideoTags []int `json:"videoTags"` // Tags associated with the entire recording (eg "intruder"). Values refer to zero-based indices of OntologyDefinition.VideoTags CropStart float64 `json:"cropStart"` // Start time of cropped video, in seconds CropEnd float64 `json:"cropEnd"` // End time of cropped video, in seconds }
Labels associated with a recording
type Ontology ¶
type Ontology struct { BaseModel CreatedAt dbh.IntTime `json:"createdAt" gorm:"autoCreateTime:milli"` Definition *dbh.JSONField[OntologyDefinition] `json:"definition,omitempty"` }
An immutable ontology, referenced by a Recording, so that we know all the possible labels which were considered when a recording was labeled.
type OntologyDefinition ¶
type OntologyDefinition struct {
Tags []OntologyTag `json:"tags"`
}
Ontology spec, which is saved as a JSON field in the DB
func (*OntologyDefinition) ContainsTag ¶
func (o *OntologyDefinition) ContainsTag(tag OntologyTag) bool
func (*OntologyDefinition) Hash ¶
func (o *OntologyDefinition) Hash() []byte
Compute a hash that can be used to check for equality with another ontology
func (*OntologyDefinition) IsSupersetOf ¶
func (o *OntologyDefinition) IsSupersetOf(b *OntologyDefinition) bool
type OntologyLevel ¶
type OntologyLevel string
const ( // SYNC-ONTOLOGY-LEVEL OntologyLevelAlarm OntologyLevel = "alarm" // If the system is armed, trigger an alarm OntologyLevelRecord OntologyLevel = "record" // Record this incident, whether armed or not OntologyLevelIgnore OntologyLevel = "ignore" // Do not record )
type OntologyTag ¶
type OntologyTag struct { Name string `json:"name"` // eg "intruder", "dog", "car" Level OntologyLevel `json:"level"` }
Ontology tag, which can be associated with a video clip
type RecordType ¶
type RecordType string
RecordType categorizes the type of Recording record in the database. The reason we have 3 different types, is because we want to be able to group together a bunch of different video files into one logical entity. There are two reasons for this:
- When recording for a long time, the video files can become large, and we want to be able to split them up into smaller files on disk.
- We will often record on all cameras at the same time, and we want them to be grouped together into one logical entity.
const ( // A recording that is both logical and physical. // Has a camera. // Parent is null. RecordTypeSimple RecordType = "s" // A logical record that is the parent of Physical records. // Doesn't have a camera. // Doesn't have any directly owned files (but it does have files *indirectly*, through it's Physical children). RecordTypeLogical RecordType = "l" // A recording file, which belongs to a Logical recording. // Has a camera // Has a parent RecordTypePhysical RecordType = "p" )
type Recording ¶
type Recording struct { BaseModel RandomID string `json:"randomID"` // Used to ensure uniqueness when merging event databases StartTime dbh.IntTime `json:"startTime"` // Wall time when recording started RecordType RecordType `json:"recordType"` // Type of record Origin RecordingOrigin `json:"origin"` // Reason why recording exists ParentID int64 `json:"parentID" gorm:"default:null"` // ID of parent recording record, if this is a Physical record FormatHD string `json:"formatHD" gorm:"default:null"` // Only valid value is "mp4" FormatLD string `json:"formatLD" gorm:"default:null"` // Only valid value is "mp4" Labels *dbh.JSONField[Labels] `json:"labels,omitempty" gorm:"default:null"` // If labels is defined, then OntologyID is also defined UseForTraining bool `json:"useForTraining" gorm:"default:null"` // If 1, then this recording will be used for training OntologyID int64 `json:"ontologyID,omitempty" gorm:"default:null"` // Labels reference indices in Ontology, which is why we need to store a reference to the Ontology Bytes int64 `json:"bytes"` // Total storage of videos + thumbnails DimensionsHD string `json:"dimensionsHD" gorm:"default:null"` // "Width,Height" of HD video DimensionsLD string `json:"dimensionsLD" gorm:"default:null"` // "Width,Height" of LD video CameraID int64 `json:"cameraID" gorm:"default:null"` // ID of camera in config DB }
A recording refers to either a high resolution video, a low resolution video, or both. However, when recording a suspicious event, we want high resolution for playback and inspection, but we also want low resolution in case the user wants to turn that video clip into training data. This is why we record both high and low whenever the auto recorder kicks in.
func (*Recording) IsPhysical ¶
func (*Recording) SetFormatAndDimensions ¶
func (r *Recording) SetFormatAndDimensions(res defs.Resolution, width, height int)
Set the width and height for the given resolution
func (*Recording) ThumbnailFilename ¶
func (*Recording) VideoContentType ¶
func (r *Recording) VideoContentType(res defs.Resolution) string
func (*Recording) VideoContentTypeHD ¶
func (*Recording) VideoContentTypeLD ¶
func (*Recording) VideoFilename ¶
func (r *Recording) VideoFilename(res defs.Resolution) string
func (*Recording) VideoFilenameHD ¶
func (*Recording) VideoFilenameLD ¶
type RecordingOrigin ¶
type RecordingOrigin string
const ( RecordingOriginBackground RecordingOrigin = "b" // A recording that was made in the background, to collect sample data RecordingOriginAuto RecordingOrigin = "a" // A recording that was made automatically by the system, because it thought it was interesting or suspicious RecordingOriginExplicit RecordingOrigin = "e" // A recording that was made by the user clicking the "record" button (for labelling) )