Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

4 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

ReelForge

An AI pipeline that forges scroll-stopping vertical reels from talking-head video.

CI Python License Gemini FFmpeg MediaPipe

πŸ“ Architecture diagram & design deep-dive β†’

Overview

ReelForge takes a single speaker clip (a podcast cut, an interview, a webinar moment) plus its word-level transcript and automatically produces a polished, captioned, color-graded, music-scored 9:16 short β€” the kind of clip you'd post to TikTok, Reels, or Shorts. It plans the edit with a vision LLM, generates or sources B-roll, tracks the speaker's face for dynamic zoom, renders kinetic captions, masters the audio, grades the color, scores it with ducked music, and finally grades its own output with an AI quality check.

It is built as a sequence of ten independent, individually-skippable stages, each with graceful fallbacks so a missing API key or unavailable service degrades quality rather than crashing the run.

Note β€” This is a self-contained portfolio/reference implementation. No API keys, credentials, or media are included. The ingest layer reads a local sample transcript (samples/sample_transcript.json) instead of any production backend, so you can read and run the pipeline without external infrastructure. Bring your own input.mp4 and API keys to generate real reels.

Key features

  • LLM-planned edit β€” one video upload, three Gemini passes: B-roll segments, camera zoom events, and emphasis words.
  • Cost-aware, quality-gated B-roll routing β€” try Sora 2, grade each clip, retry or auto-demote to free Pexels stock, and track estimated dollars saved.
  • Anchor-word timing snapping β€” AI-proposed cut points are fuzzy-matched against real transcript word timings for ~0.01 s precision.
  • Face-tracked digital zoom β€” MediaPipe detection smoothed with an exponential moving average for a steady "camera operator" punch-in.
  • Kinetic captions β€” word-chunked, bold, stroke-outlined captions with emphasis words popped in color.
  • Frame-accurate compositing β€” base video + B-roll (cut / fade / crossfade / swipe) + captions, all snapped to frame boundaries.
  • Broadcast audio mastering β€” loudness-normalized voice with transition SFX mixed in without crushing speech.
  • Cinematic color grading β€” .cube LUT presets (warm / cool / vibrant / vintage), with sample LUTs generated procedurally.
  • Content-aware background music β€” mood-classified, fetched from Freesound, and sidechain-ducked under the voice.
  • Self-evaluating output β€” the finished reel is scored by Gemini across six dimensions with a pass/fail gate.
  • Graceful degradation everywhere β€” every external dependency has a fallback.

Architecture

The orchestrator (reelforge/cli.py) runs ten ordered stages, passing typed Pydantic models between them. Any stage can be disabled with a --skip-* flag.

 input.mp4 + word-level transcript
              β”‚
              β–Ό
   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
   β”‚ 1 Β· Ingest           β”‚  ClipData (context + transcript + video)
   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
              β–Ό
   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
   β”‚ 2 Β· Analysis         β”‚  Gemini "Director" β€” upload once, 3 passes:
   β”‚   (The Director)     β”‚  segments Β· zoom events Β· emphasis words
   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
              β–Ό
   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
   β”‚ 3 Β· Routing          β”‚  per segment: Sora 2 β†’ quality gate β†’ stock
   β”‚   (The Brain)        β”‚  fallback Β· or internal zoom / text
   β””β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”˜
       β”‚           β”‚
       β–Ό           β–Ό
  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
  β”‚ 4 Β· Zoomβ”‚  β”‚ 5 Β· Captionsβ”‚   MediaPipe EMA-smoothed zoom +
  β”‚ engine  β”‚  β”‚ engine      β”‚   kinetic typography (Pillow)
  β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”˜
       β””β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”˜
             β–Ό
   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
   β”‚ 6 Β· Stitch           β”‚  MoviePy composite: base + B-roll
   β”‚                      β”‚  (+ transitions) + captions, frame-snapped
   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
              β–Ό
   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
   β”‚ 7 Β· Audio mastering  β”‚  FFmpeg loudnorm (-14 LUFS) + SFX (amix)
   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
              β–Ό
   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
   β”‚ 8 Β· Color grade      β”‚  FFmpeg lut3d (.cube preset)
   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
              β–Ό
   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
   β”‚ 9 Β· Music            β”‚  Gemini classify Β· Freesound Β· sidechain duck
   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
              β–Ό
   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
   β”‚ 10 Β· Quality eval    β”‚  Gemini scores 6 dimensions Β· pass if avg β‰₯ 75
   β”‚   (QA)               β”‚
   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
              β–Ό
   Final 9:16 reel + quality report
