SuperAPI AI Directory

motion-explainer-video

Design & creation

View repository

Updated 10-20 00:56

About this skill

Motion explainer (enhanced video) — animation explains the principles, photos serve as evidence, AI video brings emotion

This skill strings together "research online → write script → Chinese voiceover → build animation frame by frame → subtitles → color scheme → find licensed photos, generate diagrams → generate AI video → self-review → output MP4" into a fixed pipeline. Compared with the basic version motion-explainer , it adds Section 7.5'simage layer, Section 7.6's AI video layer, and Section 4'sfix mispronounced characters; all other steps are identical.Video materials are mainly AI-generated: news clips, promotional videos, and stock footage are almost all copyrighted, so they are not edited into teaching videos. It stands on the shoulders of three things:

  • HyperFrames(open-sourced by HeyGen, HTML + GSAP output to MP4) and its official skills, especially the /hyperframes entry point and the /faceless-explainer workflow.Follow the official approach.
  • This repo's motion-design(taste rules: easing, pacing, holds, Chinese typography) and review-loop(contact sheet self-review).These two are the standard for whether it looks good.
  • This folder's scripts/ tools: they fill in the Chinese voiceover, subtitles, font consistency, and three-color theme that the official flow doesn't handle well.

references/lessons.md covers pitfalls hit in real projects,required reading before starting work, and every one of them actually happened in the first video.

Path aliases: the commands below are all run inside the project folder, and tools refer to the skill folder by alias. Before starting, locate the actual paths:

Alias What it is Common location
<me> This skill's folder ~/.claude/skills/motion-explainer-video(Claude Code)、~/.agents/skills/motion-explainer-video(Codex)
<fe> HyperFrames official faceless-explainer skill hyperframes skills update faceless-explainer where it is installed, usually ~/.agents/skills/faceless-explainer or ~/.claude/skills/faceless-explainer
<review-loop> This repo's review-loop skill alongside <me> in the same skills folder
ls -d ~/.claude/skills/{motion-explainer-video,faceless-explainer,review-loop} ~/.agents/skills/{motion-explainer-video,faceless-explainer,review-loop} 2>/dev/null

PowerShell (when Windows has no bash):

Get-ChildItem "$HOME\.claude\skills","$HOME\.agents\skills" -Directory -ErrorAction SilentlyContinue | Select-Object FullName

Other agents (e.g. Gemini CLI): look for a folder of the same name in its skills folder.

Agents without sub-agents(some Codex and Gemini setups) can also run the whole flow: Section 6's "assign one sub-agent per frame" becomes doing one frame at a time in order yourself, with the same files read in the same order for each frame. All other steps are ordinary terminal commands.

0. Environment check (first time use)

  • First run python <me>/scripts/hw_check.py --project <專案>: it detects CPU, memory, GPU, and disk, and recommends which voiceover engine to use, what to set--workers to, and whether to dispatch sub-agents in batches. Tell the user according to the notes in references/hardware.md ; those recommendations are estimates, not benchmarks.
  • Node.js 22+、ffmpeg/ffprobe、Python 3 + Pillow + fonttools(pip install pillow fonttools; if brotli fonts are installed it outputs woff2, otherwise it outputs ttf).
  • HyperFrames CLI:npm install -g hyperframes, then run hyperframes doctor(Docker, Whisper, Kokoro, and MusicGen are all optional).
  • Official skills:hyperframes skills update. To make this kind of video you also need hyperframes skills update faceless-explainer。
  • Anonymous usage statistics are on by default; ask the user whether to hyperframes telemetry disable。
  • TTS (pick one, ask the user):
    • edge-tts (default):pip install edge-tts. No GPU needed, but it requires an internet connection when generating. Taiwanese accents include zh-TW-HsiaoChenNeural(female),zh-TW-HsiaoYuNeural(female),zh-TW-YunJheNeural(male).
    • Breeze TTS 2 (advanced): local NVIDIA GPU (about 7.7 GB VRAM, 12 GB or more recommended; model file is about 7 GB). You can design a voice with a text description, then do voice cloning, with the finest control over accent and emotion.
    • Other engines also work: as long as they can output for each sentence assets/voice/raw/NN.wav. For English videos you can use the built-in Kokoro/HeyGen in HyperFrames.

