Brain Fresh is a full-stack video engagement analyzer built around Meta's TRIBE v2 neural brain encoding model. You upload a video, the backend runs TRIBE-based cortical response inference, and the frontend renders the result as an interactive experience with:
- a synchronized video player
- an engagement timeline across visual, audio, and text modalities
- a cortical brain view
- transcript segments
- low-engagement section detection
- LLM-generated feedback for weak moments
At a high level, the app answers:
- Which parts of a video are likely to be less engaging?
- Which modality is weakest in those sections: visual, audio, or text?
- What does the model's cortical activity look like over time?
- What concrete changes could improve the low-engagement moments?
- React 19
- TypeScript
- Vite
- Axios
- Recharts
- Three.js
@react-three/fiber@react-three/dreilucide-react
- Python 3.10+
- FastAPI
- Uvicorn
- Pydantic /
pydantic-settings - NumPy
- TRIBE v2 from
facebookresearch/tribev2 - Nilearn / SciPy for cortical surface export utilities
- Anthropic SDK
- OpenAI SDK used against Moonshot/Kimi's OpenAI-compatible API
- Meta TRIBE v2 for cortical response prediction
- Moonshot/Kimi or Anthropic Claude for feedback generation
Frontend (React + Vite)
|
|-- upload video
|-- open processing websocket
|-- fetch final analysis JSON
|-- request feedback for low-engagement sections
v
Backend (FastAPI)
|
|-- /api/video/upload
|-- /api/video/ws/process/{video_id}
|-- /api/video/result/{video_id}
|-- /api/feedback/analyze
v
Services
|
|-- TribeProcessor
| |-- load TRIBE models
| |-- build events dataframe
| |-- run full / video-only / audio-only / text-only predictions
| |-- produce timeline, brain activations, transcript, low sections
|
|-- ClaudeFeedbackService
|-- build prompt from section context
|-- call Moonshot/Kimi or Anthropic
|-- parse concise suggestions
brain_fresh/
├── backend/
│ ├── app/
│ │ ├── main.py # FastAPI entrypoint
│ │ ├── config.py # environment-backed settings
│ │ ├── models/schemas.py # shared API/data contracts
│ │ ├── routes/video.py # upload, processing, result, streaming
│ │ ├── routes/feedback.py # low-engagement feedback endpoint
│ │ ├── services/tribe_processor.py
│ │ └── services/claude_feedback.py
│ ├── scripts/export_brain_surfaces.py
│ ├── run.sh
│ ├── pyproject.toml
│ └── .env.example
├── frontend/
│ ├── public/brain-mesh.json # current cortical mesh asset
│ ├── src/
│ │ ├── App.tsx
│ │ ├── components/
│ │ ├── hooks/useVideoSync.ts
│ │ ├── services/api.ts
│ │ ├── types/index.ts
│ │ └── utils/mockAnalysis.ts
│ ├── package.json
│ ├── vite.config.ts
│ └── run.sh
├── notebooks/
│ └── colab_brain_fresh_export.ipynb
├── CLAUDE.md
└── README.md
The frontend posts the video to POST /api/video/upload.
The backend:
- creates a short
video_id - stores the uploaded file in
backend/uploads/ - returns the upload metadata
The frontend opens WS /api/video/ws/process/{video_id}.
The backend:
- loads TRIBE models lazily
- extracts multimodal features/events from the video
- runs:
- full model
- video-only model
- audio-only model
- text-only model
- pushes progress updates back over the websocket
The backend builds an AnalysisResult containing:
timeline: normalized visual/audio/text activity over timebrain_activations: per-timestep cortical vertex activitybrain_viewer: viewer metadatalow_engagement_sectionstranscript_segments
The frontend then fetches GET /api/video/result/{video_id} and renders the results view.
When a low-engagement section is selected, the frontend posts POST /api/feedback/analyze.
The backend enriches the request with stored section context when available, then calls:
- Moonshot/Kimi if
MOONSHOT_API_KEYis set - otherwise Anthropic Claude if
ANTHROPIC_API_KEYis set
The frontend is intentionally small and component-driven.
frontend/src/App.tsx
Coordinates:
- upload state
- processing state
- results state
- selected section state
- demo mode
- playback synchronization
VideoUpload.tsx: file selection and upload entryLoadingScreen.tsx: processing progress UI and optional JSON import pathVideoPlayer.tsx: synchronized video playbackTimeline.tsx: chart for visual/audio/text engagementBrainModel.tsx: cortical mesh viewer with open/close and normal/inflated controlsTranscriptPanel.tsx: transcript windows synchronized with playbackFeedbackPanel.tsx: LLM-generated suggestions for low-engagement windows
services/api.ts: HTTP + websocket API wrapperhooks/useVideoSync.ts: current playback time / play-pause / seek synchronizationtypes/index.ts: shared TypeScript interfacesutils/mockAnalysis.ts: demo-mode mock analysis without the backend
backend/app/main.py
Responsibilities:
- applies Torch compatibility patches
- configures CORS
- mounts routers
- serves uploaded videos
- exposes
/api/health
backend/app/routes/video.py
Responsibilities:
- file upload
- websocket-driven processing
- in-memory result storage
- analysis import
- result retrieval
- uploaded video streaming
Important note:
- analysis results are currently stored in memory only
- restarting the backend clears
analysis_store
backend/app/services/tribe_processor.py
Responsibilities:
- select inference device (
cuda,mps, orcpu) - load TRIBE v2 models
- generate event dataframe from input video
- run modality ablations
- aggregate outputs into timeline scores
- downsample cortical activations for frontend transport
- extract transcript segments
- detect low-engagement windows
backend/app/services/claude_feedback.py
Responsibilities:
- build a structured prompt from timing/transcript/screenshot/context
- call Moonshot/Kimi or Anthropic
- parse the returned analysis and suggestions
GET /api/health
Returns a basic status payload.
POST /api/video/upload
Accepts multipart form data with a file.
WS /api/video/ws/process/{video_id}
Streams progress states such as:
uploadingextracting_featurespredictinganalyzingcompleteerror
GET /api/video/result/{video_id}
Returns the final AnalysisResult.
GET /api/video/stream/{video_id}
Used by the frontend video player.
POST /api/video/import-result/{video_id}
Disabled by default. Enable with ALLOW_ANALYSIS_IMPORT=1.
Useful when:
- processing in Colab or on a stronger machine
- loading a previously exported analysis JSON
POST /api/feedback/analyze
Generates a concise explanation plus concrete suggestions for a weak section.
Copy the example file before running the backend:
cd backend
cp .env.example .envKey variables:
TRIBE_DEVICE=auto- picks
cudawhen available - otherwise Apple
mpson supported Macs - otherwise
cpu
- picks
ALLOW_ANALYSIS_IMPORT=0- set to
1to allowPOST /api/video/import-result/{video_id}
- set to
MOONSHOT_API_KEY=...- enables feedback through Moonshot/Kimi
MOONSHOT_MODEL=kimi-k2.5MOONSHOT_BASE_URL=https://api.moonshot.cn/v1ANTHROPIC_API_KEY=...- fallback feedback provider if Moonshot is not configured
CLAUDE_MODEL=claude-sonnet-4-20250514
You need at least one of:
MOONSHOT_API_KEYANTHROPIC_API_KEY
if you want the feedback panel to work.
Recommended local setup:
- Python 3.10+
- Node.js 20+
- npm
uv
Notes:
- on macOS, CUDA is not available
- Apple Silicon can use
mps - first TRIBE model download can be large and slow
- CPU-only inference may be very slow
cd backend
bash run.shWhat backend/run.sh does:
- creates
.venvwithuvif it does not already exist - installs backend dependencies
- starts Uvicorn on port
8000
Backend URL:
http://localhost:8000
cd frontend
bash run.shWhat frontend/run.sh does:
- installs
node_modulesif needed - starts Vite
Frontend URL:
- usually
http://localhost:5173 - if
5173is busy, Vite will choose another port
Open the frontend in your browser and either:
- upload a real video and process it through the backend
- use demo mode to load a local video into the mock analysis path
cd frontend
npm run buildThere is no root Makefile right now. Useful direct commands:
cd backend
.venv/bin/uvicorn app.main:app --reload --host 0.0.0.0 --port 8000Optional compile sanity check:
cd /path/to/brain_fresh
backend/.venv/bin/python -m compileall backend/appUseful when local TRIBE inference is too slow.
Relevant files:
notebooks/colab_brain_fresh_export.ipynbbackend/analysis_export.jsonbackend/analysis_processed*.json
The intended workflow is:
- run TRIBE elsewhere
- export the analysis JSON
- enable
ALLOW_ANALYSIS_IMPORT=1 - load the result back into the backend through the import endpoint
The frontend currently ships with frontend/public/brain-mesh.json.
There is also a utility to export fsaverage cortical assets:
cd backend
.venv/bin/python scripts/export_brain_surfaces.pyThis writes:
frontend/public/brain-surfaces.json
and is intended for a more TRIBE-style pial/inflated cortical viewer.
- analysis results are stored in memory, not in a database
- uploads persist on disk under
backend/uploads, but metadata does not - the current frontend brain viewer is a lightweight browser renderer, not the original Meta demo implementation
Truebrain mode is not available for arbitrary uploads because there is no measured fMRI ground truth for user videos- local TRIBE inference can be expensive without a capable GPU or Apple Silicon
mps
- check
TRIBE_DEVICE - on Apple Silicon, keep
TRIBE_DEVICE=auto - CPU-only inference is expected to be slow
Make sure one of these is configured in backend/.env:
MOONSHOT_API_KEYANTHROPIC_API_KEY
Make sure:
- backend is running on
localhost:8000 - frontend is running through Vite
- Vite proxy is active for
/api
This is expected with the current in-memory analysis_store.