← 全部项目
  • 语音创作
  • macOS 应用
  • 本地数据

声绘魔法 · VoiceCanvas

一款基于 MiniMax API 的 macOS 配音工具,把文本标注、分段试听、音色管理、整篇导出与用量报表集中在本地界面中。

在 GitHub 查看源码 ↗

为什么制作

把一篇文章制作成配音,往往需要在多个步骤和工具之间来回切换:整理原文、添加情绪和语气词、选择音色、逐段试听、处理失败片段、拼接成品,再回头查看调用量。声绘魔法把这些步骤集中到一个供个人使用的 macOS 桌面应用中,让日常配音可以从原文开始,在同一套界面里完成调整和导出。

应用数据默认保存在 ~/Library/Application Support/VoiceCanvas/,生成的音频默认输出到 ~/Music/VoiceCanvas,API Key 则保存在 macOS Keychain,不以明文写入应用数据目录。不过,本地保存不等于离线处理:语音合成、音色克隆、音色设计和其他依赖 MiniMax API 的功能,仍会把完成请求所需的数据发送到用户配置的 API Base URL。

核心体验

工作台围绕“输入原文—润色标注—人工检查—解析分段—试听—整篇导出”展开。用户可以使用 AI 添加 [emotion] 情绪标签和 (语气词),再手动检查和调整;合成前还能选择音色,并设置语速、音量、Pitch 与可选音效器。编辑内容会自动保存为草稿,减少长时间处理文本时丢失内容的风险。

分段试听让用户在导出前逐段检查结果。若某些片段生成失败,首次导出的文件只包含成功片段;单段“重试”只会重新合成并播放该段,不会修改已经导出的文件。要得到包含全部片段的成品,需要再次执行整篇合成,此时所有片段都会重新生成。这个行为虽然不应被简化成“自动续传”,但它让每次导出的内容边界保持清楚。

音色库可以浏览系统音色、上传音频克隆音色、根据文字描述设计音色,并为音色保存本地备注。报表提供按天或按周的趋势、按功能拆分的统计和调用明细,还支持筛选、分页、CSV 导出与按配置单价进行费用估算。

我完成的部分

我完成了从配音流程、桌面界面到本地服务和数据管理的完整实现,并把原本分散的配置、标注、试听、音色管理、整篇导出与用量查询组织成四个清晰模块。应用使用 PyWebView 提供原生 macOS 窗口,FastAPI 在后台随机端口运行本地服务,SQLite 保存配置之外的结构化数据,Keychain 负责保护 API Key。

我还实现了语音合成、音色克隆与音色设计的 MiniMax API 接入,完成草稿自动保存、失败段标记与重试试听、用量记录、CSV 导出,以及 arm64 和 x86_64 的 macOS 打包流程。项目通过自动化测试拦截外部请求,不消耗真实额度,并在 GitHub Actions 中使用 macOS 与 Python 3.13 运行完整测试。

如何实现

前端使用原生 HTML、CSS 和 JavaScript,不需要单独的前端构建链。音频支持 MP3、WAV 和 FLAC;MP3 可选择 32、64、128 或 256 kbps,并统一使用恒定比特率,WAV 与 FLAC 则不应用 MP3 比特率设置。音频拼接所需的 ffmpeg 由 imageio-ffmpeg 随 Python 依赖提供,不要求用户另外安装系统级 ffmpeg。

整篇合成采用逐段生成后本地拼接的方式。每两个相邻的成功片段之间固定插入 1 秒静音,但音频开头和结尾不会额外增加静音。一次生成开始时,输出格式、采样率和比特率会被锁定;该次生成中的分段合成、失败段重试和最终拼接都复用同一组参数,避免一个成品内部出现不一致的音频设置。

遇到的问题与收获

这个项目让我认识到,长文本配音的难点不只在“能否生成声音”,还在于怎样定义一次生成的边界。逐段处理便于试听和定位失败,但单段重试、已导出文件与再次整篇生成之间的关系必须写得足够明确;否则用户很容易误以为重试结果已经自动进入旧文件。固定段间静音和锁定同次生成参数,也是在用明确规则换取成品的一致性。

我也更清楚地区分了“数据保存在本地”和“内容在本地处理”这两个概念。桌面界面、SQLite 与 Keychain 可以减少不必要的数据暴露,但外部语音服务仍需要接收完成请求所需的文本或音频。可靠的个人工具不仅要提供顺畅的成功路径,也要把服务地址、数据流向、失败后的操作和费用记录解释清楚。