1. Research (when web search is available)

  • Search for the latest information on the topic, with at least two independent sources. Write down anywhere the numbers don't match, and use the one the sources agree on.
  • Put every number into one of three categories, and label them on screen later:Official claims/Measured or reported/Own estimates。
  • Do simple physics or math estimates yourself so viewers can "work it out"—that is the most valuable part of a teaching video. Always check estimates against reality (e.g., "a normal car does at most 1.2 g" is overturned by a production car doing 0–100 in 1.8 s, so change it to 1.5 g).
  • Do not use brand photos or logos; use your own drawn diagrams for the subject, labeled "illustration".
  • Note image leads while researching: whether there are "precedents", "old-timers", or "experiment photos" that can serve as evidence (e.g., historical NASA photos, similar products that already exist)—these are the real photos to find in Section 7.5.

2. Requirements interview (follow /hyperframes 's intent layer, ask everything at once)

Must confirm: playback platform (determines aspect ratio: class/YouTube → 16:9), length (60–90 seconds recommended; narration length determines actual video length), whether narration is needed (recommended), whether to review the storyboard first, and whether to automate or work together and adjust as you go.

Also ask for three colors(new in this skill), like a presentation template:

  • background color、primary color(text and line art),accent color(only for answers, conclusions, key numbers, chapter cards).
  • If no preference, recommend: black background #121212, white text #F2F0EA, orange accent #FF7A1A。
  • Font: use one font throughout the whole video. The default isGenSeki Gothic Bold(OFL licensed; use it for Chinese, English, numbers, and subtitles). If the user specifies a font, switch to it, but confirm that font can be used freely.
  • Write the colors and font into the project's theme.json(example <me>/templates/theme.example.json; for the meaning of each field and how to fill in source , see references/theme-json.md)。

Compile into a requirements summary, split into "user answers" and "my inferences" sections, and start only after the user confirms.

3. Create project and storyboard

  1. hyperframes init videos/<kebab-name> --non-interactive --example=blank --skill=faceless-explainer, then write BRIEF.md, then follow /faceless-explainer 's Step 0–2 (capture/extracted/, choose a frame preset to generate frame.md)。
  2. When choosing a preset, prefer one with clear line art(for example cobalt-grid). It is only the "source color scheme"; in the end it will be replaced by theme.py with the user's three colors.
  3. In frame.md add Traditional Chinese overrides(font, font weight, letter spacing, line height, minimum projector font size); for the content, follow motion-design section 5.
  4. Run bash <me>/scripts/fetch_fonts.sh <project>, and put the Source Han Sans Bold (downloaded from the official GitHub release), the Latin font used when the frame worker was made, and Noto TC all into assets/fonts/,do not rely on Google Fonts online loading。
  5. Write STORYBOARD.md and SCRIPT.md(for the format, follow the official storyboard-format / script-format). Narration must besplit by "clause", each comma is a point in time for revealing a frame; write numbers as Chinese characters ("zero point eight one seconds"), so TTS will not read them wrong.

4. Narration

  1. Generate assets/voice/raw/NN.wav(one file per sentence, NN is the storyboard frame number):
    • edge-tts:python <me>/scripts/edge_tts_voice.py --project <p> --voice zh-TW-HsiaoChenNeural [--rate=-5%]. The whole film uses the same voice, so the sound is naturally consistent;--list zh-TW can list all voices.
    • Breeze TTS 2:python <me>/scripts/breeze_voice.py --project <p> --breeze-repo … --model … --voice "<聲音描述>" --only-ref, first designonereference voice for the user to listen to, and after confirmation remove --only-ref to generate all sentences (each sentence copies this reference voice). If there is a batch runner, use <me>/scripts/tts_jobs.py to generate the work list.
    • The user has not installed it yet, or is not sure which one to choose: follow references/tts-setup.md for suggestions, confirm step by step, and do not install on your own.
  2. First let the user preview the first one or two sentences; the accent and emotion are decided by the user by ear, not replaced by a score. If unsatisfied, change to another voice or adjust the speech rate, delete the old WAVs, and regenerate.
    • Discovering a mispronounced character only after the whole film is done(for example an English brand name, or a heteronym): do not re-record the whole sentence, otherwise the animation timing of that frame will be completely thrown off. Instead: with the same voice, generate 4–6 candidates for the same sentence; you can change the seed, or change the spelling, for example Road-ster or characters with the same sound and tone; the subtitles still use the original text; put them in assets/voice/fix/cand/NN_X.wav. edge-tts has no seed, so use spelling,--rate、--pitch to create differences:python <me>/scripts/edge_tts_voice.py --project . --line N [--text "<換拼法的整句>"] [--rate=-3%] --out assets/voice/fix/cand/NN_B.wav; Breeze changes the seed and regenerates the same sentence. Then run python <me>/scripts/fix_voice.py --project . audition --line N --clauses <那個詞所在的子句>, string the key segments into one preview file for the user to choose by ear. After choosing, run apply --line N --take NN_X, which will take the new sentenceproportionally stretch the whole sentence back to the original length, align the volume to the original sentence, then recalculate the subtitle timing of that sentence, with each frame's length unchanged. Then rebuild subtitles → patch_captions.py → theme.py(it will automatically recognize the new subtitles) → place_media.py → re-export.Do not split the re-recorded sentence into clauses by pauses and then align the timing: the pauses in the re-recording are in different places, so the split points will fall in the middle of characters, resulting in missing or repeated characters (this has actually happened). ASR can only be used to filter out obviously wrong ones; whether the tone is correct cannot be heard by ASR (real example: ASR judged "輪胎" as correct, but it sounded wrong to the user).
  3. python <me>/scripts/voice_meta.py --project <p>: trim leading and trailing silence, measure the timing of each clause, write audio_meta.json。
  4. node <fe>/scripts/audio.mjs sync-durations --audio-meta ./audio_meta.json --storyboard ./STORYBOARD.md
  5. Loudness: the final film should be about −14 LUFS, true peak ≤ −1 dBFS. First measure the final film:ffmpeg -hide_banner -nostats -i renders/video.mp4 -af ebur128=peak=true -f null -, look at Integrated loudness(I). Whatever the difference is (G = −14 − I), thenEvery narration sentenceThen apply the same G dB and compress the peaks, preserving the relative volume between sentences, and re-export:
    for f in assets/voice/[0-9]*.wav; do ffmpeg -v error -y -i "$f" -af "volume=${G}dB,alimiter=limit=0.89" "${f%.wav}.tmp.wav" && mv "${f%.wav}.tmp.wav" "$f"; done
    

5. Shot design (Step 4)

  • In shots.json(see <me>/templates/shots.example.json), write each frame as “which clause → what appears on screen”, run python <me>/scripts/apply_shots.py --project <p> to convert to real seconds, and write it back to STORYBOARD.md。
  • blueprint The field can only be <id> (Adapt)、<id> (Reproduce) or compose; put the explanation separately in note。
  • First use hyperframes catalog --query to find existing components; if none, draw it yourself.
  • For a protagonist that appears repeatedly across multiple frames (car, person, instrument), first draw it as one shared SVG, fix the coordinates of each part, and all workers must copy it exactly. Otherwise, the protagonist will look different in every frame.

6. Work on each frame in parallel

  1. node <fe>/scripts/frame-packets.mjs --project <p> --storyboard <p>/STORYBOARD.md
  2. From <me>/templates/dispatch_context.md copy one to .hyperframes/frame-packets/_dispatch_context.md, and fill in the project values: Video direction, shared assets, timing rules, fonts.
  3. Assign one sub-agent per frame, all in parallel. The prompt reads in order:_role.md → _dispatch_context.md → that frame's packet → frame.md → shared assets.When there are no sub-agents, do them yourself one frame at a time in frame-number order, reading these files in the same order for each frame; after finishing a frame, take a few screenshots to confirm before moving to the next.
  4. When adjacent frames must continue the same visual(for example, the same scale ruler), the exact geometry reported by the frame that finishes first must be passed immediately to the frame still in progress.
  5. After everything comes back:python <me>/scripts/unify_frames.py --project <p>, unify the font and hairline positions.

7. Assembly, subtitles, color scheme

node <fe>/scripts/captions.mjs build --storyboard ./STORYBOARD.md --audio-meta ./audio_meta.json --hyperframes . --out ./caption_groups.json
node <fe>/scripts/assemble-index.mjs --storyboard ./STORYBOARD.md --hyperframes .   # 要在字幕之後:輸出要看到 captions (track 2): yes
python <me>/scripts/patch_captions.py --project .     # 中文字幕字型與粗細(預設粗體 700)
python <me>/scripts/theme.py --project .              # 套用 theme.json 的三色與字型(index、每一格、字幕)
node <fe>/scripts/transitions.mjs inject --storyboard ./STORYBOARD.md --hyperframes .
node <fe>/scripts/transitions.mjs verify --storyboard ./STORYBOARD.md --index ./index.html
hyperframes lint && hyperframes check

(<fe> = the installed faceless-explainer skill folder.) After every subtitle rebuild, rerun patch_captions.py and then run theme.py。theme.json of accents to specify which elements in each frame use the accent color (block/fill/text/stroke).theme.py will automatically recognize regenerated files (those without the (theme.py) marker) and use them as the new source files; but when manually editing a file that already has the color scheme applied,.hyperframes/pre-theme/ the copy in there must be changed as well.transitions.mjs inject will lengthen each frame: every time theme.py finishes, inject again, but do not inject twice in a row (if theme.py was not run in between, the length will be extended twice);font will change all text in every frame and in the subtitles to the same font and weight, overriding the font settings originally written by workers. After changing the font, the text becomes wider, so rerun hyperframes check to check for overflow or overlap.

Only slim the font as the last step:python <me>/scripts/subset_fonts.py --project .. It keeps only the Chinese characters used in the video (CJK fonts drop from 12–17 MB to a few hundred KB), and changes each frame's @font-face to point to the slimmed file. After any action that changes text, subtitles, or color scheme, rerun:theme.py Each time, reapply the color scheme from the pre-color source file; the source file points to the full font, so newly added characters that are not in the slimmed file will fall back to the system font.

7.5 Image layer (added by this skill)

See references/images.mdfor the full rules. Key points:

  1. Planning: 3–5 per video. Use real photos asevidence cards(“someone really did this”), and Codex-generated images as the opening and closingatmosphere backgrounds. The animation is the main subject; images must not steal the principle being explained by the line art.
  2. Find photos:python <me>/scripts/find_images.py search "<關鍵字>" → get "File:…" --name <短名> --project .. Only accept public domain, CC0, CC BY, CC BY-SA; the source will be automatically written into assets/images/web/CREDITS.md. After downloading, look at them with your own eyes once; passersby, other brands' logos, and watermarks must be cropped out.
  3. Generate illustrative images: write the prompt into gen_prompts.json(see <me>/templates/gen_prompts.example.json), run python <me>/scripts/codex_images.py --project .. Requires a locally logged-in Codex CLI; uses the built-in image_gen, no API key needed. After generating, check with your own eyes whether any text or logos have appeared. If you don't have Codex, tell the user they can use another image-generation tool and put the PNG into assets/images/gen/。
  4. Color grading: in media.json write the crop, size, and mode for each image (photos use duotone, generated images use keep), run python <me>/scripts/treat_images.py --project .。
  5. Placement: first look at the contact sheet after each cell is placed, find areas that are truly empty, and in media.json 's placements write frame、mode(card/background)、box、at、label、credit. To replace the original line art with a photo, use hide. Then after theme.py afterwardsrun python <me>/scripts/place_media.py --project .。
  6. On-screen labels: photos say "Photo: author · license · source", generated images say "AI-generated illustrative image".
  7. Run hyperframes check(text contrast and overlap on photos), and only then run subset_fonts.py, because captions and sources also contain text.

7.6 AI video layer (new in this skill, optional)

Full rules in references/ai-video.md. This layer requires an environment that can run MiniMax H3 (a local NVIDIA GPU with about 26 GB of VRAM + ComfyUI, or another service that provides H3).If you don't have one, the whole video can still be completed, choose a fallback, and tell the user in the requirements summary:

  • Prompt only: follow steps 3–4 below to generate prompt.txt and the first-frame image, hand them to the user to generate somewhere themselves, put them back into assets/videos/gen/<name>/clip.mp4 and continue.
  • Use a still image instead: use the same Codex image as background or card and put it in (formedia.json use image instead of video), and label the frame "AI-generated illustrative image".
  • No video: use only animation and photos.

Key points:

  1. Planning: 2–4 segments per video. Use them for the opening hook, an action that can't be filmed but lines up exactly with the narration (e.g., "only one jump" → the car landing), and the closing emotion. Shots that need precise numbers or force directions still go to line art.
  2. Use a Codex still image for the first frame: first generate an image matching the theme's color palette as in section 7.5, then have H3 animate from this image, so the video and the film's style stay consistent.
  3. Write the spec:assets/videos/gen/specs/<name>.json(examples in templates/video-specs/). Each segment 4–15 seconds; write the subject as "no brands, no text", write the action as one clear event, and add camera movement and sound descriptions.
  4. Generate:python <me>/scripts/ai_video.py prompt --project .(official six-segment format) → run(requires the video_config.json runner: copy <me>/templates/video_config.example.json into the project; by default it calls the reference runner <me>/scripts/h3_runner.py; first run h3_runner.py --check to confirm ComfyUI and the models are present. For your own generation method see references/ai-video.md 's "runner spec"). If there is no runner, give the user prompt.txt and the first frame, and ask them to generate it using ComfyUI's official MiniMax H3 R2V template, saving it as assets/videos/gen/<name>/clip.mp4。
  5. Check:python <me>/scripts/ai_video.py check --project .,every check-1.png must be viewed with your own eyes: whether there is any distortion, extra parts, text or logos, and whether the timing of the action matches the narration. If it fails, change the seed and rerun.
  6. Placement: in media.json 's placements use "video": "assets/videos/gen/<name>/clip.mp4", add duration, and if necessary add out(fade the card out before the video ends). After theme.py run place_media.py, then hyperframes lint(the video must have an id and must not be placed inside an element with a timer) and hyperframes check。
  7. Label the footage "AI-generated video (H3)"; the video must always be muted, and the only audio should be the narration.

8. Review (review-loop)

  • First hyperframes check, then output the whole video at draft quality (hyperframes render --quality draft --workers <hw_check 建議值> --output renders/draft.mp4; always use draft during the review stage), and at0.15 seconds before the end of each clausecapture a frame (taking the settled state) and assemble them into a contact sheet;every single one must be opened and viewed with your own eyes:
    python <review-loop>/scripts/sheet.py --video renders/draft.mp4 --at "$(python <me>/scripts/review_times.py --project .)" --out review --name draft
    
  • Check item by item against references/lessons.md 's checklist, and after fixing, re-output and re-view until a full round has no issues.
  • Only after viewing, output the final version:hyperframes render --skill=faceless-explainer --quality high --output renders/video.mp4, then measure the loudness again.

9. Delivery

Hand over the MP4 path, duration, and an overview contact sheet, and list: which sources were used, which numbers are claims, which are estimates, where it differs from the requirements (e.g. duration overrun), and what was not done (e.g. no music).

Also hand over aasset source list(can be pasted directly into the video description):assets/images/web/CREDITS.md for every photo (author, license and license URL, "cropped, color-graded"); every AI-generated image and every AI video segment (what tool was used, which file the prompt is stored in:assets/images/gen/codex_prompt.txt、assets/videos/gen/<name>/prompt.txt)。