Skip to content

feat(newsletter): add motion reels step with setup, renderer and gallery - #174

Open
axsaucedo wants to merge 4 commits into
masterfrom
feat/newsletter-reels
Open

axsaucedo wants to merge 4 commits into
masterfrom
feat/newsletter-reels

Conversation

@axsaucedo

Copy link
Copy Markdown
Collaborator

The newsletter-issue skill can now propose and build motion reels for an issue: one 16:9 main video for the whole issue and optional 4:5 reels for each article post. The tooling that made the issue 408 reels only existed in gitignored scratch under tmp/reels/, so this moves what is needed into the repo and writes the workflow down as a new optional step 9.

The scripts live in scripts/newsletter/reels/. setup.mjs --issue N lays out tmp/issue-N/reels/ with the shared vendor files every reel references, three.js r170 downloaded once, a uv venv for the sound scripts, the review gallery, and links to the procedural audio library of the z-motion-reel skill. That library is found through --audio-lib, then REEL_AUDIO_LIB, then the newest installed skill, the same pattern capture-gifs uses for the site-capture engine, so nothing personal is committed. render.mjs is the scratch renderer with the hardcoded npx path replaced by loadChromium and the scratch-only mp4 guard dropped. The worker briefs are in references/reels.md, one section each so they can be pasted into a brief: shared contract, post brief, issue brief, style menu, sound brief.

Also in here, at the coordinator's request: fetch-images.mjs --apply crashed when a Choice: line pointed at an mp4, because every chosen file went through sharp:

Input file contains unsupported image format

Videos (.mp4, .mov, .webm) now skip sharp and are copied as image<ext>, which buffer-post already treats as video. Reel mp4s are now a normal post choice, so step 9 relies on this.

Verified today (2026-10-11): ran setup for a throwaway issue 999 twice (idempotent), copied the picked 408 Hugging Face reel in, rendered stills at 0 and 5s and looked at them, then a full render that ffprobe reports as 1080x1350, 10.0s, with an audio stream. A headless Playwright check of gallery.html?reels=408s-3a found the iframe and the Sound A/B/C buttons. --apply against a real issue 408 posts.md with an mp4 choice wrote image.mp4. Lint, check:ratchet and check pass.

Weaknesses: the installed z-motion-reel skill keeps score.py under template/, so setup links individual files rather than the directory, and a future layout change in that skill would make setup fail (loudly, which seemed better than guessing). The briefs record no visual style recommendations from the 408 reels, since the owner rated those styles poor, so the style menu is a list of directions and nothing more. I haven't run a fresh end-to-end issue through step 9 with real workers; the cost figure in it ($109 for twelve workers over three rounds) is from the 408 run.

Moves the motion-reel tooling out of gitignored scratch into
scripts/newsletter/reels/: setup.mjs lays out tmp/issue-<N>/reels/ with
the shared vendor files, three.js, a venv and links to the z-motion-reel
audio library (never committed); render.mjs renders a reel frame by frame
to stills or an mp4 with its audio muxed in; gallery.html compares named
reel folders side by side.
A Choice line pointing at an .mp4, .mov or .webm crashed --apply, because
every chosen file went through sharp. Videos are now copied untouched as
image<ext>, which buffer-post.mjs already treats as video.
Shared reel contract, post and issue briefs, style menu and sound brief,
each written to be copied into a worker brief as it stands.
New step 9 proposes reels, runs one durable headless worker per reel,
reviews them live in the gallery, adds sound for the picks and renders
the mp4 for Buffer. Later steps renumbered.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant