add-voiceover
Skill11 starsChanged 10 days agoMITView on GitHub
Add a spoken voiceover to a video: write the script for the ear, voice it line by line with ElevenLabs, Kokoro (a free local model) or your own text-to-speech command, and lay each line under the moment it describes, with a subtitle file. Use when the user asks to add narration, a voiceover, a voice or text-to-speech to a screen recording, demo video or walkthrough, to re-voice a video with another voice, or asks why a generated voiceover sounds robotic, echoes or drifts out of sync.
- Reads credentials
2 other projects use a version of this.
Adopted by
Most recently taken up by
- jamdotdev/skillsword for word, first seen Nov 8, 2026
- DojoCodingLabs/remotion-superpowerstheir own version, first seen Nov 1, 2026
Other versions2 projects use a version of this.
Word for word · 1
- jamdotdev/skills★ 11100% same
Edited · 0
None found.
Wrote their own version · 1
- DojoCodingLabs/remotion-superpowers★ 153same name
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
In this repository13 other files it gives its agents.
- AGENTS.mdAGENTS.md
- jam-annotateSkill
- jam-fixSkill
- jam-proofSkill
- jam-proof-tableSkill
- jam-setupSkill
- jamSkill
- jam-to-e2eSkill
- jam-to-tasksSkill
- jam-to-ticketSkill
- record-demoSkill
- record-terminal-proofSkill
- video-to-jamSkill
The file
We split this skill into the rules it gives an agent
7 rules. About 0 are common, 3 are distinctive, and 4 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈3
Distinctive · estimate
This author's own choices. Worth a look.
4
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 21
When none of the first three is set up, ask the user once which they want:
- Very specific: line 31
Write lines.json, one entry per spoken line:
- Distinctive: line 46
Write numbers and symbols the way they are said: "five-oh-three", "two seconds", "dot env".
- Very specific: line 47
No captions burned into the video unless the user asks.
- Very specific: line 53
From a recording you just made: use the times the recorder wrote.
- Very specific: line 59
No picture to match: leave at out and the lines follow each other with a short breath.
- Distinctive: line 75
Read the warnings. Late lines and narration cut at the end of the video both mean the script is too long for the picture.
≈ “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
Add a voiceover
A good voiceover sounds like a colleague showing you something: short spoken lines, each one landing on the moment it talks about. Most bad ones come from a script written for reading, one long take of text-to-speech laid over the whole video, or an expressive voice with unstable settings.
Needs ffmpeg and Node 22 or later. The script is scripts/voiceover.mjs in this skill's folder and needs no packages.
1. Pick the voice
The script takes the first voice that is set up:
VOICEOVER_TTS: the team's own command.{out}is the.wavfile to write and{text}the line, also sent on stdin. Quote an argument that holds spaces (--voice="Jane Doe"); backslash escapes are not read.ELEVENLABS_API_KEY: ElevenLabs. Defaults: modeleleven_v4, voiceiP95p4xoKVk53GoZ742B, stability 0.5, similarity 0.75, speaker boost on, and each line voiced with the two lines around it as context so the intonation carries across.ELEVENLABS_VOICE_IDandELEVENLABS_MODEL_IDchange them; for a female voice use River,SAz9YHcvj6GT2YYXdXww. v4 has no speed or style setting: pace it with punctuation and line length.- Kokoro, a free local model, once installed (
~/.cache/kokoroholds its files) and Python 3 anduvare on PATH. Voiceam_michael;KOKORO_VOICEpicks another (af_heart,bf_emma,bm_george). - macOS
say, for drafts only.
When none of the first three is set up, ask the user once which they want:
- ElevenLabs: they set
ELEVENLABS_API_KEYin their own shell. Never ask them to paste the key into the chat or a file. It bills per character, so rehearse withELEVENLABS_MODEL_ID=eleven_flash_v2_5or Kokoro and voice the final cut with the default model. - Kokoro: free and local, a one-time download of about 340 MB. On a yes:
python3 <skill-dir>/scripts/kokoro.py --install. - The OS voice: nothing to set up, sounds robotic.
In CI or with no one to ask, use what is set up and never start the download.
2. Write the script for the ear
Write lines.json, one entry per spoken line:
[
{"say": "Hey, here's the new checkout flow, end to end.", "at": 0.5},
{"say": "I'll add a jar,", "at": 3.2},
{"say": "and place the order.", "at": 6.8},
{"say": "And it fails. Payment provider timeout.", "at": 9.1}
]- One idea per line, 4 to 14 words. Split a sentence across the actions it describes: "I'll add a jar," then "go to checkout," then "and place the order."
- Say what the viewer should notice, not what the mouse does. "Every item lands in the list" beats "I click the input and type".
- Talk, don't announce: contractions, "so", "here's", first person. No sales lines.
- Tell a story in three parts: what this is, what happens, what it means. The last line lands the result.
- Write numbers and symbols the way they are said: "five-oh-three", "two seconds", "dot env". The voice reads "503" as "five hundred three".
- No captions burned into the video unless the user asks. The script writes
voiceover.vttfor players that show subtitles.
3. Time each line
at is the second the line starts. Start it about half a second before the action it names, so the word and the click land together.
- From a recording you just made: use the times the recorder wrote.
record-demowrites them tonarration.jsonin this format. - An existing video: list the moments the picture changes and look at a frame from each:
ffmpeg -i in.mp4 -vf "select='gt(scene,0.08)',showinfo" -f null - 2>&1 | grep -o 'pts_time:[0-9.]*' ffmpeg -v error -ss 9.1 -i in.mp4 -frames:v 1 at-9.1.png - No picture to match: leave
atout and the lines follow each other with a short breath.
To pace a recording by the voice instead, voice the lines first with no --video, and pass the lines.json it writes (each line with its seconds) to the recorder.
4. Voice and mix
node <skill-dir>/scripts/voiceover.mjs lines.json ./voiceover --video in.mp4Output in ./voiceover: voiced.mp4 (the picture untouched, the narration raised by one fixed gain so it peaks at -1 dB; a video with its own sound keeps it, and both are lowered together if the mix would pass -1 dB), narration.wav, lines.json with each line's final at and seconds, one .wav per line, and voiceover.vtt. Each line is cached by its text and voice, so after editing one line a re-run voices only that line (with ElevenLabs, also the two on each side, which it hears as context), and switching the voice re-voices everything.
A line that would talk over the one before starts late, and the script prints which. Shorten one of the two lines, or move the later one, and run it again.
5. Check before you share
- Read the warnings. Late lines and narration cut at the end of the video both mean the script is too long for the picture.
- Loudness:
ffmpeg -i voiceover/voiced.mp4 -af volumedetect -f null - 2>&1 | grep -E 'mean|max'. Expect a max of -1 dB and a mean between -18 and -24 dB. Never level the voice withloudnorm, a compressor or other dynamic filters: they raise each word's tail and the voice sounds like it echoes. - Sync: extract a frame one second after each line's
atand check it shows what the line names. - Give the user one line's
.wavto listen to before they watch the whole video.
An echo comes from a dynamic leveler in the mix: compare one line's .wav with the same moment in the video, and if only the video echoes, remove the filter. A laugh, a pitch jump between lines, or a voice that speeds up comes from low stability or an expressive character voice: keep the default settings and pick a narration voice. Never fix sync by stretching the audio; move the line or re-record.
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.

