One-command narrated Manim explainers via Replicate Inworld TTS.
Find a file
2026-05-06 03:04:03 -04:00
examples Initial MVP commit 2026-05-06 03:04:03 -04:00
src/manim_narrate Initial MVP commit 2026-05-06 03:04:03 -04:00
.gitignore Initial MVP commit 2026-05-06 03:04:03 -04:00
LICENSE Initial MVP commit 2026-05-06 03:04:03 -04:00
pyproject.toml Initial MVP commit 2026-05-06 03:04:03 -04:00
README.md Initial MVP commit 2026-05-06 03:04:03 -04:00

manim-narrate

One-command narrated explainer videos: Manim scenes + Inworld TTS (Replicate) → final MP4.

manim-narrate packages the workflow Luis used to ship the wellbore-geology, legal-IR, and handwritten-Ukrainian Kaggle explainers (May 2026). Instead of copy-pasting narration.py / gen_audio.py / stitch.sh per project, point it at a Manim script.py and a narration.yaml, and out comes a single narrated MP4.

Why this project

Three back-to-back sessions in the last 24h built Manim explainers with the same pipeline:

  1. Render scenes with manim -qh script.py
  2. Run a per-project Python script to call Replicate's inworld/realtime-tts-1.5-max
  3. ffmpeg-mux per scene + concat with a shell script

Every project re-implemented steps 2 and 3 from scratch. This tool eliminates that re-work and makes "send me a Kaggle competition URL → I'll send you a 60s narrated explainer" a 30-minute consulting deliverable instead of an hour of glue code.

Install

cd ~/Code/daily-mvps/manim-narrate-2026-05-06
pip install -e .

Requires manim, ffmpeg, and REPLICATE_API_TOKEN in env (or ~/.hermes/.env).

Usage

# Build everything: render → narrate → stitch
manim-narrate build script.py narration.yaml --quality qh --voice Dennis --out final.mp4

# Render-only / narrate-only / stitch-only
manim-narrate render script.py --quality qh
manim-narrate narrate narration.yaml --out-dir audio/
manim-narrate stitch  --video-dir media/videos/script/1080p60 --audio-dir audio/ --out final.mp4

narration.yaml format

voice: Dennis            # default voice; per-scene override allowed
model: inworld/realtime-tts-1.5-max
scenes:
  - name: Scene1_Title
    text: "What rock lies ahead of the drill bit?"
  - name: Scene2_Problem
    text: "Pay zones are thin — a meter off and the well drifts dry."
    voice: Ashley         # override

The name must match the Manim Scene class name. Scene order in YAML defines final concat order.

Smoke test

manim-narrate --help
manim-narrate validate examples/narration.yaml

What it does NOT do (YAGNI)

  • Does not write Manim scenes for you (that's the human-creative part).
  • Does not auto-scrape Kaggle / arXiv (separate tool, future work).
  • Does not handle background music — bring your own ffmpeg post-step.

License

MIT.