🎁 福利专区全网大模型免费应用 + 新用户福利 + 注册活动入口,低成本玩转 AI

AI 音乐工作站 iwbtc/ai-music-studio

DeepSeek Harness
iwbtc6 天前有提交已提供中文文档扫描:含敏感能力

让 AI 智能体帮你建轨、编曲、混音并导出工程

29.5/100
综合分
0
GitHub 星标
—
npm 周下载
—/5
用户评分

数据截至 2026/11/2 · 周下载取自 npm 全网(含 CI / 镜像),非本站安装数;综合分由星标、活跃度与兼容性检查合成。

安装命令 · 需先装 dsh CLI 引擎
dsh plugin --profile web add iwbtc/ai-music-studio
该包不可直接 npm 安装,改从 GitHub 源安装(明细见下方安装检查)

状态速览

判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态
信任档位:仅索引
是什么
dsh 原生插件 · desktop
装得上吗
本站尚未做安装检查
安全吗
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
还在维护吗
活跃:最近一次提交在 6 天前
档位由哪些信号合成

本站实装验证(真实安装 L4 覆盖全站;L5 为运行时冒烟或实机截图,覆盖范围小于 L4) · 验证所用 dsh 版本 · 静态安装检查 · 风险分级 · 仓库维护状态。 下方各区块是它的证据明细。

验证判据与等级说明 →
社区实装还没有人打卡 · 装过的第一个就是你
安全扫描自动 · 静态分析源码
v2.7.0
🔵 扫描:含敏感能力尚无人工评估
展开查看扫描说明与证据 ↓

静态扫描发现插件具备触达本地系统的能力:执行外部命令、读写/删除本地文件、读取剪贴板或密钥类环境变量(至少其一)。这是能力清单,不是危险判定——具体能力项与证据见下方,安装前请自行判断是否需要。

