WebSocket实现实时语音输入:边说边识别

154 阅读3分钟

功能剖析

STAR:

S (Situation) 场景:用户需要通过语音输入与AI助手进行自然语言交互,避免手动打字的繁琐操作 T (Task) 任务:实现实时语音识别并将转换后的文字实时显示在输入框中 A (Action) 行动:通过WebSocket建立持久化连接,实时传输音频流到后端进行语音识别,并将识别结果逐步回传到前端 R (Result) 结果:用户按住语音按钮说话,文字实时出现在输入框中,松开按钮完成识别,实现"边说边出字"的流畅体验

具体技术方案:

实现链路

1. 浏览器自带录音接口

//获取用户媒体设备,采集音频数据
navigator.mediaDevices.getUserMedia({ audio: true })

2. 第三方库转二进制

- 将音频数据转换为二进制数据
- 按特定字节(如1280字节)帧大小切分

3. WebSocket发送二进制

// 发送ArrayBuffer
cache.wsClient.send(frameBuffer)  // frameBuffer是二进制数据

4. 后端语音转文字

// 后端处理
- 接收二进制音频流
- 调用语音识别服务(如阿里云、腾讯云等)
- 实时返回识别结果

5. WebSocket回传文本

// 返回格式可以是(流式渲染):
{"chuckMessage": "识别文字", "isEnd": false}

6. 前端渲染

// 实际渲染:实时更新输入框
setResultText(cache.value + cache.resultText + data.chuckMessage)

技术拓展

WebSocket

WebSocket是一种基于TCP的全双工通信协议,作为对比,我们常用的HTTP是一种基于TCP的半双工通信协议。

  • 全双工:双向同时传输,效率最高。
  • 半双工:双向交替传输,同一时间只能单方向进行。
  • 单工模式:只能单向传输,一方永远发送,另一方永远接收。

WebSocket 连接一旦建立,客户端和服务器就可以随时向对方发送数据,无需像 HTTP 那样每次通信都重新建立连接,这使得它非常适合需要实时交互的场景(如实时语音输入,实时数据监控等)。

怎么启动WebSocket通信?

  1. 首先通过 HTTP 协议发起一个特殊的 "握手" 请求。
  2. 当服务器同意升级后,连接从 HTTP 协议切换到 WebSocket 协议(复用 HTTP 的端口)
  3. 此后的通信则基于同一个 TCP 连接进行全双工的数据传输 具体到协议层面:
Connection: Upgrade
Upgrade: websocket

WebSocket和HTTP的区别还在于报文格式。报文格式的差异主要是因为HTTP 追求可读性和兼容性,WebSocket 追求效率和实时性。

HTTP数据格式是明文文本协议,包含请求行、响应行、头部字段和实体内容,结构松散但可读性强。 缺点是冗余信息多(每次请求都带重复头部),不适合高频次小数据传输。

WebSocket数据格式是二进制帧结构,头部开销小,支持文本 / 二进制数据,可分片传输大消息(通过多帧拼接)。

“帧”的关键字段:

  1. FIN(1 位):表示是否为消息的最后一帧。1 表示当前帧是消息的最后一部分。

  2. Opcode(4 位):定义帧类型:

    • 0x0:延续帧(用于拼接大消息)
    • 0x1:文本帧(UTF-8 编码数据)
    • 0x2:二进制帧(任意二进制数据)
    • 控制帧:0x8(关闭连接)、0x9(Ping)、0xA(Pong)
  3. Payload Data:实际传输的数据(文本或二进制)。