{"slug": "how-i-built-a-free-self-hosted-pipeline-that-auto-generates-faceless-youtube", "title": "How I Built a Free, Self-Hosted Pipeline That Auto-Generates Faceless YouTube Shorts", "summary": "The article describes FreeFaceless, an open-source, self-hosted pipeline that automatically generates faceless YouTube Shorts using free tools and local models, avoiding the typical $75-100/month subscription costs. The pipeline handles script generation via Groq's free tier, voiceover with edge-tts, captioning through local Whisper, b-roll from Pexels, and video assembly with ffmpeg, all controlled by a single config file. The author also shares a common Windows bug fix involving TLS certificate verification and provides the repository link for setup.", "body_md": "Every \"AI YouTube\" tutorial ends the same way: sign up for ChatGPT Plus, then ElevenLabs, then Pictory, then n8n Cloud. Add it up and you're paying **$75–100/month** before you've made a single video — let alone a single dollar.\n\nI didn't want a subscription stack. I wanted something that ran on my own machine, used free tiers and local models, and that I actually owned. So I built it, and I just open-sourced it under MIT.\n\nIt's called **FreeFaceless**, and it takes one command to go from nothing to an uploaded Short:\n\n```\nscript → voiceover → captions → b-roll → assembled video → YouTube upload\n```\n\nRepo: [https://github.com/nils44344/FreeFaceless](https://github.com/nils44344/FreeFaceless)\n\nHere's how each stage works — and the one bug that cost me an evening.\n\n## The orchestration\n\nThe whole thing is a linear pipeline. Here's the heart of it (trimmed):\n\n``` python\ndef run_once(publish_at=None, upload_to_youtube=True):\n    data = script.generate()                          # 1. Groq writes the script\n    voice_mp3 = voice.synth(data[\"full_text\"], ...)   # 2. edge-tts voiceover\n    words = captions.transcribe_words(voice_mp3)      # 3. local Whisper timing\n    scenes = visuals.fetch_for_scenes(data[\"scenes\"]) # 4. Pexels b-roll\n    ass = captions.write_ass(words, ...)              # 5. caption file\n    final = assemble.build(scenes, voice_mp3, ass, …) # 6. ffmpeg\n    if upload_to_youtube:\n        upload.upload_video(final, data[\"title\"], …)  # 7. YouTube Data API\n```\n\nEvery stage is its own module, and everything is driven by a single `config.yaml`\n\n— so changing the niche, voice, or caption style is an edit, not a code change.\n\n## 1. Script generation — Groq (free tier)\n\nGroq's free tier serves Llama 3.3 70B fast, and it's OpenAI-compatible, so the official `openai`\n\nSDK works by just pointing the base URL at Groq:\n\n``` python\nfrom openai import OpenAI\nclient = OpenAI(api_key=GROQ_API_KEY, base_url=\"https://api.groq.com/openai/v1\")\n\nresp = client.chat.completions.create(\n    model=\"llama-3.3-70b-versatile\",\n    response_format={\"type\": \"json_object\"},  # forces clean JSON\n    messages=[{\"role\": \"system\", \"content\": SYSTEM_PROMPT}, ...],\n)\n```\n\nThe prompt asks for a hook + 4–6 facts + a CTA, returned as JSON with per-scene `visual_query`\n\nstrings I can feed straight to stock search. JSON mode means no fragile regex parsing.\n\n## 2. Voiceover — edge-tts (free, no key)\n\n`edge-tts`\n\nexposes Microsoft's neural voices for free, no API key:\n\n``` python\nimport edge_tts\ncommunicate = edge_tts.Communicate(text, \"en-US-ChristopherNeural\", rate=\"-12%\")\nawait communicate.save(\"voice.mp3\")\n```\n\nThe quality is genuinely good enough for faceless content, and there are dozens of voices/accents to match the niche.\n\n## 3. Word-level captions — faster-whisper (local)\n\nThis is the part most paid tools charge per-minute for. `faster-whisper`\n\nruns locally on CPU and gives **word-level timestamps**, which I turn into karaoke-style captions:\n\n``` python\nfrom faster_whisper import WhisperModel\nmodel = WhisperModel(\"base\", device=\"cpu\", compute_type=\"int8\")\nsegments, _ = model.transcribe(\"voice.mp3\", word_timestamps=True)\n```\n\nThen I write an ASS subtitle file, 3 words at a time, in a big bold style — the look every Shorts channel uses. (FreeFaceless ships the open-licensed **Anton** font so it works out of the box.)\n\n## 4. B-roll — Pexels (free API)\n\nEach scene's `visual_query`\n\nbecomes a Pexels Videos search, pulling vertical clips. Free API, generous limits.\n\n## 5. Assembly — ffmpeg\n\nffmpeg crops every clip to 1080×1920, concatenates them to match the voiceover length, overlays the audio, and burns in the captions:\n\n```\n\"-vf\", f\"subtitles='{ass_path}':fontsdir='{fonts_dir}'\"\n```\n\n## 6. Upload — YouTube Data API\n\nOAuth desktop flow, token cached after the first browser login, then every future run refreshes silently. Supports immediate or scheduled publishing.\n\n## The bug that cost me an evening: SSL on Windows\n\nOn my machine, every HTTPS call died with `CERTIFICATE_VERIFY_FAILED`\n\n. The culprit: antivirus doing TLS interception with a custom root cert that Python's bundled `certifi`\n\ndoesn't know about. The fix is one import, before any network client is built:\n\n``` python\nimport truststore\ntruststore.inject_into_ssl()  # use the OS cert store instead of certifi\n```\n\nIf you build anything network-heavy on Windows, keep this in your back pocket.\n\n## Honest limitations\n\n-\n**Free tiers are rate-limited.** This is built for one channel on a normal schedule, not bulk farms. Push it hard and you'll hit limits. -\n**Windows-first.** The Python core runs anywhere; the helper scripts are PowerShell. Cross-platform PRs very welcome. -\n**It's a production tool, not a money machine.** It automates*making*videos. Views and revenue depend on your content and the algorithm — no tool changes that.\n\n## Try it / contribute\n\nThe repo has a full setup guide (including the Google OAuth walkthrough, which is the only fiddly part):\n\n[https://github.com/nils44344/FreeFaceless](https://github.com/nils44344/FreeFaceless)\n\nIf it's useful, a star helps other people find it — and I'd genuinely love feedback, especially on making the setup smoother for non-developers and getting it running on macOS/Linux.", "url": "https://wpnews.pro/news/how-i-built-a-free-self-hosted-pipeline-that-auto-generates-faceless-youtube", "canonical_source": "https://dev.to/nils44344/how-i-built-a-free-self-hosted-pipeline-that-auto-generates-faceless-youtube-shorts-3je4", "published_at": "2026-05-23 13:35:32+00:00", "updated_at": "2026-05-23 14:02:59.442169+00:00", "lang": "en", "topics": ["open-source", "developer-tools", "artificial-intelligence"], "entities": ["FreeFaceless", "Groq", "Llama", "Pexels", "Whisper", "YouTube Data API", "edge-tts", "n8n"], "alternates": {"html": "https://wpnews.pro/news/how-i-built-a-free-self-hosted-pipeline-that-auto-generates-faceless-youtube", "markdown": "https://wpnews.pro/news/how-i-built-a-free-self-hosted-pipeline-that-auto-generates-faceless-youtube.md", "text": "https://wpnews.pro/news/how-i-built-a-free-self-hosted-pipeline-that-auto-generates-faceless-youtube.txt", "jsonld": "https://wpnews.pro/news/how-i-built-a-free-self-hosted-pipeline-that-auto-generates-faceless-youtube.jsonld"}}