Files
ImageApi/specs/001-video-wall/data-model.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

2.6 KiB

Data Model: VideoWall

Entities

VideoPreviewClip

Tracks the generation status and metadata of preview clips derived from source videos.

Table: video_preview_clips

Field Type Constraints Description
id INTEGER PRIMARY KEY, AUTOINCREMENT Unique identifier
file_path TEXT NOT NULL, UNIQUE Relative path of the source video from BASE_PATH
status TEXT NOT NULL, DEFAULT 'pending' Generation status: pending, processing, complete, failed
duration_seconds REAL NULLABLE Duration of the generated preview clip (≤10s)
file_size_bytes INTEGER NULLABLE Size of the generated MP4 file
error_message TEXT NULLABLE Error details if status is failed
created_at TEXT NOT NULL ISO 8601 timestamp when record was created
updated_at TEXT NOT NULL ISO 8601 timestamp when record was last updated

Indexes:

  • idx_preview_clips_file_path on file_path (unique, used for lookups and batch queries)
  • idx_preview_clips_status on status (used by file watcher to find pending/failed clips)

Relationships

  • VideoPreviewClip → Source Video: One-to-one via file_path. The preview clip file on disk is located at {PREVIEW_CLIPS_DIRECTORY}/{file_path}.mp4.
  • VideoPreviewClip → image_exif: Implicit relationship via shared file_path. No foreign key needed — the EXIF table may not have an entry for every video.

State Transitions

[new video detected] → pending
pending → processing  (when generation starts)
processing → complete (when ffmpeg succeeds)
processing → failed   (when ffmpeg fails or times out)
failed → pending      (on retry / re-scan)

Validation Rules

  • file_path must be a valid relative path within BASE_PATH
  • status must be one of: pending, processing, complete, failed
  • duration_seconds must be > 0 and ≤ 10.0 when status is complete
  • file_size_bytes must be > 0 when status is complete
  • error_message should only be non-null when status is failed

Storage Layout (Filesystem)

{PREVIEW_CLIPS_DIRECTORY}/
├── 2024/
│   ├── vacation/
│   │   ├── beach.mp4        # Preview for BASE_PATH/2024/vacation/beach.mov
│   │   └── sunset.mp4       # Preview for BASE_PATH/2024/vacation/sunset.mp4
│   └── birthday.mp4         # Preview for BASE_PATH/2024/birthday.avi
└── 2025/
    └── trip.mp4              # Preview for BASE_PATH/2025/trip.mkv

All preview clips use .mp4 extension regardless of source format.