外观
aliyun-speech-gateway
aliyun-speech-gateway 是一个 Bun + TypeScript 的阿里云 NLS 语音网关。它把 阿里云实时语音识别和语音合成包装成与当前本地语音链路接近的接口,便于 callflow-esl、FreeSWITCH mod_audio_fork 或管理台测试工具在不改调用方式的 情况下切换到云端 ASR/TTS。
服务启动后会同时监听两个端口:
- ASR WebSocket 服务:默认
0.0.0.0:10097 - TTS HTTP 服务:默认
0.0.0.0:9081
运行
在仓库根目录运行:
bash
bun install
bun run dev:aliyun-speech也可以进入子项目单独运行:
bash
cd apps/aliyun-speech-gateway
bun run dev # 监听模式
bun run start # 启动一次
bun run typecheck # TypeScript 类型检查配置
配置文件位于 apps/aliyun-speech-gateway/config.json。阿里云凭据建议优先通过 环境变量传入,避免把机器或账号专属值写死到代码中:
powershell
$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 与网关地址;appKey、token 可被环境变量覆盖 |
asr | host / port | ASR HTTP/WebSocket 监听地址 |
asr | healthPath / wsPath | 健康检查与音频 WebSocket 路径,默认 /health、/audio |
asr | wsSubprotocol | WebSocket 子协议,默认 audio.drachtio.org,用于兼容 mod_audio_fork |
asr | maxSessions | 最大并发 ASR 会话数 |
asr | startTimeoutMs / maxQueuedBytes / maxQueuedChunks | 阿里云 ASR 启动超时,以及启动完成前允许暂存的音频队列上限 |
asr | sampleRate / format | 发送给阿里云识别 SDK 的音频格式,默认 16000 / pcm |
tts | host / port | TTS HTTP 监听地址 |
tts | publicBaseUrl | 返回给调用方的公开访问基址,必须是 FreeSWITCH 可访问的地址 |
tts | sampleRate | 合成音频采样率 |
tts | requestTimeoutMs / streamStartTimeoutMs | 普通 TTS 总请求超时,以及流式 TTS 首包超时 |
tts | defaultVoice / voices | 默认音色与 speakerId 到阿里云 voice 的映射 |
tts | volume / pitchRate / maxTextLength | 合成音量、音调和单次文本长度上限 |
logging | dir / maxSize / maxFiles / level | 控制台与按天轮转文件日志配置 |
ASR 接口
健康检查
http
GET http://127.0.0.1:10097/health响应示例:
json
{
"ok": true,
"service": "aliyun-speech-gateway-asr",
"activeSessions": 0,
"maxSessions": 64,
"wsPath": "/audio",
"ioWorkers": 1
}实时识别 WebSocket
默认地址:
text
ws://127.0.0.1:10097/audio连接要求:
- 请求头
Sec-WebSocket-Protocol需要包含配置中的asr.wsSubprotocol。 - 第一个文本帧可携带 metadata,常见字段包括
channel_uuid、channelUuid、uuid、call_uuid、callUuid、sessionId、session_id。 - 后续二进制帧为 16kHz 单声道 PCM 音频。
- 发送零长度二进制帧表示请求服务端 flush 并关闭阿里云识别会话。
识别结果消息示例:
json
{
"type": "transcription",
"data": {
"text": "您好,请问有什么可以帮您",
"isFinal": true,
"utteranceIndex": 1,
"speechStarted": true,
"speechActive": false,
"speechSegmentDetected": true,
"speechSegmentCompleted": true,
"serverSessionId": "ws-1",
"channelUuid": "call-uuid",
"metadataText": "{\"channel_uuid\":\"call-uuid\"}",
"finalReason": "endpoint",
"flushReason": "zero-length-binary"
}
}错误消息示例:
json
{
"type": "error",
"data": {
"message": "Aliyun NLS request failed"
}
}TTS 接口
健康检查
http
GET http://127.0.0.1:9081/health响应会返回服务监听信息、当前采样率和可用 speakers。该结构兼容管理台对 TTS 服务的健康检查。
普通 WAV 合成
http
POST http://127.0.0.1:9081/tts
Content-Type: application/json
{
"text": "您好,欢迎致电。",
"speakerId": 0,
"speed": 1
}响应示例:
json
{
"wavUrl": "http://127.0.0.1:9081/wav/tts-0123456789abcdef.wav",
"fileName": "tts-0123456789abcdef.wav",
"sampleRate": 16000,
"cached": false
}相同 text + speakerId + speed + voice 的请求会复用 public/wav/ 下的缓存文件。 生成后的 WAV 可以通过以下接口读取:
http
GET http://127.0.0.1:9081/wav/tts-0123456789abcdef.wav
HEAD http://127.0.0.1:9081/wav/tts-0123456789abcdef.wav流式 MP3 合成
先创建一个短期流式播放链接:
http
POST http://127.0.0.1:9081/tts-stream
Content-Type: application/json
{
"text": "这是一段需要尽快开始播放的文本。",
"speakerId": 0,
"speed": 1
}响应示例:
json
{
"streamUrl": "http://127.0.0.1:9081/tts-stream/tts-0123456789abcdef.mp3",
"streamPath": "/tts-stream/tts-0123456789abcdef.mp3",
"sampleRate": 16000,
"cached": false
}随后客户端访问 streamUrl,服务会在该 GET 连接内调用阿里云 SDK 并输出 Content-Type: audio/mpeg 的 MP3 数据流,同时写入 public/mp3/ 下的本地缓存文件。 相同 text + speakerId + speed + voice + format=mp3 的请求会复用同一个 tts-<16位hash>.mp3,缓存命中时 POST /tts-stream 会返回 cached: true, 后续 GET /tts-stream/<file>.mp3 直接读取缓存文件并带上 Content-Length:
http
GET http://127.0.0.1:9081/tts-stream/tts-0123456789abcdef.mp3
HEAD http://127.0.0.1:9081/tts-stream/tts-0123456789abcdef.mp3首次 GET 如果合成失败、客户端断开或写文件失败,服务会删除临时文件,不留下半截 正式缓存。5 分钟 TTL 只限制未生成缓存前的内存播放票据;已经落盘的 MP3 文件不受 该 TTL 限制。
对接注意事项
- 如果要让
callflow-esl使用阿里云 ASR,把apps/callflow-esl/config.json的audioFork.wsUrl改为ws://<gateway-host>:10097/audio;bugName、mixType=mono、sampleRate=16k保持与本地 ASR 一致即可。 - 如果要让
callflow-esl使用阿里云 TTS,把tts.profiles.wav.endpoint改为http://<gateway-host>:9081/tts,把tts.profiles.shout.endpoint改为http://<gateway-host>:9081/tts-stream。流式播放仍按tts.profiles.shout.playbackPrefix交给 FreeSWITCH 播放。 - 管理台的 TTS 试听页可以直接填
http://<gateway-host>:9081/tts;ASR 测试页可把 主机和端口改成<gateway-host>:10097,上传 16kHz mono PCM16 WAV 或用浏览器录音测试。 tts.publicBaseUrl必须配置成 FreeSWITCH 或调用方能够访问到的地址;如果服务 运行在另一台机器上,不要保留默认的127.0.0.1。- ASR 输入默认按 16kHz 单声道 PCM 处理,调用方需要保证实际音频格式与
asr.sampleRate、asr.format一致。 /wav/:fileName只允许读取本服务生成的tts-<16位hash>.wav文件名,避免 通过 URL 访问其他本地文件。/tts-stream/:fileName只允许读取本服务生成的tts-<16位hash>.mp3文件名, 避免通过 URL 访问其他本地文件。- 本服务没有内置鉴权,建议只暴露在可信网络内,或放在带鉴权的反向代理之后。
- 任务结束后如果手动启动过服务,请停止对应 Bun 进程,避免端口被后续联调占用。