Communitygithub.com

xiaojinyu0426/doodle-music-reel

生成9:16涂鸦音乐短片。画布上的线条一笔一笔生长,播放头扫过时将其转化为音乐,画面与旋律同步构建。通过代码绘制图形并合成声音,在用户本地免费渲染为MP4视频。

doodle-music-reel 是什么?

该技能允许AI助手在用户本地生成9:16竖屏涂鸦音乐短片——画布上的一笔一画会随着播放头的移动被实时转化为音乐。其原理是:AI助手通过JavaScript代码定义每一笔的路径、颜色和时序,然后利用Puppeteer执行无头浏览器渲染每一帧,最终合成带有音频的MP4视频。支持Claude Code等本地运行环境,无需第三方API或云端资源。 技能附带完整的模板引擎和5个示例画作(如向日葵、蜗牛),用户只需复制模板、编写新的画作定义(包括笔触序列、颜色、音符映射等参数),即可一键生成30-50秒的短视频。关键设计规则包括:第一笔需横跨全页面并在两个音符之间波动以构建乐曲基底;按从低到高的层次逐步添加色彩与音符;保持同时发声的声部不超过10个以避免混浊;整体需呈现儿童画风格。 该技能非常适合用于生成令人满足的涂鸦音乐片段、将Logo或地图轮廓转化为歌曲等创意场景。AI助手会一步步引导:确认主题 → 复制模板 → 编写画作 → 校对音符表 → 生成静态预览 → 渲染视频 → 生成接触印相供检查。

兼容平台✓Claude Code~Codex CLI~Cursor
npx skills add https://github.com/xiaojinyu0426/doodle-music-reel/tree/HEAD/doodle-music-reel

在你喜欢的 AI 中提问

打开一个已预加载此 Agent Skill 的新对话。

文档

涂鸦音乐短片

格式:一张网格纸和一条黑线扫过画面。有人画了一条波浪,线条便演奏出来。他们添上一座小山,第二件乐器便加入。一根茎生长,你能听到它向上攀升。到最后,一幅完整的画和一首完整的歌同时诞生,两者源自同一笔触。无人言语,也无文字可读。参考短片获得了1250万播放量。

为何有效:两个问题同时悬在观众心头——“它会长成什么?”和“它会听起来像什么?”。每一笔都同时回答了两个问题的一部分,所以无人会划走,直到画面完成,而最后10秒便是高潮。

template/ 文件夹包含了引擎和5个完成画作。复制它,编写一个新画作,运行一条命令。

格式运作方式

逐帧测量自参考短片。引擎遵循以下数字。

部分行为
播放头从左向右扫动,然后跳回。一次扫动为2小节:BPM 100下持续4.8秒
线条高度音高。底部到顶部跨3个八度,采用五声音阶,共15个音符
吸附线条吸附到最近的音符,并在约60毫秒内滑至该位置,无新的起奏
每次交叉一个声部,带一个黑色圆点。被播放头穿过的圆圈同时发出两个音符
笔触何时开始发声仅当笔尖已超过播放头位置。单独作画不产生声音
颜色每种颜色代表一种乐器。均为柔和音色,接近纯正弦波
音量声部叠加时保持平稳,约-16 dB
顺序先横跨页面的波浪,再是主体形状,然后是细节;图层之间留1-2次扫动用于聆听,末尾约留2次扫动无新内容

步骤

  1. 获取主题。 如果用户没有指定要画什么,从 drawings.md 中提供3个选项,从会生长的东西开始。角落里的手柄是可选的,大多数短片没有,所以仅在用户要求时才添加。
  2. 复制模板: cp -r ~/.claude/skills/doodle-music-reel/template ~/doodle-reel && cd ~/doodle-reel && npm i puppeteer
  3. 编写画作 到 drawings/<name>.js。先阅读 drawings/sunflower.js,它是范例。规则如下。
  4. 读取歌曲: node make.cjs drawings/<name>.js --check。你无法听到它,所以这个音符表是读取它的方式。修复任何警告。请参阅“读取音符表”。
  5. 查看它: node make.cjs drawings/<name>.js --stills 4,12,20,30,40 将图片写入 out/<name>-stills/。选取视频长度(见音符表第一行)中不同时间点,最后一个时间点应在最后一笔之后。打开每一张。检查画作是否能被认作它本该是的东西,没有任何内容跑出页面,笔触没有意外碰撞。
  6. 渲染: node make.cjs drawings/<name>.js 写入 out/<name>.mp4(约1分钟)。
  7. 生成最终接触印相并检查后再交给用户:ffmpeg -i out/<name>.mp4 -vf "fps=1/3,scale=216:-1,tile=7x2" -frames:v 1 out/sheet.jpg
  8. 告诉用户打开声音收听。 你能阅读音符但无法听到混音,所以用户的耳朵拥有最终发言权。

编写画作

DRAW((E) => ({
  name: 'snail',       // 输出文件名
  key: 'D',            // 任意调:C, C#, D, Eb, E, F, F#, G, Ab, A, Bb, B
  scale: 'pentatonic', // pentatonic(明亮), minor(忧郁), major(7个音符,可能冲突)
  bpm: 100,            // 一次扫动为8拍
  hold: 2,             // 末尾无新内容的扫动次数
  // handle: '@yourapp',
  steps: [
    E.stroke('blue', E.wave(0, 1000, 1012, 34, 4), { speed: 430 }),
    E.wait(1.2),       // 秒,或 E.wait('wrap') 等待下一次扫动
    E.stroke('green', [[500, 1000], [490, 800], [510, 600]], { speed: 200, width: 12 }),
  ],
}))

