一句话定位
azure-speech-gateway 是一个 Bun + TypeScript 的 Azure Speech 兼容网关。它把
Microsoft Azure 实时语音识别(ASR)与语音合成(TTS)包装成与平台本地 / 阿里云语音
链路一致的协议,让 callflow-esl、FreeSWITCH mod_audio_fork 或管理台测试工具在
不改调用方式的情况下切换到 Azure。
它和 阿里云语音网关 是一对”姊妹网关”:协议形态、健康检查、
TTS 返回结构都一致,只是底座换成了 Azure。默认主链路仍然是mod_audio_fork + sherpa-asr-online-server + sherpa-tts-server;当你想验证 Azure
识别 / 多语言效果、给本地模型做兜底、或临时借用 Azure 音色时,单独启动这个网关即可。
Azure 网关相比阿里云网关多了一项工程能力:支持
bun build --compile打成
Windows / Linux x64 独立可执行文件,便于在没有 Bun 运行时的机器上直接部署。
服务形态
| 能力 | 默认地址 | 协议 | 用途 |
|---|---|---|---|
| ASR 健康检查 | http://127.0.0.1:10098/health |
HTTP | 查看网关状态与会话数 |
| ASR 实时识别 | ws://127.0.0.1:10098/audio |
WebSocket | 兼容 mod_audio_fork 子协议 |
| TTS 健康检查 | http://127.0.0.1:9082/health |
HTTP | 查看采样率、音色列表 |
| 普通 TTS | POST http://127.0.0.1:9082/tts |
HTTP JSON | 返回 wav URL |
| 流式 TTS | POST http://127.0.0.1:9082/tts-stream |
HTTP JSON + MP3 GET | 先返回短期 MP3 播放链接 |
ASR 侧使用 audio.drachtio.org 子协议,输入按 16kHz、单声道、PCM16 处理;TTS 侧返回{ wavUrl, fileName, sampleRate, cached },因此管理台试听与 callflow-esl 的 TTS 调用
可以复用同一套逻辑。端口与阿里云网关错开(ASR 10098 / TTS 9082,阿里云是10097 / 9081),两个网关可以同时启动做对比。
启动
在仓库根目录安装依赖并启动:
1 | bun install |
也可以进入子项目:
1 | cd apps/azure-speech-gateway |
默认不包含在根目录 bun run dev 的 8 服务并发启动组中,需要按需单独运行。
构建独立可执行文件
1 | bun run build # typecheck 后构建 Windows x64 |
构建产物是可直接部署的目录,含一个独立可执行文件和外置 config.json:
1 | dist/win_x64/azure-speech-gateway.exe + config.json |
运行时默认读取可执行文件同目录下的 config.json,也可用环境变量AZURE_SPEECH_GATEWAY_CONFIG_PATH 指定其它配置文件:
1 | cd dist\win_x64 |
Linux 二进制可在 Windows 上交叉编译,但仍需在目标 Linux 主机验证 Azure 网络访问、端口
监听、缓存目录权限。
凭据与配置
配置文件位于 apps/azure-speech-gateway/config.json。Azure Speech 凭据可以写在配置
文件里,但实际部署优先用环境变量覆盖,便于轮换:
1 | $env:AZURE_SPEECH_KEY="your-subscription-key" |
关键配置:
| 配置段 | 字段 | 说明 |
|---|---|---|
azure |
region / endpoint / ttsEndpoint |
Azure Speech 区域、资源 endpoint 与 TTS REST endpoint |
azure |
subscriptionKey |
Azure Speech key,可被 AZURE_SPEECH_KEY 覆盖 |
asr |
host / port / wsPath |
ASR 监听地址、端口(默认 10098)与 WebSocket 路径 |
asr |
wsSubprotocol |
默认 audio.drachtio.org,用于兼容 mod_audio_fork |
asr |
maxSessions |
最大并发 ASR 会话数,默认 64 |
asr |
maxQueuedAudioBytes |
Azure SDK 启动完成前每路最多缓存的音频字节数,默认 524288 |
asr |
startTimeoutMs |
Azure SDK 启动超时,默认 10000 |
asr |
autoDetectLanguages |
自动识别候选语言,默认 ["zh-CN", "en-US"] |
asr |
sampleRate / bitsPerSample / channels / format |
输入音频格式,默认 16000 / 16 / 1 / pcm |
tts |
host / port / publicBaseUrl |
TTS 监听地址、端口(默认 9082)与返回给调用方的公开基址 |
tts |
defaultVoice / voices |
默认音色与 speakerId 到 Azure voice 的映射 |
tts |
outputFormat / streamOutputFormat |
WAV 与 MP3 输出格式 |
tts |
requestTimeoutMs / maxTextLength |
TTS 请求超时与单次合成文本长度上限 |
logging |
dir / maxSize / maxFiles / level |
控制台与按天轮转文件日志 |
默认内置三个中文音色:zh-CN-XiaoxiaoNeural(id 0,默认)、zh-CN-YunxiNeural(id 1)、zh-CN-YunjianNeural(id 2);按需在 tts.voices 里补充 Azure 提供的其它 Neural 音色。
注意
仓库自带 config.json 里的 subscriptionKey 只是本地样例,不要直接用于生产。
部署时务必替换为你自己的 key,并优先用 AZURE_SPEECH_KEY 环境变量注入。tts.publicBaseUrl 必须是 FreeSWITCH 或浏览器能访问到的地址,网关部署到另一台机器后
不要继续使用 http://127.0.0.1:9082。
多语言自动识别
Azure 网关的一个特点是同一路 ASR 服务内自动检测语种:asr.autoDetectLanguages
列出候选语言,Azure 会在识别时自动判定。默认同时支持中文普通话 zh-CN 与美式英语en-US,常用候选还包括 zh-HK、zh-TW、yue-CN、en-GB、ja-JP、ko-KR、fr-FR、de-DE、es-ES 等,完整列表以 Microsoft Azure Speech 官方文档为准。
本地 sherpa ASR 默认中文 int8 模型(可切中英双语预设);如果你的场景需要多语种自动
识别又不想自建模型,Azure 网关是最省事的方案。
切换 callflow-esl 到 Azure
ASR
把 apps/callflow-esl/config.json 的 audioFork.wsUrl 改成网关地址:
1 | { |
bugName、mixType、sampleRate 不需要因为切到 Azure 而改变;关键是上游音频仍要保持
16kHz mono PCM16。
TTS
把 tts 端点改成网关的 HTTP 接口:
1 | { |
普通播放仍返回 wav URL;流式播放仍先返回 streamUrl,再由 FreeSWITCH 通过 shout://
拉取 MP3(Azure 流式输出格式由 tts.streamOutputFormat 控制,默认audio-16khz-128kbitrate-mono-mp3)。
管理台测试
- TTS 试听页把端点填为
http://<gateway-host>:9082/tts,直接试听 Azure 音色; - ASR 测试页把主机、端口、路径改为
<gateway-host>、10098、/audio,上传音频或用
浏览器录音验证; /api/asr/recognize会把浏览器侧音频统一转为 16kHz mono PCM16 WAV,再通过 WebSocket
发到网关。
会话收尾
ASR 会话在客户端发送零长度二进制帧(flush)或断开时收尾。网关会先关闭 Azure 识别会话、
把 close() 期间补发的最后一段 final 结果下发给客户端,再关闭 WebSocket,避免零长度
flush 时丢掉尾部识别;识别错误以结构化错误回调(含 errorCode、errorDetails、azureSessionId 等)记录。该收尾时序由 src/asr-server.test.ts 覆盖。
三种语音底座的取舍
| 维度 | 本地 sherpa ASR/TTS | 阿里云语音网关 | Azure 语音网关 |
|---|---|---|---|
| 数据出网 | 不出网 | 发往阿里云 | 发往 Azure |
| 成本 | 主要是机器成本 | 阿里云 NLS 计费 | Azure Speech 计费 |
| 多语言自动识别 | 需自行换模型 | 需按会话指定 | autoDetectLanguages 内置 |
| 独立可执行文件 | C++ 构建 | 需 Bun 运行时 | 支持 --compile 打包 |
| 适合场景 | 私有化、稳定生产链路 | 国内云、效果对比 | 多语言、海外、临时兜底 |
安全与运维
- 网关本身没有内置鉴权,生产环境应只暴露在可信网络内,或放到带鉴权的反向代理后;
- Azure key 泄露风险高,务必走环境变量、不要把生产 key 提交进仓库;
- WAV / MP3 缓存位于
apps/azure-speech-gateway/public/,生产环境应按需定期清理; /wav/:fileName与/tts-stream/:fileName只允许读取本服务生成的tts-<16位hash>文件,
不能通过 URL 读取其它本地文件;- 手动启动过服务后,联调结束记得停止 Bun 进程,避免端口被后续本地服务占用。