Automated AI narration and subtitle burn-in for videos using macOS say and ffmpeg.
Burned-in subtitles (English + Chinese) with synchronized AI voiceover. The GIF above is silent — ▶ watch the full version with audio.
- Script to SRT: Converts raw text or ideas into timed SRT subtitle files.
- AI Voice Synthesis: Uses the macOS system
saycommand to generate voiceover audio per subtitle cue. - Precision Mixing: Standardizes audio to 44100Hz stereo and uses
adelay+amix+dynaudnormto align narration to the timeline. - Subtitle Burn-in: Optionally hard-codes the SRT into the picture via ffmpeg's libass
subtitlesfilter, with configurable font, size, color and position. - Timing Heuristics: Built-in rules for estimating narration duration from word/character count.
# Narration only
python3 scripts/narrate.py video.mp4 video.srt output.mp4
# Narration + burned-in subtitles
python3 scripts/narrate.py video.mp4 video.srt output.mp4 --subtitles
# Subtitles only, keep original audio
python3 scripts/narrate.py video.mp4 video.srt output.mp4 --subtitles --no-voiceRun python3 scripts/narrate.py -h for all options (--voice, --rate, --volume, --font, --font-size).
- English: ~0.45 seconds per word. (e.g. 20 words ≈ 9 seconds)
- Chinese: ~0.35 seconds per character. (e.g. 20 characters ≈ 7 seconds)
- Padding: Add 0.5s–1s buffer between segments for better pacing.
- macOS: Required for the native
saycommand. - ffmpeg: Required for audio/video processing. For
--subtitles, you need a build with the libasssubtitlesfilter — the default Homebrewffmpegformula omits it, so installffmpeg-full:Verify withbrew install ffmpeg-full
ffmpeg -h filter=subtitles. - Python 3: Required to run the automation logic (standard library only).
MIT
