Turn a URL, PDF, or block of text into a brand-aligned, animated MP4 — in minutes, no editor required.
Paste a source → pick a duration → choose audio → get a rendered promo video.
Prism replaces manual After-Effects work with an automated pipeline. The user provides source material and parameters; Gemini acts as the director (writing an animated HTML/GSAP composition and an optional voiceover script), and HyperFrames renders it deterministically to MP4 via headless Chromium + FFmpeg.
| Input | Configuration | Output |
|---|---|---|
| URL · PDF · Raw text | Duration (5–300s) · Audio on/off | Downloadable 1920×1080 MP4 |
┌─────────────────────┐ POST /api/generate ┌──────────────────────────┐
│ Frontend (Vite) │ ───────────────────────────────▶ │ Backend (Express) │
│ React · Vercel │ ◀───────── SSE progress ─────── │ Docker · HF Spaces │
└─────────────────────┘ GET /api/jobs/:id/events └────────────┬─────────────┘
│
┌─────────────────────────────────────────────┼─────────────────────────┐
▼ ▼ ▼ ▼
1. Parse input 2. Gemini director 3. Gemini TTS 4. HyperFrames render
(cheerio / pdf-parse) (HTML + GSAP + script) (voiceover.wav) (Chromium → FFmpeg → MP4)
- Parse — scrape a URL (text, brand colors, hero images), extract a PDF, or pass text through.
- Generate —
gemini-3.5-flashreturns a HyperFrames-formatindex.html: a paused, seekable GSAP timeline. - Synthesize (optional) —
gemini-3.1-flash-tts-previewturns the voiceover script intonarration.wav. - Render —
hyperframes renderseeks the timeline frame-by-frame, muxes audio, encodes the MP4.
| Layer | Choice |
|---|---|
| Frontend | React 18 + Vite, deployed on Vercel |
| Backend | Express + Node 22, Dockerized on Hugging Face Spaces |
| LLM / Director | Gemini 3.5 Flash (@google/genai) |
| Voiceover | Gemini 3.1 Flash TTS Preview |
| Render engine | HyperFrames + headless Chromium + FFmpeg |
| Parsing | cheerio (URL), pdf-parse (PDF) |
.
├── frontend/ # React + Vite single-page app (Vercel)
│ ├── src/
│ │ ├── App.jsx # All UI + pipeline client logic
│ │ ├── styles.css # Warm Prism brand theme
│ │ └── main.jsx
│ ├── index.html
│ └── vite.config.js
│
├── backend/ # Express API (HF Spaces / Docker)
│ ├── src/
│ │ ├── index.js # Server + static /outputs
│ │ ├── routes/generate.js# POST /api/generate + SSE job stream
│ │ └── services/
│ │ ├── parser.js # URL / PDF / text ingestion
│ │ ├── gemini.js # HTML + GSAP composition generation
│ │ ├── tts.js # Gemini TTS → WAV
│ │ └── renderer.js # HyperFrames CLI wrapper
│ ├── Dockerfile # Chromium + FFmpeg + headless-shell
│ └── README.md # HF Space metadata
│
├── vercel.json # Frontend deploy config
└── PRD.md # Product requirements
cd backend
cp .env.example .env # add your GEMINI_API_KEY
npm install
npm run dev # http://localhost:3001Requires FFmpeg locally (
brew install ffmpeg). HyperFrames downloads its own Chromium on first run.
cd frontend
npm install
npm run dev # http://localhost:5173 (defaults to localhost:3001 backend)POST /api/generate → { "jobId": "<uuid>" }
PDF uploads use multipart/form-data with a file part plus source and
parameters as JSON-string fields.
GET /api/jobs/:id/events — Server-Sent Events stream:
{ "stage": "parse", "status": "start" }
{ "stage": "generate", "status": "done" }
{ "stage": "complete", "outputUrl": "/outputs/<id>.mp4" }GET /outputs/:id.mp4 — the rendered video.
- Root Directory:
frontend· Framework: Vite - Env var:
VITE_API_URL = https://<your-space>.hf.space
- Push
backend/contents to a Docker Space (16 GB free RAM — needed for headless Chrome). - Secrets:
GEMINI_API_KEY(required),FRONTEND_URL,HYPERFRAMES_WORKERS(optional).
⚠️ Why not 512 MB hosts? Headless Chrome needs ≥1 GB. Render/Koyeb free tiers OOM; HF Spaces (or any ≥2 GB instance) is required.
| Variable | Where | Purpose |
|---|---|---|
GEMINI_API_KEY |
backend | Gemini generation + TTS (required) |
FRONTEND_URL |
backend | Locks CORS to your frontend (defaults to *) |
HYPERFRAMES_WORKERS |
backend | Parallel render workers (default 1) |
PORT |
backend | Listen port (HF sets 7860) |
VITE_API_URL |
frontend | Backend base URL (baked in at build time) |
- Ephemeral outputs — free HF Spaces have no persistent disk; rendered MP4s are wiped on container restart. Download promptly, or wire up S3 / R2 for persistence.
- Single-instance job store — jobs are tracked in memory; not safe across replicas.
- Duration vs. tokens — very long durations produce large HTML; output is capped at 32 k tokens with low thinking effort to avoid truncation.
Post-render editing · talking-head avatars · multi-user workspaces · billing.