Files
ImageApi/specs/001-video-wall/quickstart.md
Cameron 19c099360e 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>
2026-02-25 19:40:17 -05:00

3.1 KiB

Quickstart: VideoWall

Prerequisites

  • Rust toolchain (stable) with cargo
  • diesel_cli installed (cargo install diesel_cli --no-default-features --features sqlite)
  • ffmpeg and ffprobe available on PATH
  • Node.js 18+ and Expo CLI for mobile app
  • .env file configured with existing variables plus PREVIEW_CLIPS_DIRECTORY

New Environment Variable

Add to .env:

PREVIEW_CLIPS_DIRECTORY=/path/to/preview-clips   # Directory for generated preview MP4s

Backend Development

1. Create database migration

cd C:\Users\ccord\RustroverProjects\ImageApi
diesel migration generate create_video_preview_clips

Edit the generated up.sql:

CREATE TABLE video_preview_clips (
    id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
    file_path TEXT NOT NULL UNIQUE,
    status TEXT NOT NULL DEFAULT 'pending',
    duration_seconds REAL,
    file_size_bytes INTEGER,
    error_message TEXT,
    created_at TEXT NOT NULL,
    updated_at TEXT NOT NULL
);

CREATE INDEX idx_preview_clips_file_path ON video_preview_clips(file_path);
CREATE INDEX idx_preview_clips_status ON video_preview_clips(status);

Edit down.sql:

DROP TABLE IF EXISTS video_preview_clips;

Regenerate schema:

diesel migration run
diesel print-schema > src/database/schema.rs

2. Build and test backend

cargo build
cargo test
cargo run

Test preview endpoint:

# Check preview status
curl -X POST http://localhost:8080/video/preview/status \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{"paths": ["some/video.mp4"]}'

# Request preview clip
curl http://localhost:8080/video/preview?path=some/video.mp4 \
  -H "Authorization: Bearer <token>" \
  -o preview.mp4

3. Verify preview clip generation

Check that preview clips appear in PREVIEW_CLIPS_DIRECTORY with the expected directory structure mirroring BASE_PATH.

Frontend Development

1. Start the mobile app

cd C:\Users\ccord\development\SynologyFileViewer
npx expo start

2. Navigate to VideoWall

From the grid view of any folder containing videos, switch to VideoWall mode. The view should display a 2-3 column grid of looping preview clips.

Key Files to Modify

Backend (ImageApi)

File Change
src/video/ffmpeg.rs Add generate_preview_clip() function
src/video/actors.rs Add PreviewClipGenerator actor
src/video/mod.rs Add generate_preview_clips() batch function
src/main.rs Add endpoints, extend file watcher
src/database/schema.rs Regenerated by Diesel
src/database/models.rs Add VideoPreviewClip struct
src/database/preview_dao.rs New DAO file
src/data/mod.rs Add request/response types
src/state.rs Add PreviewClipGenerator to AppState

Frontend (SynologyFileViewer)

File Change
app/(app)/grid/video-wall.tsx New VideoWall view
app/(app)/grid/_layout.tsx Add route
components/VideoWallItem.tsx New preview clip cell component
hooks/useVideoWall.ts New hook for preview state management