Manim 1080p60 Technischer Video-Erklärer & Synchronisiertes Sprachausgabe-System
Übersicht und gebündelte Ressourcen
Erstellen Sie präzise, deterministische 1920x1080 @ 60fps technische Erklärvideos und Architektur-Durchläufe in reinem Python mit Manim Community, ohne dass pdflatex oder MacTeX erforderlich sind.
Koppeln Sie Animationen optional mit sample-genauer neuronaler Sprachausgabe (offline Piper ONNX, einem beliebigen OpenAI-kompatiblen /v1/audio/speech HTTP-Endpunkt oder einem benutzerdefinierten CLI-TTS), EBU-R128-Lautheitsnormalisierung, synchronisierten .vtt WebVTT-Untertiteln und einem CDN-freien offline HTML5-Kapitelplayer.
assets/nord_manim_theme.py: Nord Polar/Frost/Aurora Farbpaletten-Token, Safe-Frame-Layout-Konstanten,BeatTimer-Synchronisationshilfe, LaTeX-freie Primitive (make_header_banner,make_node_card,make_badge,animate_blocked_pulse,safe_fit_text) und strenge port-verankerte orthogonale Schaltplanverbinder (connect_h,connect_v,connect_elbow,animate_packet_along,assert_all_orthogonal).assets/video_player_template.html: Eigenständiger, CDN-freier Nord Dunkel/Hell HTML5 Cinema Player mit Kapitel-Tabs, anklickbaren Beat-Markern, Wiedergabegeschwindigkeit (0.75x..2.0x) und optionalem zweisprachigen Audio-/Untertitelwechsel.check_scene_bounds.py: Pre-Render-Layout-Prüfer, der Manim-Szenen oder JSON-Checkpoints auf[-6.8, 6.8] x [-3.75, 3.75]Frame-Überlauf und Textlabel-Kollisionen zwischen Geschwistern prüft.mux_narration.py: Python-CLI der Standardbibliothek, die per-Beat-WAVs über Piper, einen OpenAI-kompatiblen HTTP/v1/audio/speech-Endpunkt oder einen benutzerdefinierten TTS-Befehl synthetisiert,beat_timings.jsonausgibt, eine sample-genaue Master-WAV-Spur erstellt, nachfolgende Videoframes klont (tpad=stop_mode=clone), damit Sprache nie abgeschnitten wird, optional die Lautstärke normalisiert (--loudnorm-lufs -18.0), H.264 + AAC multiplexed (+faststart) und.vtt-Untertitel schreibt.lint.py: Ausgabe-Bundle-Prüfer, derffprobeH.264yuv420p+ Audiostreams, WebVTT-Header/Cue-Monotonie und offline HTML5-Player CSP/zero-CDN/zero-Emoji-Invarianten überprüft.references/manim-layout-and-choreography.md: Lesen Sie dies, wenn Sie Multi-Node-Topologien, orthogonale Bus-/Ellbogen-Routing, dynamische Zähler, bidirektionale Pfeile oder Multi-Scene-ffmpeg-Concatenation entwerfen.references/voiceover-and-commentary.md: Lesen Sie dies, wenn Sie Erzähl-Manifeste, Anweisungen zur natürlichen Erzählweise des Sprechers, phonetische Aussprache-Glossare, EBU-R128-Normalisierung oder zweisprachige Sprachausgabe-Tracks erstellen.
1. Storyboard & Multi-Act Narrative Design
Strukturieren Sie die Erklärung, bevor Sie Manim-Code schreiben, in diskrete Akte und eine Beat-für-Beat-Storyboard-Tabelle.
Behalten Sie eine Scene-Klasse pro Akt bei, damit Bearbeitungen an Akt 2 niemals ein erneutes Rendern von Akt 1 oder Akt 3 erfordern:
- Akt 1 — Aufbau & Anfrageaufnahme: Führen Sie die Topologie, Invarianten und den Eintrittswächter ein (z.B.
Client -> API Gateway -> Token-Bucket Rate Limiter). - Akt 2 — Stationärer Zustand & Ausführung: Verfolgen Sie den primären Datenpfad und die Zustandsübergänge (z.B.
Read-Through CacheSingle-Flight-Lookup ->Primary DBHydratation -> TTL-Rückschreiben). - Akt 3 — Fehlermodi & Wiederherstellung: Zeigen Sie, was passiert, wenn Limits ausgelöst werden oder Knoten ausfallen (z.B.
HTTP 429Burst-Ablehnung oderDistributed Lock & Write-Ahead Log ReplicationQuorum-Promotion).
Planen Sie jeden Beat explizit vor dem Codieren:
beat_id | visual_action | min_visual_sec | commentary_script (falls vertont) |
|---|---|---|---|
act1_ingress | 4 Nord-Topologie-Karten + Kopfzeile rendern; Anfragepaket in Gateway animieren | 3.2 | Eingehende Schreibvorgänge durchlaufen einen Edge-Gateway, bevor sie den zustandsbehafteten Speicher berühren. |
act1_bucket | Token-Zähler 100 -> 99 dekrementieren; grünes ADMITTED-Abzeichen aufblinken lassen | 3.8 | Ein atomarer Token-Bucket-Check absorbiert Verkehrsspitzen und begrenzt gleichzeitig die Nebenläufigkeit im Backend. |
act1_reject | animate_blocked_pulse auslösen (429 RATE LIMITED), wenn Token 0 erreichen | 3.5 | Sobald die Burst-Kapazität erschöpft ist, scheitern überzählige Aufrufer schnell mit HTTP 429, anstatt sich endlos in die Warteschlange einzureihen. |
2. LaTeX-freie Manim Community-Erstellung
Isolierte Umgebungseinrichtung
Richten Sie Manim (und optional piper-tts) in einer isolierten virtuellen Umgebung ein; verifizieren Sie, dass ffmpeg und ffprobe im PATH sind:
uv venv venv
uv pip install --python venv/bin/python manim piper-tts
Strenge LaTeX-freie & Orthogonale Schema-Regeln
- Null TeX-Subprozesse: Verwenden Sie niemals
Tex,MathTex,TitleoderDecimalNumber(diepdflatex/dvisvgmaufrufen). Verwenden SieText,MarkupText(<b>,<i>,<sub>,<sup>,<span foreground="...">),Code,RoundedRectangle,Arrow,DashedVMobjectundMoveAlongPath. - Goldene Schema-Regel (Port-verankerte orthogonale Leitungen): Rufen Sie NIEMALS
Arrow(card_a, card_b)direkt auf zweiMobjects auf, wenn Sie Architektur-Blockschaltbilder erstellen – Manim zielt auf Strahlen zwischen den Mittelpunkten der Begrenzungsrahmen und erzeugt krumme diagonale Pfeile, sobald sich Kartenbreiten oder Y-Positionen unterscheiden. Routen Sie jede Kante überconnect_h(card_from, card_to, y=...),connect_v(card_from, card_to, x=...)oderconnect_elbow(points), animieren Sie Pakete mitanimate_packet_along(self, edge, ...)und validieren Sie die Drahtgeometrie mitassert_all_orthogonal(connectors, cards). - Safe-Frame-Koordinatengitter: Manims 16:9-Leinwand erstreckt sich über
[-7.11, 7.11] x [-4.0, 4.0]. Halten Sie alle erstellten Inhalte innerhalb von[-6.6, 6.6] x [-3.5, 3.5]und lassen Siey < -3.05leer, wenn WebVTT-Untertitel angezeigt werden. - Importieren Sie
assets/nord_manim_theme.py: Setzen Sieself.camera.background_color = BG_DARKund konstruieren Sie Karten, orthogonale Verbinder, Paketanimationen und Beat-Holds konsistent:
from pathlib import Path
import sys
SKILL_DIR = Path(__file__).resolve().parent
sys.path.insert(0, str(SKILL_DIR))
sys.path.insert(0, str(SKILL_DIR / "assets"))
from manim import Create, FadeIn, Scene, VGroup
from check_scene_bounds import dump_checkpoints
from nord_manim_theme import (
ACCENT_BLUE, ACCENT_CYAN, BG_DARK, STATUS_ERR, STATUS_OK,
BeatTimer, animate_blocked_pulse, animate_packet_along,
assert_all_orthogonal, connect_h, make_header_banner, make_node_card,
)
class Act1RateLimiter(Scene):
def construct(self) -> None:
self.camera.background_color = BG_DARK
timer = BeatTimer("tmp/beat_timings.json")
checkpoints: list[dict] = []
header = make_header_banner(
"Akt 1 / Anfrageaufnahme",
"API Gateway & Token-Bucket Rate Limiter",
)
gw = make_node_card("API Gateway", "TLS + Route Match", width=2.5, accent=ACCENT_CYAN).move_to([-4.5, 0.2, 0])
limiter = make_node_card("Rate Limiter", "Bucket: 100 tok", width=2.5, accent=ACCENT_BLUE).move_to([-1.5, 0.2, 0])
cache = make_node_card("Read Cache", "Single-Flight TTL", width=2.5, accent=ACCENT_CYAN).move_to([1.5, 0.2, 0])
db = make_node_card("Primary DB", "WAL Quorum", width=2.5, accent=STATUS_OK).move_to([4.5, 0.2, 0])
e_gw_lim = connect_h(gw, limiter)
e_lim_cache = connect_h(limiter, cache)
e_cache_db = connect_h(cache, db, dashed=True)
assert_all_orthogonal([e_gw_lim, e_lim_cache, e_cache_db], [gw, limiter, cache, db])
edges = VGroup(e_gw_lim, e_lim_cache, e_cache_db)
self.play(FadeIn(header), FadeIn(gw), FadeIn(limiter), FadeIn(cache), FadeIn(db), Create(edges), run_time=1.1)
spent = animate_packet_along(self, e_gw_lim, label="POST /orders", run_time=0.7)
timer.hold(self, "act1_ingress", consumed_anim_s=1.1 + spent, fallback_s=3.2, checkpoints=checkpoints)
spent = animate_packet_along(self, e_lim_cache, label="token=99", color=STATUS_OK, run_time=0.7)
timer.hold(self, "act1_bucket", consumed_anim_s=spent, fallback_s=3.8, checkpoints=checkpoints)
spent = animate_blocked_pulse(self, limiter, reason_label="429 RATE LIMITED", color=STATUS_ERR, run_time=0.95)
timer.hold(self, "act1_reject", consumed_anim_s=spent, fallback_s=3.5, checkpoints=checkpoints)
dump_checkpoints(checkpoints, "tmp/act1_bounds.json")
Grenzen & Null Kollisionen vor dem 1080p60-Rendern verifizieren
Überprüfen Sie die Layout-Geometrie immer in Sekunden, bevor Sie ein vollständiges 1080p60-Rendering starten:
# Option A: Live-Dry-Run-Hook über jeden Scene.wait()-Aufruf (< 3s, keine MP4-Kodierung)
./venv/bin/python .agents/skills/manim-video-explainer/check_scene_bounds.py \
--module scenes.py --scene Act1RateLimiter
# Option B: Ausgegebenes Checkpoint-JSON nach einem schnellen -ql-Rendering inspizieren
python3 .agents/skills/manim-video-explainer/check_scene_bounds.py \
--json tmp/act1_bounds.json
Lesen Sie references/manim-layout-and-choreography.md für mehrstufige Koordinatenvorlagen, dynamische ValueTracker-Zähler und Anti-Kollisions-Bereinigungsregeln.
3. Optionale Takt-synchronisierte Sprachausgabe-Kommentare (mux_narration.py)
Die Goldene Sprachausgabe-Regel
Lesen Sie NIEMALS Bildschirm-Box-Titel, Pfeile oder Abzeichen-Text wörtlich vor.
Zuschauer sehen "API Gateway -> Rate Limiter" sofort. Schreiben Sie erklärende Prozesskommentare, die darlegen, warum jeder Übergang stattfindet, welche Invariante das System schützt und was die Ablehnung oder Wiederherstellung verursacht.
Beat-zuerst Zwei-Durchgangs-Workflow
- Schreiben Sie
narration_manifest.json, das sauberen Untertiteltext von phonetischen Überschreibungen (tts_phonetic_textoderphonetic_glossary) trennt, damit technische Akronyme (WAL,gRPC,TTL,p99,HTTP 429) natürlich ausgesprochen werden, ohne die.vtt-Untertitel zu verunreinigen:
{
"lead_in_s": 0.20,
"inter_beat_gap_s": 0.25,
"phonetic_glossary": {
"WAL": "Write-Ahead Log",
"TTL": "T T L",
"HTTP 429": "H T T P four twenty-nine"
},
"scenes": [
{
"id": "act1",
"beats": [
{
"id": "act1_ingress",
"min_visual_s": 3.2,
"text": "Inbound writes terminate at the gateway before touching stateful storage."
},
{
"id": "act1_bucket",
"min_visual_s": 3.8,
"text": "An atomic token-bucket check absorbs burst traffic while bounding database concurrency."
},
{
"id": "act1_reject",
"min_visual_s": 3.5,
"text": "When burst tokens drain to zero, excess callers fail fast with HTTP 429."
}
]
}
]
}
- Durchgang 1 — Synthetisiere Per-Beat-WAVs & gebe genaue Zeitsteuerungen aus:
# Option A: Offline Piper ONNX neuronale TTS (keine Netzwerkaufrufe)
python3 .agents/skills/manim-video-explainer/mux_narration.py \
--manifest tmp/narration_manifest.json \
--scene-id act1 \
--wav-dir cache/beats_en \
--piper-bin ./venv/bin/piper \
--model ~/.cache/piper-voices/en_US-lessac-medium.onnx \
--emit-timings tmp/beat_timings.json
# Option B: OpenAI-kompatibler HTTP neuronaler TTS (/v1/audio/speech, stdlib urllib)
python3 .agents/skills/manim-video-explainer/mux_narration.py \
--manifest tmp/narration_manifest.json \
--scene-id act1 \
--wav-dir cache/beats_en \
--http-tts-url https://api.openai.com/v1/audio/speech \
--http-tts-key-env OPENAI_API_KEY \
--http-tts-model gpt-4o-mini-tts \
--http-tts-voice cedar \
--http-tts-instructions "Calm, clear technical documentary narrator; brief pauses at clauses." \
--emit-timings tmp/beat_timings.json
(Jeder benutzerdefinierte CLI-Synthesizer kann auch über --tts-cmd "my-tts --out {wav} --text {text}" verwendet werden, oder bereits gerenderte .wav-Dateien können direkt in --wav-dir platziert werden.)
- Rendern Sie das 1080p60 Manim-Video, gesteuert von
tmp/beat_timings.json:
./venv/bin/manim -qh --fps 60 scenes.py Act1RateLimiter
- Durchgang 2 — Sample-genaue Master-Track-Assemblierung, Lautheitsnormalisierung, Tail Guard & AAC Mux:
python3 .agents/skills/manim-video-explainer/mux_narration.py \
--manifest tmp/narration_manifest.json \
--scene-id act1 \
--wav-dir cache/beats_en \
--video media/videos/scenes/1080p60/Act1RateLimiter.mp4 \
--loudnorm-lufs -18.0 \
--output output/act1_en.mp4 \
--vtt output/act1_en.vtt
mux_narration.py platziert jeden Beat-WAV bei round(start_s * sample_rate) auf einer 16-Bit-PCM-Masterspur, verlängert den letzten Videoframe über tpad=stop_mode=clone, wenn die finale Sprache die Videodauer überschreitet (keine abgeschnittenen Wörter), wendet optional die EBU-R128-Lautheitsnormalisierung an (--loudnorm-lufs -18.0), damit die Lautstärke über Kapitel hinweg konsistent bleibt, kodiert -c:a aac -b:a 160k -movflags +faststart und schreibt output/act1_en.vtt.
Lesen Sie references/voiceover-and-commentary.md für Transformationen von schlechten zu guten Kommentaren, nicht-englische phonetische Überschreibungen und zweisprachige Audio-Workflows.
4. Web-Kodierung, Multi-Scene-Concatenation & Offline HTML5-Player
Web-kompatible Kodierung & Master-Reel-Concatenation
Stellen Sie für stille Durchläufe (ohne mux_narration.py) die universelle Browser-/QuickTime-Kompatibilität sicher (yuv420p + verschobenes moov-Atom):
ffmpeg -y -i media/videos/scenes/1080p60/Act1RateLimiter.mp4 \
-c:v libx264 -pix_fmt yuv420p -crf 23 -movflags +faststart \
output/act1_silent.mp4
Um mehrere vertonte Akt-MP4s zu einer durchgehenden Master-Reel zusammenzusetzen:
printf "file 'act1_en.mp4'\nfile 'act2_en.mp4'\nfile 'act3_en.mp4'\n" > output/concat.txt
ffmpeg -y -f concat -safe 0 -i output/concat.txt \
-c:v libx264 -pix_fmt yuv420p -crf 21 -c:a aac -b:a 160k -movflags +faststart \
output/master_en.mp4
Optionaler eigenständiger HTML5 Cinema Player
Wenn Sie einen Multi-Kapitel-Durchlauf oder ein zweisprachiges Erklärpaket ausliefern:
- Kopieren Sie
assets/video_player_template.htmlnachoutput/index.html. - Passen Sie
PLAYER_CONFIGan (chapters,sourcesundmarkers, die mit den Beat-Zeitstempeln ausbeat_timings.jsonübereinstimmen). Wenn Sie eine einzelne Sprache ausliefern, blenden Sie den sekundären Sprachbutton in#langGroupaus oder entfernen Sie ihn. - Behalten Sie alle Styles, monochromen SVG-Symbole und Skripte zu 100% inline, damit das Bundle offline ohne externe CDNs funktioniert.
- Hinweis zur HTTP-
206 Partial Content-Bereitstellung: Browser benötigen HTTP-Byte-Bereichsantworten (206), um<video>-Zeitachsen zu durchsuchen und<track>-.vtt-Dateien sauber zu laden (file://blockiert WebVTT-Tracks über CORS, und Pythons einfacherhttp.serversendet200anstelle von206, was das Scrubbing in den meisten Browsern verhindert). Verwenden Siepython3 -m http.server 8080für die Entwicklung; für die Produktion setzen Sie einen S3-kompatiblen oder CDN-verwalteten Webserver ein, der206-Bereichsanfragen unterstützt.
Bundle-Validierung mit lint.py
Überprüfen Sie vor der Bereitstellung Kodierungs-Invarianten, Offline-Sicherheit und Untertitel-Konsistenz:
# Alle MP4s im Ausgabeordner prüfen
python3 .agents/skills/manim-video-explainer/lint.py output/
lint.py führt für jede .mp4 ffprobe aus und stellt Folgendes sicher:
- Videocodec
h264(nichthevc,vp9,av1) - Pixelformat
yuv420p(nichtyuv444p,yuv420p10le) - Enthält einen
aac-Audiostream, wenn eine Tonspur existiert - Alle
.vtt-Dateien beginnen mitWEBVTTund haben streng monoton steigende Cue-Startzeiten - Alle
file://-Referenzen, externen Emoji-Images oder CDN-Quellen werden als Fehler gemeldet
5. Referenzen & Nächste Schritte
| Referenz | Wann lesen |
|---|---|
references/manim-layout-and-choreography.md | Entwerfen von Topologien mit mehr als 3 Knoten, Bus-Leitungen, dynamischen Zählern mit ValueTracker, bidirektionalen always_redraw-Pfeilen oder Multi-Scene-Verkettung mit ffmpeg |
references/voiceover-and-commentary.md | Erzähl-Metadaten, Akronym-Aussprache, R128-Normalisierung oder zweisprachige Lieferung |
| https://docs.manim.community/ | Manim Community Dokumentation zu Scene, Mobject, Animationen und config |
| https://github.com/rhasspy/piper | Offline neuronales TTS-Backend (Piper ONNX) |
Erstellen Sie beeindruckende, deterministische Erklärvideos, die sich auf das konzentrieren, was den Zuschauern wichtig ist: das Systemdesign, nicht die Präsentationssoftware.