# Stage What it does
1 Ingest Load the clip's word-level transcript + source video into typed models via a pluggable loader (local file / URL).
2 Analysis β€” "The Director" One video upload β†’ three Gemini passes: B-roll segments, camera zoom events, and emphasis words.
3 Routing β€” "The Brain" Per segment, choose the cheapest sufficient source: Sora (cinematic) β†’ quality gate β†’ stock fallback; or internal zoom/text.
4 Zoom engine Detect & track the speaker's face, apply smoothed digital "punch-in" zoom.
5 Caption engine Render word-chunked kinetic captions; emphasis words pop in color.
6 Stitch Composite base video + B-roll (with fade/crossfade/swipe transitions) + captions, frame-snapped.
7 Audio mastering Normalize the voice to broadcast loudness, then inject transition SFX without crushing speech.
8 Color grade Apply a cinematic .cube LUT (warm / cool / vibrant / vintage).
9 Music Classify the clip's mood/genre, fetch a matching CC track, duck it under speech.
10 Quality eval β€” "QA" Score the finished reel across six dimensions; pass when the average β‰₯ 75.

See docs/architecture.md for the full, stage-by-stage technical breakdown.

Tech stack

Layer Technology
Language Python 3.10+
Domain models Pydantic v2
Edit planning Β· QA Β· music classification Google Gemini (google-genai)
Cinematic B-roll generation OpenAI Sora 2 (openai)
Stock B-roll Pexels API
Background music Freesound API (Creative Commons)
Face detection MediaPipe Β· OpenCV
Caption rendering Pillow
Compositing MoviePy (v1/v2 compatible)
Audio / color / ducking FFmpeg + ffprobe (loudnorm, lut3d, sidechaincompress, amix)
Numerics NumPy
HTTP requests

Project structure

reelforge/
β”œβ”€β”€ reelforge/
β”‚   β”œβ”€β”€ cli.py              # orchestrator β€” drives all 10 stages
β”‚   β”œβ”€β”€ __main__.py         # `python -m reelforge` entry point
β”‚   β”œβ”€β”€ config.py           # environment-based settings (no hardcoded secrets)
β”‚   β”œβ”€β”€ models.py           # shared Pydantic domain models
β”‚   β”œβ”€β”€ ingest/             # transcript + video -> ClipData (pluggable backend)
β”‚   β”‚   β”œβ”€β”€ source.py
β”‚   β”‚   └── transcript_loader.py
β”‚   β”œβ”€β”€ analysis/           # Gemini "Director": segments, zoom, emphasis
β”‚   β”‚   └── director.py
β”‚   β”œβ”€β”€ routing/            # "Brain": Sora / stock routing + quality gate
β”‚   β”‚   β”œβ”€β”€ router.py
β”‚   β”‚   β”œβ”€β”€ sora_generator.py
β”‚   β”‚   └── stock_fetcher.py
β”‚   β”œβ”€β”€ effects/            # kinetic captions + face-tracked zoom
β”‚   β”‚   β”œβ”€β”€ captions.py
β”‚   β”‚   └── zoom.py
β”‚   β”œβ”€β”€ compose/            # stitching + audio mastering + color + music
β”‚   β”‚   β”œβ”€β”€ stitcher.py
β”‚   β”‚   β”œβ”€β”€ audio.py
β”‚   β”‚   β”œβ”€β”€ color.py
β”‚   β”‚   └── music.py
β”‚   └── quality/            # Gemini quality evaluation
β”‚       └── evaluator.py
β”œβ”€β”€ assets/luts/            # sample cinematic color LUT
β”œβ”€β”€ samples/                # sample transcript for a runnable demo
β”œβ”€β”€ docs/                   # architecture deep-dive
β”œβ”€β”€ tests/                  # self-contained unit tests (no network required)
β”œβ”€β”€ pyproject.toml
β”œβ”€β”€ requirements.txt
β”œβ”€β”€ .env.example
└── LICENSE

