1实现原理 · 为什么它能做到
核心主张是重建而非录屏:录屏继承静态外观、鼠标抖动与硬切,重建才拿到帧确定性、可缓动转场、任意分辨率清晰与音频驱动的时长。
A screen-recording inherits the deck's static look, mouse jitter, and abrupt slide cuts. Rebuilding in code (Remotion) buys: per-frame-deterministic reveals, transitions that actually ease, text that stays crisp at any resolution, and slide durations driven by audio length.
叙事优先:先定一句话脊梁,每页只讲一件事,页标题是论断而非标签。
- **One throughline (the spine).** State the deck's single takeaway in one sentence. Every slide must advance that sentence; if a slide doesn't, cut it or move it to an appendix.
唯一铁律:旁白掌控时钟——每页时长=该页音频实测长度+少量 handle,禁止目测。
**Each slide lasts exactly as long as its narration audio, plus a small handle.** Measure every voiceover clip's real duration, convert to frames, and make that the slide's length.
每页音频挂在自己组件内:声画由同一 Sequence 定位,物理上不可能漂移。
Because the audio lives inside the same component that draws the visuals, and both are placed by the sequencer at the same start frame, voice and picture physically cannot drift.
转场帧预算要记账:TransitionSeries 的转场是重叠而非新增时间,会吃掉邻页帧。
A `<TransitionSeries.Transition>` does **not** add time — it overlaps its neighbors, consuming frames from the end of the outgoing slide and the start of the incoming one.
页内 build 揭示要与旁白同步:元素在被念到的时刻出现,读者不领先三行。
The point of a build is pacing: show each element when the narration reaches it, so the viewer reads the line being spoken — not three lines ahead.
可读性是硬线:正文 ≥28–32px @1080p、标题 56–80px、对比 ≥4.5:1、内容留在中心 90%。
- **Type scale, not deck scale.** A deck viewed on a laptop ≠ a video viewed in a feed. Bump body to ≥ 28–32px at 1080p; titles 56–80px.
验证环:先读 compositions 拿总时长,再从「每页的驻留段」取样而不是在转场上取样。
- Use `npx remotion compositions` to read the deck's `durationInFrames`/`fps` and pick the end frame; sample a still **inside each slide's hold**, not on a transition, to judge the built state.
转场要承载逻辑(因此/但是/所以),安静的 fade 给「以及」,大 push 只给章节分隔。
- **Transitions carry logic, not just motion.** The cut between slides should answer "so what's next?" — therefore, but, which means, here's the proof.
2核心能力
3外部依赖
| 类型 | 依赖 |
|---|---|
| package | remotion(AbsoluteFill/Sequence/Audio/spring/interpolate) |
| package | @remotion/media-utils(getAudioDurationInSeconds 量测旁白) |
| package | @remotion/transitions(TransitionSeries / linearTiming / fade / slide) |
| package | @remotion/google-fonts(reference 建议的字体加载方式;选择它会在渲染期访问 Google Fonts) |
| cli | npm / npx(安装并运行 Remotion 工程、读 compositions、渲染) |
| network | iart.ai(reference 尾部推广链接,具 utm 参数;仅读者点击才请求) |
4风险提醒 风险提醒:橙色 · 评估后使用
- 依赖未在 SKILL.md 层声明完整 — @remotion/media-utils / @remotion/transitions / @remotion/google-fonts 只在 reference(或 pitfalls)出现,只读 SKILL.md 无法得到完整依赖面。
- 渲染期字体出网 — 选用 @remotion/google-fonts 会在渲染期访问 Google Fonts(可用 staticFile 规避),属未声明的出网路径。
- 旁白素材完全依赖使用者 — skill 不提供 TTS,也不校验音频质量与版权;音频缺失或损坏会直接导致 calculateMetadata 失败。
- 远程包与本地代码执行 — npm i 安装 remotion 全家桶并执行;Remotion 会 bundle 运行项目代码(框架固有属性)。
- 商业引流位 — reference 尾部固定 iart.ai 推广段与 utm 链接。
5第二遍独立确认
- [ok] 音频量测与 HANDLE 数值是否两处一致 — SKILL.md 代码块 `const HANDLE = 0.4; // breathing room after the voice ends` 与 sequencing.md 的 `const HANDLE = 0.4; // seconds of breathing room after each voice line` 同值。
- [ok] theme 数值是否与 reference 一致 — SKILL.md 示例 theme(bg #0B0B12 / fg #F5F5F7 / accent #6C5CE7 / titlePx 72 / bodyPx 30 / maxWidthPct 90)与 slide-components.md 的 theme.ts 逐项相同。
- [ok] 转场帧预算的声明与实现 — SKILL.md「A transition borrows frames from both neighbors, so add its length back into the slide budget」与 sequencing.md 的记账规则(slide.durationInFrames += TRANSITION)同口径。
- [discrepancy] @remotion/google-fonts 的声明层级 — @remotion/google-fonts 只出现在 sequencing.md 的 pitfalls(作为可选建议),SKILL.md 既未列入依赖面、也未提示渲染期可能访问 Google Fonts;照抄该建议会产生未声明的出网行为。
- [ok] SKILL.md 内联组件与 reference 组件是否冲突 — SKILL.md 的 Bullet 用 spring(...durationInFrames: 12) + interpolate(p,[0,1],[18,0]),reference 用 useEnter() 封装同一动效;属精简版与封装版的关系,非矛盾。
- [unlocatable] 旁白生成方式是否被声明 — SKILL.md workflow 第 2 步写「Generate/record narration per slide.(One audio file per slide (TTS or recorded).)」但未指名任何 TTS 服务或端点——属用户自备素材;「无 TTS 端点」这一结论无法在源码内定位到明确声明,故记 unlocatable(非档位依据)。
6结论
c9a450ffb476b92f…8ce2709c39