pdoom-video 教程:用代码逐帧渲染带逐词卡拉 OK 的音乐视频(2026)
阅读说明
仓库信息查阅日期:2026-10-23;星数、更新时间会变,以仓库页面为准;本文不写价格。
一句话结论
mexicat/pdoom-video 是歌曲 “I'm Upping My P(doom)” 的生成式音乐视频:代码逐帧渲染,歌词做逐词卡拉 OK,每一帧由歌曲时间决定,浏览器预览和离线的 1080p60 或 4K60 导出是同一套画面。README 写明概念、treatment、歌词对齐、音频分析、渲染器、每个场景和渲染,都是在 Claude Code 里和 Claude(Opus 5.5)对话完成的。适合要在本机重渲这支片子,或按 treatment 与引擎文档改其中一块画面的人;歌曲版权归原作者。
仓库信息
截至 2026-10-23,星数、最近推送和创建时间取自仓库元数据,日期为北京时间。同一行还记录分叉 362、open_issues 为 2。仓库描述是 “Code-rendered music video for "I'm Upping My P(doom)"”。
| 仓库 | 星数 | 最近推送(北京时间) | 许可 | 创建时间 |
|---|---|---|---|---|
| mexicat/pdoom-video | 3,316 | 2026-10-06 | MIT | 2026-09-25 |
README 写明代码以 MIT License 发布。app/public/fonts/ 里的字体保留各自的许可。歌曲和歌词(audio/、lyrics/、data/lyrics.json)不在 MIT 范围内,权利归原作者,详见 README 的 Credits,下文「歌曲与字体」有转述。
另一个同名项目是 JohnHeibel/PDoomVideo。截至 2026-10-23,星数 2,520,最近推送 2026-09-25(北京时间),仓库未声明许可,再利用条款不清楚。该仓库的描述是 “Source code for the Claude Opus 5.5 music video for I'm Upping My P(doom)”。
它能做什么样的视频
这是一支已经做完的音乐视频工程,预览、导出和重算时间轴都围绕仓库里的这首歌。README 写每一帧是歌曲时间的确定函数,所以浏览器里的实时预览和离线导出一致。
歌曲版权
歌曲版权归原作者。README 的 Credits 写明 “The song is not ours”。代码的 MIT 不覆盖 audio/、lyrics/ 和 data/lyrics.json。字体在 app/public/fonts/,许可另计。再使用歌曲或歌词前,要自行确认原作者的授权。
YouTube 上的 4K 版本 是稍旧的一次渲染。README 写最新、画质最好的版本要在本地渲染。
画面是一组「末日图册」式的板块。贯穿全片的是一颗橙色的 spark,拖着一条线。P(doom) 的读数嵌在画面里往上走:0.02、0.15、0.42、0.81、0.99,直到 NaN。调色在 app/src/engine/palette.ts:墨色底 #0A0A0B、骨色 #EEE9DF、信号橙 #FF4D12。大约 2 秒的蘑菇段落使用唯一的强调色 acid #D8FF3C。歌词用 Archivo,机器和标注用 IBM Plex Mono,少数庄重的句子用 Cormorant Garamond,由笔或 spark 写出的字用单线字体。每个词在自己的 start 出现或高亮,到 end 完成,字是画面的一部分。
app/src/scenes/ 里每个板块一个模块,时间窗口在 src/timeline.ts,对齐到歌词行并吸附到节拍网格。data/audio.json 里的速度是 132.007 BPM。下表的画面摘要来自 docs/TREATMENT.md,时间以 src/timeline.ts 为准。
| 模块 | TREATMENT.md 中的画面 |
|---|---|
open | 绘图笔在坐标纸上画一只由基本图形拼成的独角兽,旁边打出 TikZ 列表,笔触再收成电路 |
loss | 训练损失曲线骤降,镜头落入等高线山谷 |
prompt | 副歌前的提示框,按词打出 token,并闪过下一个 token 的概率。变体为 chatgpt、sydney、gato,各 1 次 |
hook | “I'm upping my P(doom)” 一词一拍铺满画面,共 4 次。读数放到 0.15、0.42、0.81、0.99 |
room | FOOM 的分叉、中文房间、桌上的一袋蘑菇 |
shoggoth | 侧面的白面具透出仓库自己设计的 shoggoth(雕版排线)。眼睛旁是名字和寿命标签 |
spacetime | 示波器、黑洞、原子重排成回形针轮廓 |
ascent | 雕刻的蛇眼、股价、钞票雕版底纹里的月亮、31 位滚轮转到 1e30 FLOP/s |
bureau | 骨色纸面上的安全评估表,橙色印章 SAFE ENOUGH |
leftturn | 俯视的工程路线图直角拐走。日程条上有一个空着的 CDR 槽 |
paperclips | 回形针按拍加倍,光线步进的无限晶格,中间飘过一封外出自动回复 |
fuse | 引信烧过歌词;正交性图上的一条弦跟着音高弯 |
stack | 无限向下的 transformer 方块,一拍一块 |
dense | 安全框被字挤满、100,000 格 GPU、面具顺着斜面滚 |
loom | 续写树、歌词先以 [MASK] 出现再揭开、Droste 式的自我升级 |
ilya | 光线步进的房间,一台笔记本电脑,屏幕被涂掉 |
outro | 读数越过 1,直到 NaN。然后倒放各板块,停回第 1 帧,首尾相接 |
离线渲染器在 app/scripts/render.ts:无头 Chrome 把原始帧经 WebSocket 送给 ffmpeg。README 列出的模式:
| 模式 | README 写明的结果 |
|---|---|
video | MP4。默认 1920×1080、60 fps、x264 CRF 16、AAC |
stills | 静帧。加上 --scale 2 时是 3840×2160 的 PNG |
sheet | 接触表。--cuts 覆盖每个场景边界 |
perf | 帧时间。加上 --scale 2 时测的是 4K |
plates | 重写 public/plates/,给出场倒放蒙太奇用。改过场景后要再跑一次 |
歌曲与字体
Credits 写明:
- 歌名 “I'm Upping My P(doom)”。歌词作者是 osmarks,开头的主歌和副歌来自 MusicPerson,EleutherAI Discord 上有人提过句子,结尾和最后一遍副歌得到过 Claude 的帮助。
- 原版用 Udio 生成,2024 年 11 月发布,YouTube 原版。本仓库用的是 Suno 做的 “Claude-Pop” 版本,由 deckard(@slimer48484)于 2026 年 9 月发布。音频文件是
audio/pdoom.mp3。 - 字体:Archivo、IBM Plex Mono、Cormorant Garamond 为 SIL Open Font License。单线的 EMS 和 Hershey 经
hersheytext,Credits 写的是 OFL 或公有领域。
需要准备什么
README 的 Requirements:
已提交的 data/*.json 就是渲染所需的全部数据。重算这些 JSON 时,还要仓库里没有的分轨和中间文件,模型权重大约 4 GB。
README 写预览在近期的 Mac 上可以实时画。导出不是实时,更重。4K 整首在一台 M5 Pro 上大约 57 分钟,内存峰值大约 23 GB:每个无头 Chrome 最多约 6 GB,ffmpeg 大部分时间约 3.5 GB,接近结尾时最多约 10 GB。
安装与第一次运行
从 mexicat/pdoom-video 取得代码,在仓库根目录按 README 执行。
1. 预览
cd app
bun install
bunx vite
打开 http://localhost:5173。?t=23 从给定时间开始。
| 键 | 作用 |
|---|---|
| space | play / pause |
| ← / → | seek ±1 s(按住 shift 为 ±5 s) |
, / . | step one frame |
[ / ] | previous / next scene |
l | loop the current scene |
h | hide the UI |
2. 导出 1080p
仍在 app 目录:
cd app
bun scripts/render.ts video --samples auto --shutter 0.2 --out ../out/pdoom.mp4
out/ 不在仓库里。输出是 1920×1080、60 fps、x264 CRF 16、AAC。
运动模糊(细节在 docs/ENGINE.md 的 “Motion blur and sampling”):
--shutter 0.2是一帧时间的 1/5。一帧由摊在这段快门里的许多子帧平均而成。--samples auto按每个 32×32 小块决定张数:静止为 12,普通运镜为 36,甩镜、撞击和快速变焦为 108 或 324。- 某一小块若再加子帧,变化也不超过
--tol所设的 255 级中的级数(默认 3),就停下来,后面的子帧跳过它。 --refine frame给整帧选一个张数,比按小块采样慢。--samples 4固定为 4 张,README 写这是快速草稿。
管线:
--workers 2启动 2 个无头 Chrome,轮流渲染 8 帧一块(--chunk),按顺序送给同一个 ffmpeg。成片与只用 1 个渲染器时相同。- 重的场景里一个渲染器已经占满 GPU,第二个填轻场景的空隙。
- 等编码器的帧先留在内存里,上限
--mem-gb(默认 1),然后写到系统临时目录,上限--spool-gb(默认 20)。
其他模式是 stills、sheet、perf、plates,见上一节的表。
3. 导出 4K
cd app
bun scripts/render.ts video --scale 2 --samples auto --shutter 0.2 --x264 aq-mode=3:rc-lookahead=30 --out ../out/pdoom-4k.mp4
- 输出是按物理分辨率渲染的 3840×2160。每一层、每条线和着色器都按这个分辨率画。场景仍按 1920×1080 逻辑像素排版,所以 4K 画面和 1080p 相同,只是更锐。
- 一帧大约从 40 ms(静止)到数秒(108 到 324 张子帧的光线步进房间)。整首在 M5 Pro 上大约 57 分钟。内存峰值大约 23 GB。
- 胶片颗粒按 4K 像素绘制,编码很重。默认 CRF 16 大约 670 Mbit/s,整首大约 13 GB,是 1080p 文件的 8 倍。
--crf 18大约 450 Mbit/s,--crf 20大约 230 Mbit/s。 --scale 2对每种模式都有效。stills会保存全分辨率 PNG,perf测量 4K 的帧时间。浏览器预览在 URL 后加&scale=2。
4. 用 uv 重算歌词和节拍
渲染可以停在第 2 步或第 3 步。只有要重做 data/lyrics.json 和 data/audio.json 时才跑本节。
分轨和中间文件不在仓库里:
- Demucs 模型
htdemucs_ft的输出目录是analysis/stems/htdemucs_ft/pdoom/。README 给出的命令使用-o stems和../audio/pdoom.mp3,与这个目录对应,工作目录是analysis:
uv run python -m demucs -n htdemucs_ft -o stems ../audio/pdoom.mp3
- 人声主轨来自 mel-band-roformer 的卡拉 OK 模型(audio-separator),路径是
analysis/stems/karaoke/lead.wav。 ctc_emissions.py、whisper_run.py和vocal_feats.py把中间结果写到analysis/work/。流程写在analysis/align.py开头。
cd analysis
uv run python align.py # data/lyrics.json
uv run python analyze.py # data/audio.json
模型会把大约 4 GB 的权重下载到 analysis/.cache/。README 写用完可以删掉这个目录。
align.py 写出词级(以及一部分音节级)时间。analyze.py 写出速度、拍、强拍、段落、鼓和人声的 onset,以及响度包络。README 对这条分析链的称呼是:Demucs 分轨、与 Whisper 交叉核对的 CTC 强制对齐,以及拍、强拍和 onset 分析。
在 Claude Code 里用 Opus 5.5 驱动它
在 Claude Code 里用 /model 选 Opus 5.5,详见 Claude Opus 5.5。
README 写这支片子的概念和 treatment、歌词对齐和音频分析、渲染器、每一个场景以及渲染,都是在 Claude Code 里和 Claude(Opus 5.5)对话做出来的。分镜和风格在 docs/TREATMENT.md,引擎和场景 API 在 docs/ENGINE.md。
docs/ENGINE.md 的读者是场景作者。一个场景是 app/src/scenes/<name>.ts,默认导出继承 Scene 的类,也可以有名为 scenes/<name>-*.ts 的辅助文件。画面必须是 f.t 的纯函数,随机只用带种子的 mulberry32 或 hash。视觉上不用 Math.random()、Date.now() 或 performance.now()。自适应运动模糊会打乱子帧顺序;场景若设 stateful = true,只能用固定的 --samples 导出。歌词时间用 Lyrics 按正文查找,不在场景里写死秒数。性能目标低于 25 ms/帧。场景文件和上述辅助文件以外的路径不在场景作者的修改范围内,src/timeline.ts 也不改;引擎改动要问 lead。多数切换是强拍上的硬切。
下面的检查命令,工作目录都是 app。前两条原文自带 cd app;sheet、短片、tsc 和后面的 PDOOM_NO_HMR 在原文里紧跟这些命令,没有再写 cd。
cd app && bunx vite --port 5173
cd app && bun scripts/render.ts stills --t 12.5,13.0,14.2 --only open --out ../out/wip/open
bun scripts/render.ts sheet --from 1.5 --to 9 --n 16 --cols 4 --only open --out ../out/wip/open/sheet.png
bun scripts/render.ts video --from 20 --to 25 --only hook --out ../out/wip/hook.mp4 --preset veryfast
bunx tsc --noEmit -p tsconfig.json 2>&1 | grep scenes/yourscene
文件还在改的时候,用一个不热更新的服务,避免渲染中途刷新页面:
PDOOM_NO_HMR=1 bunx vite --port 5190
再给渲染脚本加上 --url http://localhost:5190。渲染脚本会打印 SCENE ERRORS 和浏览器控制台错误。--only a,b 只加载这些时间线条目;src/timeline.ts 里没有对应条目时画面是黑的。ENGINE.md 写静帧是检查画面的主要办法,导出后要看这些 PNG。
示例提示词(按 README 写明的用法改写,不是仓库原文):
进入 app,执行 bun install 和 bunx vite。打开 http://localhost:5173/?t=23 看预览。然后按 README 导出 1080p:bun scripts/render.ts video --samples auto --shutter 0.2 --out ../out/pdoom.mp4。先出草稿时把 --samples auto 改成 --samples 4。不要改 audio/、lyrics/ 和 data/lyrics.json。
已提交的 data/lyrics.json 和 data/audio.json 足够渲染。若要重算,按 README 准备不在仓库里的 Demucs 分轨和 analysis/work 中间文件,再在 analysis 目录执行 uv run python align.py 和 uv run python analyze.py。权重在 analysis/.cache/,大约 4 GB,用完可删。歌曲和歌词归原作者。
限制与已知问题
- YouTube 上的成片是稍旧的渲染。本地按 README 渲染,得到的是仓库里的当前画面。
- README 写预览在近期的 Mac 上实时绘制。导出不是实时。4K 在 README 的例子里是 GPU 瓶颈,整首大约 57 分钟、内存峰值大约 23 GB,默认 CRF 16 的文件大约 13 GB。
- 重算时间轴依赖未入库的分轨和
analysis/work/。人声主轨在 README 里的写法是:mel-band-roformer 卡拉 OK 模型(audio-separator),文件放在analysis/stems/karaoke/lead.wav。 docs/ENGINE.md写明:自适应采样要求画面只依赖时间。stateful场景不能自适应采样,只能用固定的--samples。按 60 fps 闪烁要用frameIdx(t),不能用Math.floor(t * 60)。docs/TREATMENT.md写 shoggoth 用仓库自己的设计,不要沿用那张广为流传的 meme 图。“shinigami eyes” 只表示物体上方的名字和寿命标签,不画动漫角色。模型名只作为歌词里的文字出现,不画标志,也不模仿真实产品界面。- 仓库 issue #4(已关闭):按 osmarks 自己的注解,“without a single CDR” 里的 CDR 指 Lisp 的 cdr,不是 Critical Design Review。
- 仓库 issue #1(已关闭):视频里对 “cdr” 的解释不正确。
docs/TREATMENT.md把leftturn写成里程碑SRR · PDR · CDR · TRR · LAUNCH,空着的 CDR 槽表示评审未召开。截至 2026-10-23,仓库有 2 个 open issue。
常见问题
能不能用 Codex 或 Cursor?
README 未写明 Codex、Cursor 或其他编程代理。它写的制作环境是 Claude Code 里的 Claude(Opus 5.5)。
成品是 HTML 还是 MP4?
预览是 Vite 打开的页面,地址是 http://localhost:5173。离线成片是 MP4:默认 1920×1080、60 fps、x264 CRF 16、AAC 音频,文件名示例为 out/pdoom.mp4。4K 命令写出 out/pdoom-4k.mp4,分辨率 3840×2160。stills 是 PNG,sheet 是接触表,plates 更新 public/plates/ 里的静帧。
商用和许可怎么算?
仓库代码是 MIT,见 LICENSE。README 写明歌曲和歌词不在这个许可里,audio/、lyrics/、data/lyrics.json 归原作者。Archivo、IBM Plex Mono、Cormorant Garamond 是 SIL Open Font License;单线 EMS 和 Hershey 经 hersheytext,Credits 写 OFL 或公有领域。再发布歌曲、歌词或字体前,要另看这些权利人的条款。
要不要 API key?有中文字幕或中文配音吗?
README 未写 API key。渲染用本机的 bun、Chrome 和 ffmpeg。重算分析时,权重大约 4 GB,下载到 analysis/.cache/。片中的卡拉 OK 是这首英文歌的逐词歌词。中文字幕和中文配音 README 未写明。
相关阅读
- 热门项目合集
- 用 Opus 5.5 做视频
- 从提示词到成片
- 场景模板
- 报错与省用量
- 开源 Skill 与工具
- Claude Opus 5.5
- 环境搭建
- 开源 AI 视频 Skill 目录
- Claude Motion(官方功能)
- awesome-opus5-5-videos 教程
- lemo-opuscar 教程
- mg-styles-15 教程
- claude-motion 教程
- motion-graphics-skills 教程
- animate 教程
参考来源
- mexicat/pdoom-video(查阅日期:2026-10-23)
- 仓库 README.md(查阅日期:2026-10-23)
- docs/TREATMENT.md(查阅日期:2026-10-23)
- docs/ENGINE.md(查阅日期:2026-10-23)
- LICENSE 的链接来自 README。许可范围(代码为 MIT,字体和歌曲歌词除外)按 README 的 License 与 Credits 转述(查阅日期:2026-10-23)