Add VideoWall feature: server-side preview clip generation and mobile grid view

Backend (Rust/Actix-web):
- Add video_preview_clips table and PreviewDao for tracking preview generation
- Add ffmpeg preview clip generator: 10 equally-spaced 1s segments at 480p with CUDA NVENC auto-detection
- Add PreviewClipGenerator actor with semaphore-limited concurrent processing
- Add GET /video/preview and POST /video/preview/status endpoints
- Extend file watcher to detect and queue previews for new videos
- Use relative paths consistently for DB storage (matching EXIF convention)

Frontend (React Native/Expo):
- Add VideoWall grid view with 2-3 column layout of looping preview clips
- Add VideoWallItem component with ActiveVideoPlayer sub-component for lifecycle management
- Add useVideoWall hook for batch status polling with 5s refresh
- Add navigation button in grid header (visible when videos exist)
- Use TextureView surface type to fix Android z-ordering issues
- Optimize memory: players only mount while visible via FlatList windowSize
- Configure ExoPlayer buffer options and caching for short clips
- Tap to toggle audio focus, long press to open in full viewer

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Cameron
2026-02-25 19:40:17 -05:00
parent 7a0da1ab4a
commit 19c099360e
19 changed files with 1691 additions and 12 deletions

View File

@@ -371,6 +371,29 @@ pub struct GpsPhotosResponse {
pub total: usize,
}
#[derive(Deserialize)]
pub struct PreviewClipRequest {
pub path: String,
}
#[derive(Deserialize)]
pub struct PreviewStatusRequest {
pub paths: Vec<String>,
}
#[derive(Serialize)]
pub struct PreviewStatusResponse {
pub previews: Vec<PreviewStatusItem>,
}
#[derive(Serialize)]
pub struct PreviewStatusItem {
pub path: String,
pub status: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub preview_url: Option<String>,
}
#[cfg(test)]
mod tests {
use super::Claims;