You write a plain-text script. This repo turns it into a real MP4 video with a spoken AI voiceover, animated scenes, on-screen text, and optional background music — 100% free, running automatically on GitHub Actions. No API keys, no subscriptions, no video editing software.
This is text → video in the sense that your script generates the video: the words you write become the narration and the on-screen scene text, rendered over animated motion backgrounds.
It does not generate photorealistic AI footage from a prompt (like Sora, Runway, or Kling). Those models are paid cloud services — nothing like them is free or fully automated. Everything here is real, reproducible, and costs $0.
- You write your script in
script.md. Each paragraph = one scene. Lines starting with#become a large title scene. - On every push, the workflow runs
scripts/text_to_video.py, which:- Reads each line aloud with free AI speech (
edge-tts) and times each scene to that line's spoken length. - Renders each scene as an animated gradient background with your text
overlaid, using
ffmpeg(already on GitHub's runners). - Joins all scenes, mixes in
audio/music if present, and encodes a 1080p/30fps H.264.mp4.
- Reads each line aloud with free AI speech (
- The finished video is uploaded as a run artifact and committed back
to
output/video.mp4.
git init && git add . && git commit -m "text to video"
git branch -M main
git remote add origin https://github.com/YOU/YOUR_REPO.git
git push -u origin mainThe push triggers the workflow (Actions → "Generate video from script"). In
about a minute, download the video artifact, or git pull to grab
output/video.mp4 committed directly to the repo.
Make a new video every time: just edit script.md and push.
# Your Title Here
Welcome to the video. This first paragraph becomes its own scene, and the
voice reads this sentence aloud.
Blank line, then the next scene. It works for anything: a product pitch, an
announcement, an explainer, a lesson, a story, a greeting.
## Use a hash heading to make a big title scene- Lines with
#→ big title scene, no pause needed. - Blank lines separate scenes (each becomes a distinct animated background).
- Keep each scene roughly 1–2 sentences for a good pacing.
Drop one audio file into audio/ (.mp3, .wav, .m4a, ...). It's looped and
mixed under the voice at low volume. Remove it to go music-free.
Edit config.json:
{ "voice": "en-US-JennyNeural" }Run python3 scripts/text_to_video.py --voices locally (or in Actions) to list
hundreds of free voices across languages. A few nice ones:
en-US-ChristopherNeural (deep male), en-US-JennyNeural,
en-US-GuyNeural, en-GB-SoniaNeural, fr-FR-DeniseNeural,
es-ES-AlvaroNeural, de-DE-KatjaNeural, ar-EG-ShakirNeural,
hi-IN-MadhurNeural, sw-KE-RehemaNeural (Swahili).
| Key | Default | Meaning |
|---|---|---|
fps |
30 |
Frames per second |
width, height |
1920, 1080 |
Resolution (use 1080, 1920 for vertical reels) |
voice |
en-US-ChristopherNeural |
Voice to use |
voice_rate |
+0% |
Speak faster/slower, e.g. +8% or -10% |
voice_volume |
+0% |
Voice volume |
pause_per_scene |
0.6 |
Seconds of silence added after each scene |
bg_speed |
0.08 |
How fast the background gradient animates |
text_font_size |
62 |
On-screen text size (title scenes scale ×1.6) |
text_color |
white |
Text color (any CSS color) |
text_box |
true |
Semi-transparent box behind the text |
bg_palettes |
(list) | Color schemes per scene; cycles automatically |
Works out of the box on most systems with Python 3.9+:
pip install edge-tts
# ffmpeg on your PATH (Ubuntu: sudo apt install ffmpeg), or:
pip install imageio-ffmpeg # provides ffmpeg automatically
python3 scripts/text_to_video.py- Free and open for any use. Voice is Microsoft's cloud neural voice via the
public
edge-ttslibrary — no key needed. - If you want a quick static look, add
--no-voiceto skip TTS.