diff --git a/docs/ARCHITECTURE.md b/docs/ARCHITECTURE.md index 7dd8e230..225b3202 100644 --- a/docs/ARCHITECTURE.md +++ b/docs/ARCHITECTURE.md @@ -1,26 +1,18 @@ # Reframe Architecture -This document provides detailed technical information about Reframe's architecture, design choices, and implementation details. +This document is the source of truth for Reframe's app architecture, state flow, preview behavior, and export pipeline. --- -## Table of Contents +## Overview -- [How It Works](#how-it-works) -- [Architecture Diagram](#architecture-diagram) -- [Key Files](#key-files) -- [Tech Stack](#tech-stack) -- [Video Processing Pipeline](#video-processing-pipeline) -- [Design Choices](#design-choices) +Reframe is a client-side video editor built with Next.js and React. Users upload a local video, adjust an `EditRecipe`, preview changes in the browser, and export the final result with FFmpeg running in a Web Worker. Videos are processed locally on the user's device; no media is uploaded to a server. ---- - -## How It Works +The app has three primary layers: -1. **Load Video** → User selects a file → App detects resolution and duration -2. **Build Recipe** → User adjusts presets, framing, trim, speed → Creates `EditRecipe` -3. **Export** → Click Export → FFmpeg WASM loads from CDN (~30 MB, cached after first use) → Filtergraph runs locally → File downloads -4. **Done** → Your edited video is ready. Nothing was uploaded anywhere. +- **UI layer:** React components for layout, preview, controls, overlays, export status, and download results. +- **State layer:** `useVideoEditor` owns the active file, edit recipe, metadata, persistence, and export state. +- **Processing layer:** `ffmpeg.ts` and `ffmpeg.worker.ts` translate the recipe into FFmpeg arguments and run the export in browser-side WebAssembly. --- @@ -28,177 +20,422 @@ This document provides detailed technical information about Reframe's architectu ```mermaid graph TD - A["UI Layer · Next.js Components"] --> B["VideoEditor · FileUpload · PresetSelector · FramingControl · TrimControl"] - A --> C["AudioSpeedControl · RotateControl · ExportSettings"] - B --> D["useVideoEditor Hook · State Management"] - C --> D - D --> E["ffmpeg.ts · Lazy-loads WASM, builds filter chains"] - E --> F["FFmpeg.wasm · Single-threaded core via CDN · ~30MB"] - F --> G["Video Pipeline: trim → rotate → scale/crop → speed"] - G --> I["Output: MP4 or WebM · Blob URL → Download"] + User["User"] --> UI["UI Layer: Next.js + React Components"] + UI --> Editor["VideoEditor"] + Editor --> Hook["useVideoEditor: State + Orchestration"] + Editor --> Preview["VideoPreview: Browser Preview"] + Editor --> Controls["Controls: Preset, Trim, Rotate, Text, Audio, Adjustments, Export"] + Controls --> Hook + Hook --> Recipe["EditRecipe"] + Recipe --> Preview + Hook --> FFmpegFacade["ffmpeg.ts: Main Thread Facade"] + FFmpegFacade --> Worker["ffmpeg.worker.ts: Web Worker"] + Worker --> Wasm["FFmpeg.wasm"] + Wasm --> Result["ExportResult: Blob URL + Download"] + Result --> Editor ``` --- ## Key Files -| File | Purpose | -| -------------------------------- | -------------------------------------------------------- | -| `src/components/VideoEditor.tsx` | Root component; layout, state orchestration | -| `src/hooks/useVideoEditor.ts` | State management (file, recipe, export status) | -| `src/lib/ffmpeg.ts` | FFmpeg wrapper; lazy-loads WASM, builds filter chains | -| `src/lib/presets.ts` | 11 preset definitions (9:16, 16:9, 4:5, etc.) | -| `src/lib/types.ts` | TypeScript types for EditRecipe, ExportResult, etc. | -| `src/components/*.tsx` | Individual control panels (Trim, Rotate, Speed, Quality) | +| File | Responsibility | +| --- | --- | +| `src/components/VideoEditor.tsx` | Main editor view, layout orchestration, passes state into preview and controls. | +| `src/components/VideoPreview.tsx` | Renders the HTML video element, browser-side previews, playback controls, visual overlays, and comparison preview. | +| `src/hooks/useVideoEditor.ts` | Owns domain state, file validation, recipe updates, persistence, export status, and export orchestration. | +| `src/lib/types.ts` | Shared TypeScript contracts including `EditRecipe`, `ExportResult`, overlay options, and validation helpers. | +| `src/lib/constants.ts` | Default recipe values and shared option constants. | +| `src/lib/ffmpeg.ts` | Main-thread FFmpeg facade, worker lifecycle, request serialization, result handling, and filter builders used by tests. | +| `src/lib/ffmpeg.worker.ts` | Worker-side FFmpeg load, MEMFS staging, argument construction, execution, cleanup, and progress reporting. | +| `src/lib/presets.ts` | Output preset definitions and target dimensions. | +| `src/lib/text-overlay.ts` | FFmpeg text overlay filter generation. | --- -## Tech Stack +## Component Hierarchy + +`VideoEditor` is the main composition root. It renders: + +- `ExportOverlay` +- `OnboardingTour` +- `FileUpload` +- `VideoPreview` +- `ThumbnailStrip` +- `PresetSelector` +- `FramingControl` +- `TrimControl` +- `RotateControl` +- `TextControls` +- `AudioSpeedControl` +- brightness, contrast, and saturation controls +- `FormatSelector` +- `ExportSettings` +- `ImageOverlay` +- `DownloadResult` +- `KeyboardShortcutsPanel` + +`VideoPreview` contains the actual `