UnityWebGL使用sherpa-ncnn实时语音识别

k2-fsa/sherpa-ncnn:在没有互联网连接的情况下使用带有 ncnn 的下一代 Kaldi 进行实时语音识别。支持iOS、Android、Raspberry Pi、VisionFive2、LicheePi4A等。 (github.com)

如果是PC端可以直接使用ssssssilver大佬的 https://github.com/ssssssilver/sherpa-ncnn-unity.git

我这边要折腾的是WebGL版本的,所以修改了一番

1、WebSocket,客户端使用了psygames/UnityWebSocket: :whale: The Best Unity WebSocket Plugin for All Platforms. (github.com)

using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Text;
using UnityEngine;
using UnityEngine.UI;
using UnityWebSocket;public class uSherpaWebGL : MonoBehaviour
{IWebSocket ws;public Text text;Queue<string> msgs = new Queue<string>();// Start is called before the first frame updatevoid Start(){ws = new WebSocket("ws://127.0.0.1:9999");ws.OnOpen += OnOpen;ws.OnMessage += OnMessage;ws.OnError += OnError;ws.OnClose += OnClose;ws.ConnectAsync();}// Update is called once per framevoid Update(){if (msgs.Count > 0){string msg = msgs.Dequeue();text.text += msg;}}byte[] desArray;public void OnData(float[] input){Debug.Log("input.Length:" + input.Length);SendData(input);}void SendData(float[] input){var desArraySize = Buffer.ByteLength(input);IntPtr srcArrayPtr = Marshal.UnsafeAddrOfPinnedArrayElement(input, 0);desArray = new byte[desArraySize];Marshal.Copy(srcArrayPtr, desArray, 0, desArraySize);if (ws != null && ws.ReadyState == WebSocketState.Open){ws.SendAsync(desArray);}}void OnOpen(object sender, OpenEventArgs e){Debug.Log("WS connected!");}void OnMessage(object sender, MessageEventArgs e){if (e.IsBinary){string str = Encoding.UTF8.GetString(e.RawData);Debug.Log("WS received message: " + str);msgs.Enqueue(str);}else if (e.IsText){}}void OnError(object sender, ErrorEventArgs e){Debug.Log("WS error: " + e.Message);}void OnClose(object sender, CloseEventArgs e){Debug.Log(string.Format("Closed: StatusCode: {0}, Reason: {1}", e.StatusCode, e.Reason));}private void OnApplicationQuit(){if (ws != null && ws.ReadyState != WebSocketState.Closed){ws.CloseAsync();}}
}

服务器端使用了Fleck

