Files
ImageApi/specs/001-video-wall/contracts/api-endpoints.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.9 KiB

API Contracts: VideoWall

GET /video/preview

Retrieve the preview clip MP4 file for a given video. If the preview is not yet generated, triggers on-demand generation and returns 202.

Authentication: Required (Bearer token)

Query Parameters:

Parameter Type Required Description
path string yes Relative path of the source video from BASE_PATH

Responses:

Status Content-Type Body Description
200 video/mp4 MP4 file stream Preview clip is ready and served
202 application/json {"status": "processing", "path": "<path>"} Preview generation has been triggered; client should retry
400 application/json {"error": "Invalid path"} Path validation failed
404 application/json {"error": "Video not found"} Source video does not exist
500 application/json {"error": "Generation failed: <detail>"} Preview generation failed

Behavior:

  1. Validate path with is_valid_full_path()
  2. Check if preview clip exists on disk and status is complete → serve MP4 (200)
  3. If status is pending or no record exists → trigger generation, return 202
  4. If status is processing → return 202
  5. If status is failed → return 500 with error detail

POST /video/preview/status

Check the preview generation status for a batch of video paths. Used by the mobile app to determine which previews are ready before requesting them.

Authentication: Required (Bearer token)

Request Body (application/json):

{
  "paths": [
    "2024/vacation/beach.mov",
    "2024/vacation/sunset.mp4",
    "2024/birthday.avi"
  ]
}
Field Type Required Description
paths string[] yes Array of relative video paths from BASE_PATH

Response (200, application/json):

{
  "previews": [
    {
      "path": "2024/vacation/beach.mov",
      "status": "complete",
      "preview_url": "/video/preview?path=2024/vacation/beach.mov"
    },
    {
      "path": "2024/vacation/sunset.mp4",
      "status": "processing",
      "preview_url": null
    },
    {
      "path": "2024/birthday.avi",
      "status": "pending",
      "preview_url": null
    }
  ]
}
Field Type Description
previews object[] Status for each requested path
previews[].path string The requested video path
previews[].status string One of: pending, processing, complete, failed, not_found
previews[].preview_url string? Relative URL to fetch the preview (only when status is complete)

Behavior:

  1. Accept up to 200 paths per request
  2. Batch query the video_preview_clips table for all paths
  3. For paths not in the table, return status not_found (video may not exist or hasn't been scanned yet)
  4. Return results in the same order as the input paths