动画视频
此部分所有内容均在 remotion/ 目录下渲染,零成本。包含两个层级——始终先尝试第一层:
- 组合内置场景 通过规范文件(几分钟内完成,无需代码)。
- 向引擎添加新的场景类型 当某个创意确实需要时(编写代码、测试,然后所有代理均可复用)。
本地渲染前:如果 remotion/node_modules 缺失,请运行 cd remotion && npm ci
(首次渲染还会下载 Remotion 的无头 Chrome,约 170 MB,仅一次)。
第一层——场景工具包
场景 (shots[].type) | 最佳用途 | 关键字段 |
|---|---|---|
kinetic | 钩子、点睛之笔 | text、highlight、per_word (0.18)——单词逐个弹出 |
title | 单行加粗标题 | text ≤ 6 个词、highlight |
number | 一个醒目的数字 | value、prefix、suffix、decimals、caption、color——从 0 开始计数 |
bars | 比较大小 | title、unit、items[{label,value,color}] |
compare | 他们 vs 你、神话 vs 事实、之前/之后 | title、left{label,items,color}、right{…} |
list | “三件事”、做/不做 | items、style(勾选/叉号/数字) |
timeline | 事件如何发生 | items[{year,text}] |
chat | 用短信讲述的故事 | title(联系人)、messages[{from: me/them, text, at}] |
quote | 引用他人话语 | text、by |
media | B-roll、照片、AI 片段 | src、kenburns、headline、fit |
每个场景都可以使用 label(引导标签)、stamp(印章数字)、bg(背景图片/视频,含 credit)和 transition(默认 fade,可选 cut、slide、zoom、wipe)。覆盖层(headline、textover、lowerthird、stamp)可置于任意场景之上。完整参考:remotion/SPEC.md。每个新场景的示例:remotion/examples/animated.json。
常用配方
- 无脸讲解(20~40 秒):
kinetic钩子 →number→bars/compare→list→title呼应钩子的收尾。旁白作为audio,字幕来自words,背景音乐music音量 0.08~0.12。 - 短信故事:
kinetic钩子(“她凌晨 3 点回复了”)→ 每次对话一个chat场景(at间隔 0.8~1.4 秒,与旁白同步)→title反转。每条气泡 ≤ 10 个词。 - 口播视频中的动画插入:CLIP_1 …
number或compare(持续 2~3 秒,配合关键句)→transition: "zoom"→ 回到 CLIP_1,start设置为片段恢复的位置。 - 神话 vs 事实:
compare,left.color: "danger"、right.color: "good",然后在下一个title场景上叠加stamp"FALSE"。
使用 video-script(tools/beats.mjs 可将场景与旁白时间点对齐)规划节奏,然后运行:
cd remotion
node render.mjs job/spec.json --validate
node render.mjs job/spec.json job/final.mp4 --preview job/check.jpg --at 0.1,<每个场景的中间时间>,<结束前1秒>
交付前务必检查预览截图:确保 0.1 秒时钩子已完全绘制、没有内容被裁剪、文字无重叠、强调色清晰可读、AI 生成标签和水印正常显示。
样式规则
- 品牌色来自
settings.brand(规范中的theme):使用一种强调色,用于每个场景中最重要的元素。 - 每行标题 ≤ 7 个词,每个覆盖文本 ≤ 12 个词,每列表格/对比栏 ≤ 4 项(手机屏幕较小)。
- 每个场景至少停留 1.5 秒(按其中每行文字计算)。
- 数字必须与
citations匹配;切勿动画化未注明来源的数据。 - 不得使用品牌徽标、真人照片或真实聊天截图。
第二层——添加新的场景类型
仅当上述所有场景组合都无法展示创意时使用(例如:地图路线、进度环、分屏反应)。
src/types.ts:添加XShot = ShotBase & { type: "x"; … }并将其加入Shot联合类型。src/shots/Shots.tsx:编写组件,放在其他组件旁边——使用useCurrentFrame()配合spring/interpolate进行动画(禁止使用 CSS 动画或Math.random:渲染必须确定性);使用t.font、t.accent、tone(t, color),画面尺寸为 1080×1920;然后在ShotView中添加一行if (s.type === "x") body = …。如果场景在 0 秒时已出现(base === 0),则需完全绘制,无需入场动画。render.mjs:将"x"加入types并添加对应必填字段的验证(检查代理依赖这些错误信息)。SPEC.md及上表:记录该场景。将其加入examples/animated.json。- 测试:运行
npx tsc --noEmit -p .、node render.mjs examples/animated.json out/animated.mp4 --preview out/animated.jpg --at …并查看结果。