pdoom-video 教程:用代码逐帧渲染带逐词卡拉 OK 的音乐视频(2026)

推荐链接(推广):数字严选大约 14 分钟AI 视频Opus 5.5 做视频Claude Code 视频pdoom-video音乐视频three.js

阅读说明

仓库信息查阅日期:2026-10-23;星数、更新时间会变,以仓库页面为准;本文不写价格。

一句话结论

mexicat/pdoom-videoopen in new window 是歌曲 “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-videoopen in new window3,3162026-10-06MITopen in new window2026-09-25

README 写明代码以 MIT Licenseopen in new window 发布。app/public/fonts/ 里的字体保留各自的许可。歌曲和歌词(audio/、lyrics/、data/lyrics.json)不在 MIT 范围内,权利归原作者,详见 README 的 Credits,下文「歌曲与字体」有转述。

另一个同名项目是 JohnHeibel/PDoomVideoopen in new window。截至 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 版本open in new window 是稍旧的一次渲染。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
roomFOOM 的分叉、中文房间、桌上的一袋蘑菇
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 写明的结果
videoMP4。默认 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)”。歌词作者是 osmarksopen in new window,开头的主歌和副歌来自 MusicPersonopen in new window,EleutherAI Discord 上有人提过句子,结尾和最后一遍副歌得到过 Claude 的帮助。
  • 原版用 Udio 生成,2024 年 11 月发布,YouTube 原版open in new window。本仓库用的是 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-videoopen in new window 取得代码,在仓库根目录按 README 执行。

1. 预览

cd app
bun install
bunx vite

打开 http://localhost:5173。?t=23 从给定时间开始。

键作用
spaceplay / pause
← / →seek ±1 s(按住 shift 为 ±5 s)
, / .step one frame
[ / ]previous / next scene
lloop the current scene
hhide 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.mdopen in new window,引擎和场景 API 在 docs/ENGINE.mdopen in new window。

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,见 LICENSEopen in new window。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 未写明。

相关阅读

参考来源

上次编辑于:
贡献者: Masoooon