Skip to main content

motion-reel

Make motion-graphics videos rendered entirely from code — product ads, brand promos, launch videos, showreels, animated explainers, 抖音/视频号/小红书 竖屏广告, 宣传片, 片头, 动态海报视频 — with original beat-synced music, exported as MP4 in 9:16, 1:1 and 16:9 from one timeline. Use this whenever the user asks for a 动态视频, 广告视频, 宣传视频, 动效, motion graphics, showreel, promo/launch/ad video, or wants a company, product, PPT, PDF or website turned into a video, even if they don't say "motion" or name this skill. Also use it to revise such a video (change copy, cut a scene, retime, new format). Not for editing camera footage, and not for 硅基废话 whiteboard episodes (use guiji-feihua-video).

Informations de source

Dépôt
10291124jcjc-dotcom/motion-reel
Dernière activité de la source
30 septembre 2026 à 14:16
Langue détectée de SKILL.md
anglais
Étoiles
1
Forks
0

Options d'installation

Le prompt qui vérifie d'abord la source est sélectionné par défaut. Vous pouvez passer à une commande directe ou télécharger une copie locale.

Vérifiez les fichiers source

Lisez SKILL.md et les fichiers associés affichés par SkillsMP avant de décider de l'installer.

Affichage de SKILL.md

