FunASR C 实时语音识别客户端实战:基于 WebSocket 的 Online/2pass 流式识别与离线文件转录
2026/9/13 5:57:15 网站建设 项目流程

FunASR C# 实时语音识别客户端实战:基于 WebSocket 的 Online/2pass 流式识别与离线文件转录

【免费下载链接】FunASROpen-source speech recognition toolkit for training, inference, streaming ASR, VAD, punctuation, speaker diarization pipelines, and OpenAI-compatible/MCP serving.项目地址: https://gitcode.com/GitHub_Trending/fun/FunASR

本指南以 FunASR 仓库 runtime/csharp/ws-client/FunASRWSClient_Online 目录下的 C# 客户端为主体,讲解如何构建一个连接 FunASR WebSocket 服务端的实时语音识别程序:既支持麦克风实时流式识别(online / 2pass 两种模式),也支持对本地音频文件进行离线转录。读完本文,你将掌握该客户端的工程结构、WebSocket 协议消息的构造方式、麦克风采集与音频分块发送的实现细节,以及从编译到联调运行的全流程操作。

一、客户端能力概览

FunASRWSClient_Online 是一个基于 FunASR WebSocket 服务器的 C# 控制台客户端,核心能力在 README.md 中有明确说明:

  • 实时语音识别:使用online2pass模式,对麦克风采集到的音频流进行持续识别;
  • 离线文件转录:默认使用offline模式,转录本地音频文件;
  • 配置驱动:将配置文件放在与程序相同目录下的 config 文件夹中,在config.ini中配置服务器 IP 地址和端口号;
  • 开箱即测:配置好服务端 IP 和端口后,在 Visual Studio 中打开项目,添加NAudioWebsocket.Client两个 NuGet 程序包即可直接测试,按控制台提示操作即可。

该客户端在 Windows 11 下完成测试,编译环境为 VS2022。工程目录中包含四个核心文件:Program.cs(主流程与交互)、WebScoketClient.cs(WebSocket 通信与协议封装)、WaveCollect.cs(麦克风采集)、FunASRWSClient_Online.csproj(工程配置)。

同仓库还提供了只做离线文件转录的姊妹工程 FunASRWSClient_Offline,并支持热词与时间戳(热词需将 config 文件夹下的hotword.txt放置在执行路径下,且热词与时间戳为不同模型,需注意后台部署时模型选择)。

二、环境要求与编译运行

2.1 依赖清单

从 FunASRWSClient_Online.csproj 可以看到工程的目标框架与依赖:

<Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <OutputType>Exe</OutputType> <TargetFramework>net6.0</TargetFramework> <ImplicitUsings>enable</ImplicitUsings> <Nullable>enable</Nullable> </PropertyGroup> <ItemGroup> <PackageReference Include="NAudio" Version="2.1.0" /> <PackageReference Include="Websocket.Client" Version="4.6.1" /> </ItemGroup> </Project>
  • 目标框架:net6.0(.NET 6);
  • NAudio 2.1.0:负责麦克风音频采集、WAV 格式处理(如WaveInEventWaveFileWriterMMDeviceEnumerator);
  • Websocket.Client 4.6.1:负责与 FunASR WebSocket 服务端的连接、收发与断线重连(基于 System.Reactive 提供MessageReceived等可观察订阅)。

2.2 服务端与客户端配置

客户端通过 config.ini 读取服务端地址(注意仓库中目录名为confg):

host=127.0.0.1 port=10095

配置解析逻辑位于 Program.cs 的loadconfig()方法中:逐行读取config.ini,忽略空行以及;#开头的注释行,按key=value形式解析,仅识别hostport两个键;程序内默认值分别为0.0.0.010095(对应 FunASR WebSocket 服务端默认端口)。

启动前需先运行 FunASR 的 WebSocket 服务端(如funasr-wss-server或其 2pass 版本),确保服务端监听端口与config.ini一致。

2.3 编译与运行步骤

  1. 用 VS2022 打开解决方案 FunASRClient_CShape.sln(仓库中实际文件名为FunASRClient_CShape.sln)下的FunASRWSClient_Online工程;
  2. 通过 NuGet 还原NAudioWebsocket.Client程序包;
  3. config.ini放到程序运行目录(或与程序同目录的 config 文件夹中),填写服务端 IP 与端口;
  4. 编译运行,程序会先做麦克风与通信自检,随后进入菜单交互。

三、程序主流程:启动自检与双线程架构

3.1 启动自检

FunASR_Main()(Program.cs)启动后依次执行两类自检:

  • 麦克风状态监测:通过GetCurrentMicVolume()枚举系统录音设备,返回-2表示麦克风被静音、-1表示麦克风未连接、0表示音量被调为 0,任一异常都会在控制台给出提示并退出;
  • 通信连接测试ClientConnTest()尝试建立 WebSocket 连接,若返回信息不包含"成功"字样则判定连接失败并退出。

3.2 双线程并发架构

自检通过后,主程序启动两个后台线程再进入交互循环:

  • SendAudioThread:执行SendAudioToSeverAsync(),持续从ActiveAudioSet(并发队列)取出麦克风音频块,调用ClientSendAudioFunc()发送给服务端;
  • AudioFileThread:执行SendAudioFileToSeverAsync(),轮询AudioFileQueue,有文件路径入队即调用ClientSendFileFunc()进行离线转录。

主线程则循环读取控制台输入,提供交互菜单:输入1进入离线文件转写(随后输入文件路径),输入2进入实时语音识别(再选择1为 online、2为 2pass)。两个并发队列(ActiveAudioSetAudioFileQueue)均声明为ConcurrentQueue<T>,保证多线程安全。

四、麦克风采集:WaveCollect 的实现细节