页面为 宽1000、高1320,y=0 在顶部。x 表示音符播放的时间,y 表示哪个音符。

点与形状。 给一个笔触4-8个点,它就会呈现为平滑的手绘曲线。

  • E.wave(x0, x1, y, amp, bumps, seed) 一条横跨的波浪线
  • E.circle(cx, cy, r, startDeg, seed) 和 E.oval(cx, cy, rx, ry, startDeg, seed) 手绘,结尾会超过起点。startDeg 是笔尖落下的角度:-90为顶部,0为右侧。默认值为-100
  • E.leaf(x0, y0, x1, y1, fat) 从基部到尖端再返回的环
  • E.line(x0, y0, x1, y1) 和 E.arc(cx, cy, r, deg0, deg1)
  • E.path(svgPathString, { fit: [x0, y0, x1, y1] }) 任意SVG轮廓,使用 { sharp: true } 绘制
  • 其他情况为自己编写的点列表。对于云朵,复制 sunflower.js 中的10个点并移动它们

笔触选项。 speed 单位为像素/秒(默认520)。gap 为之后的停顿时间(默认0.22)。width 单位像素(默认10)。sharp: true 保留尖角。closed: true 将结尾与起点连接。wobble 为手抖程度(默认2.2,0为笔直)。

颜色(每种颜色代表一种乐器)。 ink, red, orange, yellow, leaf, green, sky, blue, purple, pink, brown。

五声音阶中的高度。 以下为15个阶梯,步长88单位,对应D调。其他调会改变音名但保持高度。

y音符y音符y音符
0D6440D5880D4
88B5528B4968B3
176A5616A41056A3
264F#5704F#41144F#3
352E5792E41232E3
1320D3

两个音符之间的线是中间值:1012介于A3和B3之间,1100介于F#3和A3之间。major 音阶有21个阶梯而非15个,因此请从音符表中读取其高度。

让作品优秀的原则

第一笔要横跨整个页面,位于两个音符之间的线上。 E.wave(0, 1000, 1012, 34, 4) 在整个视频中在A3和B3之间波动。它是这首歌的地板。如果它停留在一个音符上就会变成持续低音,如果它中途停止歌曲就会出现空洞。

分层构建,从低到高。 地板,然后是页面中间的主体形状,最后是高处的细节。每一层使用一种新颜色。在一个图层之后等待1-2次扫动,让人们听到它所添加的内容。

画会缓慢生长的东西。 茎或树干的速度设为170-250,让人们看着它攀升。轮廓线速度400-500。短虚线速度250-350。

形状即声音。

  • 一条长而平缓的线是一段持续旋律。
  • 一条近乎垂直的线是一串快速的音符,即播放头碰到茎时的“呼啸声”。
  • 一个圆圈是两个音符的开合。小圆圈是快速的两个音符击打,大圆圈是整个乐句。
  • 一条短虚线是一个音符。位于节拍线上的虚线(每125个单位)会产生脉冲。页面底部是低音,顶部是高音。

保持同时发声的声部不超过10个。 检查时会打印声部数量,超过时还会指明是哪些笔触导致的。每当多个笔触位于同一x位置时,声部计数就会增加,因此堆叠形状在同一列或具有深度波动的轮廓(因为每个在x方向折返的波动都会增加声部)会导致计数增加。超过10个就会变得浑浊。将形状横向移动,使波动变浅,或截断某个笔触。

保持时长30-50秒。 低于30秒歌曲无法充分构建,超过50秒观众会在结束前离开。时长会自动计算:最后一笔结束后向上取整到该扫动结束,再加上 hold 次扫动。因此它会随画作变化而变化,并且总是在一次扫动完成时结束。

它必须看起来像儿童画。 简单、可识别、使用少数颜色。如果需要标签,那就画别的。

读取音符表

--check 会按笔触打印一行:颜色、绘制时间、跨越范围、产生声部数以及演奏的音符。注意检查:

  • 第1笔 有2个或更多音符,且跨越 x 0-1000。
  • 笔触分散 在低、中、高音符区域。如果所有内容都集中在一个八度,将一些形状向页面上下移动。
  • 你意图作为旋律的形状有3个或更多音符。 只有一个音符的长线是持续低音。给它更多高度,或移动它使其跨越音符线。
  • “扫动中的静默部分”为0 或接近0。
  • 最后一笔结束 大约在视频结束前2次扫动时。

修复问题

  • 画作看起来不对: 更改点并重新运行 --stills。只需几秒,所以可以多试几次。
  • 某段听起来单薄: 添加一层虚线,或在页面底部添加一条新颜色的低音线。
  • 缺少Puppeteer: 在包含 make.cjs 的文件夹中运行 npm i puppeteer。
  • 缺少ffmpeg: 安装它(Mac上运行 brew install ffmpeg)。--check 和 --sound 不需要它即可工作,视频渲染需要它。

保持原创

复制这个格式,制作你自己的画作。不要使用其他创作者的用户名、他们的画作或他们的应用界面,也不要在视频上放置它尚未获得的播放量计数。

相关技能