- 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
134 lines
6.9 KiB
Markdown
134 lines
6.9 KiB
Markdown
# Music Visualizer
|
||
|
||
把一份 MusicXML / MXL / MIDI 谱面变成横向滚动、单行不换页的音乐视频:谱面始终只有一行,发光小球沿真实符头跳跃,支持实时调参并用 Remotion 在本地导出 MP4。
|
||
|
||
视觉与运动参数参考了 [Dancing Notes](https://github.com/SyanChen7/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 默认从常见安装路径查找,也可以显式指定:
|
||
|
||
```powershell
|
||
$env:MUSESCORE_PATH = "C:\Program Files\MuseScore 4\bin\MuseScore4.exe"
|
||
```
|
||
|
||
## 开发
|
||
|
||
```powershell
|
||
npm install
|
||
npm run dev
|
||
```
|
||
|
||
- 前端:<http://127.0.0.1:5173>
|
||
- API:<http://127.0.0.1:3001>
|
||
- Vite 会把 `/api`、`/jobs`、`/demo` 代理到服务端。
|
||
|
||
## 生产运行
|
||
|
||
```powershell
|
||
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 |
|
||
|
||
## 验证脚本
|
||
|
||
```powershell
|
||
npx tsx scripts/check-demo.ts
|
||
```
|
||
|
||
会对内置示例跑解析、Verovio 单行排版、MuseScore 导出、MIDI 映射,并输出 `data/check/score.json`。也可以直接用 Remotion CLI 验证单帧:
|
||
|
||
```powershell
|
||
# 用某个已完成任务的完整设置生成单帧 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](./THIRD_PARTY_NOTICES.md)。
|
||
|
||
使用的第三方组件包括 Remotion、Verovio、MuseScore、React、Vite、zod 等,请分别遵守其许可证。Remotion 的商用许可要求请以官方说明为准。
|