manimvox-voice
Skill2 starsChanged 22 days agoMITView on GitHub
Choosing and preparing the narration voice for a manimvox video: the ten engines (Kokoro default, Piper, macOS say, edge-tts, OpenAI, ElevenLabs, Sarvam AI, Gnani.ai, XTTS-v2, F5-TTS), their licences and privacy, listing voices, fixing pronunciation in series.json, voice-cloning consent, a music bed under the narration, burned-in captions, and subtitles. Use when the user asks for a different, online or cloned voice, or a word is mispronounced.
- Reads credentials
- Installs packages
In this repository13 other files it gives its agents.
- AGENTS.mdAGENTS.md
- docs/agents.mdAGENTS.md
- CLAUDE.mdCLAUDE.md
- manimvox-animationSkill
- manimvox-blocksSkill
- manimvox-cliSkill
- manimvox-conceptSkill
- manimvox-coreSkill
- manimvox-creativeSkill
- manimvox-paperSkill
- manimvox-playlistSkill
- manimvox-prSkill
- manimvoxSkill
The file
Show its rules and text
We split this skill into the rules it gives an agent
13 rules. About 0 are common, 8 are distinctive, and 5 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈8
Distinctive · estimate
This author's own choices. Worth a look.
5
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 28
Default to Kokoro unless the user asks for something else.
- Very specific: line 43
Add an extra with the command manimvox doctor names: uv tool install --force "manimvox[kokoro,<extra>]" for a uv install, pip install …
- Distinctive: line 47
Before the first render with an online engine, ask, and say that the narration text is sent to that service.
- Distinctive: line 48
Before a model download, say what it is and its size, and ask.
- Distinctive: line 49
Before installing a package (an extra), ask.
- Distinctive: line 69
Only with the person's agreement, and only a voice the user owns or has permission to use.
- Distinctive: line 71
Use a clean 6 to 30 second recording of one speaker.
- Very specific: line 72
Write it as xtts:clone=voice.wav or f5:clone=voice.wav.
- Distinctive: line 78
If a word is mispronounced, fix it in the voice, not in the text on screen.
- Very specific: line 94
If manimvox voices does not show the folder, the cache rule is: $MANIMVOX_CACHE, else %LOCALAPPDATA%\manimvox on Windows, else …
- Very specific: line 101
Every narration line is levelled to loudness in series.json (LUFS, −16 by default), so voices sound equally loud.
- Very specific: line 109
Subtitles: Every render writes out/<stem>.srt from the on-screen text (the text of each line, not tts).
- Distinctive: line 141
Never install, download, go online or clone a voice to get past a failure without the user's explicit go-ahead.
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
manimvox voice
The narration voice is separate from the animation. Pick it, get it ready, and fix how words sound, without touching the scenes.
How a voice is chosen
A voice is written engine:voice, for example kokoro:af_heart. manimvox takes the first of these that is set:
--voiceonmanimvox rendervoiceinseries.json- the
MANIMVOX_VOICEenvironment variable kokoro:af_heart
If the voice is missing, not installed or lacks its key, the render stops with a one-line reason. manimvox never switches voice silently, and neither should you: when a voice fails, tell the user and ask. If you cannot ask, you may use only a voice that is local and already ready (manimvox voices shows it as ready): Kokoro if its model is present, else say on macOS. Never use the fake: test engine for a final render. Say in your report which voice you used instead and why (say is non-commercial). Otherwise stop and report what is needed: a go-ahead for the download, the install or the online service.
See what exists:
manimvox voiceslists every engine: ready or not, its licence, whether text goes online, whether it is non-commercial.manimvox voices <engine>lists one engine's voices. Foredgeandelevenlabsthis goes online.
Choosing an engine
Default to Kokoro unless the user asks for something else.
| Engine | Voice example | Pick it when | Needs | Flags |
| Kokoro | kokoro:af_heart | the default; offline, good quality | extra kokoro, 354 MB model | none |
| Piper | piper:en_US-libritts_r-medium | many offline voices and languages | extra piper, ~80 MB per voice | GPL-3.0 package; each voice has its own licence (the default is CC BY 4.0) |
| macOS say | say:Samantha | a quick local check on a Mac | nothing, macOS only | non-commercial |
| edge-tts | edge:en-US-AriaNeural | free online voices | extra edge | online: text goes to Microsoft |
| OpenAI | openai:alloy, openai:tts-1-hd/onyx | the user asks for it and has a key | extra cloud, OPENAI_API_KEY | online, paid; say the voice is AI-generated |
| ElevenLabs | elevenlabs:<voice id> | the user asks for it and has a key | extra cloud, ELEVENLABS_API_KEY | online; the free tier requires attribution |
| Sarvam AI | sarvam:shubh, sarvam:anushka@hi-IN | narration in an Indian language, or Indian English; the user has a key | extra cloud, SARVAM_API_KEY | online, paid |
| Gnani.ai | gnani:Kaveri, gnani:Shivani@ta-IN | the same, or Hinglish (@hi-en) | extra cloud, GNANI_API_KEY | online, paid |
| XTTS-v2 | xtts:clone=voice.wav | a voice the user owns and consents to clone | extra xtts, ~1.9 GB plus PyTorch | non-commercial |
| F5-TTS | f5:clone=voice.wav | the same, with a transcript | extra f5, ~1.3 GB plus PyTorch | non-commercial |
Add an extra with the command manimvox doctor names: uv tool install --force "manimvox[kokoro,<extra>]" for a uv install, pip install "manimvox[kokoro,<extra>]" for pip (name every extra wanted, and keep kokoro). Licences were summarised, not legally reviewed: tell the user to verify upstream before commercial use.
Ask before anything leaves the machine or downloads
- Before the first render with an online engine, ask, and say that the narration text is sent to that service. Nothing else is sent.
- Before a model download, say what it is and its size, and ask. Kokoro and Piper files are verified by hash.
- Before installing a package (an extra), ask.
- With the user's go-ahead, pass
--yes(or setMANIMVOX_ASSUME_YES=1) so the prompts do not stop the run. Without it, a declined or unanswered download stops the render. - Name non-commercial engines (
say, XTTS-v2, F5-TTS) as non-commercial to the user whenever you suggest them.
Getting a voice ready
manimvox voices --prepare ENGINE[:VOICE] [--yes] does everything a render would do before the first line, so failures show up early. With only ENGINE it uses that engine's default voice. It checks:
- the extra is installed;
- the model files are present (and offers to download them);
- the voice exists: Kokoro, Piper, edge and
sayname close matches when it does not; OpenAI, Sarvam and Gnani check the name and the language; ElevenLabs checks the voice id with the service; - the key variable is set, for OpenAI, ElevenLabs, Sarvam and Gnani;
- for XTTS-v2 and F5-TTS, that the recording exists, and for F5-TTS that
voice.txtis beside it.
It ends with ready: engine:voice.
Piper's default voice is en_US-libritts_r-medium. A local Piper .onnx file is also accepted, as a path from the project root.
Cloning a voice
Only with the person's agreement, and only a voice the user owns or has permission to use. Do not clone a public figure or a recording the user cannot account for.
- Use a clean 6 to 30 second recording of one speaker.
- Write it as
xtts:clone=voice.wavorf5:clone=voice.wav. The path is relative to the project root. - F5-TTS also needs the exact words spoken in the recording, in
voice.txtbesidevoice.wav. Without it the render stops. - Both engines are non-commercial, and each needs a large model download: ask first.
Pronunciation
If a word is mispronounced, fix it in the voice, not in the text on screen.
series.jsonholdspron, a list of[regex, spoken]pairs. They change what the voice says and never the subtitles or the on-screen text:"pron": [["\\bNumPy\\b", "num pie"], ["\\bkubectl\\b", "cube control"]]- Common terms are already handled: API, JSON, SQL, and snake_case words.
- For one line only, pass
tts="..."tonarrate,say,stepsorintro; the writtentextstill shows in the subtitles.pronstill applies to attsstring. To hear what Kokoro will say, print its phonemes.
manimvox voicesshows where its models live (models in <dir>); use that folder:uv run python -c "from kokoro_onnx import Kokoro; k = Kokoro('<dir>/kokoro-v1.0.onnx', '<dir>/voices-v1.0.bin'); print(k.tokenizer.phonemize('Then lead calls the graph tool.', 'en-us'))"If
manimvox voicesdoes not show the folder, the cache rule is:$MANIMVOX_CACHE, else%LOCALAPPDATA%\manimvoxon Windows, else$XDG_CACHE_HOME/manimvoxor~/.cache/manimvox; thenkokoro/.- Change the spelling until the phonemes read right (for example, spell out "lead" as "led" for the metal), add the pair to
pron, and re-render. Cached audio is keyed by the spoken text, so only changed lines are re-synthesised.
Speed
System voices often speak faster than the default (about 190 words a minute against about 170). Whenever you use one, chosen or as a fallback, check the speech rate after the render (words in the .srt divided by the sum of its cue durations; the check is in narration) and lower speed in series.json only if it is above 175 words a minute (0.9 first).
Every narration line is levelled to loudness in series.json (LUFS, −16 by default), so voices sound equally loud; leave it unless the user asks for a different level, and never set it to null to fix a quiet voice.
speed in series.json is a number above 0, 1.0 by default. ElevenLabs accepts only 0.7 to 1.2, Sarvam 0.5 to 2.0 (0.3 to 3.0 on bulbul:v2) and Gnani 0.85 to 1.15; each stops the render outside its range.
Sarvam and Gnani voices are [model/]voice[@language]: the language goes after @ (sarvam:priya@ta-IN, gnani:Avinash@hi-IN). Write the narration in the script of that language. Sarvam defaults to en-IN; Gnani detects the language when none is given.
Subtitles, captions and music
Subtitles. Every render writes out/<stem>.srt from the on-screen text (the text of each line, not tts).
Configuration. series.json may hold a post object, which manimvox render applies after the audio check:
"post": {"music": "music/bed.mp3", "music_db": -16, "duck_db": -12, "captions": "burn", "end_card": ["Sources: FACTS.md"], "card_seconds": 3}musicis a file in the project. It loops or is cut to the episode, fades in and out, and dipsduck_dbunder every narration line.music_db(default -16) is its level;duck_db(default -12) is the extra cut while someone speaks. Both are numbers from -60 to 0.captionsis"srt"(the default, ship the.srtonly) or"burn"(draw the subtitles into the picture as well). Burned captions cover the bottom of the stage, so keep notes clear of it or ship the.srtonly. Burned captions are drawn without complex-script shaping; for Arabic, CJK or other complex scripts ship the.srtinstead.end_cardadds up to 4 lines (80 characters each) on a closing card; a single string is accepted.card_seconds(default 3, from 1 to 10) is how long it shows.
Music rights. manimvox ships no music and never downloads any. Use only a file the user provides and has the right to use; ask before fetching any music. With no way to ask, render without music.
The audio check runs on the narration alone, so music never hides a silent line. With post.music set, manimvox check audio checks the narration-only render in build/ and says so.
When it fails
Each failure is one line. What to do:
| The line says | Do |
not installed: uv tool install --force "manimvox[kokoro,X]" (or pip install "manimvox[kokoro,X]") | ask, then install that extra (keep every extra already wanted) |
set OPENAI_API_KEY / ELEVENLABS_API_KEY / SARVAM_API_KEY / GNANI_API_KEY | the user sets the variable; never write a key into a file in the project |
| rejected the key (HTTP 401) | the key is wrong or expired; the user fixes it |
rerun with --yes / model files are missing | ask about the download, then manimvox voices --prepare ENGINE --yes |
| no voice 'X' (did you mean ...) | use the suggestion or manimvox voices <engine> |
say is macOS only | choose another engine |
| F5-TTS needs the words spoken | write voice.txt beside the recording |
| ElevenLabs, Sarvam or Gnani speaks at speed X to Y | change speed in series.json |
audio check fails after a render | the report lists silent lines: rerun manimvox check audio <episode>, then re-render; if one line keeps failing, reword it |
Never install, download, go online or clone a voice to get past a failure without the user's explicit go-ahead. If you cannot ask, the answer is no: stop and report what you need.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