Getting started

Prerequisites: Python 3.10+ and FFmpeg (ffmpeg + ffprobe) installed separately and available on your PATH.

# 1. Install dependencies
pip install -r requirements.txt
#    ...or install as a package:  pip install -e .

# 2. Configure credentials (all optional; a missing key -> that stage is
#    skipped or falls back to a free/local alternative)
cp .env.example .env        # then edit .env with your own keys

# 3. Add a source video named input.mp4 in the project root

# 4. Run the pipeline
python -m reelforge --clip_id demo-001
#    ...or, if installed:  reelforge --clip_id demo-001

Environment variables (see .env.example): GEMINI_API_KEY, OPENAI_API_KEY, PEXELS_API_KEY, FREESOUND_API_KEY, plus optional path overrides REELFORGE_INPUT_VIDEO and REELFORGE_TRANSCRIPT.

Useful CLI flags: --skip-zoom, --skip-captions, --skip-audio, --skip-color, --skip-music, --skip-evaluation, --color-preset {cinematic_warm,cinematic_cool,vibrant,vintage,neutral}, --music-energy {low,medium,high}.

Run the tests

python -m unittest discover -s tests -v

The included tests exercise the transcript model, the ingest layer, caption chunking, and routing math using synthetic fixtures β€” no network or API keys needed.

How it works

These are the design decisions that separate "calls an API" from "a production-minded pipeline":

  • Single-upload, three-pass analysis. The source video is uploaded to the Gemini Files API once and the file handle is reused across the segment, zoom, and emphasis passes β€” a deliberate cost/latency optimization over three separate uploads, with each prompt kept narrow for more reliable structured (JSON-schema) output.
  • Anchor-word timing snapping. LLMs give loose timestamps. Instead of trusting them, each AI-proposed segment carries an anchor word that is fuzzy-matched (case-insensitive, punctuation-stripped) against the real transcript word timings, pulling cut points to ~0.01 s precision.
  • Cost-aware, quality-gated routing. Expensive Sora generation is tried first, each clip is graded by a Gemini evaluator, REGENERATE retries up to a cap, and USE_FALLBACK automatically demotes to free Pexels stock β€” with estimated dollar savings tracked per run.
  • Audio mastering in the right order. The voice is normalized to βˆ’14 LUFS first, then SFX are mixed in at a fixed relative level with amix:normalize=0 β€” deliberately avoiding a second normalization pass that would re-trigger the limiter and squash the speech.
  • Content-aware sidechain ducking. Background music is ducked under the voice with FFmpeg sidechaincompress, using per-energy presets so a calm clip and a high-energy clip duck differently.
  • EMA-smoothed face tracking. Per-frame MediaPipe detections are smoothed with an exponential moving average to mimic a real camera operator and kill jitter, with graceful fallback to the last known position / center crop.
  • Deterministic safety nets over the LLM. Spacing rules, zoom/segment overlap removal, and frame-boundary snapping correct the model's output in code rather than hoping the prompt was obeyed.

Notes / limitations

  • FFmpeg is required for stages 6–9 (audio, color, music) and must be installed separately.
  • No media, keys, or proprietary data ship with this repo. The ingest layer is a swappable adapter (ClipSource) that defaults to local files; point it at your own backend by subclassing it and overriding its resolution hooks β€” nothing downstream changes.
  • API access (Gemini, Sora 2, Pexels, Freesound) is required to generate a real reel; without keys the corresponding stages skip or fall back so the pipeline still runs end-to-end.

License

MIT

About

AI post-production pipeline that turns a talking-head clip plus its word-level transcript into a polished 9:16 reel: Gemini-planned edit, Sora/Pexels B-roll with quality-gated routing, MediaPipe face-tracked zoom, kinetic captions, FFmpeg loudness/color/sidechain-ducked music, and an AI quality check. Python, graceful fallbacks throughout.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages