在 Go 中离线实现文字转语音
Go 的标准库没有语音合成,常见方案要么是按字收费的云端 SDK,要么是封装操作系统机械声音的库。对于服务、机器人或命令行工具,两者都有缺点:文字会离开机器,或者声音因系统而异。请注意:Supertonic 3 暂不支持中文,可朗读英语、日语、韩语等 31 种语言。
本指南介绍如何通过本地 HTTP 服务器从 Go 调用免费的 SuperClonica 引擎:声音自然,WAV 文件留在你手里,在任何平台上用普通的 net/http 即可。
从 Go 发声的方式
经常需要发声的服务,自建语音服务器更省钱,也更保护隐私。
- 云端 SDK:声音自然,但需要账号、密钥、按字计费,文字还会存到对方服务器上。
- 封装操作系统声音:离线,但声音机械,且各平台不同。
- SuperClonica:本地 HTTP 服务器,支持自然声音、角色声音和自定义声音,只要能运行 Docker 就能离线使用。
- 它支持 31 种语言,暂不支持中文。
免费试听声音
写代码之前,先打开任意声音页面,输入 30 到 100 个字符的句子,选择语言并点击生成按钮。几秒后就能听到你的应用可以拥有的声音,无需注册。
启动语音服务器
有 NVIDIA 显卡时用 cuda 镜像会更快,但不是必需的。
- 在任何 CPU 上启动服务器:docker run -d -p 8000:8000 -v superclonica-models:/models superclonica/superclonica:cpu。
- 首次启动会把约 385 MB 的 Supertonic 3 模型下载到卷中;GET /health 可以告诉你何时就绪。
- POST /synthesize 接收包含 text、voice、lang、seed 和 normalize 的 JSON,返回 16 位单声道 WAV。
- voice 可以是 M1–M5、F1–F5 等标准名称,也可以是声音文件的 JSON 内容。
从 Go 调用
借助标准库中的 bytes、io、net/http 和 os,几行代码就能发出请求:voice, _ := os.ReadFile("voice.json"); body := append([]byte(`{"text": "Hello from Go!", "lang": "en", "seed": 7, "voice": `), append(voice, '}')...); res, _ := http.Post("http://localhost:8000/synthesize", "application/json", bytes.NewReader(body)); defer res.Body.Close(); out, _ := os.Create("hello.wav"); defer out.Close(); io.Copy(out, res.Body) 在正式代码中请处理错误,而不是忽略。使用标准声音时,发送 "voice": "F1" 代替文件。同样的文字、声音和 seed 总是得到同样的音频,所以请缓存重复短语的文件。
上线前的好习惯
复用一个设置了合理超时的 http.Client。不要把 8000 端口原样暴露到互联网:设置 SUPERCLONICA_API_KEY 并以 Bearer 令牌发送,或把服务器放在私有网络中。如果同时到达的请求很多,用 SUPERCLONICA_LANES 运行更多模型副本,并在你的硬件上实测:在我们的测试中,短句在 RTX 5070 Ti 上耗时 0.12 秒,在四个 CPU 线程上耗时 0.43 秒。