[English](./README.md)

# OpenKara
**把你的音乐库变成 Karaoke 舞台。**
基于端侧 AI 人声分离和同步歌词的开源桌面 Karaoke 应用。
[](https://github.com/thedavidweng/OpenKara/actions/workflows/ci.yml)
[](./LICENSE)

---
## 演示
[](https://youtu.be/OznVDmp9igk)
---
## 为什么做这个
我很喜欢在家唱卡拉 OK,但是市面上现有的解决方案都各有各的问题。
最成熟的选项可能是 [Karafun](https://www.karafun.com/),他们是一个付费服务,通过重新录制著名歌曲的方式来规避版权。这很好,但是存在以下问题:
1. 他们重新制作的伴奏会跟原版有些许区别
2. 他们的曲库不一定包含我想唱的小众歌曲
3. 我讨厌订阅制服务
除此之外,还有 [Apple Music Sing](https://www.apple.com/ca/newsroom/2022/12/apple-introduces-apple-music-sing/)。他们提供了在设备上运行去人声模型支持的卡拉 OK 功能。这很好,但 Apple Music 同样也是一个订阅服务,而我讨厌订阅制。
为了避免订阅制,你也可以选择去拥抱更传统的解决方案,比如用 [OpenKJ](https://github.com/OpenKJ/OpenKJ) 这样的项目来播放 CD+G/media+g 文件,但是 CD+G 很小众,难找到而且需要被单独购买。
最后剩下的几乎也就只剩在 YouTube 上寻找那些来路不明、版权模糊的卡拉 OK 视频了。这不仅不是一个统一良好的体验,也时常缺失我想唱的歌曲。
于是我自己的不妥协解决方案诞生了:OpenKara 使用开源技术来分离你已经拥有的以未加密形式存在的数字音乐(可能来自你的 CD 翻录、[Bandcamp](https://bandcamp.com/)、[Qobuz](https://www.qobuz.com/)、iTunes 或者你的本地图书馆提供的音乐服务)。我知道还有很多人喜欢一次性购买并拥有的感觉,因为我就是这样的人。OpenKara 可以将我已有的音乐库转换成卡拉 OK 曲库,这样我就不用去 KTV 花钱,而且曲库取决于我个人的喜好而不是大众的喜好。
## 功能亮点
- **本地音频导入** — 直接使用你已有的音乐,无需订阅,无需重复购买。
- **AI 人声分离** — 在本地完成歌曲的人声与伴奏分离。
- **流式播放** — 环形缓冲流式解码 + 分块缓存,弱网下自动切换带宽感知代理模式,失败按指数退避重试。
- **远程资料库** — 连接 Google Drive、Dropbox 或 WebDAV 资料库。刷新、发布、重新授权都不会丢失本地状态。
- **播放列表与轮唱** — 创建播放列表,为队列分配演唱者并轮换,也可按演唱者筛选队列。
- **同步歌词** — 可从在线来源、内嵌标签或 `.lrc` 伴随文件加载时间同步歌词。
- **歌词罗马音** — 13 种语言自动罗马音转写,含普通话、粤语、日语、韩语等,可按歌曲覆盖语言。
- **CD+G 伴随图形** — 如果歌曲旁边有同名 `.cdg` 文件,OpenKara 会在全屏播放时渲染对应图形。
- **AirPlay 投放** — 把 Karaoke 播放投放到 AirPlay 设备,支持观众端串流。
- **可移植曲库** — 自包含的曲库目录,可放置在 NAS、USB 硬盘上,跨设备共享。
- **跨平台** — 支持 macOS、Windows 和 Linux。
- **四轨混音器** — 人声、鼓、贝斯、其他乐器独立音量控制。可折叠的伴奏滑块,展开查看各轨详情。
- **双分离模式** — 可选择双轨(人声 + 伴奏)或四轨(人声 + 鼓 + 贝斯 + 其他)模式。支持将已分离的双轨曲目按需升级为四轨。
- **高效音轨存储** — 分离后的音轨会以紧凑方式缓存,保持曲库占用可控。
- **断点续传分离** — 逐块检查点机制,中途关闭应用后重启会自动从上次进度继续。
- **后台完成提醒** — 分离在窗口失焦时完成会发送系统通知,不必守着几分钟的推理过程。
## 快速开始
### 从 Release 安装
从 [GitHub Releases](https://github.com/thedavidweng/OpenKara/releases) 下载对应平台的构建:
| 平台 | 格式 |
| --------------------- | -------------------- |
| macOS (Apple Silicon) | `.dmg` |
| macOS (Intel) | `.dmg` |
| Windows | `.exe` (NSIS 安装包) |
| Linux | `.AppImage` / `.deb` |
**macOS (Homebrew):**
```bash
brew install thedavidweng/tap/openkara
```
**Windows (winget):**
```bash
winget install thedavidweng.OpenKara
```
**macOS Gatekeeper 提示:** 如果 macOS 提示应用已损坏或无法打开,请在终端运行:
```bash
xattr -rd com.apple.quarantine /Applications/OpenKara.app
```
**Windows SmartScreen 提示:** OpenKara 目前还没有代码签名,Windows 首次运行时可能会弹出"Windows 已保护你的电脑"提示。点击**更多信息**,再点击**仍要运行**即可启动。
首次启动时,OpenKara 会引导你创建 Karaoke 曲库,并在后台开始下载默认 AI 模型。
### 从源码构建
**前置条件:**
- [Node.js](https://nodejs.org/) 24(与 CI 一致;仓库根目录含 `.nvmrc`)
- [pnpm](https://pnpm.io/) 12
- [Rust](https://rustup.rs/) stable 工具链
- [Tauri 2](https://v2.tauri.app/start/prerequisites/) 平台依赖
```bash
git clone https://github.com/thedavidweng/OpenKara.git
cd OpenKara
pnpm install
./scripts/setup.sh # 下载 Demucs ONNX 模型用于本地开发
pnpm tauri dev
```
### 应用图标
- 源图标:`src-tauri/icons/app-icon.png`(`1024x1024` 主母版)
- 重新生成全平台图标:`pnpm icons:generate`
- 栅格图标(`icon.icns`、各尺寸 PNG、Windows/Android/iOS)由 `tauri icon` 生成
- 在 macOS 上,同一命令还会用 Xcode `actool` 将 `src-tauri/icons/OpenKara.icon` 编译为 `Assets.car`(Liquid Glass,macOS 26+)
- 生成产物会写入 `src-tauri/icons/`,用于 Tauri 桌面端以及未来可能的移动端目标
- macOS 26 使用 `Assets.car` + `CFBundleIconName=OpenKara`;更早版本回退到传统 `icon.icns` 位图
## AI 模型
OpenKara 使用自定义 ONNX 格式的 [Demucs](https://github.com/adefossez/demucs) 模型进行音轨分离。模型由独立仓库维护:
**[openkara-models](https://github.com/thedavidweng/openkara-models)** — 可复现的 ONNX 模型转换流水线
| 模型 | 说明 | 输入 | 输出 | 格式 |
| ------------- | -------------------------------- | ----------------------------- | ------------------------------ | ---------------- |
| `htdemucs` | 标准 — Hybrid Transformer Demucs | 44.1 kHz 立体声音频(7.8 秒) | 4 条音轨:鼓、贝斯、其他、人声 | ONNX(opset 17) |
| `htdemucs_ft` | 高质量 — 微调 4 模型集成 | 44.1 kHz 立体声音频(7.8 秒) | 4 条音轨:鼓、贝斯、其他、人声 | ONNX(opset 17) |
首次启动时,OpenKara 会将标准 `openkara-models` 资源(当前锁定为 generation 9)下载到应用数据目录。当前标准模型磁盘大小约为 199.8 MiB,可选的高质量模型约为 800.1 MiB。两者都已完成 ONNX Runtime 离线优化,并携带用于缓存失效的 metadata。详见 [openkara-models README](https://github.com/thedavidweng/openkara-models#readme) 了解转换流水线。开发环境和需要稳定输入的测试可运行 `./scripts/setup.sh` 填充 `src-tauri/models/`。
### 手动放置模型文件
下载中断后会断点续传,但网络太慢或受限时仍可能不现实。你可以自己放文件:OpenKara 启动时会检查托管模型路径,只要 SHA-256 与 catalog pin 一致就直接采用。
1. **设置 → 关于 → 模型文件** 显示你这个构建期望的完整路径,含当前变体的文件名。
2. 从 [openkara-models releases](https://github.com/thedavidweng/openkara-models/releases) 下载该文件。
3. 放到那个路径,重启 OpenKara。
摘要对不上的文件会被忽略并照常触发下载,所以放错或放了半个文件都不会污染安装。
## 技术栈
| 层级 | 技术 | 用途 |
| -------- | ------------------------------------------------------------------------------------------------------- | ---------------------------- |
| 桌面框架 | [Tauri 2](https://github.com/tauri-apps/tauri) | Rust 后端 + 系统 WebView |
| 前端 | [React](https://github.com/facebook/react) 19 + [TypeScript](https://github.com/microsoft/TypeScript) 5 | UI 组件 |
| 构建工具 | [Vite](https://github.com/vitejs/vite) 8 | 开发服务器与生产构建 |
| 样式 | [Tailwind CSS](https://github.com/tailwindlabs/tailwindcss) 4 | 原子化 CSS |
| 状态管理 | [Zustand](https://github.com/pmndrs/zustand) | 轻量全局状态 |
| 音频解码 | [symphonia](https://github.com/pdeljanov/Symphonia) | 纯 Rust 解码器 |
| 音频输出 | [cpal](https://github.com/RustAudio/cpal) | 跨平台音频播放 |
| AI 推理 | [ONNX Runtime](https://github.com/microsoft/onnxruntime) via [ort](https://github.com/pykeio/ort) | Demucs v4 音轨分离 |
| 歌词 | [LRCLIB](https://lrclib.net/) | 开放同步歌词 API |
| 元数据 | [lofty](https://github.com/Serial-ATA/lofty-rs) | ID3v2、Vorbis、FLAC 标签读取 |
| 音频编码 | [vorbis_rs](https://github.com/ComunidadAylas/vorbis-rs) | OGG/Vorbis 音轨压缩 |
| 数据库 | [SQLite](https://github.com/sqlite/sqlite) via [rusqlite](https://github.com/rusqlite/rusqlite) | 歌曲、歌词与 stems 缓存 |
## 系统架构
```mermaid
flowchart TB
subgraph FE["Tauri 前端 (React)"]
FI["文件导入 & 曲库"]
KP["Karaoke 播放器 / 混音器"]
PC["播放控制"]
end
subgraph BE["Tauri Rust 后端"]
AD["音频解码 & 播放"]
AS["AI 人声分离
(Demucs v4 / ONNX)"]
MR["元数据读取"]
LF["歌词抓取
(LRCLIB + 内嵌)"]
PL["可移植曲库
(SQLite + 媒体文件 + stems)"]
end
FE --> BE
FI --> AD
KP --> AS
PC --> AD
AD --> PL
AS --> PL
MR --> LF
LF --> PL
```
## 支持的格式
| 格式 | 导入 | 人声分离 |
| ------------ | ---- | -------- |
| MP3 | ✅ | ✅ |
| FLAC | ✅ | ✅ |
| WAV | ✅ | ✅ |
| OGG / Vorbis | ✅ | ✅ |
| AAC / M4A | ✅ | ✅ |
所有音频在送入 Demucs 模型前会重采样为 44.1 kHz 立体声。
## 可移植曲库
OpenKara 将所有数据存储在一个自包含的曲库目录中:
```
MyKaraokeLibrary/
├── .openkara-library # 标记文件
├── openkara.db # SQLite 数据库
├── media/ # 导入的音频副本
│ └── {hash}.mp3
└── stems/ # 分离后的音轨
└── {hash}/
├── vocals.ogg
├── accompaniment.ogg # 双轨模式
├── drums.ogg # 四轨模式
├── bass.ogg # 四轨模式
└── other.ogg # 四轨模式
```
数据库中的所有路径均为相对路径 — 曲库可以移动到 NAS、USB 硬盘或网络共享目录,任何操作系统上的 OpenKara 实例都可以直接打开使用。每台设备的配置(曲库位置)单独存储在应用数据目录中。
## 报告问题
OpenKara 会写入滚动日志文件(默认 info 级别,错误必录),即使双击启动、没有终端也能在事后排查问题。日志按天滚动,保留最近 7 天。
提交 issue 时,请附上**调试信息**,如有需要再附上**日志文件**:
1. 打开**设置 → 关于**,点击**复制调试信息**,把结果粘贴到反馈中 — 其中包含应用版本、构建 SHA、操作系统/架构、catalog generation、模型与运行时状态、执行提供程序,以及日志文件路径。(macOS 上也可从**帮助 → 复制调试信息** 导出同样的信息。)
2. 如果问题可复现,请附上当前的日志文件。
日志文件位置(`` 为滚动日期,例如 `2026-07-25`):
| 平台 | 路径 |
| ------- | -------------------------------------------------------------- |
| macOS | `~/Library/Logs/com.openkara.desktop/openkara..log` |
| Windows | `%LOCALAPPDATA%\com.openkara.desktop\logs\openkara..log` |
| Linux | `~/.local/share/com.openkara.desktop/logs/openkara..log` |
需要更详细的日志时,可用 `OPENKARA_LOG=debug` 启动 OpenKara(或使用 [`tracing`](https://docs.rs/tracing-subscriber/latest/tracing_subscriber/filter/struct.EnvFilter.html) 过滤器,例如 `OPENKARA_LOG=openkara_lib=trace,warn`)。
## 路线图
- **[Changelog](./CHANGELOG.md)** — 已完成改动和版本记录
- **[GitHub Project](https://github.com/users/thedavidweng/projects/2/views/1)** — 未来事项与优先级
**当前应用版本(源码):** 与 `package.json` / `src-tauri/Cargo.toml` / `src-tauri/tauri.conf.json` 一致,截至文档更新为 **v0.9.0**。
## 开发指南
### 前置条件
- Node.js 24(`nvm use` 或 `fnm use` 读取 `.nvmrc` / `.node-version`)
- pnpm 12
- 通过 [rustup](https://rustup.rs/) 安装的 Rust stable
- 对应平台的 [Tauri 2 依赖](https://v2.tauri.app/start/prerequisites/)
### 环境搭建
```bash
nvm use # 或 fnm use — 读取 .nvmrc / .node-version
pnpm install
./scripts/setup.sh # 下载 Demucs ONNX 模型到 src-tauri/models/
pnpm tauri dev # 启动开发服务器(支持热更新)
```
`scripts/setup.sh` 只会把模型放置到 `src-tauri/models/` 目录,供本地开发和确定性测试使用。终端用户安装后的运行时模型默认下载到应用数据目录。
### 运行测试
```bash
cd src-tauri && cargo test -q # 后端测试(175+;CI 见 .agents/skills/ci-notes)
pnpm lint # oxlint 检查
pnpm format # oxfmt 格式检查
```
### 构建
```bash
pnpm tauri build # 生产构建,生成平台特定安装包
```
### CI/CD
- 推送到 `main` 会触发 CI 流程([`.github/workflows/ci.yml`](./.github/workflows/ci.yml))— 在 macOS、Windows、Linux 上运行 lint、构建和测试。
- 推送版本标签(如 `v0.9.0`)会触发发布流程([`.github/workflows/release.yml`](./.github/workflows/release.yml))— 构建并上传二进制文件到 GitHub Release。
## 文档
- [Changelog](./CHANGELOG.md) — 已交付改动与版本说明
- [IPC 契约](./docs/references/contracts/) — 稳定的后端接口
- [产品规格](./docs/references/product/) — 用户可见行为规格
## 参与贡献
欢迎贡献!涉及较大改动时,请先提交 Issue 讨论方案。
1. Fork 本仓库
2. 创建功能分支(`git checkout -b feature/my-feature`)
3. 确保测试通过(`cargo test`)
4. 提交 Pull Request
## 致谢
- [Demucs](https://github.com/adefossez/demucs) — Meta Research 的 AI 音轨分离模型
- [openkara-models](https://github.com/thedavidweng/openkara-models) — OpenKara 的 ONNX 模型转换流水线
- [demucs.onnx](https://github.com/sevagh/demucs.onnx) — STFT/ISTFT 实值 ONNX 转换参考
- [LRCLIB](https://lrclib.net) — 开放的同步歌词 API
- [monochrome](https://github.com/monochrome-music/monochrome) — 歌词同步与 LRCLIB 集成方案参考
## 许可证
[GNU AGPL v3.0 only](./LICENSE) — Copyright (c) 2025 David Weng
历史授权与第三方许可见 [LICENSING.md](LICENSING.md)。外部贡献者需签署
[CLA 1.0](CLA.md):在 PR 回复机器人要求的声明即可,无需额外授权。
贡献者保留版权,并许可 David Weng 将贡献用于商业及闭源版本。