SKILL.md
Instructions source · Aperçu en lecture seule
name
motion-reel
description
Make motion-graphics videos rendered entirely from code — product ads, brand promos, launch videos, showreels, animated explainers, 抖音/视频号/小红书 竖屏广告, 宣传片, 片头, 动态海报视频 — with original beat-synced music, exported as MP4 in 9:16, 1:1 and 16:9 from one timeline. Use this whenever the user asks for a 动态视频, 广告视频, 宣传视频, 动效, motion graphics, showreel, promo/launch/ad video, or wants a company, product, PPT, PDF or website turned into a video, even if they don't say "motion" or name this skill. Also use it to revise such a video (change copy, cut a scene, retime, new format). Not for editing camera footage, and not for 硅基废话 whiteboard episodes (use guiji-feihua-video).
# Motion reel Videos here are programs: `index.html` draws any frame from a time value, headless Chrome captures every frame, ffmpeg encodes, and a Python synth writes a soundtrack on the same timeline. Because every frame is a pure function of time, any change is an edit plus a re-render, and every format comes from the same code. The prompt is the small part. What makes these videos good is the harness: a real brief, a beat-grid storyboard, springs instead of linear motion, sound on every hit, and looking at your own frames until they are genuinely good. ## Environment Needs Python with `playwright numpy scipy pillow`, ffmpeg on PATH, and Chrome or Edge installed (Playwright launches the installed browser; no download). Check once with `python -c "import playwright, numpy, scipy, PIL"` and `ffmpeg -version`; `pip install` what's missing. On Windows set `PYTHONIOENCODING=utf-8` when a script prints Chinese. Paths below: `<skill>` = this skill's folder. Scripts are copied into each project's `tools/`. ## Workflow ### 1. Gather facts before designing Ask only for what you can't find. Sensible defaults: ads/promos 9:16 vertical first, 20–30 s; showreels / résumé reels 16:9, 15 s (they are watched on a screen, and it is the genre's format); synthesized music; the audience the material implies. - **Source material** (URL, PPT, PDF, notes): extract the real text first (use the pptx/pdf skills; for a site, visit it and capture real screenshots, logo, colors). Pull brand colors and fonts from the material itself. - **Write `docs/brief.md`**: audience, the one message they must remember, CTA/contact, brand look, and a list of every claim you intend to show with where it came from. Never invent numbers, guarantees or contact details — leave a CONFIG slot and tell the user it's empty. - If the ad targets mainland China, read `references/compliance-cn.md` (education, medical and finance ads have hard rules about promising results). ### 2. Storyboard on the beat grid — with energy Default to high energy (炫酷): users compare against a showreel, and a tidy but calm ad reads as a slide deck and gets rejected. Go calm only when the user or the brand clearly asks for it. Two finished projects set the quality bar: `assets/examples/showreel/` (the 15 s showreel, 9:16 + 16:9) and `assets/examples/coffee-hype/` (a 20 s café opening ad). Skim their shotlist and scenes before designing; borrow ideas, but build on the freshly scaffolded engine (the examples carry older engine copies). Read `references/energy.md` and `references/storyboards.md` (the hype cut §7 layers onto any ad pattern), and write `docs/shotlist.md`: time, shot, layers (bg / hero / accents), technique, hit, on-screen text, transition, sound — on a beat grid: 120 BPM (beat = 0.5 s) by default, 128-140 for hype cuts (set the same BPM in `CONFIG.BPM` and audio.py). Hook in the first 2 s, the core message by ~30 % of the runtime, something new every 2–4 s, CTA in the last 3 s. Write copy to the viewer in their own words (for students: "你", offer, 上岸; for parents: 孩子). Share a compact version of the storyboard with the user in your reply; carry on building unless they asked to approve it first or a key fact is missing. ### 3. Scaffold ```bash python <skill>/scripts/new_project.py <project-dir> --dur 26 --title 片名 ``` This creates `index.html` (engine + 3 demo scenes, duration already set), `audio.py`, `tools/`, `docs/`, `CLAUDE.md`. Set the `C` palette and fonts, then replace everything between `SCENES START` and `SCENES END` with your scenes. Write scene code with the Write/Edit tools rather than shell heredocs — long JS in a heredoc breaks on quotes. ### 4. Build the scenes (index.html) The engine already provides: springs (`sp(t,'snappy'|'def'|'heavy'|'playful')` — playful overshoots ≈21 %, leave room; `track()` for values with several targets), easings `E`, text helpers (`slam`, `rise` per-character mask reveal, `T`, colored segments `[['拿到',C.ink],['offer',C.accent]]`, `fit()` to shrink a line to a width), `poly(pts, p)` line-draw reveal, `pop()` scale-pop, `mixHex`, backgrounds, camera shake `IMPACTS`, transitions `TRANS` (cut/push/iris/bars/wipe), motion blur that densifies inside transitions and never crosses a cut, and multi-format layout `L`. Fonts: `F_CJK` (Noto Sans SC), `F_SER` (Noto Serif SC, for food/culture/editorial brands — add it to `FONT_FAMILIES`/`FONTS_TO_LOAD`), `F_LAT` (Bahnschrift). render.py warns if a family isn't installed. - The FX library (section 5b) holds the showreel moves — use them, 2–3 per shot: `kine()` six kinetic-type styles (smear/spin/bounce/stroke/glitch/rise), `scramble`, `counter`, `shapePts` + `morphPath` + `trail`, `shockwave`, `sunburst`, `speedLines`, `tunnel(rampZ())`, `ring3D`, `flowField` (beat shockwaves, dots, vortex), `stripes`, `sheen`; `ZOOMS` camera punches next to `IMPACTS` shake; transitions stripes/tear/slice/zoom besides iris/push/bars/wipe/cut; `along()` rides an object on a `poly()` route; `ring3D({occluder})` wraps text around a hero object. - Fill backgrounds with `fillBg()` (overscans the frame) so shake, zoom punches and transitions never expose an edge. Add `{at, type:'cut'}` to `TRANS` for every cut inside a scene (montages). - Scenes are `draw(t)` with **global** time; list them in `SCENES` and their boundaries in `TRANS`. - Size everything in `L.u` and place relative to `L.cx`, `L.cy`, `L.safe` so 1:1 and 16:9 work. Keep key content inside `L.safe` (vertical apps cover the top and bottom). - The incoming scene must already be animating while its transition plays — otherwise the transition reveals an empty frame. - Avoid the AI-video look: centered title on a gradient, everything fading in, corner labels and frame borders, glow, generic particles. One accent color. Big type with real hierarchy. - Keep it deterministic: no `Math.random`, timers or carried state (use `hr(n)`). ### 5. Look at it (critique loop) Read `references/critique.md`. Render one still per beat plus every transition, make contact sheets, and actually open and look at every page: ```bash python tools/render.py --every 0.5 --trans # out/stills_9x16/ and out/trans_9x16/ python tools/check.py sheet out/stills_9x16 # paged, 12 frames per page python tools/check.py sheet out/trans_9x16 python tools/render.py --stills 3.2,3.4 --noblur # sharp frames when judging a collision ``` Score the 8 criteria (energy included), fix the three worst problems, repeat until all are 8+. Check other formats with `--fmt all --every 1` if they're being delivered. ### 6. Score the soundtrack (audio.py) List every visual event with its time (slams, transitions, impacts, list items, the logo) and give each a sound. Shape sections with the story: sparse/minor under the problem, riser into the turn, drop to a bright major progression on the core message, resolve on the end card. `audio_lib.py` has kick/clap/hat/snare/tick, pluck/bell/piano/pad/bass, blip/buzz/coin/whoosh/riser/impact/glitch, and a `Mixer` with sidechain and reverb. The mix is normalized to its loudest peak, so a quiet section needs noticeably bigger gains. Verify with `python tools/check.py sections soundtrack.wav` (RMS per 0.5 s; flags dead patches — the hook must never be one) and `check.py spec`. ### 7. Render, finish, verify ```bash python audio.py python tools/render.py --fmt 9x16 # or all; ~25 s per 6 s of 1080p60 on a laptop python tools/finish.py --name 片名 # -14 LUFS two-pass loudnorm, grain, yuv420p python tools/check.py at out/片名_9x16.mp4 <every cut and transition time> python tools/check.py phone out/片名_9x16.mp4 python tools/check.py motion out/片名_9x16.mp4 # energy: median ≥ 3, still ≤ 15 %, no still ≥ 0.6 s ``` If `motion` is below target, fix the flagged stretches (background motion, pulses, earlier cuts) and re-render — that number is how the user's "不炫酷" shows up in data. Run long renders in the background and do the audio or checks meanwhile. ### 8. Deliver Send the MP4 (SendUserFile when available). Reply with: a short scene/time table, what the music does, claims or placeholders the user must confirm (contact info, prices, promises vs. contract), and the one command to re-render. Delete bulky intermediates (stills/trans/picks folders, frames_*.mp4) but keep `index.html`, `audio.py`, `tools/`, `docs/`, `soundtrack.wav` and the final check sheets in `out/check/` so edits stay cheap and the review is traceable. ## Revisions Users usually come back with copy changes, a removed scene, or a new length. - **Copy/number change**: edit the strings everywhere they appear (grep the old text), re-check the affected stills, full render, finish. Overwrite the delivered file and remove superseded versions so the wrong one can't be posted. - **Remove a scene** (e.g. 21–25 s): don't retime everything. Remap time in the engine (`const story = t => t >= 21 ? t + 4 : t;`), replace the two transitions around it with one, shorten `DUR`, and in audio.py delete that section and set `mix.shift = -4` before the later sections. - **Removing a disclaimer the user asked to drop**: do it, then say in one line what that changes for compliance and where the condition still appears. ## Lessons that cost a re-render - Motion blur across a hard cut makes a ghosted double frame → cuts go in `TRANS` as `type:'cut'`. - Very fast push/iris with 5 blur samples shows stepped copies or a grey wash → the engine raises samples inside transitions; also prefer `inOutCubic` over `inOutExpo` for big moves. - In a panel push, both panels must move together (in and out centred on the same boundary). - White flashes over dark scenes look muddy grey; use 2–4 frames and rarely. - Load every font weight before capture (render.py does it via `META.FONTS`); CJK default is Noto Sans SC (free for commercial use), Latin display Bahnschrift. - Stamps, badges and docked headlines collide easily — check the frames where things move into place. - Things entering from off-screen can peek into the frame during a neighbouring transition; pop them in by scale at their resting place instead of flying them long distances. - Iris edge rings and glows smear into a muddy halo under the transition blur; prefer a clean edge. - A hard cut must land on a frame that already has content — start the next scene 0.1–0.2 s early. - Offsets like `L.cy - 380 * U` are sized for a 1920-tall frame and fall off a 1080-tall one. Give stacked shots a landscape branch from the start (`const LAND = !L.vert`; word left at `W*.29`, demo right at `W*.68`) so a later "also give me 16:9" is a re-render, not a rewrite.
Voir sur GitHub