# Frame Analyzer Frame Analyzer is a local-first browser app for pulling a small set of representative stills out of a video. You load a video file in the browser, scan it for scene changes, review the candidate frames, and then copy or download the stills you want. No backend is required for the app itself. Video processing happens in the browser against a local blob URL. ## What It Does - Loads a local video file without uploading it to a server - Samples the video at a configurable interval - Scores sampled moments using a hybrid of histogram shift and pixel change - Picks candidate frames across the full duration of the video instead of clustering around one active section - Shows thumbnail candidates with timestamps - Lets you copy a frame as PNG to the clipboard - Falls back to PNG download if clipboard image write is blocked - Lets you manually add the current scrubbed frame from the video preview ## How Selection Works The current frame picker is a two-stage pipeline: 1. The scanner samples the video over time and computes a visual-change score for each sampled moment. 2. The selector first tries to fill the timeline with one strong candidate per time bucket, then backfills additional high-quality frames while preserving temporal spread. This is intentionally different from a simple threshold-crossing approach. One-pass threshold gating tends to miss gradual transitions and often returns only one or two frames in videos with slow visual evolution. ## Stack - React 19 - TypeScript - Vite - Native browser video decoding through `HTMLVideoElement` - Canvas for analysis and frame extraction - Clipboard API for image copy - `nginx` for static serving in the containerized deployment ## Running Locally Requirements: - Node.js 22 or newer is recommended - A Chromium-based browser is the safest target for clipboard image support Install dependencies: ```bash npm install ``` Start the dev server: ```bash npm run dev ``` Build for production: ```bash npm run build ``` Preview the production build locally: ```bash npm run preview ``` ## Usage 1. Open the app and select a local video file. 2. Adjust scan settings if needed: - sample interval - change threshold - pixel delta - minimum gap between captures - target image count - candidate pool size - analysis size 3. Run the scan. 4. Review the candidate gallery. 5. Copy or download the frames you want. 6. Use the video scrubber and `Add current` if you want to add a frame manually. ## Deployment This repo includes CapRover deployment files: - [captain-definition](./captain-definition) - [Dockerfile](./Dockerfile) CapRover will build the app with Node, generate the Vite production output, and serve the built files from `nginx`. ## Project Structure ```text src/ analysis/ candidateRanking.ts frameDifference.ts scanVideo.ts media/ canvas.ts clipboard.ts video.ts types/ scan.ts App.tsx main.tsx styles.css ``` ## Important Browser Notes - Clipboard image writing requires a secure context such as `localhost` or HTTPS. - Browser codec support varies. MP4/H.264 is the safest general input format. - Exact frame extraction is limited by browser video seeking behavior. - The app waits for a rendered post-seek frame before capturing thumbnails or exports, but browser decoding behavior can still vary across engines. ## Known Limits - This is still a heuristic frame picker, not a frame-accurate editor. - Very long videos can take time because the browser must seek and decode many timestamps. - Videos with subtle lighting changes, heavy motion, or repeated near-identical scenes may still need manual adjustment or manual frame additions. - Safari and Firefox may behave differently from Chromium for clipboard support and media decoding.