# Phase 2: Virtual Capture Engine

**Status:** ⬜ Not Started
**Parent plan:** [PLAN.md](./PLAN.md)
**Domain:** backend

## Objective
Create a `DemoCaptureEngine` that provides virtual displays and produces animated test pattern frames, allowing screen capture workflows to function in demo mode without real monitors.

## Tasks

- [ ] Task 1: Create `server/src/wled_controller/core/capture_engines/demo_engine.py` with `DemoCaptureEngine` and `DemoCaptureStream`
- [ ] Task 2: `DemoCaptureEngine.ENGINE_TYPE = "demo"`, `ENGINE_PRIORITY = 1000` (highest in demo mode)
- [ ] Task 3: `is_available()` returns `True` only when `is_demo_mode()` is True
- [ ] Task 4: `get_available_displays()` returns 3 virtual displays:
  - "Demo Display 1080p" (1920×1080)
  - "Demo Ultrawide" (3440×1440)
  - "Demo Portrait" (1080×1920)
- [ ] Task 5: `DemoCaptureStream.capture_frame()` produces animated test patterns:
  - Horizontally scrolling rainbow gradient (simple, visually clear)
  - Uses `time.time()` for animation so frames change over time
  - Returns proper `ScreenCapture` with RGB numpy array
- [ ] Task 6: Register `DemoCaptureEngine` in `capture_engines/__init__.py`

## Files to Modify/Create
- `server/src/wled_controller/core/capture_engines/demo_engine.py` — New file: DemoCaptureEngine + DemoCaptureStream
- `server/src/wled_controller/core/capture_engines/__init__.py` — Register DemoCaptureEngine

## Acceptance Criteria
- `DemoCaptureEngine.is_available()` is True only in demo mode
- Virtual displays appear in the display list API when in demo mode
- `capture_frame()` returns valid RGB frames that change over time
- Engine is properly registered in EngineRegistry

## Notes
- Test patterns should be computationally cheap (no heavy image processing)
- Use numpy operations for pattern generation (vectorized, fast)
- Frame dimensions must match the virtual display dimensions

## Review Checklist
- [ ] All tasks completed
- [ ] Code follows project conventions
- [ ] No unintended side effects
- [ ] Build passes
- [ ] Tests pass (new + existing)

## Handoff to Next Phase
<!-- Filled in after completion -->
