I Built an Autonomous AI Video Pipeline for Under $1 per Video (Terminal-First, No n8n)
Most "AI content automation" stacks are a subscription graveyard: Apify for scraping, ElevenLabs for voice, Shotstack for rendering, n8n for glue, and a Claude bill on top. I built the same pipeline for <$1 per video — orchestrated from the terminal, with OpenCode as the LLM brain. The full source is on GitHub: pipeline-contenido-ia.
The Architecture
Seven stages, one feedback loop. Signals feed an immutable wiki; a bandit picks what to make; cheap models produce it; FFmpeg assembles it; YouTube publishes it; analytics close the loop by feeding real revenue data back into the decision layer.
1. SIGNALS yt-dlp + pytrends + Reddit JSON ($0)
2. WIKI BRAIN markdown + CLAUDE.md schema, git-versioned
3. DECISION OpenCode CLI + epsilon-greedy bandit ($0*)
4. PRODUCTION edge-tts + fal.ai video + Pillow thumbs (~$0.60)
5. ASSEMBLY local FFmpeg: captions, ducking, loudnorm ($0)
6. PUBLISH YouTube Data API, synthetic-content flag ($0)
7. FEEDBACK YT Analytics → SQLite → bandit reward ($0)
*The LLM tier runs on OpenCode Go's free models: kimi-k2.6 for
orchestration and scripts (balanced), deepseek-v4-flash for bulk
tasks like comment mining and SEO metadata.
The Upgrade Table (Where the Money Was Saved)
| Original idea | Cost | Shipped instead | Cost | |---|---|---|---| | Apify / Firecrawl / VidIQ | $60–350/mo | yt-dlp + pytrends, velocity ratio computed in-house | $0 | | Claude API orchestrator | $30–100/mo | OpenCode CLI, opencode-go free tier | $0 | | ElevenLabs + Dubbing | $5–330/mo | edge-tts neural voices + cheap-LLM translation | $0 | | Suno / Epidemic Sound | $10–24/mo | YouTube Audio Library / CC-BY (zero Content ID risk) | $0 | | Shotstack / Remotion | $20/mo | local FFmpeg (static binary inside the venv) | $0 | | ThumbnailTest | $20/mo | Pillow A/B variants + YouTube's native Test & Compare | $0 | | n8n / Temporal | $5–50/mo | run.sh + cron + SQLite job queue | $0 | | Veo/Kling for every clip | $$$ | LTX-Video default (~$0.02/s) + hard budget guard | ~$0.60/video |
Three Design Decisions That Mattered
1. SQLite is the orchestrator
No n8n, no Temporal, no Redis. One SQLite file holds the job queue, the cost ledger, the metrics, and the bandit state. The runner is a bash script with retries and exponential backoff; cron does the scheduling. When a stage fails, an ntfy.sh push notification hits my phone — free.
2. The bandit decides, the wiki remembers
An epsilon-greedy bandit (ε=0.20) chooses the next video's
niche:format arm — 80% exploit what worked, 20% explore.
Rewards are net dollars (YouTube revenue minus tracked
generation cost), pulled from the Analytics API nightly. Patterns live in a
git-versioned markdown wiki with TTLs: a pattern that stops validating
expires automatically.
3. Everything has a $0 dry-run mode
Without FAL_KEY, the video stage renders placeholder slates via
FFmpeg. The entire pipeline — decision to published private video — is
testable at zero cost. Real clips only flow when the estimated cost is under
the MAX_VIDEO_COST_USD guard.
The Gotchas (So You Don't Hit Them)
Every one of these cost me real time:
- YouTube bot-checks yt-dlp full-page extraction from flagged IPs. Flat search keeps working; for full metadata, pass
--cookies-from-browser safari. - OAuth 403 access_denied = your app is in Testing mode and your Gmail isn't in the Test users list. One-minute fix, hours of confusion if you don't know it.
- Testing-mode refresh tokens expire in 7 days. Publish the consent screen to Production (unverified is fine for personal use) or your cron silently breaks weekly.
- Custom thumbnails 403 until the channel is phone-verified at youtube.com/verify. New channel? No thumbnails. Plan for it.
- An inline comment in .gitignore disabled the rule on that line — nearly pushed mp4s to a public repo. Comments go on their own line. Always.
- Publish must be idempotent. My thumbnail failure threw after the upload succeeded; the retry loop happily re-uploaded twice more. Record the video ID immediately after insert, skip if present.
Run It Yourself
git clone https://github.com/julio-arcila/pipeline-contenido-ia
cd pipeline-contenido-ia
python3 -m venv .venv && .venv/bin/pip install -r requirements.txt
./run.sh auth # YouTube OAuth wizard (one-time)
./run.sh fal-auth --test-clip # optional: real AI clips (~$0.08 test)
./run.sh signals "your niche" # scrape + trends + reddit
./run.sh decide # bandit + LLM -> decision JSON
./run.sh produce data/decision-*.json
./run.sh assemble data/decision-*.json
./run.sh publish <video_id> # private by default
./run.sh analytics # close the loop
The repo ships with the full architecture doc (PIPELINE.md), an
upgraded Mermaid diagram, and a sample decision file so you can see exactly
what the LLM brain produces. FFmpeg is bundled inside the venv via
imageio-ffmpeg — no system installs needed.
Honest constraint: local video generation needs a GPU this machine doesn't have, which is why fal.ai is the single paid stage. On an M-series Mac with 32GB+, swap the backend to ComfyUI and the cost per video drops to zero.
Build your next project on Cloudflare
Deploy full-stack apps globally with Workers, D1, and R2. Start for free.
Try Cloudflare Workers →Buy me a coffee
If this article helped you, consider supporting my work. Every coffee fuels the next deep-dive!
Stay in the loop
Get notified when I publish new articles on TypeScript, React, Node.js, and fullstack architecture. No spam, ever.