NineToVibes Automation Pipeline
AI-generated faceless YouTube · Python · Ollama · Veo · ElevenLabs
Impact: Cut a per-video production cycle from a multi-hour manual edit to a single launchd-scheduled run — creator effort reduced to a Telegram tap.
Python · Ollama (Llama 3.1) · ElevenLabs · Google Veo · Pexels · MoviePy · FFmpeg · FastAPI · YouTube Data API · python-telegram-bot · launchdProblem
Faceless YouTube channels live or die on consistency and novelty, and doing both by hand is unsustainable for a solo creator. The first iteration of this pipeline shipped the same Porsche/Chipotle/$340K script for ~2 weeks because the Llama 3.1 8B writer was copying the in-prompt example verbatim and the dedup code only warned on collisions. On top of that, off-the-shelf TTS sounded robotic and stock-footage-only B-roll made the channel feel generic. The brief: build a system that ships fresh, branded content every day — or chooses to skip the day rather than embarrass the brand.
Approach
- 01
Banlist-as-source-of-truth. Built src/trends/banlist.py with no-TTL JSON banlists for every shipped asset (topic, hook, title, names, dollar amounts, scene queries, stock clip IDs, Bamboo action, music file). After every successful render, fingerprint_payload() and fingerprint_visuals() persist the run. Future runs must generate around the banlist or raise BannedContentError and skip the day.
- 02
Character-first visuals. Rather than the cheaper "Veo per scene" plan (~$120/mo), picked daily Veo regen of just the Bamboo/Theodore character clips (~$15/mo) plus Pexels for story B-roll with permanent clip-ID bans. Kept the brand "face" premium while controlling cost on an unfunded project.
- 03
Tuned voice chain over a flashier model. Locked in ElevenLabs "Brian" (stability 0.35 / similarity 0.80 / style 0.50) and built an FFmpeg post-chain — +10 dB @100 Hz, +4 dB @200 Hz, –3 dB @3.5 kHz, asubboost growl, tight aecho reverb, loudnorm to broadcast — then mixed under a real lo-fi instrumental at 0.18 gain. Rejected pitch-shifting (made it slow and robotic) and synthetic sine-wave music (sounded like noise).
- 04
Prompt hygiene to stop the LLM from copy-pasting. Stripped all concrete narrated examples (names, dollar amounts, brands) out of config/prompts.yaml after discovering Llama 3.1 8B was lifting them verbatim regardless of topic; replaced them with abstract structural guidance only.
- 05
Human-in-the-loop without human-in-the-grind. Two Telegram checkpoints (script review + final video review) wired into the orchestrator, plus an automatic YouTube AI-disclosure flag and private-draft upload — so the creator approves intent and the cut, but never touches an editor.
Outcome
- 01
A daily run produces a fully assembled, branded short with zero manual editing — the only creator action is tapping Approve in Telegram.
- 02
The Porsche/Chipotle/$340K duplicate-script class of failure is now structurally impossible: a collision raises and skips the day rather than shipping.
- 03
Brand consistency holds across runs — every Bamboo and Theodore appearance is a fresh Veo render from the same versioned prompt, not a recycled clip.
- 04
Voice quality crossed the "would I listen to this for 60 seconds" bar (the internal final_v5 standard) and has been the minimum baseline ever since.
Lessons
- 01
Dedup that only logs is dedup that does not exist. If a policy is load-bearing, it must raise. Two weeks of duplicate uploads is the price of a log.warn().
- 02
Do not put examples in LLM prompts unless you want them shipped verbatim. Small open-weights models (Llama 3.1 8B) treat in-prompt examples as templates, not inspiration. Use abstract structural guidance.
- 03
Spend the money where the brand lives. Veo on the characters (the channel’s face) and Pexels on the B-roll was ~8× cheaper than Veo-everywhere and visually indistinguishable to the viewer.