可执行外部命令读写/删除本地文件发起外部网络请求
查看扫描证据(共 174 处,展示前 133 条)
  • 读取本地文件
    src/host/app-status.js:62
    raw = await readFile(filePath, 'utf8')
  • 读取本地文件
    src/host/tools.js:255
    info = await stat(resolved)
  • 读取本地文件
    src/host/tools.js:271
    await access(resolved, 2)
  • 读取本地文件
    src/host/tools.js:290
    const dirs = await readdir(historyRoot, { withFileTypes: true })
  • 读取本地文件
    src/host/tools.js:313
    files = await readdir(projectsDir(dataDir))
  • 读取本地文件
    src/host/tools.js:321
    info = await stat(filePath)
  • 读取本地文件
    src/host/tools.js:328
    const parsed = JSON.parse(await readFile(filePath, 'utf8'))
  • 删除本地文件
    src/host/tools.js:647
    await rm(filePath, { force: true })
  • 删除本地文件
    src/host/tools.js:2333
    await rm(filePath, { force: true })
  • 删除本地文件
    src/host/tools.js:4222
    if (freeze.cacheFile) await rm(path.join(state.dataDir, 'plugin-cache', path.basename(freeze.cacheFile)), { force: true }).catch(() => {})
  • 删除本地文件
    src/host/tools.js:4223
    if (freeze.hash) await rm(path.join(state.dataDir, 'media', `freeze-${freeze.hash}.wav`), { force: true }).catch(() => {})
  • 读取本地文件
    src/host/tool-bridge.js:41
    const raw = await readFile(path.join(dir, ENDPOINT_FILE), 'utf8')
  • 发起网络请求
    src/host/tool-bridge.js:72
    const res = await fetch(`${url}/studio/api/health`, { signal: AbortSignal.timeout(options.timeoutMs ?? 1200) })
  • 发起网络请求
    src/host/tool-bridge.js:104
    const res = await fetch(`${baseUrl}/studio/api/tool-call`, {
  • 读取本地文件
    src/host/app-info.js:72
    const raw = readFileSync(candidate, 'utf8')
  • 读取本地文件
    src/host/app-info.js:87
    const raw = readFileSync(path.join(dataDir, 'app-endpoint.json'), 'utf8')
  • 读取本地文件
    src/host/state.js:195
    const rawLock = JSON.parse(readFileSync(lockPath, 'utf8'))
  • 写入本地文件
    src/host/state.js:206
    mkdirSync(recoveryDir, { recursive: true })
  • 写入本地文件
    src/host/state.js:207
    writeFileSync(
  • 删除本地文件
    src/host/state.js:219
    unlinkSync(lockPath)
  • 读取本地文件
    src/host/state.js:228
    rawText = readFileSync(autosavePath, 'utf8')
  • 写入本地文件
    src/host/state.js:275
    mkdirSync(dir, { recursive: true })
  • 写入本地文件
    src/host/state.js:277
    writeFileSync(target, rawText, 'utf8')
  • 写入本地文件
    src/host/state.js:295
    mkdirSync(legacyBackupDir, { recursive: true })
  • 写入本地文件
    src/host/state.js:297
    writeFileSync(target, rawText, 'utf8')
  • 读取本地文件
    src/host/state.js:334
    const rawActive = JSON.parse(readFileSync(activeMetaPath, 'utf8'))
  • 读取本地文件
    src/host/state.js:355
    raw = readFileSync(filePath, 'utf8')
  • 读取本地文件
    src/host/state.js:502
    files = await readdir(recoveryDir)
  • 删除本地文件
    src/host/state.js:509
    await unlink(path.join(recoveryDir, name))
  • 删除本地文件
    src/host/state.js:576
    rmSync(autosavePath, { force: true })
  • 读取本地文件
    src/host/state.js:581
    for (const name of readdirSync(recoveryDir)) {
  • 删除本地文件
    src/host/state.js:584
    rmSync(path.join(recoveryDir, name), { force: true })
  • 写入本地文件
    src/host/midi.js:315
    await mkdir(exportsDir, { recursive: true })
  • 写入本地文件
    src/host/midi.js:318
    await writeFile(tmpPath, buffer)
  • 写入本地文件
    src/host/midi.js:319
    await rename(tmpPath, filePath)
  • 写入本地文件
    src/host/media-files.js:54
    await mkdir(mediaDir, { recursive: true })
  • 写入本地文件
    src/host/media-files.js:65
    await writeFile(filePath, buffer, { flag: 'wx' })
  • 写入本地文件
    src/host/projects.js:74
    await mkdir(dir, { recursive: true })
  • 写入本地文件
    src/host/projects.js:76
    await writeFile(target, rawText, 'utf8')
  • 读取本地文件
    src/host/projects.js:118
    const info = await stat(projectFilePath(dataDir, name))
  • 读取本地文件
    src/host/projects.js:134
    entries = await readdir(dir, { withFileTypes: true })
  • 读取本地文件
    src/host/projects.js:149
    const [raw, info] = await Promise.all([readFile(filePath, 'utf8'), stat(filePath)])
  • 读取本地文件
    src/host/projects.js:149
    const [raw, info] = await Promise.all([readFile(filePath, 'utf8'), stat(filePath)])
  • 写入本地文件
    src/host/projects.js:211
    await mkdir(dir, { recursive: true })
  • 写入本地文件
    src/host/projects.js:214
    await writeFile(tmpPath, body, 'utf8')
  • 写入本地文件
    src/host/projects.js:215
    await rename(tmpPath, filePath)
  • 读取本地文件
    src/host/projects.js:216
    const info = await stat(filePath)
  • 读取本地文件
    src/host/projects.js:238
    ;[raw, info] = await Promise.all([readFile(filePath, 'utf8'), stat(filePath)])
  • 删除本地文件
    src/host/projects.js:280
    await unlink(filePath)
  • 写入本地文件
    src/host/projects.js:336
    await mkdir(dir, { recursive: true })
  • 删除本地文件
    src/host/projects.js:363
    await unlink(path.join(dir, stale))
  • 读取本地文件
    src/host/routes.js:364
    if (existsSync(project.lastExport.path)) return project
  • 读取本地文件
    src/host/routes.js:457
    await stat(candidatePath)
  • 写入本地文件
    src/host/routes.js:521
    await mkdir(outputDir, { recursive: true })
  • 写入本地文件
    src/host/routes.js:523
    await writeFile(`${target.path}.tmp`, buffer)
  • 写入本地文件
    src/host/routes.js:524
    await rename(`${target.path}.tmp`, target.path)
  • 读取本地文件
    src/host/routes.js:916
    ;[data, info] = await Promise.all([readFile(resolved), stat(resolved)])
  • 读取本地文件
    src/host/routes.js:916
    ;[data, info] = await Promise.all([readFile(resolved), stat(resolved)])
  • 读取本地文件
    src/host/routes.js:963
    data = await readFile(resolved)
  • 删除本地文件
    src/host/routes.js:1107
    await rm(filePath, { force: true })
  • 删除本地文件
    src/host/routes.js:1885
    await rm(String(state.dataDir) + '/plugin-cache/' + String(freeze.cacheFile).replace(/^.*[ /]/, ''), { force: true }).catch(() => {})
  • 读取本地文件
    src/host/settings.js:45
    const raw = await readFile(settingsFilePath(dataDir), 'utf8')
  • 写入本地文件
    src/host/settings.js:82
    await mkdir(dir, { recursive: true })
  • 写入本地文件
    src/host/settings.js:86
    await writeFile(temp, `${JSON.stringify(next, null, 2)}\n`, 'utf8')
  • 写入本地文件
    src/host/settings.js:87
    await rename(temp, file)
  • 删除本地文件
    src/host/settings.js:89
    await rm(temp, { force: true }).catch(() => {})
  • 读取本地文件
    src/host/update-check.js:62
    raw = await readFile(file, 'utf8')
  • 读取本地文件
    src/host/diagnostics.js:42
    names = await readdir(dir)
  • 删除本地文件
    src/host/diagnostics.js:49
    for (const name of stale) await rm(path.join(dir, name), { force: true }).catch(() => {})
  • 写入本地文件
    src/host/diagnostics.js:61
    await mkdir(dir, { recursive: true })
  • 写入本地文件
    src/host/diagnostics.js:78
    await writeFile(temp, `${JSON.stringify(report, null, 2)}\n`, 'utf8')
  • 写入本地文件
    src/host/diagnostics.js:79
    await rename(temp, file)
  • 删除本地文件
    src/host/diagnostics.js:81
    await rm(temp, { force: true }).catch(() => {})
  • 读取本地文件
    src/host/diagnostics.js:94
    names = await readdir(dir)
  • 读取本地文件
    src/host/diagnostics.js:103
    const parsed = JSON.parse(await readFile(path.join(dir, name), 'utf8'))
  • 读取本地文件
    src/host/diagnostics.js:209
    names = await readdir(dir)
  • 读取本地文件
    src/host/diagnostics.js:217
    bytes += (await stat(path.join(dir, name))).size
  • 读取本地文件
    src/host/plugin-freeze.js:217
    const buffer = await readFile(filePath)
  • 读取本地文件
    src/host/plugin-freeze.js:228
    return candidates.find((candidate) => existsSync(candidate)) ?? null
  • 写入本地文件
    src/host/plugin-freeze.js:368
    await mkdir(cacheDir, { recursive: true })
  • 删除本地文件
    src/host/plugin-freeze.js:420
    if (currentPath) await rm(currentPath, { force: true }).catch(() => {})
  • 写入本地文件
    src/host/plugin-freeze.js:430
    await copyFile(currentPath, finalCachePath)
  • 删除本地文件
    src/host/plugin-freeze.js:431
    await rm(currentPath, { force: true }).catch(() => {})
  • 写入本地文件
    src/host/plugin-freeze.js:434
    await mkdir(mediaDir, { recursive: true })
  • 写入本地文件
    src/host/plugin-freeze.js:437
    await copyFile(finalCachePath, mediaPath)
  • 读取本地文件
    src/host/plugin-freeze.js:438
    const info = await stat(mediaPath)
  • 读取本地文件
    src/host/plugin-freeze.js:451
    const finalDecoded = readPcm16Wav(await readFile(finalCachePath))
  • 删除本地文件
    src/host/plugin-freeze.js:487
    if (currentPath) await rm(currentPath, { force: true }).catch(() => {})
  • 删除本地文件
    src/host/plugin-freeze.js:525
    if (freeze.cacheFile) await rm(path.join(freezeCacheDir(dataDir), path.basename(freeze.cacheFile)), { force: true }).catch(() => {})
  • 删除本地文件
    src/host/plugin-freeze.js:526
    if (freeze.hash) await rm(path.join(String(dataDir), 'media', `freeze-${freeze.hash}.wav`), { force: true }).catch(() => {})
  • 读取本地文件
    src/host/plugin-freeze.js:559
    if (status === 'current' && cacheFile && !existsSync(cacheFile)) status = 'error'
  • 读取本地文件
    src/host/plugin-freeze.js:620
    if (cacheFile && existsSync(cacheFile)) continue
  • 读取本地文件
    src/host/plugin-host-client.js:25
    if (existsSync(resolved)) return resolved
  • 读取本地文件
    src/host/plugin-host-client.js:42
    if (existsSync(candidate)) return candidate
  • 读取本地文件
    src/host/plugin-host-client.js:51
    if (existsSync(candidate)) return candidate
  • 读取本地文件
    src/host/plugin-host-client.js:55
    if (resourcesPath && existsSync(resourcesPath)) return packagedCandidates[0] ?? DEFAULT_SIDECAR_PATH
  • 读取本地文件
    src/host/plugin-host-client.js:75
    if (existsSync(candidate)) return candidate
  • 读取本地文件
    src/host/plugin-host-client.js:91
    if (!existsSync(resolved)) throw new PluginHostError(`AIMS_NODE_BIN 不存在:${resolved}(请指向可用的 node.exe)`, 'PLUGIN_HOST_NO_NODE')
  • 删除本地文件递归
    src/host/plugin-registry.js:17
    await rm(target, { recursive: true, force: true })
  • 读取本地文件
    src/host/plugin-registry.js:30
    await stat(target)
  • 读取本地文件
    src/host/plugin-registry.js:55
    info = await stat(resolved)
  • 读取本地文件
    src/host/plugin-registry.js:67
    entries = await readdir(dir, { withFileTypes: true })
  • 读取本地文件
    src/host/plugin-registry.js:79
    try { entries = await readdir(dir, { withFileTypes: true }) } catch { return null }
  • 读取本地文件
    src/host/plugin-registry.js:150
    const parsed = JSON.parse(await readFile(plugRegistryPath(dataDir), 'utf8'))
  • 写入本地文件
    src/host/plugin-registry.js:164
    await mkdir(path.dirname(file), { recursive: true })
  • 写入本地文件
    src/host/plugin-registry.js:168
    await writeFile(temp, `${JSON.stringify(payload, null, 2)}\n`, 'utf8')
  • 写入本地文件
    src/host/plugin-registry.js:169
    await rename(temp, file)
  • 删除本地文件
    src/host/plugin-registry.js:171
    await rm(temp, { force: true }).catch(() => {})
  • 读取本地文件
    src/host/plugin-registry.js:206
    entries = await readdir(dir, { withFileTypes: true })
  • 写入本地文件
    src/host/plugin-registry.js:363
    await mkdir(managedDir, { recursive: true })
  • 写入本地文件
    src/host/plugin-registry.js:385
    await mkdir(stagingRoot, { recursive: true })
  • 写入本地文件
    src/host/plugin-registry.js:394
    await rename(targetRoot, backupRoot)
  • 读取本地文件
    src/standalone/launch.mjs:44
    const raw = await readFile(path.join(dataDir, ENDPOINT_FILE), 'utf8')
  • 发起网络请求
    src/standalone/launch.mjs:53
    const res = await fetch(`http://127.0.0.1:${port}/studio/api/health`, { signal: AbortSignal.timeout(1500) })
  • 读取本地文件
    src/standalone/launch.mjs:62
    if (existsSync(candidate)) return candidate
  • 发起网络请求
    src/standalone/launch.mjs:83
    const res = await fetch(`http://127.0.0.1:${port}/studio/api/ui-status`, { signal: AbortSignal.timeout(1500) })
  • 执行外部命令固定命令
    src/standalone/launch.mjs:95
    spawn('cmd.exe', ['/c', 'start', '', url], { detached: true, stdio: 'ignore' }).unref()
  • 写入本地文件
    src/standalone/launch.mjs:98
    await mkdir(browserProfileDir, { recursive: true })
  • 执行外部命令来自配置/变量
    src/standalone/launch.mjs:99
    const child = spawn(browser, browserArgs(url), { detached: false, stdio: 'ignore' })
  • 读取本地文件
    src/standalone/server.mjs:98
    parsed = JSON.parse(readFileSync(path.join(recoveryDir, AUTOSAVE_FILE_NAME), 'utf8'))
  • 读取本地文件
    src/standalone/server.mjs:117
    const parsed = JSON.parse(readFileSync(path.join(dataDir, 'project.json'), 'utf8'))
  • 读取本地文件
    src/standalone/server.mjs:159
    rawLock = readFileSync(lockPath, 'utf8')
  • 删除本地文件
    src/standalone/server.mjs:174
    unlinkSync(lockPath)
  • 读取本地文件
    src/standalone/server.mjs:240
    const data = await readFile(filePath)
  • 写入本地文件
    src/standalone/server.mjs:305
    await mkdir(dir, { recursive: true })
  • 写入本地文件
    src/standalone/server.mjs:306
    await writeFile(path.join(dir, ENDPOINT_FILE), body, 'utf8')
  • 读取本地文件
    src/standalone/server.mjs:484
    if (!existsSync(filePath)) return sendJson(res, 404, { ok: false, error: `缺少采样 ${pathname}` })
  • 读取本地文件
    src/standalone/server.mjs:495
    if (!existsSync(filePath)) return sendJson(res, 404, { ok: false, error: `缺少音色库 ${pathname}` })
  • 删除本地文件
    src/standalone/server.mjs:555
    await unlink(path.join(dataDir, ENDPOINT_FILE))
  • 读取本地文件
    src/standalone/stop.mjs:19
    info = JSON.parse(await readFile(endpointPath, 'utf8'))
  • 发起网络请求
    src/standalone/stop.mjs:29
    const res = await fetch(`http://127.0.0.1:${port}/studio/api/shutdown`, {
  • 执行外部命令固定命令
    src/standalone/stop.mjs:40
    execFile('taskkill', ['/PID', String(info.pid), '/F', '/T'], () => resolve())
  • 删除本地文件
    src/standalone/stop.mjs:45
    await unlink(endpointPath)
扫描于 2026/11/4(0 天前) · 范围 入口闭包 + 发布文件清单 · 来源 GitHub 仓库

静态扫描只反映源码中出现的调用,不构成安全背书;人工评估与自动扫描相互独立、互不覆盖。

给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个

Windows 桌面 AI 音乐工作站(Electron + Web Audio + VST3 + DeepSeek Harness 插件)。早期原型。

README

由 DeepSeek 最新模型翻译生成
AI 音乐工作室 · AI Music Studio 一个 Windows 桌面音乐工作站(FL Studio 风格的浅色 DAW)。你可以像普通 DAW 一样手动编曲,也可以让 AI 智能体通过工具自动建轨、写旋律、编排、混音和导出。 这是早期原型,不是成熟商业软件。 仍有很多 bug、未完成的功能,作者不承诺维护和支持;请自行备份工程,使用风险自负。 本项目与 Image-Line / FL Studio 没有任何关联。 主界面 这是什么 - 本地运行的桌面 DAW:播放列表、通道机架、钢琴卷帘、混音台、自动化曲线、效果器链、音频片段、键盘演奏/录制。 - DeepSeek Harness 插件:在 DeepSeek Harness 中安装后,AI 可以调用 110+ 个 studio_ 工具来创作和修改工程。 - 使用 GeneralUser GS 真实采样音色库(32 个采样乐器 + 4 套采样鼓机 + 15 个内置效果器)。 - 支持 外部 VST3 插件(Windows x64):乐器、效果器、参数、预设、参数自动化、冻结/导出。 - 所有工程、音频和导出都保存在本机,不需要登录、不上传工程。 这不是什么 - 不是在线 AI 音乐生成服务:仓库不包含 AI 模型,也不会把提示词变成音频。AI 只是通过工具操作本机 DAW。
展开完整文档(README 剩余 1 节)
AI 音乐工作室 · AI Music Studio

一个 Windows 桌面音乐工作站(FL Studio 风格的浅色 DAW)。你可以像普通 DAW 一样手动编曲,也可以让 AI 智能体通过工具自动建轨、写旋律、编排、混音和导出。

这是早期原型,不是成熟商业软件。 仍有很多 bug、未完成的功能,作者不承诺维护和支持;请自行备份工程,使用风险自负。
本项目与 Image-Line / FL Studio 没有任何关联。

主界面

这是什么

- 本地运行的桌面 DAW:播放列表、通道机架、钢琴卷帘、混音台、自动化曲线、效果器链、音频片段、键盘演奏/录制。
- DeepSeek Harness 插件:在 DeepSeek Harness 中安装后,AI 可以调用 110+ 个 studio_ 工具来创作和修改工程。
- 使用 GeneralUser GS 真实采样音色库(32 个采样乐器 + 4 套采样鼓机 + 15 个内置效果器)。
- 支持 外部 VST3 插件(Windows x64):乐器、效果器、参数、预设、参数自动化、冻结/导出。
- 所有工程、音频和导出都保存在本机,不需要登录、不上传工程。

这不是什么

- 不是在线 AI 音乐生成服务:仓库不包含 AI 模型,也不会把提示词变成音频。AI 只是通过工具操作本机 DAW。
- 不是完整商业 DAW:没有插件原生界面、没有 macOS、没有 VST2/32 位、没有云同步。
- AI 听不见声音:所有「混音建议/质量分析」都是本地指标算法(LUFS、频谱、峰值、RMS 等),不是人的听觉判断。
- 不包含第三方商业插件、商业歌曲或音色库;VST3 插件需要你自己安装并遵守其许可。

功能

| 模块 | 能力 |
| 编曲 | 多轨、pattern/clip 播放列表、段落、复制、拖拽、裁剪 |
| 钢琴卷帘 | 画/拖/删音符、力度、量化、人性化、和弦、琶音、MIDI 导入导出 |
| 音色 | 32 个 GeneralUser GS 采样乐器、4 套采样鼓机、8 个内置合成器音色 |
| 混音 | 音量/声像/静音/独奏、发送、返回总线 FX、侧链压缩、分轨导出 |
| 自动化 | 音量、声像、滤波、表情、CC、插件参数曲线 |
| 效果器 | 15 种内置效果器 + 外部 VST3 |
| 音频 | 导入 WAV/MP3/FLAC/OGG、录音、片段增益/淡变/反向/拉伸/变调、分割 |
| AI | 110+ 个 studio_ 工具:生成 beat/声部/变体、混音建议、质量报告、快速反馈 |
| 导出 | WAV/MP3/FLAC/MIDI/分轨 |

普通用户:安装使用

1. 打开仓库右侧 Releases,下载 AI-Music-Studio-Setup-2.4.0.exe(本地构建产物文件名为 AI音乐工作室-Setup-2.4.0.exe)。
2. 双击安装(用户级安装,不需要管理员权限),完成后打开桌面的「AI 音乐工作室」。
3. 首次打开点击界面上的「立即启用」或播放按钮解锁音频。
4. 直接播放演示工程,或 文件 → 新建工程 手动编曲。
5. 保存/导出在 文件 菜单;工程数据默认在 %APPDATA%\AI音乐工作室\data。

安装包未做代码签名,Windows SmartScreen 可能提示「仍要运行」。

AI 功能:需要 DeepSeek Harness

本仓库同时是 DeepSeek Harness (DSH) 插件。只安装桌面 exe 时,你可以手动做音乐,但 AI 不会自己出现;要使用 AI 创作,需要:

1. 安装 DeepSeek Harness(以其官方文档为准)。
2. 在本仓库目录运行:

node scripts/install.mjs --dry-run # 先看会改什么
node scripts/install.mjs # 安装到 DSH desktop profile

如果 DSH 不在默认路径,先设置 DSH_EXE 和可选的 DSH_CLI、DSH_HOME。

3. 在 DSH 对话里让 AI 使用 studio_* 工具。常用入口:
- studio_app_info:确认窗口、工程和合法音色 id;
- studio_generate_beat:一键生成鼓/贝斯/和弦/主音;
- studio_quick_mix_check:改完参数后秒级检查峰/削波/低频;
- studio_render_preview:导出前的完整质量预览;
- studio_export:导出成品。

AI 工具会读写本机工程;对话内容是否上传取决于你使用的 DSH/模型服务,与本项目无关。

外部 VST3

- 仅 Windows x64,仅 VST3。
- 在插件管理器扫描/导入 .vst3;托管副本在 data/plugins。
- 外部乐器/效果器运行在独立 Node sidecar 中;崩溃不会直接拖垮主程序。
- 首版没有插件原生 GUI,只有通用参数面板、预设、参数自动化。
- VST3 是外部代码,加载前请确认来源和许可;作者不对第三方插件负责。

从源码构建

要求:Windows 10/11 x64、Node.js 24、npm。

npm install
npm run build
npm test

桌面开发/打包:

cd desktop
npm install
$env:ELECTRON_MIRROR = 'https://npmmirror.com/mirrors/electron/'
node node_modules/electron/install.js
npx electron main.cjs

构建便携版 exe:

node desktop/build-exe.mjs
产物:dist/AI音乐工作室-win32-x64/AI音乐工作室.exe

更完整的构建、VST3 sidecar 依赖和安装包步骤见 docs/BUILDING.md。

已知问题 / 限制

- 早期原型,功能多但稳定性一般;务必保存/备份工程。
- 仅支持 Windows x64;不支持 macOS、VST2、32 位插件。
- 外部 VST3 没有原生编辑器 GUI;需要插件的图形界面时无法操作。
- AI 没有真实听觉;混音指标是算法近似,最终仍需人耳判断。
- 导出/长工程预览可能较慢;v2.4 增加快速 draft 检查和缓存。
- 安装包未签名;首次运行会触发 SmartScreen 提示。
- 没有自动更新、云同步、账号系统。
- 第三方插件崩溃/卡死由插件自身负责;sidecar 只能隔离到一定程度。

文档

- 用户手册
- 架构说明
- 从源码构建
- AI 混音反馈工作流
- AI 作曲指南(需 DSH)
- VST3 原生 GUI 方案(未实现)
- FAQ · 隐私 · 第三方许可 · AI 内容政策

目录结构

src/client/ React UI + Web Audio 引擎 src/host/ 本地 HTTP 服务 / 工程状态 / AI 工具 src/shared/ 数据模型、目录、乐理/分析 src/standalone/ 独立窗口页面 desktop/ Electron 主进程 / VST3 sidecar / 打包与安装器 assets/ 采样音色库、鼓采样与许可证 docs/ 用户/架构/构建/许可文档 test/ 单元测试

许可证与致谢

- 本项目原创代码:MIT
- 音色:GeneralUser GS(单独的 GeneralUser GS License v2.0,随 assets 分发)
- 鼓采样:Sonic Pi 采样库,CC0
- 第三方依赖:Electron/React/nvst3-host/libflacjs(MIT)、lamejs(LGPL-3.0)、7-Zip SFX(LGPL)等,详见 THIRD-PARTY-NOTICES.md 与 docs/THIRD-PARTY-LICENSES.md。
- 本项目不是 FL Studio/Image-Line 的官方或关联项目。

支持

这是一个个人原型项目,不提供商业支持,也不保证及时修 bug。欢迎 issue/PR,但请先阅读 CONTRIBUTING.md;涉及安全问题时请按 SECURITY.md 私下报告。
预览分享卡片长什么样 ↓iwbtc/ai-music-studio
分享 · DeepSeek Harness Hub
iwbtc/ai-music-studio

让 AI 智能体帮你建轨、编曲、混音并导出工程

这是你的仓库?认领条目

回到顶部