快速上手Fun-ASR语音识别:WebSocket流式接口开发与前端集成

张开发
2026/4/13 1:53:27 15 分钟阅读

分享文章

快速上手Fun-ASR语音识别:WebSocket流式接口开发与前端集成
快速上手Fun-ASR语音识别WebSocket流式接口开发与前端集成1. 项目概述与核心价值Fun-ASR-MLT-Nano-2512是阿里通义实验室推出的轻量级多语言语音识别模型支持31种语言的高精度识别。这个800M参数的模型在消费级GPU上即可流畅运行特别适合需要实时语音转写的应用场景。传统语音识别方案通常需要上传完整音频文件等待处理完成后才能获取结果。但在实际业务中我们经常需要实时会议记录边说边转文字在线教育互动即时反馈学生发言智能客服对话实时理解用户需求这些场景都要求流式识别能力——语音数据持续输入识别结果实时输出。本文将带你从零构建一个基于WebSocket的流式语音识别接口并完成前端集成。2. 环境准备与模型部署2.1 基础环境要求确保你的开发环境满足以下条件操作系统Ubuntu 20.04或更高版本Python3.8及以上GPUNVIDIA显卡可选但推荐内存至少8GB磁盘空间5GB以上2.2 快速部署模型通过以下命令一键启动模型服务# 安装依赖 pip install -r requirements.txt apt-get install -y ffmpeg # 启动服务 cd /root/Fun-ASR-MLT-Nano-2512 nohup python app.py /tmp/funasr_web.log 21 echo $! /tmp/funasr_web.pid服务启动后可以通过http://localhost:7860访问基础的Gradio界面。但我们的目标是构建更强大的流式接口。3. WebSocket流式接口开发3.1 项目结构调整首先创建专门处理流式识别的目录结构Fun-ASR-MLT-Nano-2512/ ├── model_loader.py # 模型单例加载器 ├── ws_server/ │ ├── __init__.py │ ├── server.py # WebSocket主服务 │ └── stream_processor.py # 流式处理核心 └── app.py # 原Gradio服务保留3.2 核心流式处理器实现stream_processor.py负责音频数据的实时处理import numpy as np import torch from model_loader import get_model class ASRStreamProcessor: def __init__(self, devicecuda:0): self.model get_model(device) self.cache {} # 识别状态缓存 self.audio_buffer np.array([], dtypenp.float32) self.sampling_rate 16000 def append_audio_chunk(self, chunk_bytes: bytes) - None: 追加音频数据块 audio_np np.frombuffer(chunk_bytes, dtypenp.int16).astype(np.float32) audio_np / 32768.0 # 归一化 self.audio_buffer np.concatenate([self.audio_buffer, audio_np]) def process_stream(self, language: str 中文) - Dict: 执行流式识别 if len(self.audio_buffer) self.sampling_rate * 0.2: # 至少200ms音频 return {text: , is_final: False} waveform torch.from_numpy(self.audio_buffer).unsqueeze(0) try: res self.model.generate( inputwaveform, cacheself.cache, batch_size1, languagelanguage, itnTrue ) if res and len(res) 0: self.cache res[0].get(cache, {}) return { text: res[0][text].strip() if res else , is_final: False, confidence: res[0].get(confidence, 0.8) if res else 0.0 } except Exception as e: print(f处理错误: {e}) return {text: , is_final: False} def reset(self) - None: 重置会话状态 self.audio_buffer np.array([], dtypenp.float32) self.cache {}3.3 WebSocket服务实现server.py提供WebSocket接口import asyncio import json import websockets from stream_processor import ASRStreamProcessor async def handle_client(websocket, path): processor ASRStreamProcessor() try: async for message in websocket: data json.loads(message) cmd data.get(cmd) if cmd start: processor.reset() await websocket.send(json.dumps({ status: started, language: data.get(language, 中文) })) elif cmd audio: import base64 audio_bytes base64.b64decode(data[data]) processor.append_audio_chunk(audio_bytes) result processor.process_stream(languagedata.get(language, 中文)) await websocket.send(json.dumps(result)) elif cmd stop: result processor.process_stream() await websocket.send(json.dumps({ text: result[text], is_final: True, status: finished })) finally: print(客户端断开连接) async def main(): async with websockets.serve(handle_client, 0.0.0.0, 8765): print(WebSocket服务已启动: ws://localhost:8765) await asyncio.Future() if __name__ __main__: asyncio.run(main())启动服务cd ws_server python server.py4. 前端集成实战4.1 HTML页面结构创建index.html实现录音和实时展示!DOCTYPE html html head titleFun-ASR 流式识别/title style body { font-family: sans-serif; max-width: 800px; margin: 40px auto; } #output { background: #f5f5f5; padding: 15px; min-height: 100px; } button { padding: 10px 20px; margin: 5px; } /style /head body h1Fun-ASR流式识别演示/h1 p状态span idstatus未连接/span/p button onclickstartMic()开始录音/button button onclickstopMic() disabled停止/button div label语言/label select idlangSelect option value中文中文/option option valueEnglishEnglish/option /select /div div idoutput/div script let socket; let mediaRecorder; async function startMic() { try { const stream await navigator.mediaDevices.getUserMedia({ audio: true }); socket new WebSocket(ws://localhost:8765); socket.onopen () { document.getElementById(status).textContent 已连接; document.querySelector(button[onclickstopMic()]).disabled false; document.querySelector(button[onclickstartMic()]).disabled true; socket.send(JSON.stringify({ cmd: start, language: document.getElementById(langSelect).value })); }; socket.onmessage (event) { const data JSON.parse(event.data); if (data.text) { document.getElementById(output).innerHTML div${data.text}/div; } }; mediaRecorder new MediaRecorder(stream); mediaRecorder.ondataavailable (event) { if (socket.readyState WebSocket.OPEN) { const reader new FileReader(); reader.onload () { const arrayBuffer reader.result; const base64 btoa(String.fromCharCode(...new Uint8Array(arrayBuffer))); socket.send(JSON.stringify({ cmd: audio, data: base64, language: document.getElementById(langSelect).value })); }; reader.readAsArrayBuffer(event.data); } }; mediaRecorder.start(200); // 每200ms发送一次数据 } catch (err) { console.error(录音失败:, err); document.getElementById(status).textContent 错误: err.message; } } function stopMic() { if (mediaRecorder mediaRecorder.state recording) { mediaRecorder.stop(); socket.send(JSON.stringify({ cmd: stop })); document.querySelector(button[onclickstartMic()]).disabled false; document.querySelector(button[onclickstopMic()]).disabled true; } } /script /body /html4.2 关键实现细节音频采集使用浏览器MediaRecorder API获取麦克风输入数据传输将PCM音频数据转为base64编码通过WebSocket发送实时展示服务端返回的识别结果即时显示在页面上语言切换支持动态切换识别语言5. 生产环境优化建议5.1 服务稳定性增强# 在stream_processor.py中添加资源监控 import gc class ASRStreamProcessor: # ...原有代码... def process_stream(self, language: str 中文) - Dict: # 限制缓存大小 if len(self.cache) 50: keys_to_keep list(self.cache.keys())[-10:] self.cache {k: self.cache[k] for k in keys_to_keep} gc.collect() # ...原有处理逻辑...5.2 前端自动重连机制// 在前端代码中添加 let reconnectAttempts 0; socket.onclose () { if (reconnectAttempts 3) { setTimeout(() { startMic(); reconnectAttempts; }, 3000); } }; socket.onopen () { reconnectAttempts 0; // ...原有代码... };5.3 Docker容器化部署创建Dockerfile.wsFROM python:3.11-slim WORKDIR /app RUN apt-get update apt-get install -y \ ffmpeg \ rm -rf /var/lib/apt/lists/* COPY requirements.txt . RUN pip install --no-cache-dir -r requirements.txt \ pip install websockets COPY . . EXPOSE 7860 8765 CMD [sh, -c, python app.py python ws_server/server.py]构建并运行docker build -f Dockerfile.ws -t funasr-ws . docker run -d -p 7860:7860 -p 8765:8765 --gpus all funasr-ws6. 总结与下一步通过本文你已经完成了Fun-ASR模型的WebSocket流式接口开发前端实时语音采集与识别展示集成生产环境部署优化方案这套方案可以轻松集成到各种Web应用中为你的产品添加实时语音识别能力。下一步可以考虑实现自动语言检测添加标点恢复功能支持更多音频格式输入获取更多AI镜像想探索更多AI镜像和应用场景访问 CSDN星图镜像广场提供丰富的预置镜像覆盖大模型推理、图像生成、视频生成、模型微调等多个领域支持一键部署。

更多文章