Publish explainer Shorts & Reels
End-to-end workflow for the Only Sci Facts channel (YouTube @onlyfactsci, Instagram onlyfactsci):
choose episodes → compress for upload → make covers → write captions → post on YouTube Shorts and Instagram Reels → verify.
It works for any folder of 9:16 MP4 explainers.
Scripts live in scripts/ next to this file. If they aren't there, clone https://github.com/pranaykrpiyush/video-publishing-skill and use publish-explainer-shorts/scripts/.
The scripts need ffmpeg, ffprobe, Python 3 with Pillow and numpy, and the Inter Display font. Any bold sans font works if you point the FONT_DIR environment variable at it.
0. Before you start
- Ask for (or find) the episodes folder. Episodes are named
NN-slug.mp4, for example14-falling-into-a-black-hole.mp4. - Ask how many episodes to post and on which platforms, unless the request already says.
- Check that the user is signed in to YouTube Studio and Instagram in Chrome: open each site once and look.
- Already posted? Check the YouTube Studio Shorts list and the Instagram grid so you don't post an episode twice.
1. Pick the most viral-ready episodes
-
Inventory:
scripts/inventory.sh <folder>prints duration, resolution and audio levels for each file. -
Rule out:
- anything over 60 s (it still works as a Short, but completion rate drops) or not 1080×1920;
- silent or clipping audio (max_volume above −0.5 dB);
- topics that platforms suppress (drugs, for example the "LSD mirrors" episode; graphic or medical content);
- episodes already posted.
-
Look at the content.
scripts/contact_sheet.sh <video> <out.jpg>makes one image of a frame every 4 s. Read the sheets. -
Score each remaining episode out of 5 on each of these:
- Hook in the first second: a big number, a paradox, or "what happens if…".
- Curiosity gap: a counter-intuitive answer.
- Visual drama: black holes, galaxies or explosions beat diagrams.
- Comment bait: an open question or multiple competing answers.
- Broad appeal: space and the human body beat niche topics.
Space paradoxes (black holes, the Fermi paradox, stardust, dark matter) usually score highest.
-
Tell the user your picks with one line of reasoning each, then continue. Don't wait for approval unless they asked to choose.
2. Compress for upload
The Chrome extension's file_upload tool rejects files over 3.8 MB. The re-encode is also what you keep if the user ends up picking files themselves.
scripts/compress_for_upload.sh <in.mp4> <out.mp4>
The script runs x264 at CRF 26 with -preset slow, AAC at 96k and +faststart. Then it prints the size and SSIM against the original:
- Target SSIM is at least 0.995, which is visually lossless.
- If the file is still over 3.8 MB, rerun with
CRF=28.
Put the outputs in an upload-ready/ subfolder of the episodes folder. Never overwrite the originals.
3. Make covers
python3 scripts/make_cover.py --style blackhole \
--kicker "WHAT HAPPENS IF" --headline "YOU FALL IN?" \
--tagline "Two endings.|Both true." --out 14-cover.png
python3 scripts/make_cover.py --style galaxy \
--kicker "100,000,000,000 STARS" --headline "WHERE IS|EVERYONE?" \
--tagline "No ships.|No signals." --out 12-cover.png
python3 scripts/make_cover.py --style frame --video 05-why-the-sky-is-blue.mp4 --at 12 \
--kicker "WHY IS THE" --headline "SKY BLUE?" --tagline "It's not|reflecting the sea." --out 05-cover.png
How the arguments work:
|in--headlinebreaks the line.|in--taglinesplits the text into a white part and an orange part.--style framelifts the artwork that sits between the episode's burned-in captions. If a stray label shows at the edge of the art, move the band with--art-top/--art-bottom; the defaults are 420 and 1300 px of the source frame.
Each cover is 1080×1920, and all the text stays inside the central 1080×1350 area so Instagram's grid crop keeps it.
Copywriting rules:
- The headline is a question or a shock number. Keep it to 2–4 words in caps.
- The kicker sets it up.
- The tagline teases the payoff without giving it away.
Look at every cover before using it: open it with Read.
4. Write captions
YouTube title. Keep it under 70 characters and phrase it as the question the video answers, plus an emoji and #shorts. Example: What happens if you fall into a black hole? 🕳️ #shorts
Description and Instagram caption. Use the same template on both platforms:
<Hook line: the paradox or the big number> <emoji>
<2 sentences: the payoff, in plain words>
<Comment-bait question: "Which do you believe? 👇" / "Which version would you rather experience? 👇">
Follow (@onlyfactsci on IG) for a new mind-bending science fact every day 🚀
#<topic> #<topic2> #space #science #universe #astronomy #spacefacts #shorts|#reels
5. Post on YouTube Shorts (Claude in Chrome)
- Load the chrome-browser skill. Run
tabs_context_mcp, then open a new tab. - Go to
https://studio.youtube.com/channel/<CHANNEL_ID>/videos/upload?d=ud. The channel ID is in the Studio URL after sign-in. - Attach the file:
- Try
find"file-input" first, thenfile_uploadwith the device path. - Known limitation:
file_uploadoften refuses files in the user's connected folders ("only files this session is allowed to read"). Don't retry more than once. Ask the user to click Select files and pickupload-ready/<file>.mp4. Never click Select files yourself, because it opens a native dialog you can't see.
- Try
- Details:
- Title field: click it,
ctrl+a, then type. - Description: click, then type.
- Typing a
#tagopens a suggestion dropdown. Close it by clicking an empty part of the dialog, not with Escape. - Audience: use
findfor "No, it's not made for kids", thenscroll_toand click it. - Thumbnail: the user clicks Upload file under Thumbnail and picks the cover. Studio does accept custom Short thumbnails.
- Title field: click it,
- Click Next three times (Video elements, then Checks, then Visibility). Select Public, then Publish.
- Verify: open
/videos/shortand runget_page_text. The new title should show Public and Published.
6. Post on Instagram Reels (Claude in Chrome)
- Open
https://www.instagram.com/. Dismiss "Turn on notifications" with Not Now. - Click Create in the sidebar, then Post.
- The user clicks Select from computer and picks the MP4. Same file-picker limitation as YouTube.
- Crop step: Instagram defaults to 1:1, which crops the video to a square.
- Click the crop icon at the bottom-left of the preview and choose Original.
- Check that the preview is tall (9:16), then click Next.
- Edit step: the user clicks Select From Computer next to "Cover photo" and picks the cover PNG.
- Check that the cover matches the video. Play the preview and compare the content and trim length (for example 55 s for Fermi, 47 s for the black hole). Users easily pick the wrong cover.
- Click Next.
- Caption step:
- Click the caption box and type the caption.
- End with a trailing space so the hashtag dropdown closes.
- Leave "Share to Facebook" off unless the user asks for it.
- Click Share. Use
findfor "Share button in New reel dialog header" and click by ref, because coordinates drift when the dialog resizes. - Wait until "Your reel has been shared." appears (20–40 s), then click Done.
7. Profile & branding (when asked)
python3 scripts/brand_assets.py --outdir <dir>writes:onlyscifacts-profile-picture.png: 1024², a black hole with an orange ring;onlyscifacts-youtube-banner.png: 2560×1440, with the text inside the 1546×423 safe area.
- Instagram:
- Bio:
instagram.com/accounts/edit/, then Submit. - Name:
accountscenter.instagram.com/profiles/, then the account, then Name, then Done. It can only change twice in 14 days. - Picture: Accounts Centre, then Profile picture, then Upload new photo. The user picks the file.
- Bio:
- YouTube: go to
studio.youtube.com/channel/<ID>/editing/profile.- Description: type it in.
- Picture: Change. Banner: Upload. The user picks both files.
- Click Publish.
- The channel name can only change twice in 14 days. Ask before renaming.
- Always show the user the bio and description text and get a yes before saving. Profile changes are public.
Rules
- Posting is public and hard to undo. Only post what the user asked for. Confirm anything outside the request first, such as editing an older post, archiving posts or renaming the channel.
- Never enter passwords. If a site asks to sign in, the user does it.
- Report what went live with its title and visibility. Mention anything left for the user, such as a file pick.