Uniapp 安卓實現訊飛語音聽寫(復制即用)

????????在移動應用開發中,語音交互功能能夠極大提升用戶體驗,讓操作更加便捷自然。訊飛語音聽寫技術憑借其高準確率和穩定性,成為眾多開發者的選擇。本文將詳細介紹如何在 Uniapp 項目中,實現安卓端的訊飛語音聽寫功能,幫助你快速為應用增添實用的語音交互能力。
????????但是,由于uniapp錄音管理器?uni.getRecorderManager()的實時監聽音頻大小幀的功能onFrameRecorded不支持app,app端只能在錄音結束后獲取臨時錄音文件,因此需要把錄音文件轉成base64,在切片傳輸給訊飛的接口。

一、準備工作?

1. 注冊訊飛開放平臺賬號?

首先,你需要前往訊飛開放平臺注冊賬號,完成實名認證。認證通過后,你將獲得使用訊飛相關服務的權限。?

2. 創建應用并獲取 AppID 和密鑰?

在訊飛開放平臺控制臺中,創建一個新的應用。創建成功后,你會得到該應用的 AppID、AppKey 和 AppSecret,這些信息在后續集成過程中至關重要,用于驗證應用身份。?

二、實現代碼

以下是已經實現的uniapp在app端的一個簡單的利用訊飛語音聽寫api完成的語音識別的demo,復制代碼到你的項目中,把你申請的appid、apiSecret、apiKey替換到代碼中,即可運行識別。

