一、录音实现 (audioRecorder.js)
1. 核心库
使用 RecordRTC 库实现浏览器录音功能
2. 初始化录音 (init())
// 获取麦克风流
this.mediaStream = await navigator.mediaDevices.getUserMedia({
audio: {
echoCancellation: true, // 回声消除
noiseSuppression: true, // 降噪
autoGainControl: true, // 自动增益
sampleRate: 16000, // 采样率 16kHz(阿里云要求)
channelCount: 1 // 单声道
}
});
3. 开始录音 (start())
this.recorder = new RecordRTC(this.mediaStream, {
type: 'audio',
mimeType: 'audio/wav',
recorderType: RecordRTC.StereoAudioRecorder,
numberOfAudioChannels: 1,
desiredSampRate: 16000,
timeSlice: 1000, // 每1秒触发一次数据回调
// 实时数据回调
ondataavailable: (blob) => {
// WAV格式,去掉44字节头部,提取PCM数据
const pcmData = arrayBuffer.slice(44);
this.onDataCallback(pcmData); // 回调PCM数据
}
});
4. 关键点
- 音频格式: WAV → 提取PCM数据(去掉44字节WAV头部)
- 采样率: 16kHz(阿里云要求)
- 数据切片: 每秒发送一次PCM数据
二、阿里云ASR实时识别实现
1. 认证及所需配置准备
- 阿里云实时语音识别可以领取个人版或者企业版免费的使用时长,按照其流程领取并分配给自己所创建的服务即可。
- 所需Key获取(阿里云自己手动创建获取即可)。
相关链接
https://signin.aliyun.com/1478864142734712.onaliyun.com/login.htm
获取到的相关Key自己手动配置在.env文件即可
2. 获取Token (后端 server.js)
后端服务 (Node.js Express):
// 使用阿里云SDK获取Token
const RPCClient = require('@alicloud/pop-core').RPCClient;
const client = new RPCClient({
accessKeyId: process.env.ALIYUN_AK_ID,
accessKeySecret: process.env.ALIYUN_AK_SECRET,
endpoint: 'http://nls-meta.cn-shanghai.aliyuncs.com',
apiVersion: '2019-02-28'
});
// API接口: GET /api/token
app.get('/api/token', async (req, res) => {
const result = await client.request('CreateToken');
res.json({
success: true,
token: result.Token.Id, // 返回Token
expireTime: result.Token.ExpireTime
});
});
使用时切换两个终端分别运行前端和Node,下图Node.js:

3. 前端获取Token (aliyunASR.js:28)
async _fetchToken() {
const response = await fetch(`${this.apiBaseUrl}/api/token`);
const data = await response.json();
return data.token; // 从后端获取Token
}
4. WebSocket连接 (connect())
async connect() {
// 1. 获取Token
this.token = await this._fetchToken();
// 2. 构建WebSocket URL (Token作为URL参数)
const url = `wss://nls-gateway-cn-shanghai.aliyuncs.com/ws/v1?token=${this.token}`;
// 3. 建立WebSocket连接
this.ws = new WebSocket(url);
this.ws.onmessage = (event) => {
const data = JSON.parse(event.data);
this._handleMessage(data); // 处理识别结果
};
}
5. 开始识别 (start())
start() {
this.taskId = this._generateUUID(); // 生成会话ID
const startMessage = {
header: {
message_id: this._generateUUID(),
task_id: this.taskId,
namespace: 'SpeechTranscriber',
name: 'StartTranscription',
appkey: this.appKey
},
payload: {
format: 'PCM',
sample_rate: 16000,
enable_intermediate_result: true, // 返回中间结果
enable_punctuation_prediction: true, // 添加标点
max_sentence_silence: 800 // 静音断句阈值
}
};
this.ws.send(JSON.stringify(startMessage));
}
6. 发送音频数据 (sendAudio())
sendAudio(audioData) {
// 直接发送二进制PCM数据(不需要包装在JSON中)
this.ws.send(audioData);
}
7. 处理识别结果 (_handleMessage())
_handleMessage(data) {
const name = data.header.name;
switch (name) {
case 'TranscriptionResultChanged':
// 中间识别结果(实时)
this.onResult({
text: payload.result,
isFinal: false
});
break;
case 'SentenceEnd':
// 句子结束(最终结果)
this.onResult({
text: payload.result,
isFinal: true,
confidence: payload.confidence
});
break;
}
}
8. 停止识别 (stop())
stop() {
const stopMessage = {
header: {
message_id: this._generateUUID(),
task_id: this.taskId, // 使用同一个task_id
namespace: 'SpeechTranscriber',
name: 'StopTranscription',
appkey: this.appKey
}
};
this.ws.send(JSON.stringify(stopMessage));
setTimeout(() => this.disconnect(), 1000);
}
三、完整调用流程 (MeetingMinutes.jsx)
// 1. 初始化录音器
const recorder = new AudioRecorder();
await recorder.init();
// 2. 初始化阿里云ASR并连接
const asr = new AliyunASR(CONFIG.aliyun);
await asr.connect();
// 3. 设置识别结果回调
asr.onResult = (data) => {
updateTranscript(data.text, { isFinal: data.isFinal });
};
// 4. 启动识别
await asr.start();
// 5. 开始录音,实时发送音频数据
recorder.start((audioChunk) => {
if (asr.isConnected) {
asr.sendAudio(audioChunk); // 实时发送PCM数据
}
});
// 6. 停止录音
await asr.stop();
await recorder.stop();
四、数据流向图
麦克风 → getUserMedia (16kHz, 单声道)
↓
RecordRTC录音 (WAV格式)
↓
去除WAV头部 (44字节) → 提取PCM数据
↓
每1秒触发回调
↓
WebSocket发送PCM数据 → 阿里云ASR
↓
实时返回识别结果
↓
更新UI显示
五、关键技术要点
| 项目 | 说明 |
|---|---|
| 音频格式 | PCM 16-bit, 16kHz, 单声道 |
| 通信协议 | WebSocket over SSL (WSS) |
| 认证方式 | Token认证(从后端获取) |
| 数据发送 | 直接发送二进制PCM数据 |
| 结果类型 | 中间结果 + 最终结果 |
| 断句策略 | 静音800ms自动断句 |
六、相关文件清单
- audioRecorder.js - 录音工具类
- aliyunASR.js - 阿里云ASR服务封装
- server.js - 后端Token获取服务
- MeetingMinutes.jsx - 会议纪要页面(调用)
最终大致实现效果
实时录音中

录音结束后(录音开始时就获取到了token)
