Skip to main content

motion-broll

Turn a talking-head video and its transcript into motion-graphic B-roll timed to the speaker's words, in a continuous one-shape style (one element that morphs and never cuts, driven by a cursor, spring motion). Use when someone gives a video (and ideally a transcript) and asks for motion graphics, B-roll, animated cutaways or overlays.

ソース情報

リポジトリ
Barty-Bart/motion-graphics
ソースの最終更新活動
2026年10月12日 08:48
検出された SKILL.md の言語
英語
スター
680
フォーク
118

インストール方法

デフォルトでは、最初にソースを確認する Prompt が選択されています。直接コマンドに切り替えるか、ローカルコピーをダウンロードすることもできます。

ソースファイルを確認

インストールを決める前に、SKILL.md と SkillsMP に表示されている付属ファイルをお読みください。

ファイルエクスプローラー
25 ファイル

SKILL.md を表示中

SKILL.md
ソースの指示 · 読み取り専用プレビュー
name
motion-broll
description
Turn a talking-head video and its transcript into motion-graphic B-roll timed to the speaker's words, in a continuous one-shape style (one element that morphs and never cuts, driven by a cursor, spring motion). Use when someone gives a video (and ideally a transcript) and asks for motion graphics, B-roll, animated cutaways or overlays.
# Motion B-roll You make motion-graphic clips for a creator's video. Every clip is **one shape that never cuts**: it morphs its size, corners and colour from state to state while its content swaps with a short blur. A cursor drives the changes with real clicks and drags, and every change lands on a spoken word. The output is a set of clips the creator drops into their editor. You also give them a preview render of their video with the clips cut in, and two HTML pages: one to step through the clips, one to compare before and after. Everything you need is in this skill folder: - `engine/`: the motion engine (`motion.js`), the page shell (`base.css`), `build.py` (clip → self-contained HTML), `render.js` (frame-by-frame render with motion blur), `beats.js` (contact sheets of stills), fonts (Geist, OFL). - `scripts/`: `setup.sh`, `inspect_video.py`, `words.py`, `composite.py`, `make_pages.py`. - `reference/engine-api.md`: how to write a clip. **Read it before writing your first clip.** - `examples/opus-aoe2/`: six finished clips for a real 54-second video. Use them as the quality bar and as starting points. Below, `$SKILL` means this skill's folder. Work in a `motion/` folder in the user's project. ## 1. Set up (first run only) ```bash bash $SKILL/scripts/setup.sh ./motion ``` This checks for Node, Python 3 and ffmpeg, and installs Playwright + Chromium into `motion/node_modules`. Run every engine script with `NODE_PATH=./motion/node_modules`. ## 2. Interview Use the AskUserQuestion tool; keep it to one round. You need: - **The video.** A path. Copy or reference it as `motion/work/source.*`. - **The transcript.** An SRT or VTT with timestamps is best. With plain text only, get word timestamps from the audio (`pip install faster-whisper`) or ask for an SRT. - **Density:** - Light: 2–4 clips per minute, only the strongest moments. - Medium (default): 4–7 per minute. - Heavy: most lines covered, with short gaps of face. - **Look:** - The default palette: warm gray canvas, black and white components, one orange accent. - Or their brand: colours, and optionally a font. Ask them to drop a logo, screenshots or brand colours into `motion/inputs/`, and read those. - **Anything to avoid or include.** Lines to leave on their face, real numbers or names to show, product screenshots to recreate. Skip any question the user already answered. ## 3. Inspect the footage ```bash python3 $SKILL/scripts/inspect_video.py motion/work/source.mp4 motion/work python3 $SKILL/scripts/words.py transcript.srt > motion/work/words.txt # .vtt works too ``` Look at `motion/work/contact.png` yourself. `video.json` gives resolution, fps and layout sections: - **full:** the speaker fills the frame. - **pip:** the speaker is in a box and the rest is empty. It includes the box position and a warning if the box changes size or moves. - **black:** the whole frame is black (a fade, intro or outro). Clips must match the video's resolution and fps. Word times from an SRT or VTT are estimates (±0.2s); treat them as such. ## 4. Plan, and get approval before any code Show a table with one row per clip: | # | In–Out | The line it covers | What the shape does, on which words | Treatment | Why | **Creative direction: decide how much of the frame each clip takes.** This is the most important call; make it per clip and give the reason. - **Full-frame cutaway.** The frame is all speaker, and the line describes something to *see*: a product, a process, a comparison, a number, a chapter change. - Cut away for the length of the idea (3–10s), then give the face back. - Don't cut away in the first second of the hook or on personal, emotional or opinion lines. - Leave at least ~2s of face between cutaways. - **Panel in the empty space.** The edit already leaves room: a PiP box, a split, a plain region. - Render a transparent clip (`bg:null`) centred in the empty area, sized to stay clear of the speaker's box at every moment. - It can run long (15s+) as one continuous morph, because the speaker stays on screen. - If `inspect_video.py` reports the box changing, ask whether that's intended, then size for the largest box or split the panel at the change. - **Nothing.** The line is about the speaker, or it's too close to another clip. **Content rules:** - Show the subject's real objects: the folder, the terminal, the file, the product, the result. Pull them from the words. Map each idea onto an interaction from the vocabulary in `reference/engine-api.md` (pill + click, progress, check, status island, card with a drag, slider, toggle, tabs, chart + tooltip, search/filter, file drag-and-drop, terminal typing, side-by-side comparison, chapter card). - **Never invent numbers, quotes, prices or results.** Use relative bars, skeleton text lines or labels taken from the transcript, and list what is illustrative. Put real figures in only when the user gives them. - One idea per clip. A continuous stretch (a whole PiP section) can be one long clip with several states. - Pace to speech, not music: one change per spoken beat, about 0.4–1.2s apart. Wait for the user to approve or edit the plan. ## 5. Build Write one fragment per clip in `motion/clips/NN-name.html`, following `reference/engine-api.md` and the examples. Then build: ```bash python3 $SKILL/engine/build.py motion/dist motion/clips/*.html ``` Put each state change on its word: clip-local time = word time − clip in-point. ## 6. Check stills on the key words ```bash NODE_PATH=./motion/node_modules node $SKILL/engine/beats.js motion/dist/NN-name.html motion/work/NN.png 0.4 1.2 2.1 … ``` Pick the times where each state has settled and a couple of mid-morph moments. Look at every sheet yourself. Fix anything cramped, clipped, unreadable or off-word, or where the cursor leaves the frame. Then check once more. Panel clips render on black in the sheet so you can judge them. ## 7. Render ```bash NODE_PATH=./motion/node_modules node $SKILL/engine/render.js motion/dist/NN-name.html motion/out/NN-name_0m32s40.mp4 30000/1001 ``` - Use the video's fps. - Panel clips (`bg:null`) must be written to `.mov`, which gives ProRes 4444 with alpha. - Name each file by its timeline in-point (`0m32s40` = 0:32.40). - Rendering takes 4 subframes per frame, so it is slower than real time. Run two clips in parallel on a multi-core machine. ## 8. Deliver Write `motion/plan.json` (schema in `reference/engine-api.md`), then: ```bash python3 $SKILL/scripts/composite.py motion/plan.json motion/out/preview.mp4 python3 $SKILL/scripts/make_pages.py motion/plan.json motion/out/preview.mp4 ``` The user gets, all in `motion/out/`: - the clips - `TIMING.md`: file, in, out, the line it covers, the treatment, and what is illustrative - `preview.mp4`: their video with the clips cut in, hard cuts, original audio - `viewer.html`: step through the clips - `compare.html`: original vs preview, synced, as side by side, stacked or wipe Say plainly that the preview is for review: for the final cut they place the clips in their own editor, where they can nudge timing, add transitions and mix audio. ## Style defaults The user's brand overrides these. - **Colour:** canvas `#E9E7E2`, ink `#0B0B0B`, white components, one accent `#FF5A1F`. Panel clips on dark footage use light shapes (`#F4F2EE`). - **Type and icons:** Geist for UI text, Geist Mono for code, file names and terminals. One icon set with one stroke weight (`M.icon`). - **Motion:** springs with a tiny overshoot at most. Leading and trailing edges ride different springs so indicators stretch. The camera zooms so each state fills the frame. - **Banned:** bouncy easing, particles, glows, gradients on UI chrome, mixed icon strokes, dead time, anything that looks like a template, made-up data. ## Gotchas - Never put `will-change` on anything the camera scales; text renders blurry. - Text swapping inside a morphing container needs its own enter and exit timing (`M.vis` din/lin/lout), or the old and new text overlap. - `mix-blend-mode: difference` labels must sit in a layer that has the blend mode itself. A filtered parent isolates them. - Items that slide under a highlight need `M.FAST` springs, or the highlight row sits empty for a moment. - Keep the cursor inside the frame at every camera zoom, including during morphs. - Word estimates from an SRT drift within a cue; put important changes on the first or last word of a cue when you can. - A clip ends by holding its last state; the composite holds the last frame if its slot is longer.
GitHubで見る