KeyFrame is a slide-show generation platform that is able to generate 1 minute slide-shows for only 20 cents. It achieves this cost by utilizing smaller image generation models such as the Flux-Schnell model and different TTS services such as Amazon Polly. If in the event the generation does not work, that probably means the free plans to the REDIS or Postgres service ran out. The community tab demonstrates previous videos generated by users.
Here it is: https://keyframe-one.vercel.app/
Frontend: React, Next.js, HTML, CSS, JavaScript, TypeScript
Backend: Redis, PostgrSQL, OpenAI, Flux-Schnell, Amazon Polly, FFMPEG
Dev Ops: Docker, Vercel, Railway
- Install Node.js (v18+) and Python (3.10+)
- Docker (optional but recommended) or run Redis and Postgres locally
- Place
ffmpeg/ffprobein./bin/or ensure they are installed on the PATH - Create a
.env(see.env.example) with API keys and DB/Redis URIs - Install Node deps in
backend/apiand Python deps inbackend/worker
# Redis
REDIS_URL=redis://localhost:6379
# Database
DATABASE_URL=postgresql://keyframe_user:password@localhost:5432/keyframe_db
# Backend HTTP
PORT=3001
BACKEND_URL=http://localhost:3001
# Local output folder for job artifacts
KEYFRAME_OUTPUT_DIR=C:\\tmp
# FFmpeg override (optional)
FFMPEG_PATH=./bin/ffmpeg.exe
FFPROBE_PATH=./bin/ffprobe.exe
# Third-party API keys (fill when required)
OPENAI_API_KEY=
NEBIUS_API_KEY=
AWS_ACCESS_KEY_ID=
AWS_SECRET_ACCESS_KEY=
AWS_REGION=us-east-1
POLLY_VOICE=Joanna
# Cloudflare R2 (optional)
R2_ACCOUNT_ID=
R2_ACCESS_KEY=
R2_SECRET_KEY=
R2_BUCKET=
If you don't want to install Redis/Postgres system-wide, create a docker-compose.yml in the repo root with the following services and run docker compose up -d:
version: '3.8'
services:
redis:
image: redis:7
ports:
- "6379:6379"
postgres:
image: postgres:15
environment:
POSTGRES_USER: keyframe_user
POSTGRES_PASSWORD: password
POSTGRES_DB: keyframe_db
ports:
- "5432:5432"
volumes:
- pgdata:/var/lib/postgresql/data
volumes:
pgdata:
- Recommended: put
ffmpeg.exeandffprobe.exein./bin/at the repository root. - Verify:
./bin/ffmpeg.exe -versionand./bin/ffprobe.exe -versionor add./binto your PATH.
Backend API
cd backend/api
npm install
set PORT=3001
node index.jsPython worker (Windows recommended steps)
cd backend/worker
python -m venv .venv
.\.venv\Scripts\Activate.ps1
pip install -r requirements.txt
# Run Celery worker (Windows: use --pool=solo)
set REDIS_URL=redis://localhost:6379
celery -A app worker --loglevel=info --pool=solo- Node.js v18+ (recommended)
npm(orpnpm/yarn) installed
Install dependencies and run the dev server:
cd frontend
npm install
npm run devThe dev server runs on http://localhost:3000 by default.
Place optional static assets if you want the full visual polish (not required to run):
public/assets/Logo_Transparent.png— site logopublic/assets/videos/mock.mp4— mock demo video used by example pagespublic/assets/thumbnails/mock.jpg— mock thumbnail
- The repo includes simple Next.js API routes under
src/app/api/v1/*that return mock jobIds and simulated status. These are convenient for local UI development. - To use the real backend instead, point the frontend to your backend by setting
NEXT_PUBLIC_BACKEND_URLinfrontend/.env.local, for example:
NEXT_PUBLIC_BACKEND_URL=http://localhost:3001
Then update client fetch calls to use process.env.NEXT_PUBLIC_BACKEND_URL (the code already prefers NEXT_PUBLIC_BACKEND_URL if present). If you run Next dev and keep the built-in API routes, local routes will take precedence — remove or rename the mock routes if you want all calls to go to the real backend.
/—src/app/page.tsx(home + prompt form)/status/[jobId]—src/app/status/[jobId]/page.tsx(job progress + playback)/feed—src/app/feed/page.tsx(community thumbnails)
Run the linter before creating PRs:
cd frontend
npm run lint
# auto-fix
npm run lint -- --fix