main
1// Package manifest defines types for tracking clip download state.
2package manifest
3
4import "time"
5
6// ClipStatus represents the download state of a clip.
7type ClipStatus string
8
9const (
10 StatusPending ClipStatus = "pending"
11 StatusInProgress ClipStatus = "in_progress"
12 StatusComplete ClipStatus = "complete"
13 StatusFailed ClipStatus = "failed"
14)
15
16// ClipEntry represents a single video clip from an event.
17type ClipEntry struct {
18 EventID string `json:"event_id"`
19 StartMs int64 `json:"start_ms"`
20 EndMs int64 `json:"end_ms"`
21 DurationMs int64 `json:"duration_ms"`
22 EventType string `json:"event_type"`
23 SmartTypes []string `json:"smart_types,omitempty"`
24 Score int `json:"score"`
25 Status ClipStatus `json:"status"`
26 FilePath string `json:"file_path,omitempty"`
27 FileSize int64 `json:"file_size,omitempty"`
28 Error string `json:"error,omitempty"`
29 DownloadedAt *time.Time `json:"downloaded_at,omitempty"`
30}
31
32// DurationSecs returns the clip duration in seconds.
33func (c *ClipEntry) DurationSecs() float64 {
34 return float64(c.DurationMs) / 1000.0
35}
36
37// ClipIndex holds all clips for a day with metadata.
38type ClipIndex struct {
39 CameraID string `json:"camera_id"`
40 CameraName string `json:"camera_name"`
41 Date string `json:"date"`
42 CreatedAt time.Time `json:"created_at"`
43 UpdatedAt time.Time `json:"updated_at"`
44 Clips []*ClipEntry `json:"clips"`
45}
46
47// TotalDurationMs returns the sum of all clip durations in milliseconds.
48func (ci *ClipIndex) TotalDurationMs() int64 {
49 var total int64
50 for _, c := range ci.Clips {
51 total += c.DurationMs
52 }
53 return total
54}
55
56// TotalDurationSecs returns the sum of all clip durations in seconds.
57func (ci *ClipIndex) TotalDurationSecs() float64 {
58 return float64(ci.TotalDurationMs()) / 1000.0
59}
60
61// CompletedClips returns only clips with status Complete.
62func (ci *ClipIndex) CompletedClips() []*ClipEntry {
63 var completed []*ClipEntry
64 for _, c := range ci.Clips {
65 if c.Status == StatusComplete {
66 completed = append(completed, c)
67 }
68 }
69 return completed
70}
71
72// Stats returns counts by status.
73func (ci *ClipIndex) Stats() map[ClipStatus]int {
74 stats := make(map[ClipStatus]int)
75 for _, c := range ci.Clips {
76 stats[c.Status]++
77 }
78 return stats
79}
80
81// DayMetadata holds computed information about the day's timelapse.
82type DayMetadata struct {
83 CameraID string `json:"camera_id"`
84 CameraName string `json:"camera_name"`
85 Date string `json:"date"`
86 TotalClips int `json:"total_clips"`
87 ValidClips int `json:"valid_clips"`
88 TotalDuration float64 `json:"total_duration_secs"`
89 SpeedFactor float64 `json:"speed_factor"`
90 TargetSecs int `json:"target_secs"`
91 OutputDuration float64 `json:"output_duration_secs"`
92 CreatedAt time.Time `json:"created_at"`
93}