一句话定位

aliyun-speech-gateway 是一个 Bun + TypeScript 的阿里云 NLS 兼容网关。它把
阿里云实时语音识别与语音合成包装成与平台本地 ASR/TTS 接近的协议,方便在不改
callflow 业务代码的情况下切换到云端语音能力。

它不是默认主链路;默认主链路仍然是 mod_audio_fork + sherpa-asr-online-server

  • sherpa-tts-server。当你想验证云端识别效果、给本地模型做兜底、或在机器性能不足时
    临时借用云端 TTS/ASR,可以单独启动这个网关。

服务形态

能力 默认地址 协议 用途
ASR 健康检查 http://127.0.0.1:10097/health HTTP 查看网关状态与会话数
ASR 实时识别 ws://127.0.0.1:10097/audio WebSocket 兼容 mod_audio_fork 子协议
TTS 健康检查 http://127.0.0.1:9081/health HTTP 查看采样率、音色列表
普通 TTS POST http://127.0.0.1:9081/tts HTTP JSON 返回 wav URL
流式 TTS POST http://127.0.0.1:9081/tts-stream HTTP JSON + MP3 GET 先返回短期 MP3 播放链接

ASR 侧使用 audio.drachtio.org 子协议,输入仍按 16kHz、单声道、PCM16 处理。TTS 侧
返回结构保持 { wavUrl, fileName, sampleRate, cached },因此管理台试听与
callflow-esl 的 TTS 调用可以复用同一套逻辑。

启动

在仓库根目录安装依赖并启动:

1
2
bun install
bun run dev:aliyun-speech

也可以进入子项目:

1
2
3
cd apps/aliyun-speech-gateway
bun run dev
bun run typecheck

默认不包含在根目录 bun run dev 的 8 服务并发启动组中,需要按需单独运行。

凭据与配置

配置文件位于 apps/aliyun-speech-gateway/config.json,但实际部署不建议把阿里云凭据
写死在文件里,优先使用环境变量覆盖:

1
2
3
4
$env:ALIYUN_NLS_APP_KEY="your-app-key"
$env:ALIYUN_NLS_TOKEN="your-token"
$env:ALIYUN_NLS_URL="wss://nls-gateway-cn-shanghai.aliyuncs.com/ws/v1"
bun run --cwd apps/aliyun-speech-gateway start

关键配置:

配置段 字段 说明
aliyun appKey / token / url 阿里云 NLS 应用、临时 token 与网关地址
asr host / port / wsPath ASR 监听地址、端口与 WebSocket 路径
asr wsSubprotocol 默认 audio.drachtio.org,用于兼容 mod_audio_fork
asr maxSessions / sampleRate / format 并发上限与输入音频格式
tts host / port / publicBaseUrl TTS 监听地址与返回给调用方的公开基址
tts defaultVoice / voices 默认音色与 speakerId 到阿里云 voice 的映射
tts sampleRate / volume / pitchRate 合成采样率、音量与音调
logging dir / maxSize / maxFiles / level 控制台与文件日志

注意

tts.publicBaseUrl 必须是 FreeSWITCH 或浏览器能访问到的地址。网关部署到另一台机器后,
不要继续使用 http://127.0.0.1:9081

切换 callflow-esl 到阿里云

ASR

apps/callflow-esl/config.jsonaudioFork.wsUrl 改成网关地址:

1
2
3
4
5
6
7
8
{
"audioFork": {
"wsUrl": "ws://<gateway-host>:10097/audio",
"bugName": "callflow_asr",
"mixType": "mono",
"sampleRate": "16k"
}
}

bugNamemixTypesampleRate 不需要因为切到阿里云而改变;关键是上游音频仍然要
保持 16kHz mono PCM16。

TTS

tts 端点改成网关的 HTTP 接口:

1
2
3
4
5
6
7
8
9
10
{
"tts": {
"defaults": { "speakerId": 0, "speed": 1, "requestTimeoutMs": 10000 },
"use": { "call": "shout", "conference": "wav" },
"profiles": {
"wav": { "endpoint": "http://<gateway-host>:9081/tts", "playbackTarget": "wav-url", "fsPlaybackBaseDir": "" },
"shout": { "endpoint": "http://<gateway-host>:9081/tts-stream", "playbackPrefix": "shout://" }
}
}
}

普通播放仍返回 wav URL;流式播放仍先返回 streamUrl,再由 FreeSWITCH 通过
shout:// 拉取 MP3。

管理台测试

  • TTS 试听页可以把端点填为 http://<gateway-host>:9081/tts,直接试听阿里云音色;
  • ASR 测试页可以把主机、端口、路径改为 <gateway-host>10097/audio,上传音频
    或使用浏览器录音验证识别;
  • /api/asr/recognize 会把浏览器侧音频统一转为 16kHz mono PCM16 WAV,再通过
    WebSocket 发到网关。

与本地 sherpa 服务的取舍

维度 本地 sherpa ASR/TTS 阿里云语音网关
数据出网 不出网 音频与文本会发往阿里云
成本 主要是机器成本 按阿里云 NLS 计费策略消耗
启动门槛 需要模型、C++ 构建与机器资源 需要有效凭据与公网/专线访问
延迟 内网可控,受 CPU 与模型影响 受网络和云端服务影响
适合场景 私有化、稳定生产链路 效果对比、临时兜底、云端音色验证

安全与运维

  • 网关本身没有内置鉴权,生产环境应只暴露在可信网络内,或放到带鉴权的反向代理后;
  • 阿里云 token 有有效期,自动刷新不在当前网关职责内,失效后需要更新环境变量或配置;
  • WAV 缓存位于 apps/aliyun-speech-gateway/public/wav/,生产环境应按需定期清理;
  • 手动启动过服务后,联调结束记得停止 Bun 进程,避免端口被后续本地服务占用。

下一步