A YouTube Shorts channel that runs itself. Tell it how many videos you want, and it writes them, builds them, and uploads them — no hands.
Honest origin story: I was being lazy. I liked the idea of running a YouTube channel a lot more than the idea of actually making videos for one, so I spent far more effort building a program to do it than the videos would ever have cost me.
Channel: @Quotelet1
- Pick a quote from a curated CSV (
"Quote text", "Author", "n"— the flag marks used/unused) - Pick a background clip at random from a folder of hand-picked 9:16 stock footage
- Pick a track at random
- Composite — loop/trim the video to the audio length, draw the quote and author onto a semi-transparent panel, render at 60fps across 16 CPU threads
- Upload to YouTube as a public Short via the YouTube Data API
- Mark the quote used so it never repeats
You're always trading between automation, AI and quality, and you rarely get all three.
- I tried generating quotes live from an LLM API, but the replies came back chatty and inconsistently formatted — useless to a script. So I generated a clean CSV of 100 quotes up front instead. Quality over automation.
- I tried pulling background clips from the Pexels API, but auto-picked footage was off-theme or too long. So I hand-picked 29 clips that actually fit. Quality again.
- Audio: hand-picked. Same reason.
Everything that could be automated without hurting the output is automated. Everything that couldn't, isn't. That's the whole design.
pip install moviepy pillow numpy google-api-python-client google-authExpected folder layout:
automatedvidgen/
├── audios/ background tracks
├── videos/ 9:16 stock clips
├── finishedvideos/ output
└── quotes.txt "Quote text", "Author", "n"
Update the paths at the top of quotelet.py, and point credentials_path at your own
YouTube OAuth credentials JSON (not included, obviously). Then:
python quotelet.py
> How many videos would you like to generate and upload? 5Run it from a real terminal, not the PyCharm/IDLE console — rendering starts but never finishes there.
Full story: Quotelet