PurffleShorts โ Free AI YouTube Shorts Generator, Faceless Video Maker & Opus Clip Alternative
English ยท ็ฎไฝไธญๆ ยท Espaรฑol ยท Portuguรชs ยท เคนเคฟเคจเฅเคฆเฅ ยท ๆฅๆฌ่ช
An open-source AI video generator for YouTube Shorts, TikTok and Instagram Reels. Give it a topic, a web page, a Reddit post or a long podcast, and it makes finished vertical videos (script, voiceover, footage, captions, sound effects), then uploads or schedules them on YouTube, TikTok and Instagram. YouTube automation in Python that runs on your own computer. The AI model you choose writes the script (GPT, Claude, Gemini, Llama through Ollama, DeepSeek, Grok, Mistral or any OpenAI-compatible API), using the phrases people actually search for on YouTube, and a second AI pass grades and rewrites it. Free neural voices read it, and stock footage, AI images or your own gameplay video fill the screen. Captions appear word by word, with key words in colour and an emoji per scene. It makes Reddit story videos, fake text message videos and two-voice dialogues, and clips podcasts into Shorts with jump cuts and face tracking. Free, MIT-licensed, no watermark. It also works from Claude Desktop, Claude Code and Cursor through MCP.
Features ยท Quick start ยท Colab ยท Formats ยท Reddit & gameplay ยท Clip podcasts ยท SEO ยท AI models ยท Voices ยท Publishing ยท Studio ยท API ยท MCP ยท Compare ยท FAQ
Real output, no editing: examples/flamingos.json, examples/dialogue.json and examples/chat-story.json rendered with make --script. Free Microsoft neural voices, AI images from Pollinations (for the octopus videos they were downloaded one by one into a local folder first, because keyless Pollinations now allows about one image every few minutes). GIFs have no sound.
Try it with no API keys and no sign-up (needs uv):
uvx --from git+https://github.com/Chamanrajragu/purffle-shorts purffle-shorts demo --style chat
โฆor open it in Google Colab and make videos in your browser, with nothing to install.
โญ If PurffleShorts saves you time, a star helps other creators find it. ย ยทย ๐ purffle.com/purffle-shorts
๐ค What is PurffleShorts?
PurffleShorts is a YouTube Shorts automation tool for faceless channels. Start it and it keeps going: fresh topic, retention-focused script that a second AI pass reviews and tightens, natural AI voiceover, relevant footage, captions synced to each spoken word, sound effects, a polished render, and an upload or scheduled release. It stays inside YouTube's daily API quota.
Beyond the autopilot, it is a small studio:
- Draft a script and edit any line before rendering.
- Make two-voice dialogues, text-message stories and Reddit-style stories, over stock footage or your own gameplay background.
- Turn an article or a Reddit post into a Short.
- Clip a podcast into Shorts, an Opus Clip-style workflow that runs on your computer, with jump cuts, punch-in zoom and face tracking.
- Publish the same video in several languages, and plan a week of ideas from what people search for on YouTube.
- Let the channel's own view counts steer new scripts.
It is made for content creators, faceless YouTube channels, educators and marketers who want short-form video at volume without editing by hand. It runs on your own computer (macOS, Windows, Linux), in Docker or in Google Colab. You pick every model, and the same video can go to TikTok and Instagram Reels as well as YouTube.
๐ฏ Use cases
- A faceless channel on autopilot. Pick a niche (space, history, animals, money tips), set three publish times a day and leave it running. Ideas come from real YouTube searches, Trends, Wikipedia, Reddit, RSS or your list, and are never reused. The AI is told to avoid your recent titles, and every script is reviewed before it is voiced.
- Reddit story videos over gameplay. The AI writes a first-person post, a narrator reads it over a post card, and your Minecraft parkour or other gameplay clip plays underneath: full screen, or split screen with footage on top. A real Reddit post link works as the source too.
- Fake text message videos for Shorts, TikTok and Reels: the AI writes a fictional chat, two voices read it, and the phone screen is animated with a pop as each message lands.
- Podcast, interview and stream clips.
clip episode.mp4 --count 5transcribes the video and lets the AI pick the moments that stand on their own (or the ones matching your brief, such as "the funniest bits"). You get captioned vertical clips with pauses and ums removed, the speaker kept in frame and a virality score each. There are no per-minute fees. - Articles, blog posts and notes into video.
make --url https://โฆor--from-file notes.mdturns your own writing into a Short. - One idea, many languages.
--also-lang es,hi,ptpublishes the same video with native voices in each language.LOCALIZE_METADATAtranslates the title and description of every upload. - Education and explainers. Quiz, myth-vs-fact, explainer and dialogue formats, in 9:16 for Shorts or 16:9 for regular YouTube.
- Automations and AI assistants. Drive it from n8n, Zapier or cron through the REST API, or ask Claude or Cursor to make, clip or upload videos through MCP.
โจ Features
AI scriptwriting
- One structured LLM call returns the whole Short: hook, scenes, a footage search, an image prompt, key words and an emoji per scene, title, description, hashtags, tags and YouTube category.
- Script Doctor: a second AI pass grades the draft on six points (hook, curiosity, pacing, specificity, payoff, accuracy), lists what is weak and rewrites it. The rewrite is graded again and only kept if it scores at least as well, so the 0โ100 retention score always belongs to the script you actually get. Automatic checks (hook length, filler words, missing call to action, no concrete numbers) feed the review.
- Written for search: the phrases YouTube's own search box suggests for the topic are handed to the writer, so titles, descriptions and tags use the words people actually type.
- Strict JSON-schema replies on providers that support them (OpenAI, Gemini, OpenRouter, Ollama, LM Studio, Claude), with an automatic step down for the ones that don't.
- 12 providers: OpenAI, Anthropic Claude, Google Gemini, Groq, OpenRouter, DeepSeek, Mistral, Together AI, xAI Grok, Ollama, LM Studio, or any OpenAI-compatible URL. List backups in
LLM_FALLBACKSand they are tried in order if the main one fails. - 11 formats: facts, story, listicle, myth-busting, quiz, explainer, motivational, news, two-voice dialogue, text-message story and Reddit-style story (a post card while the title is read, then the story with captions).
- Draft first and edit any line in the Studio, or write a script yourself and render it with
--script, with no LLM call.
Sources
- Your niches, questions people search for on YouTube (
TOPIC_SOURCES=search), Google Trends, Wikipedia "On this day", Reddit TIL, RSS feeds, your own list, any web page or Reddit post (--url) or document (--from-file). - Content planner: the AI brainstorms a batch of specific, true, non-repeating ideas, guided by real YouTube searches, into a queue that the autopilot uses first.
Voiceover
- 320+ free Microsoft neural voices in 75 languages, with word-level timestamps. No key needed.
- Two speakers for dialogues and chat stories, each with their own voice, joined with natural pauses.
- One video, many languages:
--also-lang es,hiadds translated copies that reuse the same footage. - Also OpenAI TTS, ElevenLabs, Kokoro-82M, Coqui and the operating-system voice. Falls back to the free voice if a paid engine fails.
Footage & backgrounds
- A separate stock-footage search for every scene (Pexels, Pixabay). Each candidate is scored by how well its own description matches the scene, the search engine's ranking, shape and length; portrait clips preferred, never reused across videos.
- Gameplay and background videos (
BACKGROUND_VIDEO): one continuous stretch of your Minecraft parkour, Subway Surfers or "satisfying" clip plays under the whole story, either full screen or split screen with the scene footage on top. - Fast pacing: scenes longer than 4.5 s are cut into several shots with different footage, each cut placed on a natural pause between words.
- AI images per scene from OpenAI (gpt-image-1 / DALLยทE 3) or Pollinations, or your own
media/folder. Ken Burns motion on photos, colour grades, transitions.
Captions, sound & editing
- Captions appear exactly when each word is spoken, with the current word highlighted. Key words and numbers get their own colour, and an emoji per scene pops up above them. 6 styles; Latin, Indic, Arabic, Thai and CJK scripts.
- Sound effects made in code (nothing to license): a whoosh on each scene change, a pop as each text message lands, a low hit under the hook. They are mixed 11 dB under the measured voice.
- Dialogues get speaker name tags and a colour per speaker; chat stories get an animated phone screen with typing indicators; Reddit-style stories open on a post card (community, poster, title, votes).
- 9:16, 16:9, 1:1 or 4:5 output (
--aspect), with captions and overlays sized for each shape. - Hook title, watermark, progress bar, end call-to-action, background music that ducks under the voice.
- Broadcast-grade audio: gentle voice clean-up (rumble cut, de-esser, compression), then two-pass loudness normalisation that measures the mix and applies one steady gain, landing on โ14 LUFS without pumping.
- Voices without word timestamps get their phrase ends pinned to the real pauses in the audio, so captions stay in sync even without an aligner.
- The cover image is the sharpest, best-exposed frame of the opening seconds, never a frame mid-transition.
- Plain ffmpeg: each shot is prepared as a short segment, the soundtrack is mixed and normalised in its own pass, then one final encode joins them and adds everything above. No MoviePy, no ImageMagick, no GPU needed.
Clipping (a free Opus Clip alternative)
- Transcribes podcasts, interviews and streams locally with Whisper. The AI picks self-contained moments with a hook and a payoff, or only the ones that fit your brief (
--prompt "every tip about sleep"). - Each clip has a virality score with the reason. It is edited with jump cuts (long pauses shortened, "um" and "uh" removed, lips kept in sync) and punch-in zoom between sentences.
- Framing: face tracking (
--crop face), the centre, or the whole picture over a blurred copy. Word-by-word captions are added too.
Publishing & SEO
- Uploads to YouTube, or schedules each video into your next free time slot.
- TikTok, Instagram Reels and more (
PUBLISH_TO=youtube,tiktok,instagram): the same video goes out with a caption written for each network, at the same publish slot, through Upload-Post or Instagram's own API. Each network's result is saved, and a retry only re-sends what failed. - Localised titles and descriptions (
LOCALIZE_METADATA=es,pt,hi), so viewers see the video under a title in their own language, and optional caption-track upload (UPLOAD_CAPTIONS) so YouTube can index every word. - Quota-aware queue, AI-content disclosure, playlists, privacy, made-for-kids flag.
- Every video also gets a cover image, SRT subtitles and a metadata file for cross-posting.
Workflow
- Autopilot loop, one-off videos, bulk batches with parallel workers, several channels from separate settings files.
- Studio web app: create, draft and edit, and watch every stage live (pushed instantly, with a percentage and a time-left estimate learned from your machine). Cancel a running job, browse and play the library, plan ideas, clip videos and read channel stats.
STUDIO_PASSWORDprotects it when it runs on a server. - REST API for n8n, Zapier, cron or your own scripts (docs/api.md), a Google Colab notebook, and docker compose for servers.
- A live progress line in the terminal, and a voice cache so re-rendering an edited script only voices the lines that changed.
- MCP server: ask Claude Desktop, Claude Code or Cursor to make, clip or upload videos.
- Learns from your channel (opt-in): view counts of your uploads show the AI what works for your audience, and the format of each new video is chosen by Thompson sampling over your own results.
statstells you whether the retention score actually predicts your views (Spearman correlation) and which publish hours did best. - Discord / Slack / webhook notifications, a
doctorself-check, SQLite history, and CI that renders real videos on every pull request.
๐ New since 3.0
The changelog has the full list, with the measured before-and-after numbers.
โ๏ธ How it compares
Open-source Shorts tools each cover part of the job: some write videos from a topic, some clip long videos, some make Reddit stories. PurffleShorts does all three. It is the only one we found with text-message stories, two-voice dialogues, a script review pass, and an MCP server that covers writing, clipping and uploading.
โ yes ยท โ partly ยท โ no ยท โ not stated. Compiled on 29 September 2026 from each project's README and code; the gameplay, silence-removal and Colab rows were checked on 20 October 2026. Projects change quickly: if a cell is wrong, please open an issue and it will be fixed. Where others are ahead: RedditVideoMakerBot ships a library of background videos, and MoneyPrinterTurbo has a one-click Windows package.
๐ธ Screenshots
New in 3.0: text-message stories, two-voice dialogues and Reddit-style stories. Rendered from examples/chat-story.json, examples/dialogue.json and examples/reddit-story.json.
Frames from the flamingo Short above: hook title, word-highlighted captions, progress bar, end call-to-action.
Six caption styles, drawn by the same renderer the videos use:
Studio, the local web app, in light and dark. The Create page is a numbered brief (subject, format, shape and voice, look and sound, model and publishing) beside a program monitor that previews the caption style, shape and safe area.
The library is a contact sheet of everything you made. Open a video to play it, publish it to YouTube, TikTok and Instagram, edit and re-render it, or delete it.
Command line: doctor checks the setup, make renders a Short.
๐๏ธ Earlier releases
Version 2 is a rewrite. The 1.x pipeline had problems: the pinned openai SDK no longer had the API the code called, landscape footage was stretched into portrait, captions were evenly spaced rather than following the voice, the title and description were generated separately from the script, and every video went through six MoviePy re-encodes.
๐ How it works
flowchart LR
A["Topic<br/>idea queue ยท niches ยท YouTube searches ยท<br/>Trends ยท Wikipedia ยท Reddit ยท RSS ยท web page"] --> B["AI script<br/>any LLM, one JSON reply,<br/>real search phrases"]
B --> R["Script Doctor<br/>rubric ยท rewrite ยท re-grade"]
R --> C["Neural voice<br/>one or two speakers"]
C --> D["Footage per shot<br/>stock video ยท photos ยท AI images<br/>or a gameplay background"]
D --> E["Captions & overlays<br/>key words ยท emoji ยท hook ยท CTA"]
E --> F["ffmpeg render<br/>9:16 ยท 16:9 ยท 1:1 ยท 4:5<br/>sound effects ยท โ14 LUFS"]
F --> G["Upload or schedule<br/>localised titles ยท captions"]
F -. also-lang .-> T["Translated copies<br/>same footage"]
G -. next video .-> A
๐ Quick start
Needs: Python 3.10+. ffmpeg is used if installed; if not, the bundled imageio-ffmpeg binary is used. ImageMagick is no longer needed.
Fastest: with uv installed, run it straight from GitHub without cloning anything:
uvx --from git+https://github.com/Chamanrajragu/purffle-shorts purffle-shorts demo
To keep it and configure it, clone and install:
git clone https://github.com/Chamanrajragu/purffle-shorts.git
cd purffle-shorts
python -m venv venv && source venv/bin/activate # Windows: venv\Scripts\activate
pip install -e . # or: pip install -r requirements.txt
1. See it work with no keys at all. This renders a sample Short with a built-in script, a free neural voice and generated backgrounds:
python -m purffle_shorts demo
python -m purffle_shorts demo --style chat # text-message story
python -m purffle_shorts demo --style dialogue # two voices
python -m purffle_shorts demo --style reddit # Reddit-style story with a post card
Or open the web app and click through it (demo mode is on until you add a key):
python -m purffle_shorts studio
2. Configure. Copy .env.example to .env, add one LLM key (or run Ollama) and a Pexels and/or Pixabay key (both free), then run the self-check:
python -m purffle_shorts doctor
3. Make one video (kept locally, not uploaded):
python -m purffle_shorts make --topic "why octopuses have three hearts" --no-upload
4. Connect YouTube once. Create an OAuth client of type Desktop app in Google Cloud Console with the YouTube Data API v3 enabled, save it as credentials.json, then:
python -m purffle_shorts auth
5. Autopilot:
python -m purffle_shorts plan --count 14 # optional: queue two weeks of ideas first
python -m purffle_shorts run # or the old way: python YT.py
Optional extras: pip install -e ".[clip]" adds faster-whisper and yt-dlp for clipping podcasts and long videos, and pip install -e ".[face]" adds face tracking.
โ๏ธ Run it in Google Colab
The notebook installs PurffleShorts in Google's free cloud machines and walks through it in six cells:
- install;
- a demo with no keys;
- your keys from Colab Secrets (a free Gemini key is enough to write scripts);
- a Short about any topic;
- clipping an uploaded podcast, faster on a free T4 GPU;
- downloading everything as a zip.
Nothing is uploaded to YouTube from the notebook.
๐ฌ Formats
Pick one with SCRIPT_STYLE / --style, or leave it on auto.
purffle-shorts make --style chat --topic "a babysitter gets texts from an unknown number"
purffle-shorts make --style dialogue --topic "why the sky is blue"
purffle-shorts make --style reddit --topic "a neighbour who keeps borrowing my ladder"
purffle-shorts make --url "https://www.reddit.com/r/tifu/comments/โฆ" # a real post as the source
Scripts from the LLM are fiction for chat and reddit (the prompt forbids real people). Reddit post links are read through the post's public feed; only reuse posts when you have the author's permission. As with every format, read before you publish.
๐ฎ Reddit story videos over gameplay (split screen)
The classic Reddit-story look is a narrator over Minecraft parkour, Subway Surfers or a "satisfying" clip. Give PurffleShorts a background video (or a folder of them, one picked at random per Short) and one continuous, randomly chosen stretch of it plays under the whole story:
purffle-shorts make --style reddit --background media/backgrounds/parkour.mp4 # full screen
purffle-shorts make --style reddit --background media/backgrounds/ --layout split # footage on top, gameplay below
purffle-shorts make --style chat --background media/backgrounds/ # a text story over gameplay
purffle-shorts demo --style reddit --background my-gameplay.mp4 # try it with no keys
Or set BACKGROUND_VIDEO=media/backgrounds and BACKGROUND_LAYOUT=full|split in .env, or pick a video in the Studio's Look card (it lists everything in media/backgrounds/). In the split layout the scene footage is searched in the top half's shape and the captions sit on the seam, the usual "brainrot" layout that keeps eyes on screen. Sound effects, key-word captions and the post card work as usual. Use only gameplay you recorded yourself or have the rights to reuse.
โ๏ธ Clip podcasts into Shorts (free Opus Clip alternative)
pip install faster-whisper # free, local transcription (or set OPENAI_API_KEY)
purffle-shorts clip podcast.mp4 --count 3 # fill the frame
purffle-shorts clip interview.mp4 --crop face # follow the speaker (pip install opencv-python-headless)
purffle-shorts clip talk.mp4 --count 5 --crop blur # whole picture over a blurred copy
purffle-shorts clip episode.mp4 --prompt "the funniest moments" # only the moments that fit a brief
purffle-shorts clip "https://โฆ" --count 3 # URLs need: pip install yt-dlp
It works like Opus Clip, Klap or Vidyo.ai, but locally, with no per-minute fees and no watermark beyond your channel name. The video is transcribed with word timings. The LLM reads the timestamped transcript and picks moments of 20โ58 s (--min-seconds, --max-seconds) that open with a hook and end on a complete thought, or only those matching your --prompt. Each moment gets a title, hashtags and a virality score with the reason. Each clip is cut on sentence boundaries, cropped to 9:16, captioned word by word with a hook title, and loudness-normalised.
Edited like a pro editor would: jump cuts shorten pauses longer than CLIP_MAX_PAUSE (0.6 s) and remove "um" and "uh". Cuts land on frame boundaries and the sound is cut at exactly the same instants, so lips stay in sync however many cuts there are. Punch-in zoom changes the framing between sentences, at most every 2 seconds. Turn them off with --no-jump-cuts and --no-zoom (or CLIP_JUMP_CUTS=false, CLIP_ZOOM=false).
Without an LLM it still works, with moments spread evenly over the video instead. Transcription uses WHISPER_MODEL (auto picks large-v3-turbo on an NVIDIA GPU and small on a CPU) with voice-activity detection, so music and silence don't turn into invented words. --crop face finds the speaker's face twice a second (OpenCV's YuNet detector, a 230 KB model downloaded once) and keeps it in frame, switching framing only when the camera cuts. Clips upload like any other video when UPLOAD=true; add --no-upload to only cut them. Only clip videos you own or have permission to reuse.
๐๏ธ Ideas, sources and languages
- What people search for:
TOPIC_SOURCES=niche:2,search:2mixes in questions people type into YouTube's search box about your niches ("why do octopuses have three hearts", "what happens when two oceans meet"); the AI answers the one that fits best. - Plan ahead:
purffle-shorts plan --count 14 --niche "space"asks the AI for specific, true, non-repeating ideas with a format and an angle each, guided by real YouTube searches.ideaslists the queue (--add,--remove,--clear). Queued ideas are always made first; if a video fails, its idea goes back in the queue. - From a web page, a Reddit post or a document:
make --url https://โฆormake --from-file notes.mduses the text as the script's source material. A Reddit post link picks the Reddit story format automatically. - RSS:
RSS_FEEDS=https://โฆ/feed.xml,https://โฆandTOPIC_SOURCES=niche:3,rss:1. - Many languages:
ALSO_LANGUAGES=es,hi(or--also-lang) makes a translated copy of every video with a native voice, reusing the original's footage. Each copy is its own upload, linked to the original in the library.
๐ SEO built in: real YouTube searches, localised titles, captions
A Short that nobody searches for only lives as long as the Shorts feed shows it. PurffleShorts writes with search in mind:
- Real search phrases (
SEO_KEYWORDS=true, the default): before writing, it asks YouTube's own search box what people type about the topic ("why do octopuses have three hearts", "octopus blue blood"). It hands those phrases to the script writer, which uses the matching ones word for word in the title, the first line of the description and the tags. Off-topic suggestions (documentaries, games, "in hindi" and so on), sensitive and adult ones are filtered out. They are saved inmetadata.jsonassearch_keywords. - Topics people are looking for (
TOPIC_SOURCES=search) and a planner that prefers ideas answering real searches. - Localised titles and descriptions (
LOCALIZE_METADATA=es,pt,hi,fr): one extra LLM call translates the title and description, and the upload carries them as YouTube localizations. Viewers whose YouTube is in Spanish see the Spanish title, and so on, while the video stays one upload. - Caption tracks (
UPLOAD_CAPTIONS=true): the exact subtitles are uploaded with the video, so YouTube has every spoken word to index (400 API units per video; runauthonce more after turning it on). - Titles under 100 characters with
#shorts, descriptions with a question that invites comments, 3โ5 hashtags, tags kept under YouTube's 500-character limit, the right category, language and audio language, and the synthetic-media disclosure.
๐ Learn from your channel
LEARN_FROM_STATS=true
YOUTUBE_API_KEY=... # optional: reads public stats without asking for more OAuth access
purffle-shorts stats (and the Studio's Channel page) reads view, like and comment counts of the videos PurffleShorts uploaded: one API unit per 50 videos. With LEARN_FROM_STATS=true the autopilot refreshes them twice a day and shows the LLM your best and worst performers (public for 48 hours or more) when it writes and plans. Without YOUTUBE_API_KEY, run auth once more to grant read access.
Once 8 or more videos have stats, SCRIPT_STYLE=auto stops picking formats at random: each format's typical view count gets a statistical estimate that tightens as its videos come in, and the next format is drawn by Thompson sampling. Formats that work for your audience are chosen more often, and untried ones still get a fair chance. stats also checks the predictions against reality: the Spearman correlation between the Script Doctor's retention score and real views, median views per format, and the publish hours that did best.
๐ง AI models
Set LLM_PROVIDER and LLM_MODEL in .env, or pass --provider / --model. With LLM_PROVIDER=auto the first key found is used, and a running Ollama is used when there is no key. LLM_FALLBACKS=anthropic,gemini retries with other providers when the main one fails. Any model a provider offers works; the defaults are only starting points.
python -m purffle_shorts providers shows which providers have a key and whether Ollama / LM Studio are running.
Script Doctor (SCRIPT_REVIEW): rewrite (default) scores every script and uses the improved version, score only records the score and the problems, off skips it (--no-review). Rewrite mode adds two LLM calls per video (the review with its rewrite, then the re-grade), score mode one.
Facts need a capable model. In testing, a 3B local model wrote a confident but wrong claim ("flamingos get their colour from carrots"). Use a larger model for fact-based formats, or check
script.json, fix it, and re-render with--script.
๐๏ธ Voices
python -m purffle_shorts voices --lang enlists the free voices for a language (322 voices in 75 languages when checked; try--lang es,--lang hiand so on). SetTTS_VOICE=en-US-GuyNeural, or a comma list to rotate voices between videos.LANGUAGE=es(orhi,ta,fr,pt,ja, โฆ) switches the script, the voice and the caption font together. Tamil, Hindi, Arabic, Thai and similar scripts are rendered through libass so they are shaped correctly.pip install faster-whispergives precise word timing for engines without native timestamps (ALIGN=auto).- The second speaker in dialogues and chats uses
TTS_VOICE_B, or a contrasting voice picked for the language. - If the chosen engine fails, the video falls back to the free edge voice instead of failing.
๐จ Captions & look
The caption font is downloaded once from Google Fonts (Anton for Latin scripts, Noto Sans for other scripts). Set CAPTION_FONT=/path/font.ttf to use your own.
Visual sources (VISUAL_SOURCES, tried in order per scene): pexels, pixabay, local (your media/ folder, matched by filename keywords), openai-images (gpt-image-1 / DALLยทE 3), pollinations (AI images). Searches and AI images follow the output shape (portrait, landscape or square).
Pollinations without a key is no longer practical for whole videos. Tested on 29 September 2026: the first request returned an image, the next ones answered HTTP 402 "payment required", roughly one image every few minutes. When that happens PurffleShorts stops asking for the rest of that video and those scenes fall back to the next source.
POLLINATIONS_API_KEYis sent as a Bearer token for keyed access; that path has not been tested here. Pexels and Pixabay keys are free and are the dependable choice.
๐ Publishing & scheduling
PUBLISH_TO lists where each video goes: youtube (the default), tiktok, instagram, and through Upload-Post also facebook, threads, x, linkedin, bluesky and pinterest. With PUBLISH_TIMES, every network gets the same slot.
Captions are written for each network: the title, the description and its hashtags, without #shorts, cut to each network's length. The cover frame is passed to Instagram. A network that fails never stops the others or the video. Its result is saved in metadata.json and shown in the Studio, and upload --id N (or Publish the rest in the Studio) re-sends only what didn't go out.
These integrations follow each service's published API and are covered by tests against recorded responses, but they have not yet been run against live TikTok and Instagram accounts. Please open an issue if a post doesn't go out as expected.
YT_PRIVACY=public|unlisted|private.PUBLISH_TIMES=09:00,14:00,19:00withTIMEZONE=Asia/Kolkatauploads each video as private and schedules it into the next free slot. Render in bulk, release on schedule.- Paced and quota-aware.
YT_DAILY_LIMIT=6uploads a day by default. That is a pace you choose, not the API's ceiling: uploads now have their own API bucket of 100 a day at 1 unit each (Google's quota table, updated 15 September 2026). Extra videos are queued, and so are videos YouTube refuses because the project or the channel hit a limit (quotaExceeded,uploadLimitExceeded); after a refusal nothing else is tried that day. On autopilot the queue is uploaded first after the reset at midnight Pacific time, and production waits instead of piling up. Without autopilot, runupload --pendingafter the reset. SYNTHETIC_MEDIA=truesets YouTube's altered or synthetic content disclosure.MADE_FOR_KIDS,PLAYLIST_IDand category (chosen by the AI) are set too.- Each video's folder holds
short.mp4(video.mp4for 16:9),cover.jpg,captions.srt,script.jsonandmetadata.json(including the retention score and where it was posted).KEEP_VIDEOS=falsedeletes the MP4 once every destination has it. - Notifications:
NOTIFY_WEBHOOK=https://discord.com/api/webhooks/โฆ(or a Slack incoming webhook, or any URL for JSON) posts a message when a video is rendered, uploaded, scheduled, queued or fails.
๐ป Command line
python -m purffle_shorts <command> [options] # or `purffle-shorts <command>` after pip install
Common options: --source queue|search|trending|wikipedia|reddit|rss|file|niche, --niche "space", --style facts|story|listicle|myth|quiz|explainer|motivational|news|dialogue|chat|reddit, --lang, --duration 45, --aspect 9:16|16:9|1:1|4:5, --also-lang es,hi, --provider, --model, --no-review, --tts, --voice, --voice-b, --visuals, --caption-style, --grade, --transition, --resolution, --background video.mp4, --layout full|split, --no-music, --no-sfx, --no-emoji, --no-upload, --privacy, --publish-times, --publish-to youtube,tiktok,instagram, --env-file.
Your own script: every video folder has a script.json. Edit the narration, title or image prompts and render it again with make --script path/to/script.json. The files in examples/ show the format.
Several channels: keep one settings file per channel (niche, voice, YT_TOKEN_FILE, DATA_DIR) and run python -m purffle_shorts run --env-file .env.channel2.
Upgrading from 1.x: python YT.py, --once, --no-upload, --count N and the old SHORTS_* variables still work, and token.pickle is migrated to token.json automatically. Install the new requirements first.
๐ฅ๏ธ Studio (web app)
python -m purffle_shorts studio # opens http://127.0.0.1:8765
- Create: topic, web page, idea queue or "surprise me"; eleven formats; language, length, aspect, voices, caption style (with a preview), grade, transitions, footage sources, a background video (full or split screen), sound effects, key-word colours, emoji, model, Script Doctor mode, extra languages, and publishing to YouTube, TikTok and Instagram.
- Draft, then edit: the AI writes and reviews the script, you see the retention score and the problems it found, change any line, reorder or add scenes, switch speakers, then render exactly that script.
- Live progress through topic, script, review, voice, footage, captions, render and upload, with the log.
- Library: thumbnails with status, format, language and score; open one to play it, download the MP4 or captions, upload it, edit and re-render it, or delete it.
- Ideas, Clip, Channel and System pages: plan and queue ideas, clip long videos (with a brief, jump cuts, zoom and face tracking; each clip shows its virality score), see views per video and per format, run the setup checks and copy the MCP config.
The design is its own: warm paper and ink with one signal colour (a camera's red tally light), Schibsted Grotesk and JetBrains Mono bundled with the app, a light and a dark theme (or the system's), and layouts that work on a phone. The page needs no build step and loads nothing from a CDN. The Studio listens on localhost only, refuses requests for any other host name, sends a strict Content-Security-Policy, and every action needs a token (new each session, or fixed with STUDIO_TOKEN). On a server, STUDIO_PASSWORD puts a password on every page and API call.
๐ REST API and automation (n8n, Zapier, cron)
Everything the Studio does is a small JSON API, so n8n, Make, Zapier (through a webhook), a cron job or your own script can make, clip, plan and upload videos:
STUDIO_TOKEN=change-me purffle-shorts studio --no-browser
curl -X POST localhost:8765/api/make -H "X-Studio-Token: change-me" -H "Content-Type: application/json" \
-d '{"topic": "why octopuses have three hearts", "style": "facts", "duration": 35}' # โ {"job": 1}
curl localhost:8765/api/jobs/1 # status, stage, percentage, time left, then the result with the video id
curl -o short.mp4 localhost:8765/files/12/short.mp4
Jobs run one at a time in order. Follow them by polling GET /api/jobs/<id>, or listen to the Server-Sent Events stream at /api/events. docs/api.md lists every endpoint and field, with Python and curl examples and an n8n recipe that turns every new RSS item into a Short.
๐ค Use it from Claude and other AI apps (MCP)
PurffleShorts is an MCP server too. Add it to Claude Desktop, Claude Code, Cursor or any MCP client:
{
"mcpServers": {
"purffle-shorts": {
"command": "purffle-shorts",
"args": ["mcp"],
"env": { "PURFFLE_HOME": "/path/to/your/purffle/folder" }
}
}
}
Without installing anything, uv can run it straight from GitHub: use "command": "uvx" with "args": ["--from", "git+https://github.com/Chamanrajragu/purffle-shorts", "purffle-shorts", "mcp"].
PURFFLE_HOME is the folder with your .env. Then ask things like "make a 30-second text story about a haunted smart speaker, in Spanish", "draft a dialogue about black holes and show me the script first", "clip my interview.mp4 into three Shorts" or "plan ten ideas about ancient Rome". Tools: make_short (with a background video, layout, sound effects and emoji switches), draft_script, clip_video (with a brief, jump cuts and zoom), plan_ideas, list_videos, upload_video. Nothing is uploaded unless the request says so (upload: true); demo: true works without any keys.
๐ณ Docker
Each release is published as ghcr.io/chamanrajragu/purffle-shorts. With docker-compose.yml, a server, NAS or VPS runs the Studio, plus the autopilot if you want it:
cp .env.example .env # add your keys and a STUDIO_PASSWORD
docker compose up -d # Studio on http://localhost:8765
docker compose --profile autopilot up -d # also make and upload on schedule
Or with plain Docker:
docker run --rm -it --env-file .env -v "$PWD:/work" ghcr.io/chamanrajragu/purffle-shorts run
docker build -t purffle-shorts . # build your own from this checkout
Run auth once on your own computer so token.json exists in the mounted folder. For the Studio in Docker, publish the port on localhost only: docker run --rm -it --env-file .env -v "$PWD:/work" -p 127.0.0.1:8765:8765 purffle-shorts studio --host 0.0.0.0 --no-browser. Keep comments in .env on their own lines: --env-file reads a comment after a value as part of the value.
โ FAQ
Is PurffleShorts free?
Yes. It is MIT-licensed and runs on your own computer. The default voices, Ollama models, faster-whisper and the Pexels and Pixabay APIs cost nothing. You only pay for paid APIs you choose to use, such as OpenAI, Claude or ElevenLabs. The Script Doctor adds two LLM calls per video (SCRIPT_REVIEW=off to skip it).
Can it make text-message stories, Reddit story videos or two-person conversations?
Yes: --style chat renders an animated phone screen with messages popping in as each side's voice reads them, --style reddit opens on a Reddit-style post card and then tells the story with captions, and --style dialogue voices two people with name tags on the captions.
Is there a free, open-source alternative to Opus Clip?
purffle-shorts clip does the same job on your own computer. It transcribes a podcast, interview or stream, lets an LLM (a local Ollama model works) pick self-contained moments with a virality score, and cuts captioned 9:16 clips. The clips get jump cuts (pauses and ums removed, lips in sync), punch-in zoom and, with --crop face, face tracking. --prompt "โฆ" tells it what to look for. There are no per-minute credits, and the only watermark is your channel name from CHANNEL_NAME (it reads PurffleStudios until you set it; WATERMARK=none removes it).
How do I make Reddit story videos with Minecraft parkour or Subway Surfers gameplay?
Put a gameplay video you may reuse in media/backgrounds/ and run purffle-shorts make --style reddit --background media/backgrounds/ (add --layout split for footage on top and gameplay below). A random, continuous stretch plays under the whole story, with the post card, narration, captions and sound effects on top. More.
Can it remove silences and filler words from my podcast clips?
Yes, by default: pauses longer than 0.6 s are shortened and "um" and "uh" are cut. Picture and sound are cut on the same frame boundaries, so lips stay in sync. CLIP_MAX_PAUSE sets the threshold, and --no-jump-cuts keeps everything.
Does it add sound effects, emoji and highlighted key words like Submagic?
Yes. Each video gets a whoosh on scene changes, a pop per text message and a hit under the hook, mixed 11 dB under the voice. The AI marks the key words of each scene, and those words and every number are drawn in colour. An emoji per scene pops up above the captions. Turn any of them off with SOUND_EFFECTS, CAPTION_EMPHASIS or CAPTION_EMOJI.
Can I run it in Google Colab, on a server or from n8n?
Yes. There is a Colab notebook, a docker-compose.yml for servers, and a REST API with an n8n recipe.
Does it help my Shorts get found in YouTube search?
It writes titles, descriptions and tags with the phrases YouTube's own search box suggests for the topic, can pick topics from what people search for, can translate titles and descriptions into other languages for viewers there (LOCALIZE_METADATA), and can upload the exact captions (UPLOAD_CAPTIONS). Details. No tool can promise views; a good hook and a satisfying payoff still matter most, and the Script Doctor grades both.
How is it different from MoneyPrinterTurbo or ShortGPT? All three turn a topic into a Short. PurffleShorts adds a script review pass, text-message, dialogue and Reddit-style formats, long-video clipping, scheduled uploads through the official YouTube API, and an MCP server. See the comparison table for the details and where the others are ahead.
Can Claude or another AI assistant make YouTube Shorts with this? Yes, through MCP: add PurffleShorts to an MCP client that runs local servers, such as Claude Desktop, Claude Code or Cursor (setup). Ask for a video in plain words and it writes, renders and, only if you ask, uploads it.
Can it turn my podcast or stream into Shorts?
Yes: purffle-shorts clip episode.mp4 --count 5 --no-upload (leave out --no-upload to upload the clips too). It needs faster-whisper (free, local) or an OpenAI key for the transcript.
Can I try it without an API key?
Yes. python -m purffle_shorts demo renders a sample Short with no keys, and so does the Colab notebook. With Ollama installed, make writes scripts with a local model, also without a key.
Does it work with ChatGPT, Claude, Gemini, DeepSeek or Llama? Yes: OpenAI GPT models (including GPT-5 and the o-series), Anthropic Claude, Google Gemini, DeepSeek, Mistral, xAI Grok, Llama through Groq, Together AI, Ollama or LM Studio, hundreds more through OpenRouter, and any OpenAI-compatible endpoint.
Can it post to TikTok or Instagram Reels?
Yes: PUBLISH_TO=youtube,tiktok,instagram. TikTok goes through Upload-Post, because TikTok's own API only lets audited apps publish public videos. Instagram can use its free official API or Upload-Post. Each network gets its own caption and the same publish slot (details). Every video is also a standard MP4 with a cover image and subtitles, if you would rather post it yourself.
How many Shorts can it upload per day?
Six by default (YT_DAILY_LIMIT). You can raise it: the YouTube API now gives uploads their own bucket of 100 a day. Posting many videos at once rarely helps a channel, so the default stays modest. Anything over the limit waits in a queue and uploads after the daily reset.
Can I write or fix the script myself?
Yes. Edit any video's script.json (or write one like examples/flamingos.json) and run make --script file.json.
Which languages are supported?
Set LANGUAGE (for example es, hi, ta, ar, ja) and the script, voice and caption font follow. The free voices cover 75 languages. ALSO_LANGUAGES=es,hi publishes every video in those languages too.
Do I need a GPU? No. Rendering uses ffmpeg on the CPU. A GPU only speeds up optional local models (Ollama, Kokoro, faster-whisper).
Is automated uploading allowed? It uses the official YouTube Data API with your own Google sign-in, and sets YouTube's synthetic-content disclosure for you. You are responsible for what you publish: review the videos and follow YouTube's policies, including its monetisation rules on mass-produced, repetitive content.
๐๏ธ Tech stack
๐ Project structure
purffle-shorts/
โโโ YT.py # 1.x-compatible entry point (python YT.py)
โโโ purffle_shorts/
โ โโโ cli.py # commands: run, make, demo, clip, plan, ideas, stats, upload, auth, doctor, studio, mcp
โ โโโ pipeline.py # topic โ script โ review โ voice โ footage โ render โ upload โ translations
โ โโโ llm.py # 12 LLM providers + fallback chain
โ โโโ script.py # prompt, JSON schema, Script Doctor, translation, clean-up, offline writer
โ โโโ planner.py # AI content planner โ idea queue
โ โโโ clipper.py # long video โ transcript โ best moments โ jump cuts, zoom, face framing โ clips
โ โโโ tts.py # voice engines, two-speaker joining, word alignment
โ โโโ sfx.py # sound effects made in code (whoosh, pop, hit)
โ โโโ seo.py # YouTube search suggestions โ topics and keywords
โ โโโ timing.py # word timing, scene timeline, caption chunks, SRT
โ โโโ media.py # Pexels / Pixabay / local / AI images, de-duplication
โ โโโ overlays.py # captions (Pillow + libass), key words, emoji, chat screen, post card, hook, CTA, fonts
โ โโโ render.py # ffmpeg segments, transitions, split screen, grading, audio mix
โ โโโ youtube.py # OAuth, upload, scheduling, quota
โ โโโ analytics.py # view counts โ what the LLM learns from
โ โโโ notify.py # Discord / Slack / webhook messages
โ โโโ topics.py # idea queue, niches, YouTube searches, Trends, Wikipedia, Reddit, RSS, web pages, documents
โ โโโ history.py # SQLite history + migrations
โ โโโ doctor.py # setup checks (CLI and Studio)
โ โโโ mcp_server.py # MCP server over stdio
โ โโโ studio.py # local web app server + JSON API
โ โโโ web/ # the Studio's HTML, CSS and JS
โโโ examples/ # ready-to-render scripts (make --script examples/flamingos.json)
โโโ notebooks/ # Google Colab notebook
โโโ tests/ # unit + offline end-to-end render tests (200+)
โโโ docs/ # REST API reference (api.md), screenshots, improvement notes
โโโ .env.example # the main settings, documented
โโโ Dockerfile, docker-compose.yml
โโโ output_videos/ # renders (gitignored)
๐ ๏ธ Troubleshooting
๐ค Contributing
Bug reports, ideas and pull requests are welcome. See CONTRIBUTING.md for the dev setup (tests run offline and render a real video), and CHANGELOG.md for what changed. Questions and ideas are welcome in Discussions once they are enabled, or as an issue.
โ ๏ธ Disclaimer
This is an open-source automation tool for educational purposes. It needs your own API keys. Review AI-generated content before publishing, keep the synthetic-media disclosure on, and follow YouTube's Terms of Service and Community Guidelines. Not affiliated with YouTube, OpenAI, Anthropic, Google, Microsoft, Pexels, Pixabay, Pollinations or Reddit.
Built by Chaman Raj
Part of the Purffle ecosystem โ PurffleTools ยท PurffleAI ยท Purffle.com
๐งฉ The Purffle toolset
PurffleShorts is part of Purffle โ a growing set of free, open-source tools built in the open. If this saved you time, please drop a โญ โ it genuinely helps the project reach more people!
๐ purffle.com ยท ๐ผ by Chaman Raj ยท โญ Star to support open-source
Need Something Like This Built for You?
I wrote this. I also write Python for other people โ fixed price, agreed before I start.
- Python automation โ batch file processing, Excel/CSV cleaning, API pulls, scheduled reports, packaged as a
.exeif you do not use Python ยท 1โ5 days - Web scraping โ clean data as Excel, CSV, JSON or Sheets, plus the reusable scraper ยท 1โ4 days
- Custom AI chatbots โ trained on your own docs, full source code, no monthly fee ยท 2โ7 days
- Excel and Google Sheets โ formulas, dashboards, macros, Apps Script ยท 1โ4 days
I only take work I can verify myself before delivering it โ I run it on your real data first.
More of what I have built: purffle.com ยท purffle.tools ยท purffleai.com ยท purfflestudios.com