WaveCollect.cs 基于 NAudio 实现音频采集,关键参数:

参数说明
wave_buffer_milliseconds600每次采集缓冲的毫秒数(BufferMilliseconds
wave_buffer_collectbits16位深 16bit
wave_buffer_collectchannels1单声道
wave_buffer_collectfrequency16000采样率 16kHz

采集流程:StartRec()先枚举并打印系统录音设备信息,随后创建WaveInEvent(16kHz / 16bit / 单声道),在DataAvailable事件回调中将e.Buffer入队到静态并发队列voicebuff,同时用WaveFileWriter写入tmp.wavStopRec()停止录制并释放资源。实时识别循环中,主线程不断从voicebuff出队并转存到ActiveAudioSet供发送线程消费。

五、WebSocket 协议交互:客户端与服务端的消息约定

5.1 首帧:识别启动参数

实时识别开始前,ClientFirstConnOnline()构造首帧 JSON 文本发送给服务端(WebScoketClient.cs):

{"mode": "online", "chunk_size": [5,10,5], "chunk_interval": 10, "wav_name": "microphone", "is_speaking": true}
  • modeonline2pass(由用户选择,2pass 会在流式识别结果基础上输出修正后的最终结果);
  • chunk_size[5,10,5],服务端在 websocket-server-2pass.cpp 中会校验其长度为 3 且第二个元素非 0,否则报Wrong chunk_size!
  • chunk_interval:10(毫秒,客户端据此计算发送切片大小);
  • wav_namemicrophone(实时识别会话标识);
  • is_speakingtrue(正在说话,流式会话进行中)。

5.2 音频数据帧

采集线程送来的每个缓冲块,在ClientSendAudioFunc()中按公式CHUNK = 采样率/1000 * 60 * chunk_size[1] / chunk_interval切成更小的片段逐段发送,每个片段之间Thread.Sleep(1)限速,保证与服务端流式处理节奏匹配。当连接断开时调用client.Reconnect()触发重连。

5.3 结束帧

实时识别退出(捕获 Ctrl+C)后,ClientLastConnOnline()发送{"is_speaking": false}通知服务端当前说话结束;finally块中同时执行StopRec()停止采集。服务端收到is_speaking=false后结束本次会话并返回最终结果。

5.4 离线文件转录的消息约定

ClientSendFileFunc()按扩展名区分处理(WebScoketClient.cs):

  • wav / pcm:发送{"mode": "office", "chunk_size": [5,10,5], "chunk_interval": 10, "wav_name": "xxx.wav", "is_speaking": true, "wav_format": "pcm"},随后 wav 文件跳过 44 字节 WAV 头按 102400 字节分块发送,pcm 文件按 1024000 字节分块发送;
  • mp3 / mp4:发送{"mode": "offline", "chunk_size": "5,10,5", "chunk_interval": 10, "wav_name": "xxx.mp3", "is_speaking": true, "wav_format": "mp3"}chunk_size为字符串形式),同样分块发送;
  • 不支持的扩展名返回-1,通信断开返回-2

发送完所有数据后统一发送{"is_speaking": false}收尾。

5.5 服务端响应与结果解析

rec_message()解析服务端返回的 JSON,读取modetextis_finalwav_name字段:

  • mode == "2pass-online":流式中间结果,累积到onlinebuff后与recbuff拼接打印;
  • mode == "2pass-offline":2pass 修正后的最终结果,累积到recbuff打印;
  • is_final == true:当前识别段结束,清空recbuff缓存。

这一消息结构与服务端 websocket-server-2pass.cpp 中的行为一致:在线阶段返回mode: "2pass-online"的临时文本,离线修正阶段返回mode: "2pass-offline"的最终文本,并在会话结束时返回is_final: truewav_name。协议细节可进一步参阅 WebSocket 协议文档。

六、完整运行流程实操

  1. 启动 FunASR WebSocket 服务端(online 或 2pass 版本),确认端口(默认 10095);
  2. config.ini中配置服务端hostport,与程序放在同一运行目录;
  3. VS2022 编译运行,程序自动完成麦克风与通信自检;
  4. 按提示输入1(离线文件转写)并给出音频文件路径,等待转录结果打印;
  5. 输入2(实时语音识别)再选择1(online)或2(2pass),对着麦克风说话,控制台实时打印识别文本;按 Ctrl+C 结束本次会话并返回菜单。

七、结合仓库源码的扩展提示

  • 服务端对应实现:客户端的 JSON 消息字段(modechunk_sizechunk_intervalwav_nameis_speakingwav_format)与 runtime/websocket/bin 下的服务端解析逻辑一一对应,联调时可直接对照该目录源码排查字段不匹配问题;
  • 离线纯转录场景:若只需批量转写本地文件,可改用 FunASRWSClient_Offline 工程,其还支持热词(hotword.txt)与时间戳能力;
  • 多语言服务端:仓库中 runtime/websocket 目录下包含 online / 2pass 多种服务端实现,均可与本 C# 客户端配合使用。

结语

FunASRWSClient_Online 演示了在 .NET 生态中对接 FunASR WebSocket 服务端的完整路径:从 config.ini 配置、NAudio 麦克风采集,到符合 FunASR 协议的 JSON 首帧、分块音频数据帧与结束帧发送,再到 2pass 中间/最终结果解析。理解其消息约定与线程模型后,你可以轻松将此客户端改造为 WinForms / WPF 图形界面、集成到现有 C# 业务系统,或扩展支持更多音频格式与热词功能。

【免费下载链接】FunASROpen-source speech recognition toolkit for training, inference, streaming ASR, VAD, punctuation, speaker diarization pipelines, and OpenAI-compatible/MCP serving.项目地址: https://gitcode.com/GitHub_Trending/fun/FunASR

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询