Overview
Input a concept (e.g. "sound phenomena") → two dynamic outputs,both are MP4s rendered by HyperFrames, sharing the same index.html:
| Output | Spec | Use |
|---|---|---|
| Narrated video | 1080p, ~90s, Chinese narration + subtitles | Full explanation, post to video channels / show to kids |
| Silent animation | 1080p, ~32s, silent, looping | Auto-plays embedded in official account article body |
Key: both outputsshare the same index.html, switched via the HyperFrames variable mode(video/silent)——
build the content once, and both can be produced. Silent mode has a compact timeline, no subtitles, no fade-out (seamless loop), and the quality and motion effects
are exactly the same as the video version.
Shared: 7-segment structure (1 title + 5 sub-concepts + 1 summary),the same set of theme colors
(references/color-palettes.md)、the same storyboard script (references/storyboard-guide.md)。
Trigger routing
| User says | What to do |
|---|---|
| "teaching video" / "narration" / "narrated version" | Build index.html → build_video.sh |
| "teaching animation" / "silent" / "loop" / "embedded in official account" | Build index.html → build_silent.sh |
| "I want both the video and the animation" | Build index.html once, run both scripts |
When unsure, first ask clearly about the concept + applicable grade level (default: 8th-grade physics), don't ask anything else.
Unified flow (both outputs share the first 4 steps)
# 第 0 步: 写分镜 (见 references/storyboard-guide.md)
# 把概念拆成 7 段, 写 storyboard.json: 每段 title / narration (旁白 30-50 字, 口语化,
# 不读公式) / visual (画面描述) / transition。配色按主题族选 (color-palettes.md)。
# 拆解质量决定一切 — 对照教材知识点, 参考 examples/sound-video/storyboard.json。
# 1. TTS 配音 (需要 MINIMAX_API_KEY; 无 key 时 --provider say 走通预览)
export MINIMAX_API_KEY=... # 可选: MINIMAX_GROUP_ID / MINIMAX_API_HOST / MINIMAX_TTS_MODEL
python3 scripts/minimax_tts.py storyboard.json --outdir audio/
# → audio/seg-0N.mp3 + audio/durations.json (时间轴来源, 无声版也需要它做骨架)
# 2. 生成骨架 (时间轴/配色/audio/SEGMENTS/silent机制 全部自动填好, 不要手搭)
python3 scripts/scaffold_video.py <project_dir>
# 3. 填场景内容: s2-s6 的 SVG 示意图 (零件拷 references/svg-parts.md) + 卡片文案
# + scene2()-scene6() 入场编排。规则见 references/video-authoring.md
# 4. 出片 (二选一或都要):
bash scripts/build_video.sh <project_dir> # → 配音视频 renders/<name>.mp4
bash scripts/build_silent.sh <project_dir> # → 无声动图 renders/<name>-silent.mp4
build_video.sh: lint + WCAG contrast audit + render (video mode) + scene midpoint montage.
build_silent.sh: temporarily change data-duration + render (silent mode, compact 32s silent) + montage.
Both scripts read the same index.html, only the rendered mode variable differs.
After changing the voice/timbre or narration and rerunning TTS, use python3 scripts/sync_timeline.py <project_dir> to sync
the timeline (don't copy the numbers by hand), then re-render.
Scene content standard: section-chip + SVG diagram (≥3 graphic elements) + info-card + callout.
Video size specs, SVG drawing methods, motion-effect choreography, the silent mechanism, and measured lint pitfalls are all in references/video-authoring.md。
Environment: Node.js ≥22 + ffmpeg (npx hyperframes doctor self-check); Minimax TTS uses the HTTP API,
no extra Python dependencies.
How silent mode works
index.html the <html> declares the mode variable. At render time --variables '{"mode":"silent"}' switches to the silent version:
- Timeline: each segment is equally long and compact (
SILENT_SEG=4.6s, ~32s total), does not depend on audio length - No subtitles:
MODE !== "silent"only generates subtitles - No fade-out: the last segment does not fade out all the way, loop is seamless from end to start
- All texture and motion effects retained: gradients/grain/waveform flow are all there (MP4 has inter-frame compression, unlike GIF which fears continuous tones and motion)
Why not output GIF? GIF has no inter-frame compression. A complete 7-segment clip at 720p HD will inevitably be >2MB (measured), so it can only be lowered to 480p, and small text becomes blurry. WeChat Official Accounts have long supported embedded MP4 autoplay. A silent MP4 = complete 1080p + 8~10MB, clearer than any GIF. So for animated image output, use silent MP4, not GIF.
Output File Specifications
<topic>/
├── storyboard.json # 分镜 (第 0 步)
├── audio/
│ ├── seg-01..07.mp3 # TTS 分段配音
│ └── durations.json # 时间轴来源
├── index.html # HyperFrames 组合 (video/silent 双模式)
├── renders/
│ ├── <topic>.mp4 # 配音视频 (~90s)
│ └── <topic>-silent.mp4 # 无声循环动图 (~32s)
└── preview/
├── montage.png # 配音视频蒙太奇
└── montage-silent.png # 无声动图蒙太奇
Resources
assets/video-template/index.html— HyperFrames template (components + video/silent dual mode + transitions/subtitles/waveform engine)examples/sound-video/— Complete example of sound phenomena (storyboard → audio → index.html → voiced video + silent animated image)scripts/minimax_tts.py— Minimax segmented voiceover + timelinescripts/scaffold_video.py— Skeleton generation (step 2, including silent mechanism)scripts/sync_timeline.py— Synchronize timeline after re-voicingscripts/build_video.sh— Voiced video rendering (lint + validate + render + montage)scripts/build_silent.sh— Silent looping animated image rendering (silent mode)references/storyboard-guide.md— Storyboard breakdown + narration specifications (mandatory reading for step 0)references/video-authoring.md— Hard rules for scene writing + silent mechanism + tested pitfalls (mandatory reading)references/svg-parts.md— SVG symbol library (electrics/waveforms/graphs/mechanics/optics; come here first to copy when drawing schematic diagrams)references/color-palettes.md— 7 sets of themed palettes (60-30-10 + Morandi, including CSS variables)