A Next.js frontend for the Centroid Finder Video Processing application. The frontend lets users select a video to process, preview a thumbnail, sample a target color, set a threshold, submit a processing job, and analyze CSV results returned by the backend.
- Overview
- Features
- Tech Stack
- Key Pages
- Project Structure
- Key Components
- Global State
- How It Works
- Running the App
- Troubleshooting
This frontend provides an interactive workflow for tracking an object's centroid in videos and analyzing the results in zone-based layouts. The frontend pairs with a separate backend that performs thumbnail extraction, video processing, binarization, centroid extraction, and CSV export.
- Browse available videos and processed results fetched from the backend
- Hover to sample pixels from the thumbnail and click to lock a
targetColorvalue - Adjust a detection
thresholdand preview a binarized image with computed centroid - Submit processing jobs and monitor them via a job ID/status
- Analyze returned CSV results in three layouts: 3 vertical zones, 3 horizontal zones, or a 4-zone grid
- Visual and numeric feedback for each zone (frame count, duration, and percent of total)
- Next.js 16 (App Router)
- React 19
- Zustand for global state
/— Home page that lists available videos and results and allows navigation to preview or results pages/preview— Thumbnail preview, color picking, threshold selection, job submission/processing— Polls for job status and shows progress/results— Shows parsed CSV data and zone analytics
app/
├── components/
│ ├── AnalysisCard.jsx
│ ├── ColorPicker.jsx
│ ├── HomeButton.jsx
│ ├── Info.jsx
│ ├── List.jsx
│ ├── OptionCard.jsx
│ ├── ThresholdSelector.jsx
| └── VideoProcessor.jsx
├── preview/page.jsx # Video selection & configuration
├── processing/page.jsx # Processing status page
├── results/page.jsx # Analysis & visualization UI
├── store/useGlobalStore.jsx
└── page.jsx # Home page (videos + results navigation)
| Component | Purpose |
|---|---|
List.jsx |
Fetches videos & results and lists files for selection |
ColorPicker.jsx |
Displays thumbnail; hover to sample pixel color, click to set targetColor |
ThresholdSelector.jsx |
Binarizes thumbnail with targetColor and threshold, draws centroid overlay |
VideoProcessor.jsx |
Starts a processing job (POST /process/:video?targetColor=<hex>&threshold=<int>) |
OptionCard.jsx |
Shows zone overlay for layouts (vertical/horizontal/grid) on results page |
AnalysisCard.jsx |
Shows per-zone frames, duration (seconds), and percentages |
ResultsTable.jsx |
Renders CSV rows as a table (time, x, y) |
HomeButton.jsx |
Simple navigation back to home |
Global state is located in app/store/useGlobalStore.jsx. Important values:
videoArray- array of video files available for processingcsvArray- array of csv files that have been previously processedjobId- unique job identifier used to poll backend job statusselectedVideo- video filename selected by userselectedCsv- csv filename selected by the userthumbnail- blob URL loaded for the selected videotargetColor- 6-digit hex color without#(e.g.FF00AA)threshold- integer value used by the binarizervideoWidth- pixel width of video used for analysisvideoHeight- pixel height of video used for analysis,
Setters exist for each of these variables and the store contains default values for local testing.
- Navigate Home and choose a video (or a CSV result) from the
List. - When a video is selected, the app requests
/thumbnail/:videoand displays it as a preview. - Hover on the thumbnail to preview a pixel's color; click to set the
targetColor. - Use the
ThresholdSelectorto adjust the threshold and preview the binarized image and the centroid of the largest component. - Click
Processto callPOST /process/:videowithtargetColorandthresholdquery parameters; backend returns{ jobId }. /processingpolls for job completion. When finished, results appear underGET /api/resultsand the CSV itself is available viaGET /api/csv/:filename./resultsreads, parses, and computes zone analytics (counts, duration, and percentage) using the loaded rows and the video dimensions.
- Node.js (v18+ recommended)
- A backend server (the Salamander backend) that exposes the endpoints used by the frontend
npm installRun the dev server:
npm run dev -p 3001By default Next.js runs on port 3000. Because the frontend currently makes absolute fetches to http://localhost:3000, it’s easiest for local development to ensure the frontend is running on a different port (e.g., 3001).
Thumbnail missing
- Ensure the backend
/thumbnail/:videoendpoint is reachable and returns a binary image (the frontend expects an image blob).
No files listed
- Check that
GET /api/videosandGET /api/resultsreturn JSON arrays of strings (video and csv file names).
Processing fails / job does not start
- Ensure POST
/process/:videoacceptstargetColorandthresholdquery params and returns{ jobId: string }.
CORS or network issues
- If the frontend and backend are on different ports, configure CORS on the backend or set a proxy during development.
Incorrect analysis
- Confirm CSV rows are in the proper
(time, x, y)format and thatvideoWidthandvideoHeightvalues match the video dimensions used for coordinates.