Skip to content

Commit dff621b

Browse files
committed
[*] refactor: video editor
1 parent 7d32dc9 commit dff621b

File tree

9 files changed

+617
-295
lines changed

9 files changed

+617
-295
lines changed

lib/video-editor/examples/media_import_demo.rs

Lines changed: 11 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use std::path::PathBuf;
1+
use std::{path::PathBuf, time::Duration};
22
use video_editor::{
33
Result,
44
media::{ImportOptions, MediaImporter},
@@ -9,16 +9,15 @@ fn main() -> Result<()> {
99

1010
log::info!("=== Media Import Demo ===");
1111

12-
// Create library and cache
13-
let mut library = video_editor::media::MediaLibrary::new();
14-
let cache_dir = PathBuf::from("tmp").join(".cache");
15-
let mut cache = video_editor::media::MediaCache::new(cache_dir)?;
16-
17-
// Load cache index from previous run
18-
let cache_index = PathBuf::from("tmp").join(".cache").join("index.json");
19-
if let Err(e) = cache.load_cache_index(&cache_index) {
20-
log::debug!("Failed to load cache index: {}", e);
21-
}
12+
// Create library with integrated cache
13+
let cache_dir = PathBuf::from("tmp").join("cache");
14+
let mut library = video_editor::media::MediaLibrary::new().with_cache_configured(
15+
cache_dir.clone(),
16+
320,
17+
180,
18+
Duration::from_secs(86400),
19+
)?;
20+
log::info!("Cache directory: {:?}", cache_dir);
2221

2322
// Configure import with custom options
2423
let import_options = ImportOptions::new()
@@ -40,7 +39,7 @@ fn main() -> Result<()> {
4039
}
4140

4241
log::info!("Importing from: {}", data_dir.display());
43-
let _results = importer.import_directory(&data_dir, &mut library, &mut cache)?;
42+
let _results = importer.import_directory(&data_dir, &mut library)?;
4443

4544
// Show progress
4645
let progress = importer.progress();
@@ -93,12 +92,6 @@ fn main() -> Result<()> {
9392
}
9493
}
9594

96-
// Save cache for next run
97-
let cache_index = PathBuf::from("tmp").join(".cache").join("index.json");
98-
if let Err(e) = cache.save_cache_index(&cache_index) {
99-
log::warn!("Failed to save cache: {}", e);
100-
}
101-
10295
log::info!("\n=== Import Complete ===");
10396

10497
Ok(())

lib/video-editor/examples/media_library_demo.rs

Lines changed: 80 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -9,24 +9,40 @@ fn main() -> Result<()> {
99

1010
log::info!("=== Media Library Demo ===");
1111

12-
// Step 1: Create a media library
13-
log::info!("Step 1: Creating media library...");
14-
let mut library = MediaLibrary::new();
15-
16-
// Step 2: Create a media cache for thumbnails and metadata
17-
log::info!("Step 2: Creating media cache...");
18-
let cache_dir = PathBuf::from("tmp").join(".cache");
19-
let mut cache = video_editor::media::MediaCache::new(cache_dir)?
20-
.with_thumbnail_size(320, 180)
21-
.with_max_age(std::time::Duration::from_secs(86400));
22-
23-
// Load existing cache index
24-
let cache_index_path = PathBuf::from("tmp").join(".cache").join("index.json");
25-
if let Err(e) = cache.load_cache_index(&cache_index_path) {
26-
log::debug!("No existing cache index found (this is normal for first run). error: {e}");
12+
// Step 1: Create a media library with integrated cache
13+
log::info!("Step 1: Creating media library with cache...");
14+
let cache_dir = PathBuf::from("tmp").join("cache");
15+
let mut library = MediaLibrary::new().with_cache_configured(
16+
cache_dir.clone(),
17+
320,
18+
180,
19+
std::time::Duration::from_secs(86400),
20+
)?;
21+
log::info!(" Cache directory: {:?}", cache_dir);
22+
23+
// Step 2: Demonstrate add_file (auto-detect media type and generate thumbnail)
24+
log::info!("Step 2: Adding files with auto-detection...");
25+
let test_files = vec!["data/video1.mp4", "data/video2.mp4", "data/song1.mp3"];
26+
27+
for file_path in &test_files {
28+
match library.add_file(PathBuf::from(file_path)) {
29+
Ok(id) => {
30+
if let Some(item) = library.get_item(&id) {
31+
log::info!(" ✓ Added: {} (ID: {})", item.name, id);
32+
log::info!(" Type: {}", item.media_type.as_str());
33+
log::info!(" Duration: {}", item.format_duration());
34+
if let Some(ref thumbnail) = item.thumbnail_path {
35+
log::info!(" Thumbnail: {}", thumbnail.display());
36+
}
37+
}
38+
}
39+
Err(e) => {
40+
log::warn!(" ✗ Failed to add {}: {}", file_path, e);
41+
}
42+
}
2743
}
2844

29-
// Step 3: Configure import options
45+
// Step 3: Configure import options for bulk import
3046
log::info!("Step 3: Configuring import options...");
3147
let import_options = ImportOptions::new()
3248
.with_import_thumbnails(true)
@@ -37,25 +53,25 @@ fn main() -> Result<()> {
3753
log::info!("Step 4: Importing media files from data/ directory...");
3854
let data_dir = PathBuf::from("data");
3955

40-
if !data_dir.exists() {
56+
if data_dir.exists() {
57+
let mut importer = MediaImporter::new(import_options);
58+
// Note: importer doesn't need separate cache anymore, library has it
59+
let import_results = importer.import_directory(&data_dir, &mut library)?;
60+
61+
// Display import results
62+
log::info!("Import Results:");
63+
log::info!(" Total files processed: {}", import_results.len());
64+
let successful = import_results.iter().filter(|r| r.success).count();
65+
let failed = import_results.iter().filter(|r| !r.success).count();
66+
log::info!(" Successful: {}", successful);
67+
log::info!(" Failed: {}", failed);
68+
} else {
4169
log::warn!("Data directory does not exist: {}", data_dir.display());
4270
log::info!(
4371
"Please add some media files (mp4, mkv, mp3, wav, jpg, png, srt) to the data/ directory"
4472
);
45-
return Ok(());
4673
}
4774

48-
let mut importer = MediaImporter::new(import_options);
49-
let import_results = importer.import_directory(&data_dir, &mut library, &mut cache)?;
50-
51-
// Display import results
52-
log::info!("Import Results:");
53-
log::info!(" Total files processed: {}", import_results.len());
54-
let successful = import_results.iter().filter(|r| r.success).count();
55-
let failed = import_results.iter().filter(|r| !r.success).count();
56-
log::info!(" Successful: {}", successful);
57-
log::info!(" Failed: {}", failed);
58-
5975
// Step 5: Display library statistics
6076
log::info!("=== Library Statistics ===");
6177
log::info!("Total items: {}", library.item_count());
@@ -182,14 +198,42 @@ fn main() -> Result<()> {
182198
log::info!(" - {} ({} bytes)", item.name, item.file_size);
183199
}
184200

185-
// Step 12: Save cache index
201+
// Step 12: Cache management (now integrated into MediaLibrary)
186202
log::info!("=== Cache Management Demo ===");
187-
log::info!("Cache size: {} entries", cache.cache_size());
188-
let cache_index_path = PathBuf::from("tmp").join(".cache").join("index.json");
189-
if let Err(e) = cache.save_cache_index(&cache_index_path) {
190-
log::warn!("Failed to save cache index: {}", e);
191-
} else {
192-
log::info!("Cache index saved to: {}", cache_index_path.display());
203+
log::info!("Cache size: {} entries", library.cache_size());
204+
205+
// Cleanup expired cache entries
206+
library.cleanup_cache()?;
207+
log::info!("Cache cleanup complete");
208+
209+
// Step 13: Serialization and deserialization test
210+
log::info!("=== Serialization/Deserialization Demo ===");
211+
let json = library.to_json(true)?;
212+
log::info!(" Serialized library to JSON ({} bytes)", json.len());
213+
214+
// Test deserialization and cache rebuilding
215+
match MediaLibrary::from_json(&json) {
216+
Ok(restored_library) => {
217+
log::info!(" Successfully restored library from JSON");
218+
log::info!(
219+
" Restored library has {} items",
220+
restored_library.item_count()
221+
);
222+
log::info!(" Cache is configured: {}", restored_library.has_cache());
223+
224+
// Verify thumbnails are preserved
225+
for item in restored_library.all_items().iter().take(3) {
226+
let thumb_status = if item.thumbnail_path.is_some() {
227+
"has thumbnail".to_string()
228+
} else {
229+
"no thumbnail".to_string()
230+
};
231+
log::info!(" {} - {}", item.name, thumb_status);
232+
}
233+
}
234+
Err(e) => {
235+
log::warn!(" Failed to restore library: {}", e);
236+
}
193237
}
194238

195239
log::info!("=== Demo Complete ===");
Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
use std::{path::PathBuf, time::Duration};
2+
use video_editor::{media::MediaType, playlist::Playlist};
3+
4+
fn main() -> Result<(), Box<dyn std::error::Error>> {
5+
env_logger::init();
6+
7+
log::info!("=== Simple Playlist Demo ===");
8+
9+
// Create playlist with cache configuration
10+
let cache_dir = PathBuf::from("tmp").join("cache");
11+
let mut playlist = Playlist::new("Videos".to_string()).with_cache_configured(
12+
cache_dir,
13+
160,
14+
90,
15+
Duration::from_secs(86400),
16+
)?;
17+
18+
let video_files = vec![
19+
"data/test.mp4",
20+
"data/test.mkv",
21+
"data/test.wav",
22+
"data/test.png",
23+
"data/test.srt",
24+
];
25+
26+
for file_path in &video_files {
27+
match playlist.add_file(PathBuf::from(file_path)) {
28+
Ok(index) => {
29+
let item = &playlist.items[index];
30+
log::info!(
31+
" Added: {} ({}, {})",
32+
item.name,
33+
item.media_type.as_str(),
34+
item.format_duration()
35+
);
36+
}
37+
Err(e) => {
38+
log::warn!(" Failed to add {}: {}", file_path, e);
39+
}
40+
}
41+
}
42+
43+
log::info!(
44+
" Created video playlist with {} items",
45+
playlist.item_count()
46+
);
47+
48+
log::info!("Query and filter...");
49+
50+
for (i, item) in playlist.items.iter().enumerate() {
51+
log::info!(" [{}] {} ({})", i, item.name, item.format_duration());
52+
}
53+
54+
// Get audio items
55+
let audio_items = playlist.items_by_type(MediaType::Audio);
56+
log::info!(" Audio items: {}", audio_items.len());
57+
58+
// Search items
59+
let results = playlist.search("song");
60+
log::info!(" Search results for 'song': {}", results.len());
61+
62+
log::info!("Modifying playlist...");
63+
64+
// Get item
65+
if let Some(item) = playlist.get_item(0) {
66+
log::info!(" First item: {}", item.name);
67+
}
68+
69+
// Move an item
70+
if playlist.item_count() > 1 {
71+
playlist.move_item(0, 1)?;
72+
log::info!(" Moved item 0 to position 1");
73+
}
74+
75+
// Remove an item
76+
if playlist.item_count() > 0 {
77+
let removed = playlist.remove_item(0)?;
78+
log::info!(" Removed item: {}", removed.name);
79+
}
80+
81+
log::info!(" Remaining items: {}", playlist.item_count());
82+
83+
log::info!("Serializing modified playlist...");
84+
let modified_json = playlist.to_json(true)?;
85+
log::info!(" Modified playlist JSON:\n{}", modified_json);
86+
87+
// Test deserialization and cache rebuilding
88+
log::info!("Testing deserialization and cache rebuilding...");
89+
match Playlist::from_json(&modified_json) {
90+
Ok(restored_playlist) => {
91+
log::info!(" Successfully restored playlist from JSON");
92+
log::info!(
93+
" Restored playlist has {} items",
94+
restored_playlist.item_count()
95+
);
96+
log::info!(" Cache is configured: {}", restored_playlist.has_cache());
97+
98+
// Verify thumbnails are still present
99+
for (i, item) in restored_playlist.items.iter().enumerate() {
100+
let thumb_status = if item.thumbnail_path.is_some() {
101+
format!("has thumbnail: {:?}", item.thumbnail_path)
102+
} else {
103+
"no thumbnail".to_string()
104+
};
105+
log::info!(" [{}] {} - {}", i, item.name, thumb_status);
106+
}
107+
}
108+
Err(e) => {
109+
log::warn!(" Failed to restore playlist: {}", e);
110+
}
111+
}
112+
113+
log::info!("=== Demo Complete ===");
114+
115+
Ok(())
116+
}

0 commit comments

Comments
 (0)