实现Unity录音、百度云语音转文字

在unity中录制声音,调用百度云-语音转文字标准版接口,获取转换后的文字内容 调用示例: BtnStartVoice.onClick.AddListener(()=>{//开始录音MicrophoneRecorderManager.Instance.StartRecording();});BtnEndVoice.onClick.AddListener(()=>{//结束录音MicrophoneRecorderManager.Instance.StopRecording(strContent=>{InputChat.text=strContent;});});

百度云-语音识别API及代码示例地址:
百度智能云-语音识别

以下为相关代码实现:

usingSystem;usingSystem.Collections;usingSystem.Collections.Generic;usingQFramework;usingUnityEngine;//麦克风录音管理器publicclassMicrophoneRecorderManager:MonoSingleton<MicrophoneRecorderManager>{publicoverridevoidOnSingletonInit(){Init();base.OnSingletonInit();}privateAudioClipcurrentRecording;privatestring_selectedDevice;privateAudioSource_audioSource;//播放录音,用于测试是否录音成功privateintsampleRate=16000;//固定采样率privateintmaxRecordingTime=60;// 最大录音时长(秒)//是否正在录音privateboolisRecording;voidInit(){// 获取所有麦克风设备string[]devices=Microphone.devices;if(devices.Length==0){Debug.LogError("没有检测到麦克风设备");return;}devices.ForEach(x=>Debug.Log($"devices:{x}"));// 选择第一个可用设备_selectedDevice=devices[0];Debug.Log($"已选择麦克风设备:{_selectedDevice}");/* // 添加并配置AudioSource组件,用于测试是否录音成功 _audioSource = gameObject.AddComponent<AudioSource>(); _audioSource.loop = false; // 不循环播放 */}// 开始录音publicvoidStartRecording(){if(string.IsNullOrEmpty(_selectedDevice)){Debug.LogError("没有可用的麦克风设备");return;}//如果正在录音if(Microphone.IsRecording(_selectedDevice)){return;}/* // 停止之前可能正在播放的音频,用于测试录音时使用 if (_audioSource.isPlaying) { _audioSource.Stop(); } */// 开始录音,采样率44100Hz,时长10秒currentRecording=Microphone.Start(_selectedDevice,false,maxRecordingTime,sampleRate);isRecording=true;Debug.Log("录音已开始");}// 停止录音publicvoidStopRecording(Action<string>callBack){if(!isRecording)return;// 获取当前录音位置intrecordingLength=Microphone.GetPosition(_selectedDevice);// 停止录音Microphone.End(_selectedDevice);isRecording=false;Debug.Log("录音已停止");// 创建新的AudioClip,只包含实际录音的部分if(recordingLength>0){AudioCliprecordedClip=AudioClip.Create("Recording",recordingLength,currentRecording.channels,sampleRate,false);// 获取录音数据float[]samples=newfloat[recordingLength*currentRecording.channels];currentRecording.GetData(samples,0);recordedClip.SetData(samples,0);// 保存并播放currentRecording=recordedClip;LogUtilits.LogWarning($"采样率:{currentRecording.frequency}");byte[]audioData=WavUtility.ConvertAudioClipToPCM(currentRecording);StartCoroutine(BDSmartManager.Instance.SpeechToText(audioData,callBack,null));//PlayRecording();Debug.Log("播放录音中...");;}else{Debug.LogError("录音失败或时长太短");;}}/// <summary>/// 播放录音,用于测试是否正确录音成功/// </summary>privatevoidPlayRecording(){if(currentRecording==null){Debug.LogWarning("没有可播放的录音");return;}// 设置音频源并播放_audioSource.clip=currentRecording;_audioSource.Play();}// 在组件被销毁时停止录音privatevoidOnDestroy(){if(Microphone.IsRecording(_selectedDevice)){Microphone.End(_selectedDevice);}if(_audioSource!=null&&_audioSource.isPlaying){_audioSource.Stop();}}}
usingNewtonsoft.Json;usingQFramework;usingSystem;usingSystem.Collections;usingSystem.Collections.Generic;usingSystem.Net.NetworkInformation;usingUnity.Burst.Intrinsics;usingUnityEngine;usingUnityEngine.Networking;//百度智能语音publicclassBDSmartManager:MonoSingleton<BDSmartManager>{privatestringaccessToken;//http通信的请求tokenprivateboolisTokenValid=false;//是否有效token#region获取token/// <summary>/// 使用 AK, SK 生成鉴权签名(Access Token)/// </summary>/// <returns>鉴权签名信息(Access Token)</returns>publicIEnumeratorGetAccessToken(){stringapiKey=BDInterfaceDefine.ApiKey;stringsecretKey=BDInterfaceDefine.SecretKey;stringurl=$"https://aip.baidubce.com/oauth/2.0/token?grant_type=client_credentials&client_id={apiKey}&client_secret={secretKey}";usingUnityWebRequestrequest=UnityWebRequest.Post(url,newWWWForm());request.timeout=-1;yieldreturnrequest.SendWebRequest();if(request.result==UnityWebRequest.Result.Success){stringresponseContent=request.downloadHandler.text;Debug.Log($"responseContent:{responseContent}");BaiduTokenResponseresult=JsonConvert.DeserializeObject<BaiduTokenResponse>(responseContent);accessToken=result.access_token;isTokenValid=true;// 这里可以返回token或者执行其他操作Debug.Log($"获取Token成功:{accessToken}");}else{Debug.LogError($"获取Token失败:{request.error}");}}#endregion#region语音识别-标准版/// <summary>/// 语音识别-标准版/// </summary>publicIEnumeratorSpeechToText(byte[]audioData,Action<string>onSuccess,Action<string>onError){if(!isTokenValid){Debug.LogWarning("Token无效,正在重新获取...");yieldreturnStartCoroutine(GetAccessToken());}// 准备请求数据varrequestData=newDictionary<string,object>{{"format","pcm"},//语音文件的格式,pcm/wav/amr/m4a。不区分大小写。推荐pcm文件{"rate",16000},//采样率,16000、8000,固定值{"channel",1},//声道数,仅支持单声道,请填写固定值 1{"token",accessToken},{"cuid",SystemInfo.deviceUniqueIdentifier},//用户唯一标识,用来区分用户,计算UV值。建议填写能区分用户的机器 MAC 地址或 IMEI 码,长度为60字符以内。{"len",audioData.Length},//本地语音文件的的字节数,单位字节{"speech",Convert.ToBase64String(audioData)}//本地语音文件的二进制语音数据 ,需要进行base64 编码。与len参数连一起使用。};stringjsonData=JsonConvert.SerializeObject(requestData);LogUtilits.LogMsg($"requestData:{jsonData}");byte[]postData=System.Text.Encoding.UTF8.GetBytes(jsonData);// 发送请求//string url = "https://vop.baidu.com/server_api";stringurl=BDInterfaceDefine.SpeechRecognition_Standard;UnityWebRequestrequest=UnityWebRequest.Post(url,newWWWForm());request.timeout=-1;request.SetRequestHeader("Content-Type","application/json");request.SetRequestHeader("Accept","application/json");//request.uploadHandler=newUploadHandlerRaw(postData);request.downloadHandler=newDownloadHandlerBuffer();yieldreturnrequest.SendWebRequest();if(request.result==UnityWebRequest.Result.Success){LogUtilits.LogMsg($"识别结果:{request.downloadHandler.text}");varresponse=JsonConvert.DeserializeObject<BaiduASRResponse>(request.downloadHandler.text);if(response.err_no==0&&response.result!=null&&response.result.Length>0){stringrecognizedText=response.result[0];onSuccess?.Invoke(recognizedText);Debug.Log($"识别成功:{recognizedText}");}else{stringerrorMsg=$"err_msg识别失败:{response.err_msg}(err_no错误码:{response.err_no})";onError?.Invoke(errorMsg);Debug.LogError(errorMsg);}}else{stringerrorMsg=$"网络请求失败:{request.error}";onError?.Invoke(errorMsg);Debug.LogError(errorMsg);}}#endregion}
//百度云接口定义publicstaticclassBDInterfaceDefine{publicconststringApiKey="替换为自己的ApiKey";publicconststringSecretKey="替换为自己的SecretKey";/// <summary>/// 短语音识别标准版/// </summary>publicconststringSpeechRecognition_Standard="https://vop.baidu.com/server_api";}// 百度智能云API响应数据结构[System.Serializable]publicclassBaiduASRResponse{publicstringcorpus_no;publicstringerr_msg;publicinterr_no;publicstring[]result;publicstringsn;}// Token获取响应[System.Serializable]publicclassBaiduTokenResponse{publicstringrefresh_token;publicintexpires_in;publicstringsession_key;publicstringaccess_token;publicstringscope;publicstringsession_secret;}
usingSystem;usingUnityEngine;//录音数据转换工具类publicstaticclassRecordAudioUtility{publicstaticbyte[]ConvertAudioClipToPCM(AudioClipclip){// 获取音频数据float[]samples=newfloat[clip.samples*clip.channels];clip.GetData(samples,0);// 转换为16位PCMbyte[]pcmData=ConvertFloatToPCM16(samples);// 如果是立体声,转换为单声道if(clip.channels==2){pcmData=ConvertStereoToMono(pcmData);}returnpcmData;}privatestaticbyte[]ConvertStereoToMono(byte[]stereoData){// 16位PCM,每个采样2字节intsampleCount=stereoData.Length/4;// 每个通道的采样数byte[]monoData=newbyte[sampleCount*2];for(inti=0;i<sampleCount;i++){intstereoPos=i*4;intmonoPos=i*2;// 获取左右声道采样shortleft=BitConverter.ToInt16(stereoData,stereoPos);shortright=BitConverter.ToInt16(stereoData,stereoPos+2);// 计算平均值shortmono=(short)((left+right)/2);// 写入单声道数据byte[]monoBytes=BitConverter.GetBytes(mono);monoData[monoPos]=monoBytes[0];monoData[monoPos+1]=monoBytes[1];}returnmonoData;}privatestaticbyte[]ConvertFloatToPCM16(float[]samples){byte[]pcmBytes=newbyte[samples.Length*2];intposition=0;for(inti=0;i<samples.Length;i++){// 限制在[-1, 1]范围内floatsample=Mathf.Clamp(samples[i],-1f,1f);// 转换为16位整型shortintSample=(short)(sample*32767f);// 小端字节序pcmBytes[position++]=(byte)(intSample&0xFF);pcmBytes[position++]=(byte)((intSample>>8)&0xFF);}returnpcmBytes;}}

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

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

相关文章

维基百科志愿者创建AI写作特征库,现推出插件帮助规避检测

上周六&#xff0c;科技企业家Siqi Chen发布了一个开源插件&#xff0c;专门用于Anthropic公司的Claude Code AI助手&#xff0c;该插件能指导AI模型避免使用典型的AI写作风格。这个名为"Humanizer"的简单提示插件向Claude提供了一份包含24种语言和格式模式的清单&am…

2026年天猫代运营公司排名前五权威发布:专业深度测评

2026年天猫淘宝代运营公司十大排名权威发布:基于EEAT框架的专业深度测评 随着电商行业进入精细化与全域运营的新阶段,品牌方对专业、高效、可量化的天猫淘宝代运营服务需求持续攀升。面对市场上服务商能力参差不齐的…

MX Linux 25.1恢复可切换初始化系统功能

MX Linux 25.1恢复了切换初始化系统的能力&#xff0c;这是旧版MX Linux的杀手级功能。此次更新经历了一个非常短暂的测试期——25.1 beta 1版本在一周前发布。不过&#xff0c;这并不是普通的错误修复点版本。正如测试版公告所说&#xff1a;"我们通常不会为点版本更新制…

offline_install_processor.cpp中的IPC通信

offline_install_processor.cpp中的IPC通信IPC 概念解析与代码中使用场景详解 结合你提供的离线升级代码,我先帮你理清 IPC 是什么,再具体分析代码中为什么必须用到 IPC、以及用到了哪些 IPC 能力。 一、先搞懂:什么…

微软CEO重新定义AI主权:关键在控制权而非数据中心位置

微软CEO萨蒂亚纳德拉在达沃斯世界经济论坛上与贝莱德CEO拉里芬克的对话中表示&#xff0c;数据中心位置是AI主权"最不重要的因素"。纳德拉认为&#xff0c;企业AI主权的关键在于控制基于专有知识训练的模型&#xff0c;而不是物理基础设施的位置。"如果你无法将…

Nginx多服务静态资源路径冲突解决方案

在使用Nginx反向代理多个Flask应用时,遇到了一个棘手的问题:不同服务的静态资源(CSS/JS)会互相干扰。本文记录了问题的分析过程和解决方案。 关键词:Nginx反向代理、Flask静态资源、location匹配、proxy_pass问题…

CIO如何解锁人工智能战略价值并实施落地

毫无疑问&#xff0c;CIO在识别人工智能高价值应用场景方面发挥着关键作用。北卡罗来纳州卡里镇IT负责人Nicole Coughlin这样描述&#xff1a; "我们的工作是倾听&#xff0c;真正倾听工作中的模式和痛点&#xff0c;"Coughlin说。如果CIO与业务部门之间缺乏这种联系…

Mobileye关键之年,Robotaxi去安全员、SuperVisionChauffeur迈入量产

作者 |德新 编辑 |王博2026年&#xff0c;被Mobileye创始人兼CEO Amnon Shashua教授视为关键的一年&#xff0c;这年公司将会达成两项重要的里程碑&#xff1a; 第一&#xff0c;Robotaxi实现 “去安全员”无人化驾驶&#xff1b;第二&#xff0c;与保时捷合作的SuperVision&am…

scheme3.1.1 局部状态变量

通过改变局部变量,我们可以完成一些需要改变状态的操作。例如,我们可以设计一个收支系统,对某一账户内的金额进行增加和提取。 初始系统:点击查看代码 #lang racket (define (make-account balance)(define (withd…

机器学习模型部署需超越聚合指标评估

MIT研究人员发现&#xff0c;当机器学习模型应用于训练数据之外的新数据时&#xff0c;会出现重大失效问题&#xff0c;这表明在新环境中部署模型时需要进行充分测试。"我们证明了即使在大量数据上训练模型并选择最佳平均模型&#xff0c;在新环境中这个最佳模型可能对6%-…

如何直接编辑Github的Readme.md文件

GitHub的markdown语法在标准的markdown语法基础上做了扩充,称之为GitHub Flavored Markdown。简称GFM。https://github.com/guodongxiaren/README GitHub的markdown语法在标准的markdown语法基础上做了扩充,称之为Gi…

(新卷,200分)- 区间交叠问题(Java JS Python)

(新卷,200分)- 区间交叠问题&#xff08;Java & JS & Python&#xff09;题目描述给定坐标轴上的一组线段&#xff0c;线段的起点和终点均为整数并且长度不小于1&#xff0c;请你从中找到最少数量的线段&#xff0c;这些线段可以覆盖柱所有线段。输入描述第一行输入为所…

(新卷,200分)- 区块链文件转储系统(Java JS Python)

(新卷,200分)- 区块链文件转储系统&#xff08;Java & JS & Python&#xff09; 题目描述 区块链底层存储是一个链式文件系统&#xff0c;由顺序的N个文件组成&#xff0c;每个文件的大小不一&#xff0c;依次为F1,F2,...,Fn。随着时间的推移&#xff0c;所占存储会越…

JVM(Java虚拟机) - 教程

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

(新卷,200分)- 任务调度(Java JS Python)

(新卷,200分)- 任务调度&#xff08;Java & JS & Python&#xff09;题目描述现有一个CPU和一些任务需要处理&#xff0c;已提前获知每个任务的任务ID、优先级、所需执行时间和到达时间。 CPU同时只能运行一个任务&#xff0c;请编写一个任务调度程序&#xff0c;采用“…

全网最全9个AI论文软件,本科生毕业论文必备!

全网最全9个AI论文软件&#xff0c;本科生毕业论文必备&#xff01; AI 工具如何成为论文写作的得力助手 随着人工智能技术的不断进步&#xff0c;AI 工具在学术写作中的应用越来越广泛。对于本科生而言&#xff0c;撰写毕业论文是一项既重要又充满挑战的任务。而 AI 工具的出现…

(新卷,200分)- 上班之路(Java JS Python)

(新卷,200分)- 上班之路&#xff08;Java & JS & Python&#xff09;题目描述Jungle 生活在美丽的蓝鲸城&#xff0c;大马路都是方方正正&#xff0c;但是每天马路的封闭情况都不一样。 地图由以下元素组成&#xff1a; 1&#xff09;”.” — 空地&#xff0c;可以达到…

【课程设计/毕业设计】基于springboot的小区蔬菜水果商城系统蔬菜超市系统【附源码、数据库、万字文档】

博主介绍&#xff1a;✌️码农一枚 &#xff0c;专注于大学生项目实战开发、讲解和毕业&#x1f6a2;文撰写修改等。全栈领域优质创作者&#xff0c;博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围&#xff1a;&am…

Java计算机毕设之基于Springboot的生鲜超市管理系统基于springboot的蔬菜超市系统(完整前后端代码+说明文档+LW,调试定制等)

博主介绍&#xff1a;✌️码农一枚 &#xff0c;专注于大学生项目实战开发、讲解和毕业&#x1f6a2;文撰写修改等。全栈领域优质创作者&#xff0c;博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围&#xff1a;&am…

day166—递归—多边形三角剖分的最低得分(LeetCode-1039)

题目描述你有一个凸的 n 边形&#xff0c;其每个顶点都有一个整数值。给定一个整数数组 values &#xff0c;其中 values[i] 是按 顺时针顺序 第 i 个顶点的值。假设将多边形 剖分 为 n - 2 个三角形。对于每个三角形&#xff0c;该三角形的值是顶点标记的乘积&#xff0c;三角…