Skip to main content

vidsage_core/video/
metadata.rs

1//! Video metadata definitions
2
3use chrono::{DateTime, Duration, Utc};
4use serde::{Deserialize, Serialize};
5use uuid::Uuid;
6
7/// Video format enumeration
8#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
9pub enum VideoFormat {
10    #[serde(rename = "mp4")]
11    MP4,
12    #[serde(rename = "webm")]
13    WebM,
14    #[serde(rename = "avi")]
15    AVI,
16    #[serde(rename = "mov")]
17    MOV,
18    #[serde(rename = "mkv")]
19    MKV,
20    #[serde(rename = "flv")]
21    FLV,
22    #[serde(rename = "other")]
23    Other,
24}
25
26/// Video quality settings
27#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq)]
28pub enum VideoQuality {
29    #[serde(rename = "low")]
30    Low,
31    #[serde(rename = "medium")]
32    Medium,
33    #[serde(rename = "high")]
34    High,
35    #[serde(rename = "ultra")]
36    Ultra,
37    #[serde(rename = "custom")]
38    Custom(u32), // Bitrate in kbps
39}
40
41/// Video metadata structure
42#[derive(Debug, Clone, Serialize, Deserialize)]
43pub struct VideoMetadata {
44    /// Unique identifier for the video
45    pub id: String,
46
47    /// Video title
48    pub title: String,
49
50    /// Video duration
51    pub duration: Duration,
52
53    /// Video resolution (width, height)
54    pub resolution: (u32, u32),
55
56    /// Video format
57    pub format: VideoFormat,
58
59    /// Video file size in bytes
60    pub file_size: u64,
61
62    /// Video bitrate in kbps
63    pub bitrate: u32,
64
65    /// Video frame rate
66    pub frame_rate: f64,
67
68    /// Number of audio tracks
69    pub audio_tracks: u32,
70
71    /// Audio bitrate in kbps
72    pub audio_bitrate: u32,
73
74    /// Video codec
75    pub video_codec: String,
76
77    /// Audio codec
78    pub audio_codec: String,
79
80    /// Creation timestamp
81    pub created_at: DateTime<Utc>,
82
83    /// Last updated timestamp
84    pub updated_at: DateTime<Utc>,
85}
86
87impl VideoMetadata {
88    /// Create a new VideoMetadata instance
89    pub fn new(
90        title: String,
91        duration: Duration,
92        resolution: (u32, u32),
93        format: VideoFormat,
94    ) -> Self {
95        let now = Utc::now();
96        Self {
97            id: Uuid::new_v4().to_string(),
98            title,
99            duration,
100            resolution,
101            format,
102            file_size: 0,
103            bitrate: 0,
104            frame_rate: 0.0,
105            audio_tracks: 0,
106            audio_bitrate: 0,
107            video_codec: String::new(),
108            audio_codec: String::new(),
109            created_at: now,
110            updated_at: now,
111        }
112    }
113
114    /// Update the updated_at timestamp
115    pub fn update_timestamp(&mut self) {
116        self.updated_at = Utc::now();
117    }
118}
119
120#[cfg(test)]
121mod tests {
122    use super::*;
123    use serde_json;
124
125    #[test]
126    fn test_video_format_serialization() {
127        // Test serialization
128        let format = VideoFormat::MP4;
129        let json = serde_json::to_string(&format).unwrap();
130        assert_eq!(json, "\"mp4\"");
131
132        // Test deserialization
133        let deserialized: VideoFormat = serde_json::from_str(&json).unwrap();
134        assert_eq!(deserialized, VideoFormat::MP4);
135
136        // Test deserialization from string
137        let deserialized: VideoFormat = serde_json::from_str("\"webm\"").unwrap();
138        assert_eq!(deserialized, VideoFormat::WebM);
139    }
140
141    #[test]
142    fn test_video_quality_serialization() {
143        // Test serialization for predefined qualities
144        let quality = VideoQuality::High;
145        let json = serde_json::to_string(&quality).unwrap();
146        assert_eq!(json, "\"high\"");
147
148        // Test serialization for custom quality
149        let quality = VideoQuality::Custom(5000);
150        let json = serde_json::to_string(&quality).unwrap();
151        assert_eq!(json, "{\"custom\":5000}");
152
153        // Test deserialization
154        let deserialized: VideoQuality = serde_json::from_str("\"medium\"").unwrap();
155        assert_eq!(deserialized, VideoQuality::Medium);
156
157        let deserialized: VideoQuality = serde_json::from_str("{\"custom\":3000}").unwrap();
158        assert_eq!(deserialized, VideoQuality::Custom(3000));
159    }
160
161    #[test]
162    fn test_video_metadata_creation() {
163        let duration = Duration::seconds(3600);
164        let resolution = (1920, 1080);
165        let format = VideoFormat::MP4;
166
167        let metadata = VideoMetadata::new("Test Video".to_string(), duration, resolution, format);
168
169        assert_eq!(metadata.title, "Test Video");
170        assert_eq!(metadata.duration, duration);
171        assert_eq!(metadata.resolution, resolution);
172        assert_eq!(metadata.format, format);
173        assert_eq!(metadata.file_size, 0);
174        assert_eq!(metadata.bitrate, 0);
175        assert_eq!(metadata.created_at, metadata.updated_at);
176    }
177
178    #[test]
179    fn test_video_metadata_update_timestamp() {
180        let duration = Duration::seconds(3600);
181        let resolution = (1920, 1080);
182        let format = VideoFormat::MP4;
183
184        let mut metadata =
185            VideoMetadata::new("Test Video".to_string(), duration, resolution, format);
186        let old_updated_at = metadata.updated_at;
187
188        // Wait a bit to ensure time difference
189        std::thread::sleep(std::time::Duration::from_millis(10));
190
191        metadata.update_timestamp();
192
193        assert!(metadata.updated_at > old_updated_at);
194    }
195
196    #[test]
197    fn test_video_metadata_serialization() {
198        let duration = Duration::seconds(3600);
199        let resolution = (1920, 1080);
200        let format = VideoFormat::MP4;
201
202        let metadata = VideoMetadata::new("Test Video".to_string(), duration, resolution, format);
203
204        let json = serde_json::to_string(&metadata).unwrap();
205        let deserialized: VideoMetadata = serde_json::from_str(&json).unwrap();
206
207        assert_eq!(deserialized.title, metadata.title);
208        assert_eq!(deserialized.duration, metadata.duration);
209        assert_eq!(deserialized.resolution, metadata.resolution);
210        assert_eq!(deserialized.format, metadata.format);
211        assert_eq!(deserialized.id, metadata.id);
212    }
213}