2026-10-30
用 Claude Code 做一条「Vibe 知识大赏」:从原理到成片的完整教程
拆解最近刷屏抖音、B 站、小红书的「Vibe 知识大赏」类知识短片:需要的背景知识、工具与环境、SVG 代码视频「画面 = f(t)」的工作原理,以及用 Claude Code 从选题、分镜、逐帧渲染到混音成片的完整步骤。
国庆之后,你大概率刷到过这样的视频:深蓝近黑的背景,没有人出镜,也常常没有旁白;屏幕中央一条金色曲线自己”长”出来,底部一行中文字幕配一行英文斜体小字,背景是一段 77 BPM 左右的钢琴 pad。两三分钟讲完一个”信息论”“秘书问题”“邓巴数”,看完像刷了一支 MV,还顺手学到了点东西。
这就是 「Vibe 知识大赏」。它最反直觉的一点是:画面里没有一帧是”生成”出来的像素,全部是代码画的。 作者用自然语言指挥 Claude 写 HTML/SVG/Canvas 动画,再让无头浏览器逐帧截图,最后用 ffmpeg 压成 MP4。
这篇文章讲清楚三件事:
- 这类视频为什么能用代码做,SVG 视频的核心原理是什么;
- 要做它,需要准备哪些知识、工具和环境;
- 用 Claude Code 从一个选题走到一条成片,每一步该做什么、该对 Agent 说什么。
说明:本文是方法教程,文中的代码片段和命令是用来解释原理和流程的示意代码,写作时没有在本机实际渲染过视频。各开源 Skill 的安装方式迭代很快,动手前请以各仓库 README 的最新说明为准。
0. 先认识一下:什么是「Vibe 知识大赏」
0.1 一个由模型能力撬开的内容风口
时间线大致是这样的:
- 2026 年 9 月 22 日,Anthropic 发布 Claude Opus 5.5。社区很快发现它写动画代码的能力有了质变,”用一句话让模型写出一支动效短片”在 X 和 GitHub 上刷屏,这股风潮被称为 Vibe Video;
- 9 月底到 10 月初,抖音开始运营
#Vibe知识大赏话题,配合固定 BGM 的知识短片集中出现; - 据界面新闻 10 月 20 日的报道,抖音该话题已有 5.1 万人参与、11.7 亿次播放;小红书同名话题浏览量超过 6.6 亿;B 站新人 UP 主”比特新语”半个月涨粉 60 万。
同一篇报道给了一个很说明问题的对比:过去回形针 PaperClip 这种知识可视化头部团队,一条 5 分钟视频要 4–5 人做 2–4 周;而现在,一个熟练的个人创作者一天就能迭代出一条。门槛被压低的不是”审美”,而是”把审美变成画面”的那部分手艺。
0.2 这类视频长什么样
社区里有人对 8 条爆款原片做了逐帧逆向(见 vibe-knowledge-video 的风格规范),归纳出的”风格 DNA”大致如下:
| 维度 | 典型取值 |
|---|---|
| 规格 | 1920×1080 横屏,30fps,H.264 + AAC |
| 时长 | 2–3 分钟居多(实测 119–166 秒,中位约 130 秒) |
| 声音 | 多数无旁白;纯器乐 BGM,76–78 BPM,小调 |
| 配色 | 深蓝黑背景 #050510~#12122a,白字 + 一种强调色(暖橙 / 金色) |
| 字幕 | 底部中文主句 + 一行英文斜体小字,每句 ≤ 20 字 |
| 结构 | 先抛问题(钩子)→ 15–20 秒处落片名卡 → 演示 / 模拟 → 泛化到生活 → 引用与声明 |
| 动效 | 画面”一直在动”;ease-in-out 缓动,禁止匀速;转场是”长出来的”,极少黑场硬切 |
| 严谨性 | 年份、人名、数字上屏;历史文献复原标”图为示意”;结尾给学术引用 |
也有带旁白的流派——比如 andyhuo520/vibe-knowledge 默认使用 TTS 旁白、44 套风格。但”代码逐帧画面 + 字幕 + 音乐”的骨架是一样的。
1. 需要提前了解的背景知识
不需要你是前端工程师,但下面这几块概念最好心里有数——你不用自己写代码,但你得看得懂 Agent 在干什么,并且能准确地提出修改意见。
1.1 两条完全不同的 AI 视频路线
| 代码动效(本文) | 视频生成模型(Sora、可灵等) | |
|---|---|---|
| 画面来源 | 代码按时间逐帧绘制 | 模型从噪声中生成像素 |
| 文字和数字 | 永远清晰准确,可以逐字改 | 容易错字、变形 |
| 写实人物 / 实景 | 弱,天然偏图形化 | 强 |
| 时长 | 不受限 | 单段通常十几秒,需拼接 |
| 修改方式 | 改一行代码重新渲染,结果确定 | 重新抽卡,结果随机 |
知识类视频的核心是概念、数据、文字和图表,这正是代码动效的主场。这也是为什么这个赛道是被一个”写代码的模型”引爆的,而不是被一个”生成视频的模型”引爆的。
1.2 前端三件套:够用就行
- HTML / CSS:网页的骨架和样式,视频的”舞台”就是一个 1920×1080 的网页;
- JavaScript:负责”在第 t 秒,每个东西应该在哪、长什么样”;
- SVG 与 Canvas:两种在网页上画图的方式,是本文的重点,第 3 节详细讲。
1.3 视频与音频的基础概念
| 概念 | 你需要知道的 |
|---|---|
| 帧率(fps) | 30fps 意味着 130 秒的片子要画 3900 帧 |
| 编码 / 封装 | 视频常用 H.264(libx264),音频 AAC,封装成 .mp4;像素格式用 yuv420p 才能在手机上正常播放 |
| BPM / 拍 | 77 BPM ≈ 每拍 0.78 秒。爆款片的关键动作通常卡在拍点或小节头上 |
| 响度(LUFS) | 短视频平台常用 −14 LUFS 左右做标准化,太小声会被淹没、太大声会被压缩 |
1.4 Claude Code 的几个关键概念
Claude Code 是 Anthropic 的终端 Agent,它能读写文件、执行命令、自己看截图再改。做视频时会频繁用到:
- Skill:放在
~/.claude/skills/<名字>/SKILL.md的一套”做某件事的说明书”,Agent 在任务匹配时会自动加载。社区里的 Vibe 知识大赏工具基本都以 Skill 的形式发布; - Plugin / Marketplace:打包分发 Skill 的方式,通过
/plugin marketplace add、/plugin install安装; - CLAUDE.md:项目根目录下的长期指令,适合写”本系列的配色、字体、水印、字幕规范”,保证每一期风格一致;
- 权限模式:渲染会跑大量命令,
Shift+Tab可以切换权限模式,决定哪些操作需要你确认; - 多模态读图:Agent 可以读取自己截出来的静帧来检查画面,这是”看图改图”闭环的基础。
2. 需要安装的工具与环境
2.1 清单
| 工具 | 用途 | 是否必需 |
|---|---|---|
| Claude Code + Claude 订阅(Pro / Max)或 API | 写脚本、写动画代码、跑渲染、看图改图 | 必需 |
| Node.js 20+ | 跑本地预览服务、Node 版渲染脚本 | 视 Skill 而定,建议装 |
| Python 3.11+ | 多数 Skill 的渲染 / 混音脚本用 Python | 建议装 |
| Playwright + Chromium | 无头浏览器,逐帧截图 | 必需 |
| ffmpeg | 图片序列 → 视频,混音,响度标准化 | 必需 |
| 开源字体(Noto Sans SC / Noto Serif SC / EB Garamond 等) | 中文粗黑体、衬线标题、英文斜体 | 必需(字体决定一半的质感) |
| numpy / scipy | 程序化合成 BGM 与音效 | 视 Skill 而定 |
| TTS 服务 | 做有旁白的版本时生成配音 | 可选 |
| 图像 / 视频生成 MCP | 少数写实镜头的”增强档” | 可选 |
2.2 安装参考(以 macOS 为例)
下面的命令只是参考,具体以各工具官网为准:
# 1. Claude Code(官方原生安装脚本;也可以 brew install --cask claude-code)
curl -fsSL https://claude.ai/install.sh | bash
claude --version
# 2. 基础运行时与 ffmpeg
brew install node python@3.12 ffmpeg
# 3. 建一个独立的 Python 虚拟环境,装渲染依赖
python3 -m venv ~/.venvs/vibe
~/.venvs/vibe/bin/pip install playwright numpy scipy pillow
~/.venvs/vibe/bin/python -m playwright install chromium
Windows 用户建议直接在 WSL 里完成上面这些步骤,路径和命令几乎一致。
几个容易忽略的点:
- 字体要本地化:不要依赖 Google Fonts 的在线加载,渲染几千帧时网络一抖就会出现”字体闪变帧”。把
.ttf/.woff2下载到工程目录,用@font-face引用。Noto、EB Garamond 都是 SIL Open Font License,可以放心商用; - API Key 不要写进工程:TTS、生图服务的密钥放在环境变量或
~/.config/下,别让 Agent 把它写进film.js再被你 commit 上 GitHub; - 磁盘空间:1080p PNG 一帧几百 KB 到 1–2 MB,3900 帧就是几个 GB。渲染完记得清理帧目录,或者直接用管道喂给 ffmpeg(见 3.6)。
2.3 选一个现成 Skill,还是从零搭
你完全可以从零让 Claude Code 搭一套渲染管线(第 4 节会给提示词),但更省事的做法是先装一个社区 Skill,看懂它的结构,再按自己的审美改。截至本文写作时比较有代表性的几个:
| 仓库 | 特点 | 绘图技术 |
|---|---|---|
| andyhuo520/vibe-knowledge | 带旁白、每句有出处;44 套风格;三次人工确认点;含 OCR 质检 | SVG 分层插画 + three.js 引擎 |
| HeyChengC/vibe-knowledge-film | 无旁白;”夜曲 / 寓言”两套外观;极其强调”先找形象再写文案”的讲解设计 | Canvas + seek(t) |
| wchhywizd/vibe-knowledge-interactive | 168 拍固定节奏;互动式”先下注”开场;附 100 条爆款样本数据 | Canvas 2D |
| xiazhuo123456789/vibe-knowledge-video | 逆向 8 条原片得到的风格 DNA 文档,适合当风格参考 | — |
通用的”HTML 转视频”框架如 HyperFrames、Remotion 也能做,但它们不包含知识片特有的讲解方法论。
Skill 的安装通常就是把目录拷进 ~/.claude/skills/,例如:
git clone https://github.com/HeyChengC/vibe-knowledge-film.git ~/.claude/skills/vibe-knowledge-film
版权提醒:有些仓库附带的 BGM 或示例分镜版权不属于仓库作者(README 里通常写明了),只能用于学习复现,公开发布前必须替换。
3. SVG 视频的工作原理
这一节是全文的核心。理解了它,你就能看懂所有同类 Skill,也能在 Agent 卡住时给出正确的指令。
3.1 一句话原理:画面是时间的确定性函数
传统动画是”让它动起来”;代码视频是“告诉我第 t 秒长什么样”。
整个工程只需要遵守一个约定——页面暴露一个函数:
window.DUR = 130; // 片长(秒)
window.render = (t) => { ... } // 给定任意时刻 t,把画面摆成那一帧的样子
window.READY = true; // 字体、图片都加载完了,可以开拍
只要 render(t) 是确定性的——同一个 t 永远画出同一帧,不依赖上一帧的状态、不读系统时间、不用不带种子的随机数——那么:
- 浏览器里拖进度条预览的效果,和离线导出的成片完全一致;
- 任意一帧都可以单独渲染,于是可以多进程并行,也可以只重渲出错的那 5 秒;
- 帧率是”算”出来的而不是”录”出来的:第
i帧就是render(i / fps),不管这一帧多复杂、画了 2 秒还是 20 毫秒,成片都是丝滑的 30fps。
这就是为什么绝对不要用录屏:录屏受电脑性能影响,复杂场景会掉帧;逐帧渲染则完全不受影响。
3.2 为什么是 SVG
SVG(Scalable Vector Graphics)是用 XML 描述的矢量图。一条曲线、一个圆、一行字,都是 DOM 里的一个元素,位置和样式都是属性:
<svg viewBox="0 0 1920 1080">
<circle cx="960" cy="540" r="12" fill="#fff"/>
<path d="M 260 760 C 700 760 760 300 960 300" stroke="#C9A96A" fill="none"/>
<text x="960" y="960" text-anchor="middle">运气,是有形状的</text>
</svg>
做”动画”,本质就是在 render(t) 里根据 t 改这些属性。SVG 之所以特别适合知识片:
- 矢量、与分辨率无关:用
viewBox="0 0 1920 1080"定义坐标系后,同一份代码可以渲 1080p,也可以把截图倍率调成 2 直接出 4K,线条和文字依然锐利; - 文字排版是一等公民:中英双语字幕、书名号片名卡、文献复原件里的衬线斜体,在 SVG/HTML 里都是真文字,不是图片;
- 自带几何 API:
getTotalLength()、getPointAtLength()能直接拿到路径长度和路径上任意一点,”曲线自己长出来”“小球沿曲线走”几行就能写; - 结构化、好修改:每个元素有 id,你可以对 Agent 说”把
#curve的颜色改成暖橙、线宽加粗到 8”,它改起来很准; - 模型写得特别好:大模型见过海量 SVG/图标/图表代码,写 SVG 插画(人物剪影、印章、纸卡、地图)的成功率很高。
3.3 SVG 动画的三种驱动方式
SVG 本身有好几种”动起来”的写法,但做视频时,最终都要能被 t 精确控制:
| 方式 | 写法 | 能否 seek 到任意 t | 做视频是否推荐 |
|---|---|---|---|
| SMIL | <animate attributeName="cx" dur="3s" .../> |
可以:svg.pauseAnimations() + svg.setCurrentTime(t) |
一般,复杂编排难维护 |
| CSS / Web Animations | @keyframes 或 el.animate() |
可以:遍历 document.getAnimations(),pause() 后设置 currentTime = t * 1000 |
可以,适合简单元素 |
| GSAP 时间线 | tl.to('#dot', {x: 500, duration: 2}) |
可以:tl.pause(); tl.seek(t) |
推荐,缓动丰富、编排方便 |
纯函数 render(t) |
自己算每个属性 | 天然支持 | 最推荐,最可控、最易排错 |
前三种都是”先让它自己播,再想办法把时钟按住”;第四种是从一开始就没有时钟,只有 t。社区里成熟的 Skill 基本都走第四种,或者在第四种外面包一层小工具函数。
3.4 一个最小可运行的 SVG 视频页面(示意)
下面这个页面演示了知识片里最常见的三个动作:曲线描边自绘、小点沿曲线移动、字幕淡入上移。
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<style>
@font-face { font-family: "NotoSansSC"; src: url("fonts/NotoSansSC-Bold.woff2"); }
html, body { margin: 0; background: #07070f; overflow: hidden; }
text { font-family: "NotoSansSC", sans-serif; }
</style>
</head>
<body>
<svg id="stage" width="1920" height="1080" viewBox="0 0 1920 1080">
<defs>
<filter id="glow">
<feGaussianBlur stdDeviation="6" result="blur"/>
<feMerge><feMergeNode in="blur"/><feMergeNode in="SourceGraphic"/></feMerge>
</filter>
</defs>
<path id="curve" d="M 260 760 C 700 760 760 300 960 300 S 1220 760 1660 760"
fill="none" stroke="#C9A96A" stroke-width="6" filter="url(#glow)"/>
<circle id="dot" r="12" fill="#EAEAF2"/>
<text id="sub" x="960" y="960" text-anchor="middle" font-size="46" fill="#EAEAF2"></text>
</svg>
<script>
// ---------- 工具函数:全部是 t 的纯函数 ----------
const clamp = (x, a = 0, b = 1) => Math.min(b, Math.max(a, x));
const easeInOut = x => (x < 0.5 ? 4 * x * x * x : 1 - Math.pow(-2 * x + 2, 3) / 2);
// 把 t 映射到 [t0, t1] 区间内的 0→1 进度,并加上缓动
const prog = (t, t0, t1) => easeInOut(clamp((t - t0) / (t1 - t0)));
const curve = document.getElementById("curve");
const dot = document.getElementById("dot");
const sub = document.getElementById("sub");
const L = curve.getTotalLength();
curve.style.strokeDasharray = L;
// 字幕表:[开始秒, 结束秒, 文本]
const SUBS = [
[0.5, 4.0, "运气,是有形状的"],
[4.5, 9.0, "它长得像一座山"],
];
window.DUR = 10;
window.READY = false;
window.render = (t) => {
// 1. 曲线在 1s→6s 之间"长"出来:dashoffset 从 L 减到 0
const p = prog(t, 1, 6);
curve.style.strokeDashoffset = L * (1 - p);
// 2. 小点永远停在曲线的"笔尖"上
const pt = curve.getPointAtLength(L * p);
dot.setAttribute("cx", pt.x);
dot.setAttribute("cy", pt.y);
// 3. 当前字幕:淡入 0.4s,同时上移 8px
const s = SUBS.find(([a, b]) => t >= a && t < b);
sub.textContent = s ? s[2] : "";
const k = s ? prog(t, s[0], s[0] + 0.4) : 0;
sub.setAttribute("opacity", k);
sub.setAttribute("transform", `translate(0, ${8 * (1 - k)})`);
};
// 字体就绪后才允许开拍,避免前几帧字体闪变
document.fonts.ready.then(() => { window.render(0); window.READY = true; });
</script>
</body>
</html>
几个值得记住的技巧:
- 描边自绘:把
stroke-dasharray设为路径总长 L,再把stroke-dashoffset从 L 动到 0,线条就会像被笔画出来一样。图标、手写字、地图路线都是这么”画”出来的; - 辉光:
feGaussianBlur+feMerge就是那种”发光金线”的质感。但滤镜很吃性能,全屏大面积使用会让每帧渲染时间翻倍; - 路径变形(morph):两个
d属性插值要求命令结构一致,复杂形状可以让 Agent 引入 flubber 之类的插值库; - 随机要带种子:星点、粒子的位置不能用
Math.random(),而要用带种子的伪随机数,否则每一帧星空都会”跳”:
// mulberry32:一个常用的小型带种子 PRNG
function mulberry32(seed) {
return function () {
seed |= 0; seed = (seed + 0x6D2B79F5) | 0;
let r = Math.imul(seed ^ (seed >>> 15), 1 | seed);
r = (r + Math.imul(r ^ (r >>> 7), 61 | r)) ^ r;
return ((r ^ (r >>> 14)) >>> 0) / 4294967296;
};
}
const rand = mulberry32(42);
const STARS = Array.from({ length: 200 }, () => ({ x: rand() * 1920, y: rand() * 1080, phase: rand() * 6.28 }));
// render(t) 里:opacity = 0.3 + 0.2 * Math.sin(t * 1.5 + star.phase)
星点”闪烁”也只是 sin(t + phase)——依然是 t 的纯函数。
3.5 逐帧捕获:让无头浏览器当摄像机
有了 render(t),”拍摄”就是一个循环:设置时间 → 等浏览器画完 → 截图。用 Playwright(Node 版)示意:
// capture.mjs —— 示意代码
import { chromium } from "playwright";
import { mkdirSync } from "node:fs";
const FPS = 30;
mkdirSync("frames", { recursive: true });
const browser = await chromium.launch();
const page = await browser.newPage({
viewport: { width: 1920, height: 1080 },
deviceScaleFactor: 1, // 改成 2 即输出 3840×2160
});
await page.goto("http://localhost:8080/index.html");
await page.waitForFunction(() => window.READY === true);
const dur = await page.evaluate(() => window.DUR);
const total = Math.round(dur * FPS);
for (let i = 0; i < total; i++) {
await page.evaluate((t) => {
window.render(t);
// 等下一次绘制完成,确保截到的是新画面
return new Promise((r) => requestAnimationFrame(() => r()));
}, i / FPS);
await page.screenshot({ path: `frames/${String(i).padStart(5, "0")}.png` });
}
await browser.close();
为什么要起一个本地 HTTP 服务(localhost:8080)而不是直接打开 file://?因为字体、图片、fetch 读 JSON 在 file:// 协议下经常撞上跨域限制。
并行:因为每一帧互相独立,把 [0, total) 切成 4 段交给 4 个浏览器实例同时跑,速度近似线性提升。社区 Skill 普遍支持 --jobs 4 之类的参数,还支持中断后续跑。
3.6 合成:ffmpeg 把帧和声音缝起来
# 1. 响度标准化(-14 LUFS,峰值 -1 dBTP)
ffmpeg -i mix.wav -af loudnorm=I=-14:TP=-1:LRA=11 mix_norm.wav
# 2. 图片序列 + 音轨 → MP4
ffmpeg -framerate 30 -i frames/%05d.png -i mix_norm.wav \
-c:v libx264 -preset slow -crf 18 -pix_fmt yuv420p \
-c:a aac -b:a 192k -shortest -movflags +faststart film.mp4
-pix_fmt yuv420p:不加的话,PNG 截图会被编码成 yuv444,很多手机和平台播不了;-crf 18:接近视觉无损,深色渐变背景的片子码率给低了会出现明显色带;-movflags +faststart:把索引放到文件头,上传后能边下边播。
想省磁盘的话,可以不落地 PNG,而是把截图的二进制直接写进 ffmpeg 的标准输入(-f image2pipe -i -)。
3.7 全景图
把上面拼起来,一条 Vibe 知识片的技术管线是这样的:
┌───────────────────── 时间轴(唯一事实来源) ─────────────────────┐
│ SUBS 字幕表 · 场景表 · 音效事件表 EV(都以秒或"拍"为单位) │
└───────┬───────────────────────┬───────────────────────┬────────┘
│ │ │
┌──────▼──────┐ ┌──────▼──────┐ ┌──────▼──────┐
│ 画面 render(t)│ │ BGM(采样 / │ │ 音效:在事件 │
│ SVG / Canvas │ │ numpy 合成) │ │ 时刻生成拟音 │
└──────┬──────┘ └──────┬──────┘ └──────┬──────┘
│ Playwright 逐帧截图 └────────── 混音 ─────────┘
┌──────▼──────┐ │ loudnorm -14 LUFS
│ frames/*.png │ ▼
└──────┬──────┘ mix_norm.wav
└─────────────── ffmpeg ──────────┘
▼
film.mp4
时间轴是唯一的事实来源:字幕什么时候出、音效什么时候响、哪个动作落在第几拍,都从同一张表里读。这样改一句字幕的时长,画面和声音会一起跟着动,不会错位。
3.8 SVG 还是 Canvas?
你会发现不少 Skill 其实用的是 Canvas。两者并不冲突,按画面内容选:
| SVG | Canvas 2D | |
|---|---|---|
| 模型 | 保留模式:DOM 元素,改属性 | 立即模式:每帧清空重画 |
| 擅长 | 线条、图标、图表、文字排版、插画 | 成千上万的粒子、手绘笔触、像素风、逐像素特效 |
| 缺点 | 元素多了(数千个)或大面积滤镜时变慢 | 文字排版、点击区域都要自己管 |
| 修改体验 | 对 Agent 说”改 #curve“很准 |
要定位到某个绘制函数里 |
实践中常见的组合是:背景星空 / 粒子用 Canvas 画在底层,主体插画、图表、字幕用 SVG 叠在上面。只要两层都由同一个 render(t) 驱动,就依然是确定性的。
4. 用 Claude Code 制作一条视频:完整步骤
技术管线只占这类视频的一半。另一半,也是决定一条片子是”爆款”还是”PPT 动画”的部分,是讲解设计。下面的步骤融合了几个社区 Skill 的流程,每一步都给出过关标准和可以直接对 Claude Code 说的话。
第 1 步:选题与事实表
好选题的三个检验(来自 vibe-knowledge 的流程):
- 3 秒内能不能让观众先猜、先选?(”一张纸折多少次能到月球?”)
- 有没有一个贯穿全片的道具?(晾衣绳上的卡片、一条成功率曲线)
- 有没有反转?(直觉是 5%,答案是 90%)
另一个值得参考的数据结论来自 vibe-knowledge-interactive 的样本统计:条数最多的题材往往不跑量,认知心理类的单条均值明显高于社会经济类。囚徒困境、熵增、墨菲定律这类题已经被讲烂了,避开它们。
选定后,先建事实表 facts.md:每个年份、人名、数字、引文都要有出处和把握程度。
我想做一期 Vibe 知识大赏,主题是「秘书问题 / 37% 法则」。
先不要写代码。请帮我:
1. 用一句话写出本片的论点;
2. 列出 3–8 个要讲的概念,每个写清"要观众明白什么"和"外行卡在哪";
3. 建 facts.md,列出所有要上屏的年份、人名、数字和出处,标注把握程度;
查不到可靠出处的,换例子,不要编。
过关标准:论点一口气说得完;每个概念你自己能不用术语讲给外行听。
第 2 步:给每个概念找”形象”
这是 vibe-knowledge-film 最强调的一步,也是大量跟风作品失败的原因:屏上的东西只是”配图”,而不是在”讲解”。
它举过一个自己失败的例子:讲蛋白质折叠,全片主体是一串星点连成的折线,颜色、字体、节奏都很像爆款,但观众从头到尾没见过蛋白质是什么——”那串星点换给任何一段文案都成立”。重做后,镜头钻进血管里的红细胞,找到一串珠子,第 6 颗变色,细胞随之弯成镰刀。
找形象时依次问:它本身是个东西吗?是个过程吗?是个量吗?是观众脑子里的事吗?是条规律吗?都不是,才上纯文字。
对 facts.md 里的每个概念,找一个外行在生活里认得的形象来"演"它:
- 屏上的主体必须叫得出日常名字,长得像它本身(不要用点、线、圈、方框代替);
- 字幕里的动词,屏上要真的发生;
- 定下全片唯一的"世界"、一把贯穿的"尺子",以及哪些道具会回场;
- 告诉我全片哪一下最让人"哦——"。
给我 3 个开场钩子方向和你的推荐。
第 3 步:文案和分镜表一起写
没有分镜表,不建工程。 分镜表一句字幕一行:
| 时间 | 字幕(中 / 英) | 画法 | 屏上是什么、在干什么 | 小字注释 | 观众明白了什么 | 声音 |
|---|---|---|---|---|---|---|
| 0:00 | 你该在第几个人,停下来? / When should you stop looking? | 不画 | 晾衣绳上一排背面朝上的卡片,轻轻摆动 | — | 这是一个”顺序选择”的问题 | pad 进 |
| 0:04 | 一张一张翻,错过了不能回头 / … | 演示 | 卡片从左到右依次翻开,翻过的变灰 | 注意:只能往前 | 不可逆 | 每翻一张一声轻响 |
几条硬规矩:
- 遮住字幕那一列,只读”屏上是什么”,也能看出在讲什么;
- 提问、命名、结论、引文这类句子不硬配新画面,大约占五分之一;
- 一个场景撑两句以上,每句只改一处;结尾回到开头的画面;
- 每句字幕 ≤ 20 字,一眼读完,停留 3–5 秒。
第 4 步:定外观,写进 CLAUDE.md
外观跟着题材走:讲心理 / 行为机制,适合”寓言”式的暖色纸艺;讲抽象概念,适合”夜曲”式的深色辉光。定下来以后写进工程根目录的 CLAUDE.md,让每次对话、每一期都遵守:
# 本系列视觉规范
- 画布 1920×1080,30fps;背景 #07070f,主文字 #EAEAF2,强调色 #C9A96A(全片只表示"最优 / 关键")
- 字体:中文 Noto Sans SC 700,片名 Noto Serif SC 900,英文 EB Garamond Italic,全部本地加载
- 纵向 80%–95% 只放字幕;中文 46px,英文 26px #8A8AA0
- 动效只用 ease-in-out;禁止匀速滑动、禁止黑场转场;任何一刻只有一个主体在动
- render(t) 必须确定性:禁用 Date.now(),随机数用带种子的 PRNG
- 示意画面标"图为示意";不加水印以外的署名
第 5 步:建工程,先做最难的一镜
如果装了 Skill,Agent 会用 Skill 自带的脚手架建工程;如果从零开始,可以这样说:
按 CLAUDE.md 的规范,在 ./ep01 下建一个代码视频工程:
- index.html + film.js,暴露 window.DUR / window.render(t) / window.READY;
- 用 SVG 画主体,底层用一个 Canvas 画星点背景,都由同一个 render(t) 驱动;
- 写一个 Playwright 渲染脚本,支持:--sheet 拼接若干时刻的缩略图、--stills 原尺寸截几帧、
--clip 起止秒 只渲一段、--jobs N 并行渲全片、--det 同一帧渲两次比对是否一致;
- 先只实现分镜表里最难画的那一镜,截静帧给我看。
为什么先做最难的一镜?因为如果最难的那个形象画不出来,就得回第 2 步换形象,越早发现越便宜。
第 6 步:看图改图,至少两轮
这类片子是看着图改出来的,不是写完代码就完了的。Claude Code 能读取自己截的图,要充分利用这个闭环:
用 --sheet 截 3、8、15、22 秒四帧拼图,你自己先看一遍:
遮住字幕和小字,回答"这是什么 / 它在干什么 / 我明白了什么";
检查主体够不够大、缩到手机横屏还认不认得出、有没有东西伸进字幕区、
颜色是否发白、是否有两样东西同时抢着动。
把问题列出来,改完重截同样的时刻,确认改掉了、没改坏别的。至少两轮后再给我看。
你作为导演,给反馈时要具体到时间点和元素:
- ❌ “感觉不够高级”
- ✅ “8.2 秒卡片翻开太快,改成 0.6 秒并带一点回弹;翻开后停 1 拍再出下一句字幕”
第 7 步:先交付 30 秒样片,再铺全片
开头 30 秒只讲一件事,让它在屏上完整发生一遍。确认节奏、外观都对了,再按”一个概念一个函数”铺全片,长片按章节拆文件。每做完两三个概念就拼一张缩略图自查:相邻两段是不是长得一样?该回场的道具回来了没有?
第 8 步:声音
- BGM:可以用有授权的曲子,也可以让 Agent 用 numpy 合成:76–78 BPM、小调、低音 pad + 每小节钢琴柱式和弦 + 很轻的打击。钩子段只有 pad,机制演示段进钢琴,反转时加琶音;
- 对拍:先量出 BPM,把每段开头对齐到小节线,把最大的那次”揭晓”对到音乐重新进入的那一拍;
- 音效:在
film.js里登记事件({ t: 8.2, type: "flip" }),混音脚本按事件时刻生成翻牌声、上滑音、落定低音;提问那一镜保持安静; - 旁白(可选):逐句 TTS → 语音识别回读校验 → 用真实时长反推字幕时间轴。只用你本人或已授权的声音。
第 9 步:终检与发布
整片渲完后做三遍检查:
- 静音、遮住字幕看一遍:每一段在讲什么,看得出来吗?
- 只读字幕一遍:通顺吗?句子里的名词,屏上都找得到吗?
- 对照技术门槛:
--det确定性检查通过;1920×1080 / 30fps;屏上每个数字和facts.md一致;响度约 −14 LUFS;没有冻结帧。
发布包可以一起让 Agent 生成:
为成片生成发布包:标题(「Vibe知识大赏 | 《片名》+ 一句钩子」)、2–3 句简介(含年份、人名、反直觉结论)、
5–8 个话题标签、封面(取最有冲击力的那一帧,叠片名)、评论区置顶(学术引用 + 本片由 AI 代码生成的说明)。
5. 常见坑
| 现象 | 原因 | 解决 |
|---|---|---|
| 前几帧字体闪一下 | 字体没加载完就开拍 | document.fonts.ready 之后才置 READY = true;字体本地化 |
| 星空每帧都在”跳” | 用了 Math.random() |
带种子的 PRNG,位置在初始化时算一次 |
| 预览正常、成片错乱 | render 依赖上一帧状态(比如累加 x += v) |
改成 x = f(t) 的纯函数,用 --det 检查 |
| 字幕整体错位 | 时间单位混用(有的用秒、有的用”拍”) | 全工程统一单位,在 CLAUDE.md 里写死 |
| 渲染越来越慢 | 大面积 SVG 滤镜、几千个 DOM 元素 | 粒子挪到 Canvas;滤镜只加在小元素上 |
| 手机上播放黑屏 / 花屏 | 像素格式是 yuv444 | ffmpeg 加 -pix_fmt yuv420p |
| 深色背景出现色带 | 码率太低 | 降低 crf(18 左右),背景加极淡噪点 |
| 片子”像 PPT” | 只有配图、没有讲解;画面静止超过 4 秒 | 回到第 2 步找形象;保证持续微动画 |
| 一期 token 烧得很快 | 反复全片重渲、上下文过长 | 用 --clip 只重渲出问题的段落;阶段之间 /clear,靠 facts.md 和分镜表传递状态 |
6. 版权、合规与”模型味”
- 音乐版权:别直接用从视频网站扒下来的热门 BGM,平台曲库或自己合成的音乐最稳妥。部分 Skill 附带的默认 BGM 版权不归作者,公开发布前务必替换;
- AI 生成标识:国内《人工智能生成合成内容标识办法》已于 2025 年 9 月起施行,各平台发布时都有”AI 生成”声明选项,照实勾选。用生图模型补的写实镜头,画面里也建议标”AI 示意”;
- 事实准确:知识片最怕错。数字精确、示意的地方写明示意、有争议的结论并列两说;结尾放学术引用;
- 不要照搬别人的片子:一些仓库附带了对爆款原片的逐句拆解,那是学习材料,字幕和画面设计版权属于原作者;
- 警惕”模型味”:界面新闻那篇报道也指出了这个问题——相似的暗色背景、发光线条、粒子特效、同一类电子 BGM,刷到第 10 支就分不清彼此了。工具抹平了手艺门槛,但选题嗅觉、找形象的能力和逐帧打磨的耐心,依然是你自己的。
7. 总结
把整篇文章压缩成一张清单:
- 本质:Vibe 知识大赏是”代码即画面”——模型写网页,网页里的每一帧都是时间 t 的确定性函数,无头浏览器逐帧截图,ffmpeg 合成,不调用任何视频生成模型;
- SVG 的价值:矢量、分辨率无关、文字排版强、自带路径几何 API、模型写得好;描边自绘、路径跟随、辉光滤镜三板斧覆盖了大部分知识片画面;
- 环境:Claude Code + Node/Python + Playwright(Chromium) + ffmpeg + 本地开源字体,就够出片;
- 流程:选题与事实表 → 找形象 → 文案与分镜表 → 定外观写进 CLAUDE.md → 先做最难的一镜 → 看图改图 → 30 秒样片 → 铺全片 → 声音 → 三遍终检 → 发布;
- 真正的门槛:不在代码,而在讲解设计——屏上的东西观众要认得出、看得见它在变、看完讲得出”因为……所以……”。
技术管线是可以复制的,一个 Skill 就能装好;但”一个概念该用什么形象来演”这件事,没法复制。这也是这股风潮退去以后,真正能留下来的东西。
参考资料
- 界面新闻:新人半月涨粉 60 万,抖音、B 站、小红书抢跑”Vibe 知识”赛道
- 七牛云:Opus 5.5 动效视频完整教程:用代码”拍”视频的技术原理与 6 个开源模板
- andyhuo520/vibe-knowledge:带旁白、44 套风格的 Claude Code Skill
- HeyChengC/vibe-knowledge-film:无旁白知识短片 Skill,讲解设计方法论很值得读
- wchhywizd/vibe-knowledge-interactive:互动式开场与爆款样本数据
- xiazhuo123456789/vibe-knowledge-video 风格规范:逆向 8 条原片的风格 DNA
- Claude Code Quickstart:官方安装与入门文档
分类:AI / 教程 · 标签:Claude Code / Vibe知识大赏 / SVG / 代码动画 / Playwright / ffmpeg / AI视频 / Agent Skill