Zero-cost, cloud-hosted YouTube Shorts generator and uploader. Write scripts once with any AI, then let GitHub Actions create and publish 2 Shorts per day automatically. No API keys for AI, no fragile cookies, no monthly fees.
| Feature | v1.x | v2.0 |
|---|---|---|
| Video clips per short | 5 | 10 + 8 images (interleaved) |
| Transitions | None | Direct cuts (stable concatenation) |
| Ken Burns zoom | None | Slow zoom (1.0 → 1.08) on all clips & images |
| Captions | Static sentences at bottom | MrBeast-style: dark background box, phrase-by-phrase, fade animation, higher position |
| Image support | None | Pexels photos with Ken Burns zoom |
| Music | — | Optional — skip for no background music |
| Step | Component | Service | Cost |
|---|---|---|---|
| Scripts | You provide them | Any AI (ChatGPT, Gemini, Claude) | Free |
| Voiceover | Google Gemini TTS / Edge TTS | google-genai / edge-tts |
Free / API Key |
| Video clips + Images | Pexels API | requests → Pexels |
Free |
| BGM & SFX | Openverse CC0 API | requests → Openverse |
Free (no key) |
| Video composition | MoviePy 1.0.x | ffmpeg + ImageMagick | Free |
| Upload | YouTube Data API v3 | OAuth refresh token (official API) | Free (3,200 of 10,000 daily quota) |
| Scheduling | GitHub Actions | Cron (configurable) | Free (2000+ min/month) |
| # | Stage | What happens |
|---|---|---|
| 1 | Read | ScriptReader picks the first unused script from scripts.json, marks it used, commits back |
| 2 | Audio | google-genai generates voiceover using Gemini 3.1 Flash (Aoede voice), falling back to edge-tts if keyless |
| 3 | Download | Pexels searched per keyword → up to 10 video clips + 8 images downloaded |
| 4 | Music | Openverse CC0 → downloads background music and parses [sfx: ...] tags to download sound effects |
| 5 | Compose | MoviePy crops to 1080×1920, applies Ken Burns zoom, interleaves images, adds MrBeast-style animated captions, mixes BGM (ducked at 8%) and SFX, renders with fast settings |
| 6 | Upload | Gets fresh access token from refresh token → uploads via YouTube Data API v3 |
When all scripts are used → prints "All N scripts used. Generate fresh ones." and exits cleanly.
- Fully automated — set up once, videos publish daily with zero manual work
- Zero AI API costs — scripts are pre-generated by you using any free AI in your browser
- No fragile cookies — uses YouTube Data API v3 with OAuth refresh tokens (last for years)
- MrBeast-style captions — phrase-by-phrase with dark background box, fade-in animation
- Background music — Pixabay (free API key, optional — skip for no music)
- Ken Burns zoom — slow progressive zoom on all clips and images for cinematic feel
- Visual variety — Pexels images interleaved with video clips, each with Ken Burns effect
- Phrase-based captions — splits script into shorter phrases for more frequent visual changes
- Batch script management — supports unlimited scripts with auto-marking used ones
- GitHub Actions powered — runs on free Ubuntu runners, no server needed
- SEO & monetization ready — original audio, royalty-free visuals and music
.
├── main.py # Orchestrator — runs the 6-stage pipeline
├── auth_setup.py # One-time local script to get OAuth tokens
├── requirements.txt # Python dependencies
├── SETUP-GUIDE.txt # Detailed step-by-step setup (18+ pages)
├── README.md # This file
├── scripts/
│ └── scripts.json # Pre-generated scripts (you provide these)
├── src/
│ ├── __init__.py
│ ├── reader.py # Reads scripts.json, picks next unused script
│ ├── audio.py # edge-tts → MP3 voiceover
│ ├── downloader.py # Pexels API → video clips + images
│ ├── music.py # Pixabay API (optional background music)
│ ├── editor.py # MoviePy → 9:16 video, Ken Burns, captions, music mix
│ └── uploader.py # YouTube Data API v3 (OAuth) upload
└── .github/workflows/
└── schedule.yml # GitHub Actions: cron schedule + env config
You need 2 free accounts (plus 1 optional):
| Account | Required | Purpose |
|---|---|---|
| GitHub | Yes | Host code + run Actions |
| Pexels API | Yes | Video clips + images |
Advanced neural voiceovers via Google Gemini API (optional fallback to free edge-tts). No YouTube API quota issues.
| Secret | Description |
|---|---|
PEXELS_API_KEY |
Pexels API key (free at pexels.com/api) |
YT_REFRESH_TOKEN |
YouTube OAuth refresh token (get via auth_setup.py) |
YT_CLIENT_ID |
Google Cloud OAuth client ID |
YT_CLIENT_SECRET |
Google Cloud OAuth client secret |
GEMINI_API_KEY |
(Optional) Google AI Studio API key for advanced Gemini TTS (Aoede, Leda, etc.) |
Note: Background music and sound effects (SFX) are searched and downloaded automatically using Openverse CC0 (no API key needed). You can also add custom local music files to the bgm/ folder as a fallback.
- Google Cloud Console — create project → enable YouTube Data API v3 → create OAuth 2.0 Desktop credentials → add your email as test user
- Run
auth_setup.pylocally — paste client ID & secret → sign in to Google → get refresh token - Add secrets to GitHub —
PEXELS_API_KEY,YT_REFRESH_TOKEN,YT_CLIENT_ID,YT_CLIENT_SECRET(and optionallyGEMINI_API_KEY) - Generate scripts — copy the prompt from
SETUP-GUIDE.txt→ paste into ChatGPT/Gemini → save the JSON output asscripts/scripts.json - Push to GitHub — commit all files including
scripts/scripts.json - Run workflow — go to Actions tab → "Run workflow" → watch live logs
Detailed 18-page illustrated guide with screenshots for every step: read SETUP-GUIDE.txt
[
{
"id": 1,
"title": "Your Catchy Title Here",
"description": "Description with relevant hashtags",
"tags": ["tag1", "tag2"],
"voiceover_script": "Your script under 150 words (~50 seconds)",
"visual_keywords": ["keyword1", "keyword2", "keyword3"],
"used": false
}
]Generate 10–30 scripts at once using any AI with the prompt template from SETUP-GUIDE.txt. The system processes them sequentially, one per scheduled run.
| Aspect | Cookies (old approach) | OAuth Refresh Token (this project) |
|---|---|---|
| Lifespan | Days to weeks | Years (until revoked) |
| GitHub setup | Playwright + Chromium (~300 MB) | Zero browser dependencies |
| Upload method | Browser automation (fragile UI) | Official YouTube API (never breaks) |
| Maintenance | Re-export cookies every few days | Set up once, forget forever |
| Quota | Unlimited (but unreliable) | 10,000 units/day (only 3,200 used) |
| Speed | ~15 min total | ~10 min (no browser launch) |
edge-tts>=6.1.0 # Microsoft Edge TTS — voiceover generation
moviepy>=1.0.3,<2.0.0 # Video editing — composition, effects, rendering
Pillow>=10.0.0 # Image processing — ANTIALIAS compatibility
requests>=2.31.0 # HTTP client — Pexels, Pixabay, YouTube API
google-auth>=2.0.0 # OAuth 2.0 — YouTube token refresh
All dependencies are free and open-source. Total install size ~50 MB.
Contributions, issues, and feature requests are welcome!
- Report bugs — open a GitHub issue with the workflow run log
- Suggest features — open a discussion or issue
- Submit PRs — fork the repo, make your changes, and open a pull request
This project is licensed under the MIT License. Feel free to use, modify, and distribute.
- ⭐ Star this repo if you find it useful
- 📖 Read the full SETUP-GUIDE.txt for detailed setup
- 🐛 Open a GitHub Issue — include workflow run logs for faster help
Built with ❤️ for content creators — completely free, forever.