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

116 lines
3.1 KiB
Markdown

# 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`:
```bash
PREVIEW_CLIPS_DIRECTORY=/path/to/preview-clips # Directory for generated preview MP4s
```
## Backend Development
### 1. Create database migration
```bash
cd C:\Users\ccord\RustroverProjects\ImageApi
diesel migration generate create_video_preview_clips
```
Edit the generated `up.sql`:
```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`:
```sql
DROP TABLE IF EXISTS video_preview_clips;
```
Regenerate schema:
```bash
diesel migration run
diesel print-schema > src/database/schema.rs
```
### 2. Build and test backend
```bash
cargo build
cargo test
cargo run
```
Test preview endpoint:
```bash
# 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
```bash
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 |