<template><div class="asr"><button class="btn" shape="circle" type="info" @touchstart="openMedia" @touchend="stopMedia">按住說話</button><view v-if="show" class="iating"><text text="正在說話中...." color="#49ABFE" size="27rpx" line-height="60rpx" align="center"></text></view></div>
</template><script>
import CryptoJS from "crypto-js";export default {data() {return {config: {hostUrl: "wss://iat-api.xfyun.cn/v2/iat",host: "iat-api.xfyun.cn",appid: "申請的訊飛appid",apiSecret: "申請的訊飛apiSecret",apiKey: "申請的apiKey",uri: "/v2/iat",highWaterMark: 1280,},uniSocketTask: null,show: false,resultText: "",resultTextTemp: "",renderText: ""};},methods: {// 鑒權簽名getAuthStr(date) {let signatureOrigin = `host: ${this.config.host}\ndate: ${date}\nGET ${this.config.uri} HTTP/1.1`;let signatureSha = CryptoJS.HmacSHA256(signatureOrigin, this.config.apiSecret);let signature = CryptoJS.enc.Base64.stringify(signatureSha);let authorizationOrigin =`api_key="${this.config.apiKey}", algorithm="hmac-sha256", headers="host date request-line", signature="${signature}"`;let authStr = CryptoJS.enc.Base64.stringify(CryptoJS.enc.Utf8.parse(authorizationOrigin));return authStr;},getUrl() {let date = new Date().toUTCString();let wssUrl =this.config.hostUrl +"?authorization=" +this.getAuthStr(date) +"&date=" +encodeURIComponent(date) +"&host=" +this.config.host;console.log("websocke科大訊飛的地址為", wssUrl);return wssUrl;},// 打開麥克風openMedia() {this.connectSocket();},// 創建連接并返回數據connectSocket() {if (this.uniSocketTask === null) {this.uniSocketTask = uni.connectSocket({url: this.getUrl(),success() {},});this.uniSocketTask.onOpen(() => {console.log("監聽到開啟連接成功");this.startRecord();});this.uniSocketTask.onClose(() => {console.log("監聽到關閉連接成功");this.uniSocketTask = null;});this.uniSocketTask.onError(() => {console.log("監聽到連接發生錯誤");});this.uniSocketTask.onMessage((res) => {const message = JSON.parse(res.data);if (res.data) {console.log("收到服務器消息,并開始渲染", message);this.renderResult(message);if (message.code === 0 && message.data.status === 2) {console.log('最后一條', this.renderText);this.closeSocket();// 注意:這里需要根據實際情況處理事件觸發// this.$emit('renderText', this.renderText);}if (message.code !== 0) {this.closeSocket();console.error(message);}} else {console.log("未監聽到消息:原因:", JSON.stringify(res));}});} else {console.log("socketTask實例已存在");}},// 發送給科大訊飛的第一幀的模板數據格式getInitialFrame() {return {common: {app_id: this.config.appid,},business: {language: "zh_cn",domain: "iat",accent: "mandarin",dwa: "wpgs", // 可選參數,動態修正vad_eos: 5000,},data: {status: 0,format: "audio/L16;rate=16000",encoding: "lame"},};},// 發送消息sendMessage(sendData) {console.log('發送', JSON.stringify(sendData));this.uniSocketTask.send({data: JSON.stringify(sendData),success() {},fail() {console.log("發送失敗");},});},// 關閉連接closeSocket() {console.log("開始嘗試關閉連接");this.uniSocketTask.close();},// 開啟錄音startRecord() {const recordOption = {sampleRate: 16000,format: "mp3",};const recordManager = uni.getRecorderManager();recordManager.onStart(() => {console.log("開始錄音");this.show = true;});recordManager.onStop((res) => {console.log("錄音停止,文件路徑為:", res.tempFilePath);this.sendMessage(this.getInitialFrame());this.pathToBase64(res.tempFilePath).then(base64 => {let buff = base64.split(",")[1];const arrayBuffer = uni.base64ToArrayBuffer(buff);const audioString = this.toString(arrayBuffer);console.log("文件讀取成功", audioString.length);let offset = 0;while (offset < audioString.length) {const subString = audioString.substring(offset, offset + 1280);offset += 1280;const isEnd = offset >= audioString.length;let params = {data: {status: isEnd ? 2 : 1,format: "audio/L16;rate=16000",encoding: "lame",audio: btoa(subString)}};this.sendMessage(params);}}).catch(error => {console.error(error);});});recordManager.onError((err) => {console.log("錄音出現錯誤", err);});recordManager.start(recordOption);},// 關閉錄音stopMedia() {const recordManager = uni.getRecorderManager();recordManager.stop();this.show = false;},// 工具方法toString(buffer) {var binary = '';var bytes = new Uint8Array(buffer);var len = bytes.byteLength;for (var i = 0; i < len; i++) {binary += String.fromCharCode(bytes[i]);}return binary;},// 錄音文件路徑轉base64pathToBase64(path) {return new Promise((resolve, reject) => {if (typeof plus === 'object') {plus.io.resolveLocalFileSystemURL(path, function(entry) {entry.file(function(file) {var fileReader = new plus.io.FileReader();fileReader.onload = function(evt) {resolve(evt.target.result);};fileReader.onerror = function(error) {reject(error);};fileReader.readAsDataURL(file);}, function(error) {reject(error);});}, function(error) {reject(error);});return;}reject(new Error('not support'));});},// 訊飛回復字段拼接renderResult(jsonData) {if (jsonData.data && jsonData.data.result) {let data = jsonData.data.result;let str = "";let ws = data.ws;for (let i = 0; i < ws.length; i++) {str = str + ws[i].cw[0].w;}if (data.pgs) {if (data.pgs === "apd") {this.resultText = this.resultTextTemp;}this.resultTextTemp = this.resultText + str;} else {this.resultText = this.resultText + str;}this.renderText = this.resultTextTemp || this.resultText || "";}console.log("渲染后的數據為", this.renderText);}}
}
</script><style scoped>
.asr {display: flex;justify-content: center;padding: 20rpx;
}.btn {width: 200rpx;height: 200rpx;
}.iating {position: fixed;top: 50%;left: 50%;transform: translate(-50%, -50%);display: flex;flex-direction: column;align-items: center;background-color: rgba(0, 0, 0, 0.7);padding: 30rpx;border-radius: 20rpx;z-index: 999;
}</style>    

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/80007.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/80007.shtml
英文地址,請注明出處:http://en.pswp.cn/web/80007.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

【golang】DNS 資源記錄(RR)接口

Go 中 miekg/dns 包對 DNS 資源記錄&#xff08;RR&#xff09;接口 的定義&#xff1a; type RR interface {Header() *RR_HeaderString() stringcopy() RRlen(off int, compression map[string]struct{}) intpack(...)unpack(...)parse(...)isDuplicate(r2 RR) bool }這個接…

16.2 VDMA視頻轉發實驗之模擬源

文章目錄 1 實驗任務2 系統框圖3 硬件設計3.1 IP核配置3.2 注意事項3.3 自定義IP核源碼 4 軟件設計4.1 注意事項4.2 工程源碼4.2.1 main.c文件 1 實驗任務 基于14.1&#xff0c;相較于16.1&#xff0c;使用自定義IP核vid_gen_motion替換Xilinx TPG IP核。 2 系統框圖 基于14…

深度學習之用CelebA_Spoof數據集搭建一個活體檢測-訓練好的模型用MNN來推理

一、模型轉換準備 首先確保已完成PyTorch到ONNX的轉換&#xff1a;深度學習之用CelebA_Spoof數據集搭建活體檢測系統&#xff1a;模型驗證與測試。這里有將PyTorch到ONNX格式的模型轉換。 二、ONNX轉MNN 使用MNN轉換工具進行格式轉換&#xff1a;具體的編譯過程可以參考MNN的…

JVM學習專題(一)類加載器與雙親委派

目錄 1、JVM加載運行全過程梳理 2、JVM Hotspot底層 3、war包、jar包如何加載 4、類加載器 我們來查看一下getLauncher&#xff1a; 1.我們先查看getExtClassLoader() 2、再來看看getAppClassLoader(extcl) 5、雙親委派機制 1.職責明確&#xff0c;路徑隔離?&#xff…

部署安裝gitlab-ce-17.9.7-ce.0.el8.x86_64.rpm

目錄 ?編輯 實驗環境 所需軟件 實驗開始 安裝部署gitlab171.配置清華源倉庫&#xff08;版本高的系統無需做&#xff09;vim /etc/yum.repos.d/gitlab-ce.repo 2.提前下載包dnf localinstall gitlab-ce-17.9.7-ce.0.el8.x86_64.rpm --rocklinux 3.修改配…

使用LoRA微調Qwen2.5-VL-7B-Instruct完成電氣主接線圖識別

使用LoRA微調Qwen2.5-VL-7B-Instruct完成電氣主接線圖識別 動機 任務適配需求 Qwen2.5-VL在視覺理解方面表現優異&#xff0c;但電氣主接線圖識別需要特定領域的結構化輸出能力&#xff08;如設備參數提取、拓撲關系解析&#xff09;。微調可增強模型對專業符號&#xff08;如…

系統集成項目管理工程師學習筆記

第九章 項目管理概論 1、項目基本要素 項目基礎 項目是為創造獨特的產品、服務或成果而進行的臨時性工作。 項目具有臨時性、獨特性、漸進明細的特點。項目的“臨時性”是指項目只有明確的起點和終點。“臨時性”并一定意味著項目的持續時間短。 項目可宣告結束的情況&…

Secs/Gem第七講(基于secs4net項目的ChatGpt介紹)

好的&#xff0c;那我們現在進入&#xff1a; 第七講&#xff1a;掉電重連后&#xff0c;為什么設備不再上報事件&#xff1f;——持久化與自動恢復的系統設計 關鍵詞&#xff1a;掉電恢復、狀態重建、初始化流程、SecsMessage 緩存機制、自動重連、事件再注冊 本講目標 你將理…

室內定位:熱門研究方向與未解難題深度解析

I. 引言:對普適性室內定位的持續探索 A. 室內定位在現代應用中的重要性 室內定位系統(IPS)正迅速成為眾多應用領域的基石技術,其重要性源于現代社會人們約70%至90%的時間在室內度過的事實 1。這些應用橫跨多個行業,包括應急響應 1、智能建筑與智慧城市 6、醫療健康(如病…

Android學習總結之Glide自定義三級緩存(實戰篇)

一、為什么需要三級緩存 內存緩存&#xff08;Memory Cache&#xff09; 內存緩存旨在快速顯示剛瀏覽過的圖片&#xff0c;例如在滑動列表時來回切換的圖片。在 Glide 中&#xff0c;內存緩存使用 LruCache 算法&#xff08;最近最少使用&#xff09;&#xff0c;能自動清理長…

Linux的文件查找與壓縮

查找文件 find命令 # 命令&#xff1a;find 路徑范圍 選項1 選項1的值 \[選項2 選項2 的值…]# 作用&#xff1a;用于查找文檔&#xff08;其選項有55 個之多&#xff09;# 選項&#xff1a;# -name&#xff1a;按照文檔名稱進行搜索&#xff08;支持模糊搜索&#xff0c;\* &…

python處理異常,JSON

異常處理 #異常處理 # 在連接MySQL數據庫的過程中&#xff0c;如果不能有效地處理異常&#xff0c;則異常信息過于復雜&#xff0c;對用戶不友好&#xff0c;暴露過多的敏感信息 # 所以&#xff0c;在真實的生產環境中&#xff0c; 程序必須有效地處理和控制異常&#xff0c;按…

線程的兩種實現方式

線程的兩種實現方式——內核支持線程&#xff08;kernal Supported Thread, KST&#xff09;&#xff0c; 用戶級線程&#xff08;User Level Thread, ULT&#xff09; 1. 內核支持線程 顧名思義&#xff0c;內核支持線程即為在內核支持下的那些線程&#xff0c;它們的創建&am…

vue3基礎學習(上) [簡單標簽] (vscode)

目錄 1. Vue簡介 2. 創建Vue應用 2.1 下載JS文件 2.2 引用JS文件 2.3 調用Vue方法?編輯 2.4 運行一下試試: 2.5 代碼如下 3.模塊化開發模式 3.1 Live Server插件 3.2 運行 4. 常用的標簽 4.1 reactive 4.1.1 運行結果 4.1.2 代碼: 4.2 ref 4.2.1 運行結果 4.2.2…

自定義分區器-基礎

什么是分區 在 Spark 里&#xff0c;彈性分布式數據集&#xff08;RDD&#xff09;是核心的數據抽象&#xff0c;它是不可變的、可分區的、里面的元素并行計算的集合。 在 Spark 中&#xff0c;分區是指將數據集按照一定的規則劃分成多個較小的子集&#xff0c;每個子集可以獨立…

深入解析HTTP協議演進:從1.0到3.0的全面對比

HTTP協議作為互聯網的基礎協議&#xff0c;經歷了多個版本的迭代演進。本文將詳細解析HTTP 1.0、HTTP 1.1、HTTP/2和HTTP/3的核心特性與區別&#xff0c;幫助開發者深入理解網絡協議的發展脈絡。 一、HTTP 1.0&#xff1a;互聯網的奠基者 核心特點&#xff1a; 短連接模式&am…

基于windows環境Oracle主備切換之后OGG同步進程恢復

基于windows環境Oracle主備切換之后OGG同步進程恢復 場景&#xff1a;db1是主庫&#xff0c;db2是備庫&#xff0c;ogg從db2備庫抽取數據同步到目標數據庫 db1 - db2(ADG) – ogg – targetdb 場景&#xff1a;db2是主庫&#xff0c;db1是備庫&#xff0c;ogg從db1備庫抽取數…

微服務,服務粒度多少合適

項目服務化好處 復用性&#xff0c;消除代碼拷貝專注性&#xff0c;防止復雜性擴散解耦合&#xff0c;消除公共庫耦合高質量&#xff0c;SQL穩定性有保障易擴展&#xff0c;消除數據庫解耦合高效率&#xff0c;調用方研發效率提升 微服務拆分實現策略 統一服務層一個子業務一…

【工奧閥門科技有限公司】簽約智橙PLM

近日&#xff0c;工奧閥門科技有限公司正式簽約了智橙泵閥行業版PLM。 忠于質量&#xff0c;臻于服務&#xff0c;精于研發 工奧閥門科技有限公司&#xff08;以下簡稱工奧閥門&#xff09;坐落于浙江永嘉&#xff0c;是一家集設計、開發、生產、銷售、安裝、服務為一體的閥門…

2025-5-15Vue3快速上手

1、setup和選項式API之間的關系 (1)vue2中的data,methods可以與vue3的setup共存 &#xff08;2&#xff09;vue2中的data可以用this讀取setup中的數據&#xff0c;但是反過來不行&#xff0c;因為setup中的this是undefined &#xff08;3&#xff09;不建議vue2和vue3的語法混用…