这是基于Web技术的FunASR( 阿里巴巴达摩院 开源语音识别项目) 前端实现方案,支持麦克风实时录音识别与本地音频文件上传识别两大核心场景。整体功能围绕WebSocket通信、音频数据处理、语音识别结果解析三大关键环节展开,以下从代码结构、核心模块及关键逻辑三方面进行详细剖析。
一、代码整体结构
代码采用原生JavaScript编写,无框架依赖,整体架构清晰,主要划分为初始化配置、UI交互 控制 、音频 数据 处理、WebSocket通信、识别结果解析五大模块,完整流程如下:
-
页面加载时初始化 WebSocket 连接对象、录音对象、UI 控件状态;
-
用户通过按钮选择「麦克风模式」或「文件模式」,配置识别参数(如热词、是否开启 ITN);
-
建立 WebSocket 连接,向后端 FunASR 服务发送音频数据(实时录音流或文件流);
-
接收后端返回的识别结果,解析并展示(支持带时间戳的文本输出);
-
识别结束后停止连接,支持音频回放。
二、核心模块解析
1. 初始化配置(页面加载时执行)
定义全局对象与初始状态,为后续各模块功能的正常运行奠定基础。
全局变量/对象 | 作用 | 关键参数 |
---|---|---|
wsconnecter |
WebSocket 连接对象 | msgHandle :接收后端消息的回调;stateHandle :连接状态变化的回调 |
rec |
录音对象(依赖 Recorder.js) | type: "pcm" (音频格式);sampleRate: 16000 (采样率,ASR 常用);bitRate: 16 (位深) |
sampleBuf |
音频数据缓冲区 | 存储待发送的 PCM 音频数据,避免单次发送数据量过大 |
isfilemode |
识别模式标记 | true :文件上传模式;false :麦克风实时模式 |
rec_text /offline_text |
识别结果存储 | 分别存储在线/离线识别的文本结果 |
2. UI 交互与控件绑定
通过绑定页面核心按钮(开始录音、停止录音、连接服务、选择文件)的点击事件,实现识别流程的可视化控制。
关键按钮逻辑
-
连接按钮(btnConnect) :触发
start()
函数,清除历史结果、初始化 WebSocket 连接,根据模式(文件/麦克风)进入不同流程; -
开始录音按钮(btnStart) :触发
record()
函数,调用rec.open()
初始化录音设备,rec.start()
开始采集音频; -
停止录音按钮(btnStop) :触发
stop()
函数,停止录音、发送「结束标识」给后端、关闭 WebSocket 连接; -
文件选择按钮(upfile) :触发
upfile.onchange()
,读取本地音频文件(支持 WAV 格式),解析文件头获取采样率等信息。
3. 音频处理(核心模块)
该模块是前端音频处理的核心,包含实时录音处理 与本地文件解析两大分支,最终目标是将音频数据转换为FunASR服务支持的PCM格式。
3.1 实时录音处理(麦克风模式)
在录音过程中,recProcess
回调函数会持续触发,对音频流进行实时处理,具体步骤如下:
-
采样率转换 :录音默认采样率可能为 48kHz,通过
Recorder.SampleData()
转为 16kHz(ASR 服务常用采样率); -
数据缓冲 :将转换后的 16kHz PCM 数据存入
sampleBuf
; -
分片发送 :当
sampleBuf
数据长度达到chunk_size: 960
(对应约30ms音频,满足实时ASR低延迟需求)时,进行分片发送至后端,避免单次发送数据量过大导致网络阻塞。
3.2 本地文件解析(文件模式)
通过readWavInfo()
函数解析WAV文件头信息,提取关键参数,具体逻辑如下:
-
验证文件格式:检查是否为「RIFF-WAVE」格式,确保是单声道/双声道 PCM 数据;
-
提取参数:读取
sampleRate
(采样率)、bitRate
(位深)、numChannels
(声道数); -
数据截取:跳过 WAV 文件头(通常 44 字节),仅保留 PCM 数据部分,存入
file_data_array
。
文件发送逻辑:调用start_file_send()
函数,将file_data_array
按chunk_size: 960
进行分片发送,发送完成后自动调用stop()
函数结束流程。
4. WebSocket 通信(与后端交互)
wsconnecter
对象封装了WebSocket连接的创建、数据发送、连接关闭等核心逻辑,是前端与FunASR后端服务进行数据交互的关键通道。
4.1 连接初始化
-
连接地址生成:页面加载时,通过
window.location.href
自动生成WebSocket连接地址(将https
协议转为wss
,端口默认设为10095,用户可通过wssip
输入框手动修改); -
连接状态回调:
getConnState()
函数负责处理连接状态变化:
4.2 数据发送与接收
-
数据发送 :通过
wsconnecter.wsSend()
方法发送数据,支持两种数据类型: -
结果接收 :通过
getJsonMessage()
函数解析后端返回的JSON格式消息:
5. 识别结果解析与增强
该模块包含时间戳处理 与热词配置两大功能,旨在提升识别结果的可用性与准确性。
5.1 时间戳处理(handleWithTimestamp()
)
将后端返回的时间戳数据(格式示例:[[0, 300], [300, 600]]
,单位为毫秒)与识别文本进行关联,根据语言类型(中文/英文)调整时间戳粒度:
-
英文:按「单词」拆分,每个单词对应一个时间戳;
-
中文:按「字符」拆分,每个字符对应一个时间戳;
-
输出格式:
时间戳(秒): 文本片段
(示例:0.3: 你好
)。
5.2 热词配置(getHotwords()
)
支持用户自定义热词及对应权重,以此提升特定词汇的识别准确率,具体规则如下:
-
输入格式:每行一个热词,空格后接权重(如
阿里巴巴 10
); -
解析逻辑:按换行符拆分输入内容,过滤非数字权重项,最终生成JSON格式数据(示例:
{"阿里巴巴": 10}
),随连接请求一同发送至后端。
三、关键流程梳理
以下分别以「麦克风实时识别」和「本地文件识别」为场景,梳理完整的业务流程。
1. 麦克风实时识别流程
-
点击「连接」按钮,触发
start()
函数,清除历史识别结果并初始化WebSocket连接; -
监听连接状态,若连接失败则弹窗提示地址错误,并重置按钮状态;
-
连接成功后,页面提示「连接成功,点击开始」,同时启用「开始录音」按钮;
-
点击「开始录音」按钮,触发
record()
函数,初始化录音设备并启动音频采集; -
录音过程中,
recProcess()
函数实时处理音频流,将转换后的16kHz PCM数据存入sampleBuf
,当数据长度达到960时进行分片发送; -
点击「停止录音」按钮,触发
stop()
函数,停止录音并向后端发送「结束标识」; -
通过
getJsonMessage()
函数接收并解析后端返回的最终识别结果; -
更新页面文本框展示识别结果,随后关闭WebSocket连接。
2. 本地文件识别流程
-
选择「文件模式」,页面自动切换至文件上传相关交互界面;
-
点击「选择文件」按钮上传WAV格式音频文件,触发
upfile.onchange()
函数解析文件头,提取采样率、位深等参数及PCM数据存入file_data_array
; -
点击「连接」按钮,触发
start()
函数,清除历史结果并初始化WebSocket连接; -
监听连接状态,若连接失败则弹窗提示地址错误,重置按钮状态;
-
连接成功后,触发
start_file_send()
函数,将file_data_array
按960的chunk_size进行分片发送; -
通过
getJsonMessage()
函数接收并解析后端返回的识别结果; -
判断结果是否为最终结果(
is_final=true
),若是则调用play_file()
函数进行音频回放,并关闭WebSocket连接; -
更新页面文本框展示识别结果,提示用户「请点击连接」以开始下一次识别。
四、注意事项与扩展建议
-
浏览器兼容性:
- WebSocket与录音功能依赖HTTPS环境(localhost除外),HTTP环境下可能存在功能限制;
- 录音功能需用户授权麦克风权限,部分浏览器(如Safari)需手动触发授权流程。
-
后端依赖:
- 需部署FunASR后端服务(默认端口为10095),确保服务支持WebSocket协议与PCM音频输入;
- 识别模式(在线/离线)需后端服务支持,文件模式下强制使用离线模式(
mode: "offline"
)。
-
功能扩展:
-
支持更多音频格式(如MP3):需引入音频解码库(如
lamejs
)将非PCM格式转换为PCM; -
实时字幕展示:基于
timestamp
字段实现逐句/逐词的滚动字幕效果; -
识别结果导出:添加「导出TXT」功能按钮,将
varArea
中的识别文本下载为本地文件。
-
该代码是FunASR前端应用的典型实现方案,核心在于音频格式适配 与WebSocket实时通信两大技术点,确保前端采集与解析的音频数据能被后端ASR服务正确处理,同时通过友好的UI交互与结果增强功能(时间戳、热词)提升整体用户体验。