ASR 服务 API 文档
This content is not available in your language yet.
本文档描述 ASR 服务对外提供的 HTTP 与 WebSocket 接口规范,包括鉴权、模型查询、健康检查及实时语音识别能力。
服务地址示例:
http://127.0.0.1:8250、ws://127.0.0.1:8250/ws/asr
2. 路由总览
Section titled “2. 路由总览”POST /api/token获取访问 TokenPOST /api/verify验证 Token(从 Header 或 Query 取 Token)GET /api/models获取已启用模型与语言列表GET /health健康检查
WebSocket
Section titled “WebSocket”GET /ws/asrASR 双向流网关
3. 网关协议支持矩阵
Section titled “3. 网关协议支持矩阵”| 链路 | 支持协议 | 说明 |
|---|---|---|
| 客户端 -> ASR 网关 | HTTP/1.1, WebSocket | HTTP 用于 Token/模型/健康检查;WebSocket 用于实时语音流 |
| ASR 网关 -> 上游识别服务 | WebSocket (ws/wss) | 根据 asr.models[].upstream.ssl 选择 ws 或 wss |
网关不提供 gRPC / SSE 接口。
当前容器部署由三个服务组成:asr-go 提供 HTTP/WebSocket 网关,funasr-mlt-gguf 提供 Fun-ASR-MLT-Nano GGUF 离线识别上游,funasr-sensevoice 提供 SenseVoiceSmall 上游。asr.models[].upstream.host 应填写对应容器服务名或可访问地址。
4. HTTP 接口
Section titled “4. HTTP 接口”GoFrame 已启用 MiddlewareHandlerResponse,HTTP 成功响应统一为:
{ "code": 0, "message": "", "data": {}}失败时 code != 0,message 为错误信息。
4.1 获取 Token
Section titled “4.1 获取 Token”- 方法:
POST - 路径:
/api/token - Content-Type:
application/json
请求体:
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
api_key | string | 是 | 与配置 security.apiKey 一致 |
user_id | string | 是 | 业务用户标识 |
expires_in | int | 否 | 秒;<=0 时回退配置 jwt.expire(默认 3600) |
示例:
curl -X POST http://127.0.0.1:8250/api/token \ -H "Content-Type: application/json" \ -d '{ "api_key": "ascjajwfjawjkfio2iiuudahha", "user_id": "user123", "expires_in": 3600 }'成功示例:
{ "code": 0, "message": "", "data": { "token": "eyJhbGciOiJIUzI1NiIs...", "expires_in": 3600, "expires_at": "2026-05-15T10:30:00" }}4.2 验证 Token
Section titled “4.2 验证 Token”- 方法:
POST - 路径:
/api/verify
Token 提取顺序:
Authorization: Bearer <token>- Query 参数
token
成功示例:
{ "code": 0, "message": "", "data": { "valid": true, "user_id": "user123", "expires_at": "2026-05-15T10:30:00" }}4.3 获取支持模型
Section titled “4.3 获取支持模型”- 方法:
GET - 路径:
/api/models
返回内容为已启用模型、模型支持的识别模式和当前 ASR 网关支持的语言码;模型显示名直接使用 code。
响应示例:
{ "code": 0, "message": "", "data": { "models": [ { "code": "Fun-ASR-MLT-Nano-GGUF", "modes": ["offline"], "enabled": true }, { "code": "SenseVoiceSmall", "modes": ["offline", "online", "2pass"], "enabled": true } ], "languages": [ { "code": "zh-CN" }, { "code": "en-US" }, { "code": "yue-HK" }, { "code": "ja-JP" }, { "code": "ko-KR" }, { "code": "vi-VN" }, { "code": "id-ID" }, { "code": "th-TH" }, { "code": "ms-MY" }, { "code": "fil-PH" }, { "code": "ar-SA" }, { "code": "hi-IN" }, { "code": "bg-BG" }, { "code": "hr-HR" }, { "code": "cs-CZ" }, { "code": "da-DK" }, { "code": "nl-NL" }, { "code": "et-EE" }, { "code": "fi-FI" }, { "code": "el-GR" }, { "code": "hu-HU" }, { "code": "ga-IE" }, { "code": "lv-LV" }, { "code": "lt-LT" }, { "code": "mt-MT" }, { "code": "pl-PL" }, { "code": "pt-PT" }, { "code": "ro-RO" }, { "code": "sk-SK" }, { "code": "sl-SI" }, { "code": "sv-SE" } ] }}当前内置 CPU 部署同时运行 Fun-ASR-MLT-Nano-GGUF 与 SenseVoiceSmall 两个本地上游服务,也可以显式配置 MicrosoftAzureSpeech 云上游;设备和 Core 配置必须显式选择模型,不做空值兜底。Fun-ASR-MLT-Nano-GGUF 仅支持 offline 模式,SenseVoiceSmall 与 MicrosoftAzureSpeech 支持 offline、online 与 2pass。本地模型语言能力对齐 Fun-ASR-MLT-Nano 的 31 语种:
| 语言码 | 语言 |
|---|---|
zh-CN | 中文 |
en-US | 英语 |
yue-HK | 粤语 |
ja-JP | 日语 |
ko-KR | 韩语 |
vi-VN | 越南语 |
id-ID | 印尼语 |
th-TH | 泰语 |
ms-MY | 马来语 |
fil-PH | 菲律宾语 |
ar-SA | 阿拉伯语 |
hi-IN | 印地语 |
bg-BG | 保加利亚语 |
hr-HR | 克罗地亚语 |
cs-CZ | 捷克语 |
da-DK | 丹麦语 |
nl-NL | 荷兰语 |
et-EE | 爱沙尼亚语 |
fi-FI | 芬兰语 |
el-GR | 希腊语 |
hu-HU | 匈牙利语 |
ga-IE | 爱尔兰语 |
lv-LV | 拉脱维亚语 |
lt-LT | 立陶宛语 |
mt-MT | 马耳他语 |
pl-PL | 波兰语 |
pt-PT | 葡萄牙语 |
ro-RO | 罗马尼亚语 |
sk-SK | 斯洛伐克语 |
sl-SI | 斯洛文尼亚语 |
sv-SE | 瑞典语 |
4.4 健康检查
Section titled “4.4 健康检查”- 方法:
GET - 路径:
/health
示例:
{ "code": 0, "message": "", "data": { "status": "healthy", "timestamp": "2026-05-15T09:30:00+08:00", "active_connections": 2 }}5. WebSocket 接口
Section titled “5. WebSocket 接口”5.1 连接地址
Section titled “5.1 连接地址”ws://127.0.0.1:8250/ws/asr
连接示例:
wss://asr.iprtapp.com/ws/asr?hotwordCacheId=hotword_label_daily_v1&language=zh-CN&model=Fun-ASR-MLT-Nano-GGUF&token=<JWT_TOKEN>
5.2 Query 参数
Section titled “5.2 Query 参数”| 参数 | 必填 | 说明 |
|---|---|---|
token | 是 | JWT Token |
model | 是 | 模型编码 |
language | 否 | 语言偏好(用于热词查询和结果语言标准化) |
hotwordCacheId | 否 | 热词缓存 ID(服务端按 ID+语言回源 DB 查热词) |
5.3 参数校验与路由规则
Section titled “5.3 参数校验与路由规则”网关只按 model 选择识别模型:
model未传时返回 HTTP 400。model不在配置的模型列表内时返回 HTTP 400。- 网关内部按
asr.models[].code找到同一项的upstream,再连接对应 provider/host/port。
客户端必须显式传
model,不要依赖连接级默认模型选择。
5.4 握手阶段失败响应(HTTP)
Section titled “5.4 握手阶段失败响应(HTTP)”以下情况发生在 WS 升级前,返回普通 JSON:
- 连接数超限:
{"error":"服务器连接数已满","code":503} - 缺少 token:
{"error":"缺少token参数","code":401} - token 无效:
{"error":"Token无效或已过期","code":401}
5.5 连接成功消息(网关 -> 客户端)
Section titled “5.5 连接成功消息(网关 -> 客户端)”固定字段:
| 字段 | 类型 | 说明 |
|---|---|---|
type | string | 固定为 connected |
user_id | string | 用户标识 |
language | string | 连接语言参数 |
model | string | 连接模型参数 |
hotword_cache_id | string | 热词缓存 ID |
message | string | 固定为 连接成功 |
{ "type": "connected", "user_id": "user123", "language": "zh-CN", "model": "Fun-ASR-MLT-Nano-GGUF", "hotword_cache_id": "12345", "message": "连接成功"}5.6 客户端发送消息
Section titled “5.6 客户端发送消息”网关识别两类消息:
- 文本帧(JSON):透传前会补充/覆盖部分字段
- 二进制帧:视为音频数据直接转发给上游
文本帧固定字段(网关转发给上游):
| 字段 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
mode | string | 否 | offline | 识别模式 |
wav_name | string | 否 | audio | 音频标识 |
is_speaking | bool | 否 | true | 语音状态;false 时触发结束信号 |
wav_format | string | 否 | pcm | 音频格式 |
audio_fs | int | 否 | 16000 | 采样率 |
chunk_size | array | 否 | [5,10,5] | 分块参数 |
itn | bool | 否 | true | ITN 开关 |
hotwords | string | 否 | "" | 热词 JSON 字符串 |
language | string | 否 | 连接语言 | 标准语言码;未传时使用连接参数 |
retain_asr_record | bool | 否 | false | 是否保留本次识别记录(设备级开关);当该字段为 true 或配置 asr.recording.globalEnabled=true 时,网关会在停止帧或断开连接时写入 b_asr_record,并上传录音到在线存储后写入 b_file(业务类型:recording,支持 oss/s3) |
文本帧示例:
{ "mode": "offline", "wav_name": "mic", "is_speaking": true, "chunk_size": [5, 10, 5], "wav_format": "pcm", "audio_fs": 16000, "itn": true}文本帧处理规则:
- 若
is_speaking=false,网关不会透传原 JSON,而是向上游发送结束信号{"is_speaking":false}。 - 若消息带
hotwords,网关将其标准化后缓存到连接上下文。 - 若未带
hotwords且有hotwordCacheId,首帧时网关会尝试从本地缓存/数据库回填热词。 language优先级:连接 URL 参数language-> 首帧language覆盖连接值。mode必须包含在当前模型配置的modes中;例如Fun-ASR-MLT-Nano-GGUF只允许offline。- 文本帧会被标准化为上表固定字段集合后再转发。
- Query 参数
model仅用于连接级模型选择,不会回填到文本帧消息体。 - 设备侧只需要使用标准
language语言码;网关会按上游协议需要在内部转换语种字段。
停止帧扩展字段:
设备结束一次 ASR 会话时,仍通过文本帧发送 {"is_speaking": false}。该停止帧可额外携带录音校验和设备侧错误信息,字段均为可选;未携带时云端不会做对应校验。
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
crc32 | string | 否 | 本次会话全部原始音频字节的 CRC32,十六进制字符串;兼容字段名 crc、crcCheckCode、audioCrc32、crs |
audioBytes | int | 否 | 本次会话全部原始音频字节长度;兼容字段名 audioLength、rawAudioLength、rawAudioBytes |
errCode | int/array | 否 | 设备主动上报的错误码,可为单个错误码或错误码数组 |
msg | string | 否 | 设备主动上报的错误说明;为空时管理端会按错误码字典展示默认说明 |
停止帧示例:
{ "is_speaking": false, "crc32": "0x1a2b3c4d", "audioBytes": 128000, "errCode": [], "msg": ""}设备本地因内存不足主动丢弃了部分录音字节时,应在停止帧上报错误码 2012,并尽量通过 msg 说明丢弃原因或范围:
{ "is_speaking": false, "crc32": "1a2b3c4d", "audioBytes": 124000, "errCode": [2012], "msg": "device memory pressure, dropped 4000 bytes before upload"}云端记录规则:
crc32存在时,云端会用实际收到的二进制音频字节计算 CRC32;不一致时在 ASR 记录追加错误码2010和错误提示。audioBytes存在时,云端会与实际收到的二进制音频字节长度比对;不一致时在 ASR 记录追加错误码2011和错误提示。- 云端不会把
crc32、audioBytes或云端计算值作为独立字段存储;仅在校验不一致时,把客户端/云端的 CRC32 与字节长度写入 ASR 记录msg。 errCode存在时,云端会写入 ASR 记录的错误码数组;设备msg非空时写入 ASR 记录msg。msg为空时,管理端会根据错误码字典展示默认错误名称/描述。
设备状态警告上报:
ASR 运行期间出现不影响设备继续运行的异常时,设备应通过设备状态上报的 warnCode 数组同步给云端:
| warnCode | 场景 | 上报建议 |
|---|---|---|
2012 | 本地内存不足,主动丢弃部分录音字节 | 停止帧继续上报 errCode:[2012];同时通过设备状态 warnCode:[2012] 上报运行警告 |
2013 | ASR WebSocket 连接异常断开,未完成正常停止流程 | 通过设备状态 warnCode:[2013] 上报;下一次状态恢复正常时可重新上报 warnCode:[] |
设备状态上报示例:
{ "msgId": "f4fca7e5f0d24d70a7bb4f96f1f36c11", "ts": 1724040060000, "rssi": -58, "battery": 90, "paper": 1, "errCode": [], "warnCode": [2013], "firmware": []}二进制帧发送规范(依据首帧配置):
- 首帧文本消息发送完成后,再开始发送二进制音频帧。
- 网关对二进制帧不做内容解析,按原样转发到上游 ASR 服务。
- 二进制帧的发送方式由首帧参数决定,重点字段为:
mode、wav_format、audio_fs、chunk_size。
首帧 mode | 二进制帧发送方式 | 结束方式 |
|---|---|---|
offline | 可连续发送完整音频内容(可分片发送) | 发送文本帧 {"is_speaking": false} |
online | 按小块持续发送流式音频(建议固定块大小) | 发送文本帧 {"is_speaking": false} |
2pass | 与 online 相同,按流式分块发送 | 发送文本帧 {"is_speaking": false} |
二进制音频内容说明:
wav_format=pcm:发送裸 PCM 数据(通常不含文件头)。wav_format=wav/mp3/mp4/flac...:按对应编码后的音频字节流发送。audio_fs表示音频采样率(例如16000)。chunk_size用于上游流式处理参数,推荐与实际二进制分片节奏保持一致。
5.7 结果消息(网关 -> 客户端)
Section titled “5.7 结果消息(网关 -> 客户端)”网关会把上游结果转为统一结构:
{ "type": "result", "mode": "2pass-online", "text": "识别文本", "is_final": false, "model": "SenseVoiceSmall", "timestamp": [[0, 120], [120, 260]], "detected_language": "en", "emotion": "neutral", "event": "speech"}上游若返回带标签文本,例如:
"<|zh|><|NEUTRAL|><|Speech|> 牛排。"
网关会清洗为:
text:"牛排。"detected_language:"zh-CN"
固定字段:
| 字段 | 类型 | 说明 |
|---|---|---|
type | string | 固定为 result |
mode | string | 识别模式;客户端请求 mode 存在时以请求值为准 |
text | string | 识别文本 |
is_final | bool | 最终结果标识 |
model | string | 连接模型 |
timestamp | array/null | 时间戳 |
detected_language | string | 上游识别语种(标准化,如 zh -> zh-CN) |
language | string | 连接语种回传 |
emotion | string/null | 情绪信息 |
event | string/null | 事件信息 |
错误消息示例:
固定字段:
| 字段 | 类型 | 说明 |
|---|---|---|
type | string | 固定为 error |
error | string | 错误信息 |
model | string | 连接模型 |
{ "type": "error", "error": "错误描述", "model": "Fun-ASR-MLT-Nano-GGUF"}6. 音频与连接约束(默认配置)
Section titled “6. 音频与连接约束(默认配置)”- 最大并发连接数:
1000(websocket.maxConnections) - 单连接超时:
300s(websocket.timeout) - 建议采样率:
16000 - 建议音频块大小:
8000 bytes
7. ASR Gateway 配置(config.yaml)
Section titled “7. ASR Gateway 配置(config.yaml)”以下配置用于 ASR 服务自身,在线存储配置按本地配置文件读取,不依赖数据库在线存储配置表。
asr: hotwordCache: # 热词缓存仅使用进程内本地缓存,不依赖 Redis localExpireSeconds: 1800 recording: # 全局录制开关:true 时,默认录制所有会话 globalEnabled: false defaultDealerId: "system" defaultOwnerId: "system" storage: # 存储服务类型:oss 或 s3 providerType: "oss" # 对象键规则:{basePath}/asr/{dealerId}/{yyyy-MM-dd}/{filename} # 路径规则与 ByteOne 主项目文件存储规则保持一致 basePath: "byteone" oss: endpoint: "oss-cn-xxxx.aliyuncs.com" region: "cn-xxxx" accessKeyId: "REPLACE_WITH_OSS_ACCESS_KEY_ID" accessKeySecret: "REPLACE_WITH_OSS_ACCESS_KEY_SECRET" bucket: "your-oss-bucket-name" s3: # 至少配置一个 endpoint;internalEndpoint 优先用于服务内部访问 internalEndpoint: "s3.internal.example.com" externalEndpoint: "s3.amazonaws.com" region: "us-east-1" accessKeyId: "REPLACE_WITH_S3_ACCESS_KEY_ID" secretAccessKey: "REPLACE_WITH_S3_SECRET_ACCESS_KEY" bucket: "your-s3-bucket-name" models: # enabled=true 的模型才会对外暴露并允许客户端选择;upstream 是该模型内部连接的上游识别服务。 - code: "Fun-ASR-MLT-Nano-GGUF" enabled: true modes: ["offline"] upstream: provider: "funasr" host: "funasr-mlt-gguf" port: 10095 ssl: false - code: "SenseVoiceSmall" enabled: true modes: ["offline", "online", "2pass"] upstream: provider: "funasr" host: "funasr-sensevoice" port: 10097 ssl: false - code: "MicrosoftAzureSpeech" enabled: false modes: ["offline", "online", "2pass"] upstream: provider: "microsoft" host: "eastus.stt.speech.microsoft.com" port: 443 ssl: true region: "eastus" key: "REPLACE_WITH_AZURE_SPEECH_KEY" format: "detailed" profanity: "raw" audioContentType: "audio/wav; codecs=audio/pcm; samplerate=16000" sendWAVHeader: true8. 版本信息
Section titled “8. 版本信息”- 文档版本:
v3.4 - 更新日期:
2026-06-26