// See https://aka.ms/new-console-template for more information
using Fleck;
using System.Text;namespace uSherpaServer
{internal class Program{// 声明配置和识别器变量static SherpaNcnn.OnlineRecognizer recognizer;static SherpaNcnn.OnlineStream onlineStream;static string tokensPath = "tokens.txt";static string encoderParamPath = "encoder_jit_trace-pnnx.ncnn.param";static string encoderBinPath = "encoder_jit_trace-pnnx.ncnn.bin";static string decoderParamPath = "decoder_jit_trace-pnnx.ncnn.param";static string decoderBinPath = "decoder_jit_trace-pnnx.ncnn.bin";static string joinerParamPath = "joiner_jit_trace-pnnx.ncnn.param";static string joinerBinPath = "joiner_jit_trace-pnnx.ncnn.bin";static int numThreads = 1;static string decodingMethod = "greedy_search";static string modelPath;static float sampleRate = 16000;static IWebSocketConnection client;static void Main(string[] args){//需要将此文件夹拷贝到exe所在的目录modelPath = Environment.CurrentDirectory + "/sherpa-ncnn-streaming-zipformer-small-bilingual-zh-en-2023-02-16";// 初始化配置SherpaNcnn.OnlineRecognizerConfig config = new SherpaNcnn.OnlineRecognizerConfig{FeatConfig = { SampleRate = sampleRate, FeatureDim = 80 },ModelConfig = {Tokens = Path.Combine(modelPath,tokensPath),EncoderParam =  Path.Combine(modelPath,encoderParamPath),EncoderBin =Path.Combine(modelPath, encoderBinPath),DecoderParam =Path.Combine(modelPath, decoderParamPath),DecoderBin = Path.Combine(modelPath, decoderBinPath),JoinerParam = Path.Combine(modelPath,joinerParamPath),JoinerBin =Path.Combine(modelPath,joinerBinPath),UseVulkanCompute = 0,NumThreads = numThreads},DecoderConfig = {DecodingMethod = decodingMethod,NumActivePaths = 4},EnableEndpoint = 1,Rule1MinTrailingSilence = 2.4F,Rule2MinTrailingSilence = 1.2F,Rule3MinUtteranceLength = 20.0F};// 创建识别器和在线流recognizer = new SherpaNcnn.OnlineRecognizer(config);onlineStream = recognizer.CreateStream();StartWebServer();Update();Console.ReadLine();}static void StartWebServer(){//存储连接对象的池var connectSocketPool = new List<IWebSocketConnection>();//创建WebSocket服务端实例并监听本机的9999端口var server = new WebSocketServer("ws://127.0.0.1:9999");//开启监听server.Start(socket =>{//注册客户端连接建立事件socket.OnOpen = () =>{client = socket;Console.WriteLine("Open");//将当前客户端连接对象放入连接池中connectSocketPool.Add(socket);};//注册客户端连接关闭事件socket.OnClose = () =>{client = null;Console.WriteLine("Close");//将当前客户端连接对象从连接池中移除connectSocketPool.Remove(socket);};//注册客户端发送信息事件socket.OnBinary = message =>{float[] floatArray = new float[message.Length / 4];Buffer.BlockCopy(message, 0, floatArray, 0, message.Length);// 将采集到的音频数据传递给识别器onlineStream.AcceptWaveform(sampleRate, floatArray);};});}static string lastText = "";static void Update(){while (true){// 每帧更新识别器状态if (recognizer.IsReady(onlineStream)){recognizer.Decode(onlineStream);}var text = recognizer.GetResult(onlineStream).Text;bool isEndpoint = recognizer.IsEndpoint(onlineStream);if (!string.IsNullOrWhiteSpace(text) && lastText != text){if (string.IsNullOrWhiteSpace(lastText)){lastText = text;if (client != null){client.Send(Encoding.UTF8.GetBytes(text));//Console.WriteLine("text1:" + text);}}else{if (client != null){client.Send(Encoding.UTF8.GetBytes(text.Replace(lastText, "")));lastText = text;}}}if (isEndpoint){if (!string.IsNullOrWhiteSpace(text)){if (client != null){client.Send(Encoding.UTF8.GetBytes("。"));}// Console.WriteLine("text2:" + text);}recognizer.Reset(onlineStream);//Console.WriteLine("Reset");}Thread.Sleep(200); // ms}}}
}

2、Unity录音插件使用了uMicrophoneWebGL 绑定DataEvent事件实时获取话筒数据(float数组)

最后放上工程地址

客户端 uSherpa: fork from https://github.com/ssssssilver/sherpa-ncnn-unity.git改成 Unity WebGL版

服务器端 GitHub - xue-fei/uSherpaServer: uSherpaServer 给Unity提供流式语音识别的websocket服务

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/6433.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

[嵌入式系统-62]:RT-Thread-内核:多核CPU SMP的支持与移植

目录 RT-Thread SMP 介绍与移植 1. 多核的优点 2. 多核启动 2.1 概述 2.2 CPU0 启动流程 2.3 次级 CPU 启动流程 3. 多核调度 3.1 任务特性 3.2 调度策略 4. SMP 内核接口 处理器间中断 IPI OS Tick 自旋锁 spinlock 任务绑定 4. SMP移植说明 编译环境准备 创…

配置网关,解决本地连接不上Linux虚拟机的问题

在Window环境下&#xff0c;使用远程终端工具连接不了VMware搭建的Linux虚拟机&#xff08;CentOS 7&#xff09;&#xff0c;并且在命令行ping不通该Linux虚拟机的IP地址。下面通过配置网关解决本地与Linux虚拟机连接问题&#xff1a; 1 查看虚拟机网关地址 在VMware虚拟机上…

数据库开发关键之与DQL查询语句有关的两个案例

案例 案例1 条件分页查询 查看项目经理提供给我们的需求文档 模糊匹配的含义是 只要包含"张"就可以 use dduo;-- 按照需求完成员工管理的条件分页查询 根据输入条件 查询第一页的数据 每页展示10条记录 -- 输入条件&#xff1a; -- 姓名&#xff1a; 张 -- 年龄&…

基于YOLOv8的水稻虫害识别系统,加入BiLevelRoutingAttention注意力进行创新优化

&#x1f4a1;&#x1f4a1;&#x1f4a1;本文摘要&#xff1a;基于YOLOv8的水稻虫害识别&#xff0c;阐述了整个数据制作和训练可视化过程&#xff0c;并加入BiLevelRoutingAttention注意力进行优化&#xff0c;最终mAP从原始的 0.697提升至0.732 博主简介 AI小怪兽&#xff…

c语言从入门到函数速成(2)

温馨提醒&#xff1a;本篇文章适合人群&#xff1a;刚学c又感觉那个地方不怎么懂的同学以及以及学了一些因为自身原因停学一段时间后又继续学​​​c的学 好&#xff0c;正片开始&#xff01; 数组 概念&#xff1a;数组中存放的是1个或者多个数据&#xff0c;但是数组元素个…

由于找不到msvcr110.dll,无法继续执行代码的解决方法

在日常使用计算机的过程中&#xff0c;可能会遇到系统提示缺少msvcr110.dll文件的情况&#xff0c;这一问题往往导致某些应用程序无法正常运行。幸运的是&#xff0c;有多种方法可以有效应对这一困境&#xff0c;帮助您的计算机恢复顺畅运作。以下是解决计算机丢失msvcr110.dll…

JavaWeb--1.Servlet

Servlet&#xff08;基础&#xff09; 1、配置依赖&#xff1a; ​ 在pom.xml文件中加入相关依赖 <dependencies><dependency><groupId>jakarta.servlet</groupId><artifactId>jakarta.servlet-api</artifactId><version>5.0.0&l…

Python数据分析案例43——Fama-French回归模型资产定价(三因子/五因子)

案例背景 最近看到要做三因子模型的同学还挺多的&#xff0c;就是所谓的Fama-French回归模型&#xff0c;也就是CAMP资本资产定价模型的升级版&#xff0c;然后后面还升级为了五因子模型。 看起来眼花缭乱&#xff0c;其实抛开金融资产定价的背景&#xff0c;从机器学习角度来…

HTML_CSS学习:常用文本属性

一、文本颜色 相关代码&#xff1a; <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>文本颜色</title><style>div{font-size: 90px;}.atguigu1{color: #238c20;}.atguigu2{color: rgb(2…

【b站vue教程】1 宏观视角下的浏览器——前端大厂面试必刷:前后端必学的网络安全浏览器工作原理:从入门到精通全套【附带所有源码】

课程地址&#xff1a;【前端大厂面试必刷&#xff1a;前后端必学的网络安全浏览器工作原理&#xff1a;从入门到精通全套【附带所有源码】】 https://www.bilibili.com/video/BV1UL41157hP/?share_sourcecopy_web&vd_sourceb1cb921b73fe3808550eaf2224d1c155 目录 1、宏…

vue3中使用crypto-js库进行加密/解密

使用crypto-js库进行加密/解密 安装 npm install crypto-js 基本使用 <template><div>使用crypto-js库进行加密/解密</div> </template><script setup> import CryptoJS from crypto-js; import { onMounted } from vue;// 加密函数 const encr…

记某APP登录逆向解密过程

最近在学习APP逆向相关的知识&#xff0c;刚好拿到了一个APP目标&#xff0c;该APP登录过程存在加密&#xff0c;所以记录下逆向破解的过程。流程 先介绍下拿到该APP后续所做的一些工作流程 选择相应版本安装到测试机当中进行抓包&#xff0c;查看数据包分析登录请求包&#x…

中国目前比较有影响力的人物颜廷利:不能升命, 活着何用?

不能‘升命’&#xff0c; 活着何用&#xff1f;…&#xff08;升命学说&#xff09; 21世纪东方哲学家思想家、科学家、当代中国教育界知名教授、专业周易起名改名字、易经姓名学专家、目前比较有影响力的人物、现代国学大师泰斗杰出代表颜廷利教授在《升命学说》‘净化论’里…

Java 类与对象

目录 1 类是什么 1.1 面向对象 1.2 面向对象与面向过程 2 类定义和使用 2.1 类的定义格式 2.2 练习定义一个狗类 3 类的实例化 4 this引用 5 对象的构造与初始化 5.1 构造方法与初始化 5.2 默认初始化 5.3 就地初始化 1 类是什么 关于类是什么&#xff0c;我们需要对…

开源版本管理系统的搭建一:SVN服务端安装

作者&#xff1a;私语茶馆 1.Windows搭建SVN版本管理系统 点评&#xff1a;SVN本身非常简洁易用&#xff0c;VisualSVN文档支撑非常好&#xff0c;客户端TortoiseSVN非常专业。5星好评。 1.1.SVN概要和组成 背景介绍 Svn是一个开源版本管理系统&#xff0c;由CollabNet公司…

一、Mysql索引的底层数据结构与算法

Mysql索引的底层数据结构与算法 前言一、索引数据结构为什么 MySQL 的索引要使用 B 树而不是其他树形结构?比如 B 树?为什么InnoDB存储引擎选择使用Btree索引结构&#xff1f; 二、索引分类思考&#xff1a;以下SQL语句&#xff0c;那个执行效率高&#xff1f;为什么&#xf…

SQL如何利用Bitmap思想优化array_contains()函数

目录 0 问题描述 1 位图思想 2 案例实战 3 小结 0 问题描述 在工作中&#xff0c;我们往往使用array_contains()函数来进行存在性问题分析&#xff0c;如判断某个数是否在某个数组中&#xff0c;但是当表数据量过多&#xff0c;存在大量array_contains()函数时&#xff0c;…

【软件测试】测试用例设计方法

1. 等价类划分法1.1. 等价类划分法的定义1.2. 有效等价类和无效等价类1.3. 等价类划分法实例分析 2. 边界值分析法2.1. 边界值分析法的定义2.2. 边界点2.3. 边界值法实例分析 3. 判定表法3.1. 如何用判定表法设计测试用例3.2. 判定表法实例分析 4. 正交表法4.1. 什么是正交表4.…

批量美化图片,轻松实现多张图片描边,让图片瞬间焕发新生!

图片已成为我们日常生活中不可或缺的一部分。无论是社交媒体上的个人分享&#xff0c;还是商业宣传中的产品展示&#xff0c;高质量、精美的图片都扮演着至关重要的角色。然而&#xff0c;对于许多人来说&#xff0c;图片处理仍然是一个令人头疼的问题。现在&#xff0c;我们为…

商超物联网方案-Hotspot Service和客流分析方案概述

商超物联网方案-Hotspot Service和客流分析方案概述 场景概述 大型商场、大型综合体在相互竞争及线上消费的影响下&#xff0c;利润增长缓慢&#xff0c;迫切需要通过提供个性化服务提升顾客购物体验&#xff0c;促进利润增长。 向不同顾客推送其感兴趣的广告&#xff0c;不仅…