@amaster.ai/asr-client 1.0.0-beta.7 → 1.0.0-beta.73
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +394 -78
- package/dist/index.cjs +499 -153
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +284 -24
- package/dist/index.d.ts +284 -24
- package/dist/index.js +498 -151
- package/dist/index.js.map +1 -1
- package/package.json +53 -45
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Amaster Team
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,131 +1,447 @@
|
|
|
1
|
-
#
|
|
1
|
+
# ASR Realtime WebSocket Client SDK
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
基于 Web Audio + WebSocket 的 **实时语音识别(ASR)客户端 SDK**,用于将浏览器麦克风音频实时发送到 ASR 服务(如 Qwen ASR Realtime),并接收实时/最终转写结果。
|
|
4
|
+
|
|
5
|
+
遵循 [Qwen-ASR Realtime API](https://help.aliyun.com/zh/model-studio/qwen-realtime-speech-recognition) 协议实现,完整支持会话管理、VAD 模式、手动模式等全部功能。
|
|
6
|
+
|
|
7
|
+
---
|
|
4
8
|
|
|
5
9
|
## 特性
|
|
6
10
|
|
|
7
|
-
-
|
|
8
|
-
-
|
|
9
|
-
-
|
|
10
|
-
-
|
|
11
|
-
-
|
|
12
|
-
-
|
|
11
|
+
- 🎙 浏览器麦克风实时采集(16kHz / 单声道)
|
|
12
|
+
- 🔁 实时音频流式发送(Base64 PCM16)
|
|
13
|
+
- 🧠 支持 VAD 模式(自动检测语音开始/结束)和 Manual 模式(手动控制)
|
|
14
|
+
- 🌍 支持 25 种语言识别
|
|
15
|
+
- ✍️ 支持中间结果与最终转写结果
|
|
16
|
+
- 📡 完整的会话生命周期管理(session.update、session.finish)
|
|
17
|
+
- 🔌 事件 ID 自动生成,符合协议规范
|
|
18
|
+
- 🌐 同时支持 WebSocket 实时识别和 HTTP 按压识别
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## 安装与环境要求
|
|
13
23
|
|
|
14
|
-
|
|
24
|
+
### 安装
|
|
15
25
|
|
|
16
26
|
```bash
|
|
27
|
+
# npm
|
|
17
28
|
npm install @amaster.ai/asr-client
|
|
29
|
+
|
|
30
|
+
# pnpm
|
|
31
|
+
pnpm add @amaster.ai/asr-client
|
|
32
|
+
|
|
33
|
+
# yarn
|
|
34
|
+
yarn add @amaster.ai/asr-client
|
|
18
35
|
```
|
|
19
36
|
|
|
37
|
+
### 浏览器要求
|
|
38
|
+
|
|
39
|
+
- 支持 `getUserMedia`
|
|
40
|
+
- 支持 `AudioContext`
|
|
41
|
+
- 支持 `WebSocket`
|
|
42
|
+
|
|
43
|
+
推荐使用 **Chrome / Edge 最新版本**。
|
|
44
|
+
|
|
45
|
+
---
|
|
46
|
+
|
|
20
47
|
## 快速开始
|
|
21
48
|
|
|
22
|
-
|
|
23
|
-
import { createASRClient } from '@amaster.ai/asr-client';
|
|
49
|
+
### 方式一:WebSocket 实时 ASR(流式识别)
|
|
24
50
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
51
|
+
适合需要实时看到识别结果的场景,如语音输入、实时字幕等。
|
|
52
|
+
|
|
53
|
+
#### VAD 模式(推荐)
|
|
54
|
+
|
|
55
|
+
自动检测语音开始和结束:
|
|
56
|
+
|
|
57
|
+
```ts
|
|
58
|
+
import { createASRClient } from "@amaster.ai/asr-client";
|
|
59
|
+
|
|
60
|
+
const client = createASRClient({
|
|
61
|
+
// 语言配置
|
|
62
|
+
language: "zh", // 支持 zh、yue、en、ja 等 25 种语言
|
|
63
|
+
|
|
64
|
+
// VAD 配置(自动检测语音)
|
|
65
|
+
enableVAD: true,
|
|
66
|
+
vadThreshold: 0.0, // 推荐设为 0.0,默认 0.2
|
|
67
|
+
vadSilenceDurationMs: 400, // 推荐设为 400ms,默认 800ms
|
|
30
68
|
|
|
31
|
-
//
|
|
32
|
-
|
|
33
|
-
|
|
69
|
+
// 回调函数
|
|
70
|
+
onReady() {
|
|
71
|
+
console.log("ASR 连接成功,会话已配置");
|
|
72
|
+
},
|
|
73
|
+
|
|
74
|
+
onSpeechStart() {
|
|
75
|
+
console.log("🎤 检测到说话开始");
|
|
76
|
+
},
|
|
77
|
+
|
|
78
|
+
onSpeechEnd() {
|
|
79
|
+
console.log("🛑 检测到说话结束");
|
|
80
|
+
},
|
|
81
|
+
|
|
82
|
+
onTranscript(text, isFinal) {
|
|
83
|
+
console.log(isFinal ? "✅ 最终结果:" : "📝 实时结果:", text);
|
|
84
|
+
},
|
|
85
|
+
|
|
86
|
+
onSessionFinished() {
|
|
87
|
+
console.log("👋 会话已结束");
|
|
88
|
+
},
|
|
89
|
+
|
|
90
|
+
onError(err) {
|
|
91
|
+
console.error("❌ ASR 错误", err);
|
|
92
|
+
},
|
|
93
|
+
|
|
94
|
+
onClose() {
|
|
95
|
+
console.log("🔌 连接已关闭");
|
|
96
|
+
},
|
|
34
97
|
});
|
|
35
98
|
|
|
36
|
-
|
|
37
|
-
|
|
99
|
+
// 1. 建立连接(自动发送 session.update)
|
|
100
|
+
await client.connect();
|
|
101
|
+
|
|
102
|
+
// 2. 开始录音
|
|
103
|
+
await client.startRecording();
|
|
104
|
+
|
|
105
|
+
// 3. 停止录音(VAD 模式下可选,会自动检测结束)
|
|
106
|
+
await client.stopRecording();
|
|
107
|
+
|
|
108
|
+
// 4. 关闭连接(自动发送 session.finish)
|
|
109
|
+
await client.close();
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
#### Manual 模式(非 VAD)
|
|
113
|
+
|
|
114
|
+
手动控制识别时机,适合按住说话、松开识别的场景:
|
|
115
|
+
|
|
116
|
+
```ts
|
|
117
|
+
const client = createASRClient({
|
|
118
|
+
language: "zh",
|
|
119
|
+
enableVAD: false, // 关闭 VAD,使用手动模式
|
|
120
|
+
|
|
121
|
+
onReady() {
|
|
122
|
+
console.log("准备就绪");
|
|
123
|
+
},
|
|
124
|
+
|
|
125
|
+
onTranscript(text, isFinal) {
|
|
126
|
+
if (isFinal) {
|
|
127
|
+
console.log("识别结果:", text);
|
|
128
|
+
}
|
|
129
|
+
},
|
|
130
|
+
|
|
131
|
+
onAudioBufferCommitted() {
|
|
132
|
+
console.log("音频已提交,等待识别结果...");
|
|
133
|
+
},
|
|
38
134
|
});
|
|
39
135
|
|
|
40
|
-
|
|
41
|
-
|
|
136
|
+
await client.connect();
|
|
137
|
+
await client.startRecording();
|
|
138
|
+
|
|
139
|
+
// 用户说话中...
|
|
140
|
+
|
|
141
|
+
await client.stopRecording(); // 触发 input_audio_buffer.commit
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
---
|
|
145
|
+
|
|
146
|
+
### 方式二:HTTP 按压式 ASR(一句话识别)
|
|
147
|
+
|
|
148
|
+
适合按住说话、松开识别的场景,如语音消息、语音搜索等。
|
|
149
|
+
|
|
150
|
+
```tsx
|
|
151
|
+
import { useRef, useState } from "react";
|
|
152
|
+
import { createASRHttpClient } from "@amaster.ai/asr-client";
|
|
153
|
+
|
|
154
|
+
function VoiceButton() {
|
|
155
|
+
const [recording, setRecording] = useState(false);
|
|
156
|
+
const [text, setText] = useState("");
|
|
157
|
+
const [error, setError] = useState<string | null>(null);
|
|
158
|
+
|
|
159
|
+
// 创建 HTTP ASR 客户端
|
|
160
|
+
const asrHttpClient = useRef(
|
|
161
|
+
createASRHttpClient({
|
|
162
|
+
onRecordingStart() {
|
|
163
|
+
setRecording(true);
|
|
164
|
+
setText("");
|
|
165
|
+
setError(null);
|
|
166
|
+
},
|
|
167
|
+
onRecordingStop() {
|
|
168
|
+
setRecording(false);
|
|
169
|
+
},
|
|
170
|
+
onResult(result) {
|
|
171
|
+
setText(result);
|
|
172
|
+
},
|
|
173
|
+
onError(err) {
|
|
174
|
+
setError(err.message);
|
|
175
|
+
},
|
|
176
|
+
})
|
|
177
|
+
).current;
|
|
178
|
+
|
|
179
|
+
return (
|
|
180
|
+
<div>
|
|
181
|
+
<button
|
|
182
|
+
onMouseDown={() => asrHttpClient.startRecording()}
|
|
183
|
+
onMouseUp={() => asrHttpClient.stopRecording()}
|
|
184
|
+
onTouchStart={() => asrHttpClient.startRecording()}
|
|
185
|
+
onTouchEnd={() => asrHttpClient.stopRecording()}
|
|
186
|
+
style={{
|
|
187
|
+
padding: "12px 24px",
|
|
188
|
+
background: recording ? "#f87171" : "#4ade80",
|
|
189
|
+
}}
|
|
190
|
+
>
|
|
191
|
+
{recording ? "松开识别" : "按住说话"}
|
|
192
|
+
</button>
|
|
193
|
+
|
|
194
|
+
<div>
|
|
195
|
+
<strong>识别结果:</strong>
|
|
196
|
+
<div>{text || "(暂无)"}</div>
|
|
197
|
+
</div>
|
|
198
|
+
|
|
199
|
+
{error && <div style={{ color: "red" }}>错误:{error}</div>}
|
|
200
|
+
</div>
|
|
201
|
+
);
|
|
202
|
+
}
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
---
|
|
206
|
+
|
|
207
|
+
## API 说明
|
|
208
|
+
|
|
209
|
+
### `createASRClient(config): ASRClient`
|
|
210
|
+
|
|
211
|
+
WebSocket 实时 ASR 客户端。
|
|
212
|
+
|
|
213
|
+
#### `ASRClientConfig`
|
|
214
|
+
|
|
215
|
+
| 参数 | 类型 | 默认值 | 说明 |
|
|
216
|
+
| ------------------------ | ------------------------------------------ | ------- | -------------------------------------------------------- |
|
|
217
|
+
| `audioFormat` | `"pcm" \| "opus"` | `"pcm"` | 音频格式 |
|
|
218
|
+
| `sampleRate` | `16000 \| 8000` | `16000` | 采样率。8000 会先升采样到 16000,可能引入微小延迟 |
|
|
219
|
+
| `language` | `ASRLanguage` | `"zh"` | 音频源语言,支持 25 种语言(见下方语言列表) |
|
|
220
|
+
| `enableVAD` | `boolean` | `true` | 是否启用 VAD 模式。`true`=自动检测,`false`=手动控制 |
|
|
221
|
+
| `vadThreshold` | `number` | `0.2` | VAD 检测阈值,推荐设为 `0.0`,范围 `[-1, 1]` |
|
|
222
|
+
| `vadSilenceDurationMs` | `number` | `800` | VAD 断句检测阈值(ms),推荐设为 `400`,范围 `[200, 6000]` |
|
|
223
|
+
| `getAccessToken` | `() => string \| null` | - | 获取访问令牌(用于 WebSocket 认证) |
|
|
224
|
+
| `onReady` | `() => void` | - | 会话创建并配置完成(收到 session.updated) |
|
|
225
|
+
| `onSpeechStart` | `() => void` | - | 检测到语音开始(VAD 模式) |
|
|
226
|
+
| `onSpeechEnd` | `() => void` | - | 检测到语音结束(VAD 模式) |
|
|
227
|
+
| `onTranscript` | `(text: string, isFinal: boolean) => void` | - | 转写回调,`isFinal` 表示是否为最终结果 |
|
|
228
|
+
| `onAudioBufferCommitted` | `() => void` | - | 音频缓冲区已提交(非 VAD 模式) |
|
|
229
|
+
| `onSessionFinished` | `() => void` | - | 会话已结束(收到 session.finished) |
|
|
230
|
+
| `onError` | `(error: Error) => void` | - | 错误回调 |
|
|
231
|
+
| `onClose` | `() => void` | - | 连接关闭回调 |
|
|
232
|
+
|
|
233
|
+
#### 支持的语言 (ASRLanguage)
|
|
234
|
+
|
|
235
|
+
| 代码 | 语言 | 代码 | 语言 |
|
|
236
|
+
| ----- | ------------------------------------ | ---- | -------- |
|
|
237
|
+
| `zh` | 中文(普通话、四川话、闽南语、吴语) | `it` | 意大利语 |
|
|
238
|
+
| `yue` | 粤语 | `es` | 西班牙语 |
|
|
239
|
+
| `en` | 英文 | `hi` | 印地语 |
|
|
240
|
+
| `ja` | 日语 | `id` | 印尼语 |
|
|
241
|
+
| `de` | 德语 | `th` | 泰语 |
|
|
242
|
+
| `ko` | 韩语 | `tr` | 土耳其语 |
|
|
243
|
+
| `ru` | 俄语 | `uk` | 乌克兰语 |
|
|
244
|
+
| `fr` | 法语 | `vi` | 越南语 |
|
|
245
|
+
| `pt` | 葡萄牙语 | `cs` | 捷克语 |
|
|
246
|
+
| `ar` | 阿拉伯语 | `da` | 丹麦语 |
|
|
247
|
+
| `fil` | 菲律宾语 | `fi` | 芬兰语 |
|
|
248
|
+
| `is` | 冰岛语 | `ms` | 马来语 |
|
|
249
|
+
| `no` | 挪威语 | `pl` | 波兰语 |
|
|
250
|
+
| `sv` | 瑞典语 | | |
|
|
251
|
+
|
|
252
|
+
#### `ASRClient`
|
|
253
|
+
|
|
254
|
+
```ts
|
|
255
|
+
interface ASRClient {
|
|
256
|
+
/** 建立 WebSocket 连接并发送 session.update */
|
|
257
|
+
connect(): Promise<void>;
|
|
258
|
+
|
|
259
|
+
/** 开始录音并流式发送音频 */
|
|
260
|
+
startRecording(): Promise<void>;
|
|
261
|
+
|
|
262
|
+
/**
|
|
263
|
+
* 停止录音
|
|
264
|
+
* - VAD 模式:停止发送音频
|
|
265
|
+
* - 非 VAD 模式:停止发送音频并触发识别(发送 input_audio_buffer.commit)
|
|
266
|
+
*/
|
|
267
|
+
stopRecording(): Promise<void>;
|
|
268
|
+
|
|
269
|
+
/**
|
|
270
|
+
* 关闭连接
|
|
271
|
+
* - 发送 session.finish
|
|
272
|
+
* - 等待 session.finished
|
|
273
|
+
* - 关闭 WebSocket
|
|
274
|
+
*/
|
|
275
|
+
close(): Promise<void>;
|
|
276
|
+
|
|
277
|
+
/** 是否正在录音 */
|
|
278
|
+
isRecording(): boolean;
|
|
279
|
+
|
|
280
|
+
/** 是否已连接到服务器 */
|
|
281
|
+
isConnected(): boolean;
|
|
282
|
+
}
|
|
283
|
+
```
|
|
284
|
+
|
|
285
|
+
---
|
|
286
|
+
|
|
287
|
+
### `createASRHttpClient(config): ASRHttpClient`
|
|
288
|
+
|
|
289
|
+
HTTP 按压式 ASR 客户端。
|
|
290
|
+
|
|
291
|
+
#### `ASRHttpClientConfig`
|
|
292
|
+
|
|
293
|
+
| 参数 | 类型 | 说明 |
|
|
294
|
+
| ------------------ | ------------------------ | -------------------- |
|
|
295
|
+
| `getAccessToken` | `() => string \| null` | 获取访问令牌 |
|
|
296
|
+
| `language` | `string` | 语言,默认 `'zh'` |
|
|
297
|
+
| `sampleRate` | `number` | 采样率,默认 `16000` |
|
|
298
|
+
| `onRecordingStart` | `() => void` | 录音开始回调 |
|
|
299
|
+
| `onRecordingStop` | `() => void` | 录音停止回调 |
|
|
300
|
+
| `onResult` | `(text: string) => void` | 识别结果回调 |
|
|
301
|
+
| `onError` | `(error: Error) => void` | 错误回调 |
|
|
302
|
+
|
|
303
|
+
#### `ASRHttpClient`
|
|
304
|
+
|
|
305
|
+
```ts
|
|
306
|
+
interface ASRHttpClient {
|
|
307
|
+
startRecording(): Promise<void>; // 开始录音
|
|
308
|
+
stopRecording(): Promise<string>; // 停止录音并返回识别结果
|
|
309
|
+
recordAndRecognize(durationMs: number): Promise<string>; // 录音指定时长
|
|
310
|
+
recognizeFile(file: File | Blob): Promise<string>; // 识别音频文件
|
|
311
|
+
recognizeUrl(audioUrl: string): Promise<string>; // 识别音频 URL
|
|
312
|
+
}
|
|
313
|
+
```
|
|
314
|
+
|
|
315
|
+
---
|
|
316
|
+
|
|
317
|
+
## 配合统一客户端使用
|
|
318
|
+
|
|
319
|
+
推荐与 `@amaster.ai/client` 统一客户端一起使用,自动处理认证:
|
|
320
|
+
|
|
321
|
+
```tsx
|
|
322
|
+
import { createClient } from "@amaster.ai/client";
|
|
323
|
+
|
|
324
|
+
const client = createClient({
|
|
325
|
+
baseURL: "https://api.amaster.ai",
|
|
42
326
|
});
|
|
43
327
|
|
|
44
|
-
|
|
45
|
-
|
|
328
|
+
// WebSocket ASR
|
|
329
|
+
const asrClient = client.asr({
|
|
330
|
+
onTranscript(text, isFinal) {
|
|
331
|
+
console.log(isFinal ? "[最终]" : "[实时]", text);
|
|
332
|
+
},
|
|
46
333
|
});
|
|
47
334
|
|
|
48
|
-
|
|
49
|
-
await
|
|
50
|
-
await asr.startRecording(); // 自动请求麦克风权限
|
|
335
|
+
await asrClient.connect();
|
|
336
|
+
await asrClient.startRecording();
|
|
51
337
|
|
|
52
|
-
//
|
|
53
|
-
|
|
338
|
+
// HTTP ASR
|
|
339
|
+
const asrHttpClient = client.asrHttp({
|
|
340
|
+
onResult(text) {
|
|
341
|
+
console.log("识别结果:", text);
|
|
342
|
+
},
|
|
343
|
+
});
|
|
54
344
|
|
|
55
|
-
|
|
56
|
-
|
|
345
|
+
await asrHttpClient.startRecording();
|
|
346
|
+
// ... 用户说话 ...
|
|
347
|
+
const result = await asrHttpClient.stopRecording();
|
|
57
348
|
```
|
|
58
349
|
|
|
59
|
-
|
|
350
|
+
---
|
|
60
351
|
|
|
61
|
-
|
|
352
|
+
## VAD 模式 vs Manual 模式
|
|
62
353
|
|
|
63
|
-
|
|
354
|
+
| 特性 | VAD 模式(enableVAD: true) | Manual 模式(enableVAD: false) |
|
|
355
|
+
| -------- | -------------------------------------- | ------------------------------- |
|
|
356
|
+
| 语音检测 | 服务端自动检测 | 客户端手动控制 |
|
|
357
|
+
| 适用场景 | 连续对话、实时字幕 | 按住说话、语音消息 |
|
|
358
|
+
| 开始录音 | `startRecording()` | `startRecording()` |
|
|
359
|
+
| 停止录音 | 自动检测 / `stopRecording()` | `stopRecording()` 触发识别 |
|
|
360
|
+
| 事件触发 | `onSpeechStart` / `onSpeechEnd` | `onAudioBufferCommitted` |
|
|
361
|
+
| 配置参数 | `vadThreshold`, `vadSilenceDurationMs` | 无需 VAD 配置 |
|
|
64
362
|
|
|
65
|
-
|
|
66
|
-
- `gatewayUrl`: Gateway WebSocket URL(会自动追加 model 参数)
|
|
67
|
-
- `language`: 识别语言,默认 `'zh'`
|
|
68
|
-
- `audioFormat`: 音频格式,默认 `'pcm16'`
|
|
69
|
-
- `sampleRate`: 采样率,默认 `16000`
|
|
363
|
+
### VAD 配置建议
|
|
70
364
|
|
|
71
|
-
|
|
365
|
+
```ts
|
|
366
|
+
// 快速响应场景(如实时字幕)
|
|
367
|
+
const client = createASRClient({
|
|
368
|
+
enableVAD: true,
|
|
369
|
+
vadThreshold: 0.0, // 最灵敏
|
|
370
|
+
vadSilenceDurationMs: 400, // 较短停顿即断句
|
|
371
|
+
});
|
|
72
372
|
|
|
73
|
-
|
|
373
|
+
// 长句输入场景(如文章朗读)
|
|
374
|
+
const client = createASRClient({
|
|
375
|
+
enableVAD: true,
|
|
376
|
+
vadThreshold: 0.2, // 默认灵敏度
|
|
377
|
+
vadSilenceDurationMs: 1200, // 较长停顿才断句
|
|
378
|
+
});
|
|
379
|
+
```
|
|
380
|
+
|
|
381
|
+
---
|
|
382
|
+
|
|
383
|
+
## 音频参数说明
|
|
384
|
+
|
|
385
|
+
### WebSocket ASR
|
|
74
386
|
|
|
75
|
-
|
|
387
|
+
- **采样率**:16000 Hz(推荐)或 8000 Hz
|
|
388
|
+
- **声道**:单声道
|
|
389
|
+
- **格式**:PCM16 → Base64
|
|
390
|
+
- **缓冲大小**:4096 frames
|
|
76
391
|
|
|
77
|
-
|
|
392
|
+
### HTTP ASR
|
|
78
393
|
|
|
79
|
-
|
|
394
|
+
- **采样率**:自动检测(通常为 16000 Hz)
|
|
395
|
+
- **声道**:单声道
|
|
396
|
+
- **格式**:WAV(内部将 PCM 转为 WAV)
|
|
80
397
|
|
|
81
|
-
|
|
398
|
+
---
|
|
82
399
|
|
|
83
|
-
|
|
400
|
+
## 常见问题
|
|
84
401
|
|
|
85
|
-
|
|
402
|
+
### Q: WebSocket 和 HTTP ASR 有什么区别?
|
|
86
403
|
|
|
87
|
-
|
|
404
|
+
| 特性 | WebSocket ASR | HTTP ASR |
|
|
405
|
+
| -------- | ---------------------- | ------------------- |
|
|
406
|
+
| 实时性 | 实时流式返回 | 说完后一次性返回 |
|
|
407
|
+
| 适用场景 | 语音输入、实时字幕 | 语音消息、语音搜索 |
|
|
408
|
+
| 交互方式 | 开始 → 持续识别 → 停止 | 按住说话 → 松开识别 |
|
|
409
|
+
| 网络开销 | 持续连接 | 每次请求独立 |
|
|
88
410
|
|
|
89
|
-
|
|
90
|
-
- `connected`: WebSocket 连接建立
|
|
91
|
-
- `session-created`: 会话创建成功
|
|
92
|
-
- `recording-started`: 录音已开始
|
|
93
|
-
- `speech-started`: VAD 检测到语音开始
|
|
94
|
-
- `speech-stopped`: VAD 检测到语音停止
|
|
95
|
-
- `transcript-partial`: 中间识别结果(实时更新)
|
|
96
|
-
- `transcript-final`: 最终识别结果(确认)
|
|
97
|
-
- `error`: 发生错误
|
|
98
|
-
- `closed`: 连接关闭
|
|
411
|
+
### Q: 为什么必须是 16kHz?
|
|
99
412
|
|
|
100
|
-
|
|
413
|
+
ASR 服务通常要求 16kHz PCM 输入,否则会影响识别效果或直接报错。
|
|
101
414
|
|
|
102
|
-
|
|
415
|
+
### Q: 支持移动端吗?
|
|
103
416
|
|
|
104
|
-
|
|
417
|
+
支持,但需注意:
|
|
105
418
|
|
|
106
|
-
|
|
419
|
+
- iOS Safari 需用户手势触发录音
|
|
420
|
+
- 后台会自动暂停音频采集
|
|
107
421
|
|
|
108
|
-
|
|
109
|
-
- 格式:PCM 16-bit Mono
|
|
110
|
-
- 编码:Base64
|
|
111
|
-
- 发送频率:约每秒 4 次(每次 4096 采样点)
|
|
422
|
+
### Q: VAD 模式下为什么要等一段时间才返回最终结果?
|
|
112
423
|
|
|
113
|
-
|
|
424
|
+
VAD 需要检测到静音(silence)才会认为一句话结束,然后返回最终结果。`vadSilenceDurationMs` 配置了这个静音时长阈值。
|
|
114
425
|
|
|
115
|
-
|
|
116
|
-
|
|
426
|
+
### Q: 如何切换语言?
|
|
427
|
+
|
|
428
|
+
```ts
|
|
429
|
+
const client = createASRClient({
|
|
430
|
+
language: "en", // 英文识别
|
|
431
|
+
});
|
|
432
|
+
```
|
|
117
433
|
|
|
118
|
-
|
|
434
|
+
---
|
|
119
435
|
|
|
120
|
-
|
|
121
|
-
- `conversation.item.input_audio_transcription.text` - 中间结果
|
|
122
|
-
- `conversation.item.input_audio_transcription.completed` - 最终结果
|
|
436
|
+
## 注意事项
|
|
123
437
|
|
|
124
|
-
|
|
438
|
+
- WebSocket 必须在 HTTPS 页面下使用麦克风
|
|
439
|
+
- 页面关闭前建议调用 `await client.close()` 优雅关闭
|
|
440
|
+
- 不建议在多个 ASR Client 实例中共享麦克风
|
|
441
|
+
- HTTP ASR 会自动将录音转为 WAV 格式上传
|
|
442
|
+
- 每个事件都会自动生成唯一的 `event_id`,符合协议规范
|
|
125
443
|
|
|
126
|
-
|
|
127
|
-
- `input_audio_buffer.speech_started` - 开始说话
|
|
128
|
-
- `input_audio_buffer.speech_stopped` - 停止说话
|
|
444
|
+
---
|
|
129
445
|
|
|
130
446
|
## License
|
|
131
447
|
|