Skip to main content

转写接口

通过 WebSocket 长连接进行语音转写:边推音频边返回中间结果,停止时返回最终文本。

与「语音识别接口」的区别:本接口面向一次连续录音的流式转写,采用 start / stop / cancel 控制协议,并支持热词与计费幂等键 recording_id


一、接口信息

  • 路径: /v1/asr/stream
  • 方式: GET(WebSocket 升级)
  • 认证: 非浏览器客户端用 Header X-API-Key;浏览器客户端用 Query 参数 api_key
场景方式示例
非浏览器Header X-API-KeyX-API-Key: your-secret-key-here
浏览器Query api_keywss://api.vuilabs.cn/v1/asr/stream?api_key=your-secret-key-here

浏览器 WebSocket 无法自定义请求头,故浏览器场景用 api_key 查询参数。 API Key 在 控制台 → 项目空间 选择项目后,于「API Key 管理」创建/查看。


二、交互流程

一条 WebSocket 连接对应一次录音,顺序固定:

  1. 发送 start 控制帧(文本帧,JSON);
  2. 收到 recording_started 后,即可开始发送音频;
  3. 持续发送二进制音频块,其间可能多次收到 asr_partial
  4. 发送 stop 后,接收最终结果 asr_final
  5. 如需中途放弃,发送 cancel
client ──(text) start──────────────▶
◀──────recording_started────── 转写 API
client ──(binary) audio chunk──────▶
◀──────asr_partial──────────── 转写 API
client ──(text) stop───────────────▶
◀──────asr_final────────────── 转写 API

三、客户端发送消息

控制消息为文本帧(JSON);音频为二进制帧

1. start:开始录音

{
"type": "start",
"audio_format": "opus",
"recording_id": "rec-20260622-0001",
"hotwords": ["Hi SaySo", "氨基酸"]
}
字段类型必填说明
typestring固定为 start
audio_formatstring音频格式:opus / pcm,默认 opus
recording_idstring本次录音 ID,计费幂等键,建议客户端生成且全局唯一
hotwordsstring[]热词列表,提升专有名词、品牌名等的识别准确率
selected_textstring选中文本。传入则进入 AI 助手模式(见下方说明),不传为普通转写

AI 助手模式(划词)

start 帧带上 selected_text 时,本次录音不再只是转写,而是把这次语音转写出的内容当作"指令",对 selected_text 执行你想做的操作(翻译、润色、总结、改写、答疑等):

{
"type": "start",
"audio_format": "opus",
"selected_text": "The weather is nice today."
}

例如选中 The weather is nice today. 后说"翻译成中文",asr_final 会在 assistant_text 里返回处理结果(见四、响应事件)。

说明:

  • 单次交互——一条连接一次"选中→说指令→出结果",结束即关连接(与普通转写一致)。
  • 助手处理为尽力而为:失败或无结果时 assistant_text 为空,此时可回退为仅展示指令转写。

2. 发送音频块

直接发送 binary 音频块,无需 Base64:

  • audio_format = pcm:raw PCM(16-bit 有符号小端、16000 Hz、单声道);
  • audio_format = opus:Opus 编码后的音频块。

3. stop / cancel

{ "type": "stop" }

结束录音,并接收最终转写结果 asr_final

{ "type": "cancel" }

中途放弃转写,连接随后关闭。


四、响应事件

响应为 JSON 文本消息,通过 type 区分事件类型。

type说明
recording_started转写已就绪,可开始发送音频
asr_partial中间结果,过程中可能多次返回
asr_final最终结果,stop 后返回一次
error识别失败

事件字段

字段类型说明
typestring事件类型
textstring识别文本(asr_partial / asr_final)。AI 助手模式下为指令转写(听到的内容)
source_textstring文本优化生效时,asr_final 返回优化前的原始转写;否则为空
assistant_textstringAI 助手模式(startselected_text)下,asr_final 返回对选中文本执行指令后的处理结果;普通转写为空
audio_duration_msnumber音频时长(毫秒,asr_final,计费向下取整到秒)
word_countnumber转写字数(asr_final
modelstring实际使用的识别模型(asr_final
codestring错误码(仅 error
messagestring错误信息(仅 error

事件示例

{ "type": "asr_partial", "text": "今天天气" }
{
"type": "asr_final",
"text": "今天天气不错。",
"audio_duration_ms": 2480,
"word_count": 7,
"model": "qwen3-asr-flash-realtime"
}

AI 助手模式(startselected_text,例如选中英文后说"翻译成中文"):

{
"type": "asr_final",
"text": "翻译成中文",
"assistant_text": "今天天气不错。",
"audio_duration_ms": 1860,
"word_count": 5,
"model": "qwen3-asr-flash-realtime"
}
{ "type": "error", "code": "ASR_COMMIT_FAILED", "message": "upstream commit failed" }

五、请求示例

Python

import asyncio, json, websockets

async def main():
uri = "wss://api.vuilabs.cn/v1/asr/stream"
headers = {"X-API-Key": "your-secret-key-here"}
async with websockets.connect(uri, additional_headers=headers) as ws:
await ws.send(json.dumps({
"type": "start",
"audio_format": "pcm",
"recording_id": "rec-20260622-0001",
"hotwords": ["Hi SaySo", "氨基酸"],
}))
with open("sample.pcm", "rb") as f:
while chunk := f.read(4096):
await ws.send(chunk)
await ws.send(json.dumps({"type": "stop"}))
async for message in ws:
event = json.loads(message)
print(event)
if event.get("type") in ("asr_final", "error"):
break

asyncio.run(main())

Browser JavaScript

const ws = new WebSocket("wss://api.vuilabs.cn/v1/asr/stream?api_key=your-secret-key-here");
ws.binaryType = "arraybuffer";

ws.addEventListener("open", () => {
ws.send(JSON.stringify({ type: "start", audio_format: "opus", hotwords: ["Hi SaySo"] }));
ws.send(audioArrayBuffer); // 录音编码后的二进制块
ws.send(JSON.stringify({ type: "stop" }));
});

ws.addEventListener("message", (event) => console.log(JSON.parse(event.data)));

六、错误码

识别失败时通过 error 事件返回 codemessage

错误码 / 状态说明
401API Key 无效或未授权(握手阶段返回 HTTP 401)
429请求频率超限
402余额不足
INVALID_METAstart 消息缺失或格式错误
ASR_INIT_FAILED初始化语音识别失败
ASR_CONNECT_FAILED连接语音识别服务失败
ASR_COMMIT_FAILED提交音频并获取最终识别结果失败
QUOTA_EXCEEDED单次录音音频超出大小上限

七、计费说明

具体计费规则、价格和免费额度请参见 产品计费