当前位置: 首页 > news >正文

实现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.jsqmd.com/news/285867/

相关文章:

  • Java毕设选题推荐:基于springboot大学生就业服务平台springboot的面向大学生的职业兴趣评估与就业指导平台【附源码、mysql、文档、调试+代码讲解+全bao等】
  • 亿可达×飞书:一键搞定定时群通知,告别人工重复提醒
  • 2026最新版!微信小程序SaaS模板平台前十排名报告
  • 深入解析:Rust 练习册 :Matching Brackets与栈数据结构
  • 2026 年 AI PPT 工具深度评测:拒绝 “科技与狠活”,寻找真正能解决职场痛点的生产力工具
  • 2026年专业深度测评:淘宝代运营公司排名前五权威榜单
  • 【计算机毕业设计案例】基于Java的在线食品安全信息平台基于springboot的食品安全管理系统(程序+文档+讲解+定制)
  • Java毕设项目:基于springboot的食品安全管理系统(源码+文档,讲解、调试运行,定制等)
  • AI代码质检员:如何用大模型提前揪出软件缺陷?
  • 湖州职业技术学院:Wi-Fi 7全覆盖,打造智慧校园“湖职样本”
  • Linux命令创意
  • :计算机Java毕设实战-基于springboot的食品安全管理系统食品安全档案管理系统【完整源码+LW+部署说明+演示视频,全bao一条龙等】
  • Vue3底层原理——keep-alive
  • :vtkBooleanOperationPolyDataFilter 布尔运算全解析
  • 2026年拼多多代运营服务商专业深度测评:排名前五权威榜单
  • APS1604M-SQR-SN核心性能特点及应用
  • GD5F2GM7UEYIGR核心性能及应用
  • 维基百科志愿者创建AI写作特征库,现推出插件帮助规避检测
  • Java毕设选题推荐:基于springboot+vue的食品安全管理系统基于springboot的食品安全管理系统【附源码、mysql、文档、调试+代码讲解+全bao等】
  • 计算机Java毕设实战-基于SpringBoot+Vue线上素菜超市平台蔬菜商城springboot的蔬菜超市系统【完整源码+LW+部署说明+演示视频,全bao一条龙等】
  • AI助力托管安全服务商降本增效实战分享
  • 2026 年办公效率新标杆:AI PPT 工具的全流程生成能力评测,重新定义演示文稿制作
  • ThinkPHP框架学习全攻略
  • 前端性能优化系列(一):问题分析与诊断
  • Java毕设选题推荐:基于SpringBoot生鲜商城系统基于springboot的蔬菜超市系统【附源码、mysql、文档、调试+代码讲解+全bao等】
  • 高管无视AI泡沫担忧,坚定推进技术采用计划
  • 2026年天猫代运营公司排名前五权威发布:专业深度测评
  • MX Linux 25.1恢复可切换初始化系统功能
  • offline_install_processor.cpp中的IPC通信
  • 微软CEO重新定义AI主权:关键在控制权而非数据中心位置