From ab8e48573dce8b301be840eeed99487cee06f483 Mon Sep 17 00:00:00 2001 From: Blake Sims Date: Wed, 14 Jan 2026 10:52:10 +0700 Subject: [PATCH] Fix multi-segment recording data loss during recovery The recovery process sorted segment directories alphabetically, causing segment-10 to come before segment-2. Combined with index assignment from enumeration, this caused middle segments (2-9) to be incorrectly processed and their video data lost. Fixes: - Use natural numeric sort for segment directories - Parse segment index from folder name instead of enumeration - Use actual segment path from metadata in create_project_config Fixes #1509 Co-Authored-By: Claude Opus 4.5 --- crates/recording/src/recovery.rs | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/crates/recording/src/recovery.rs b/crates/recording/src/recovery.rs index 52aad3896a..df62dbbade 100644 --- a/crates/recording/src/recovery.rs +++ b/crates/recording/src/recovery.rs @@ -136,11 +136,22 @@ impl RecoveryManager { .filter(|e| e.path().is_dir()) .collect(); - segment_dirs.sort_by_key(|e| e.file_name()); + segment_dirs.sort_by_key(|e| { + let name = e.file_name().to_string_lossy().to_string(); + name.strip_prefix("segment-") + .and_then(|s| s.parse::().ok()) + .unwrap_or(u32::MAX) + }); - for (index, segment_entry) in segment_dirs.iter().enumerate() { + for segment_entry in &segment_dirs { let segment_path = segment_entry.path(); + let folder_name = segment_entry.file_name().to_string_lossy().to_string(); + let index: u32 = folder_name + .strip_prefix("segment-") + .and_then(|s| s.parse().ok()) + .unwrap_or(0); + let display_dir = segment_path.join("display"); let display_info = Self::find_complete_fragments_with_init(&display_dir); let mut display_fragments = display_info.fragments; @@ -186,7 +197,7 @@ impl RecoveryManager { let cursor_path = Self::probe_cursor(&segment_path.join("cursor.json")); recoverable_segments.push(RecoverableSegment { - index: index as u32, + index, display_fragments, display_init_segment, camera_fragments, @@ -899,11 +910,7 @@ impl RecoveryManager { .iter() .enumerate() .filter_map(|(i, segment)| { - let segment_base = format!("content/segments/segment-{i}"); - let display_path = recording - .project_path - .join(&segment_base) - .join("display.mp4"); + let display_path = recording.project_path.join(segment.display.path.as_str()); let duration = get_media_duration(&display_path) .map(|d| d.as_secs_f64())