Faceless YouTube Automation Kit
Turn a script into a captioned long-form video plus 3 vertical Shorts and a thumbnail, check it against what gets a video rejected, and package it ready to upload. Free local stack: edge-tts, ffmpeg, Pexels. No subscriptions.
➜ tree what-you-get/
- ├── ✓ make_video.py: one command renders a long-form YouTube video with chapter cards, captions, broll, and a music bed
- ├── ✓ Three vertical Shorts from the same scene JSON, each with hook card, captioned tips, and CTA
- ├── ✓ make_thumbnail.py: generates a 1280x720 thumbnail from your title text
- ├── ✓ qc.py: checks black frames, freezes, silence, true-peak clipping, loudness against -14 LUFS, and resolution and frame count, then exits non-zero so it can gate a build
- ├── ✓ A 12-frame contact sheet with the platform safe zone drawn on vertical renders, so you can see whether your captions land where the app covers them
- ├── ✓ package_upload.py: builds a publish/ folder with the video, thumbnail, a caption to paste, and a relative-path manifest. It refuses to package a render that failed QC
- ├── ✓ Pexels broll fetcher (broll/fetch_pexels.py) pulls and caches stock footage by keyword, no API key needed for CDN fallback
- ├── ✓ CC-BY music fetcher with attribution metadata baked into the render
- ├── ✓ Bundled Noto fonts so renders are identical on any machine
- ├── ✓ Scene JSON format: write once, render long-form and Shorts from the same file
- ├── ✓ edge-tts narration (free Microsoft neural voices, chosen per scene file, with a voice per speaker in dialogue scenes)
- ├── ✓ 15 scene files ready to render: the five demo scenes plus ten on money, sleep, meetings, desk and learning, each with a distinct opener
- ├── ✓ docs/TITLES.md: the five title levers counted from two large channels, the thumbnail layout, and the retention numbers behind the opener rule
- ├── ✓ setup.py: a guided first run that saves your keys, fetches starter music and broll, and renders a smoke test
- └── ✓ AGENTS.md for coding agents: the render-QC-package sequence, why --expect matters, and the refusals it must not force past
A local Python pipeline that takes a scene JSON file and produces a publish-ready long-form YouTube video, three vertical Shorts, and a thumbnail. No cloud render queue, no subscription, no watermarks.
The output matches what the channel already ships: synchronized karaoke captions, B-roll cuts on sentence boundaries, a ducked music bed, chapter markers in the description, and a CTA card at the end. Shorts share the same scenes so you write the content once.
A render that looks finished is not yet a finished upload. qc.py checks the defects that quietly ruin a video (black frames, freezes, silence, true-peak clipping, loudness off the -14 LUFS every feed targets) and exits non-zero, so a bad render never reaches the upload step. A 12-frame contact sheet draws the platform safe zone on vertical renders, because most viewers watch on mute and captions sitting under the app’s own UI is the failure you only notice after publishing. package_upload.py then builds a publish/ folder with the video, thumbnail, caption, and a manifest whose paths are relative to itself, so the folder survives being moved between machines. It refuses to package a render that failed QC.
Runs on Windows, macOS, or Linux. Requires Python 3.10+, ffmpeg, and a free Pexels account (or use the CDN fallback with no key).
Available now with launch code LAUNCH for EUR 19 (regular price EUR 29). The code is use-capped and will be removed once the intro period closes.