Files
music-visualizer/README.md
T
blumia a237a7c604 Add one-line score visualizer with 3D orb and MP4 export
- Verovio single-system engraving, MuseScore audio/MIDI from the same source
- React + Remotion player with live camera, colour and orb controls
- Express pipeline, render queue and local H.264/AAC export
- MIT license plus third-party notices for the reference skill
2026-11-05 11:38:25 +08:00

6.9 KiB
Raw Blame History

Music Visualizer

把一份 MusicXML / MXL / MIDI 谱面变成横向滚动、单行不换页的音乐视频:谱面始终只有一行,发光小球沿真实符头跳跃,支持实时调参并用 Remotion 在本地导出 MP4。

视觉与运动参数参考了 Dancing Notes(MIT),本项目重写了排版、音频、对齐、滚动和 Web 端流水线。

功能

  • 单行谱面:Verovio breaks: none 生成一条超宽 system,按播放进度横向滚动到结尾,不换行、不翻页。
  • 音画同源:默认调用本机 MuseScore 4,从同一份 MusicXML 生成 WAV 和 MIDI;动画时间来自 MIDI,谱面符头坐标来自 Verovio SVG。
  • 发光小球:每个声部一颗球,沿符头连续跳跃;包含起跳、抛物线、落点光环、拖尾和纸面光晕。
  • 反复段:按演奏顺序回到前面的谱面位置,滚动也会短暂回退。
  • 实时预览:生成一次后,画面高度、滚动提前量、3D 视角、颜色、光晕、小球大小、标题显示等参数会立即反映在 Remotion Player 中,不需要重新跑流水线。
  • 3D 倾斜视角:可调俯仰、滚转、偏航、透视距离和缩放,内置平视 / 轻斜 / 电影 / 强透视预设。
  • 导出:使用 @remotion/renderer 在本地渲染 1080p H.264 + AAC MP4。导出前会把当前实时参数写回任务,保证视频与预览一致。
  • 输入:MusicXML、MXL(压缩包)、MIDI。MIDI 会先由 MuseScore 识别成 MusicXML。
  • 可选音频:可以上传自己的 WAV / MP3 / M4A / OGG / FLAC 替代自动合成音频;动画仍使用 MIDI/谱面时间轴。

环境要求

  • Node.js 22+(推荐 24)
  • MuseScore 4(自动合成音频、MIDI 转谱需要)
  • Chrome 或 Edge(Remotion 渲染会优先使用本机浏览器,避免下载 Headless Shell)
  • Windows PowerShell 下开发即可;其他平台同样适用

MuseScore 默认从常见安装路径查找,也可以显式指定:

$env:MUSESCORE_PATH = "C:\Program Files\MuseScore 4\bin\MuseScore4.exe"

开发

npm install
npm run dev

生产运行

npm run build
npm start

生产模式由 Express 同时提供 API 和 dist/client 静态文件,默认端口 3001。

可配置环境变量:

变量 默认值 说明
PORT 3001 服务端口
PUBLIC_BASE_URL http://127.0.0.1:${PORT} Remotion 渲染时访问 SVG / 音频的公开地址
DATA_DIR data 任务与产物目录
MUSESCORE_PATH 自动查找 MuseScore 4 可执行文件
REMOTION_BROWSER_EXECUTABLE / BROWSER_EXECUTABLE 自动查找 指定 Chrome / Edge 可执行文件

使用流程

  1. 拖入 MusicXML / MXL / MIDI;或者点“加载示例曲”。
  2. 可选填写标题、副标题、作曲者;留空时读取谱面信息。
  3. 选择画幅、帧率、谱面高度、3D 视角和颜色。
  4. 点“生成预览”,等待解析、MuseScore 合成、Verovio 排版和 MIDI 对齐完成。
  5. 在右侧 Remotion Player 中播放、拖动时间轴、实时调整左侧画面参数。
  6. 点“导出 MP4”,服务端会先保存当前参数,再在本地渲染视频并给出下载链接。

首次生成需要先跑完一次流水线;之后调整视觉参数都是即时预览。修改谱面/音频/标题文字本身需要重新生成,标题、副标题、作曲者的非空修改也会在导出前写入。

开发时改渲染代码

服务端第一次导出时会把 Remotion 项目打包一次,并缓存在内存里。缓存带源码指纹:改动 src/remotion/、src/shared/ 或 public/ 后再次导出会自动重新打包(日志会打印 [render] sources changed, rebuilding the Remotion bundle),不需要重启服务,也不会出现“预览是新的、导出还是旧画面”。

3D 视角

“3D 视角”把纸面、谱面、纸面光和 Canvas 小球放进同一个 CSS 3D 变换平面,因此小球和符头会一起倾斜、透视,不会错位。

  • 俯仰角:数值越大,谱面上方越向后倒。
  • 滚转角:负值让谱面右侧抬高,形成参考视频里的斜线。
  • 偏航角:左右转向;过大时透视会明显压缩。
  • 透视距离:越小透视越强,越大越接近正交投影。
  • 视角缩放:倾斜后用于补足画面;谱面被裁切或留白时优先调它。

API

方法 路径 说明
GET /api/health MuseScore / 浏览器 / FFmpeg 状态
GET /api/jobs 最近任务
POST /api/jobs 创建任务,multipart/form-data:score、可选 audio、settings(JSON)、title、subtitle、composer
GET /api/jobs/:id 任务状态与预览数据
PATCH /api/jobs/:id/settings 保存实时预览参数,并重新计算滚动关键帧
POST /api/jobs/:id/render 加入渲染队列
GET /api/jobs/:id/video 下载 MP4

验证脚本

npx tsx scripts/check-demo.ts

会对内置示例跑解析、Verovio 单行排版、MuseScore 导出、MIDI 映射,并输出 data/check/score.json。也可以直接用 Remotion CLI 验证单帧:

# 用某个已完成任务的完整设置生成单帧 props(含按当前画幅重算的滚动关键帧)
npx tsx scripts/props-from-job.ts <jobId> data/check/p-job.json

npx remotion still src/remotion/index.ts MusicScroll data/check/frame.png `
  --frame=300 --props=data/check/p-job.json `
  --browser-executable="C:\Program Files\Google\Chrome\Application\chrome.exe"

<jobId> 是 data/jobs/ 下的目录名,props-from-job.ts 会读取该任务的 score.json 与 job.json,因此导出的单帧和网页里看到的一致。

已知限制

  • 反复、ending、D.C./D.S. 等跳转按谱面结构做近似展开;复杂跳转建议先在 MuseScore 中展开后导出 MusicXML。
  • 多声部/多谱表会渲染成同一条 system 上的多组五线谱,不是多行总谱。
  • 歌词、和弦符号、指法、tab 等会随 Verovio SVG 显示,但不参与小球坐标。
  • 上传音频时,动画时间仍来自 MIDI/谱面;录音速度与谱面差异过大时会渐进漂移,可用“音频偏移”做整体校准。
  • 视频最长 20 分钟,上传文件最大 30MB。
  • 渲染是 CPU 本地渲染,长曲会比较慢;可降低 fps 或谱面分辨率来加速。

许可与归属

本项目代码以 MIT 许可发布。

视觉与运动设计参考 Dancing Notes,Copyright (c) 2026 言说新事 (SyanChen7),MIT License。原版权声明与许可全文见 THIRD_PARTY_NOTICES.md。

使用的第三方组件包括 Remotion、Verovio、MuseScore、React、Vite、zod 等,请分别遵守其许可证。Remotion 的商用许可要求请以官方说明为准。