uniapp調(diào)用百度語音實(shí)現(xiàn)錄音轉(zhuǎn)文字功能
經(jīng)歷三天時(shí)間各種遇到困難 之后終于實(shí)現(xiàn)了這個(gè)功能,參照網(wǎng)上了許多文章 才找到一個(gè)能正常實(shí)現(xiàn)的方法,網(wǎng)上能找到的例子都不起作用,相信很多人困惑在這,為了避免別人出現(xiàn)這種情況,我分享我的代碼,絕對可用,包括 uniapp前端使用了recorderManager和java端調(diào)用百度語音轉(zhuǎn)文字,我相信很多人都很需要我寫的東西,我只試驗(yàn)了安卓手機(jī),html5 + 里面
plus.speech這個(gè)方式就不要用了,不好用,調(diào)用百度的語音識別時(shí)在百度的管理控制臺會看到dev_id這個(gè)參數(shù)沒傳的錯(cuò)誤也沒找到添加這個(gè)參數(shù)的地方,所以在hbuildx里面當(dāng)前項(xiàng)目的app模塊配置這個(gè)地方不需要選
1.非常重要的一個(gè)步驟 manifest.json里面添加android.permission.RECORD_AUDIO這個(gè)權(quán)限,無論是想真機(jī)調(diào)試,由其是使用了自定義基座一定要在線打個(gè)包,讓基座包含這個(gè)權(quán)限然后在手機(jī)系統(tǒng) 里面應(yīng)用管理當(dāng)前這個(gè)app的權(quán)限管理里面必須要看到有錄音權(quán)限這一項(xiàng)
2.為了能夠在使用recorderManager在進(jìn)入要使用錄音功能的頁面會詢問是否允許錄音這樣的權(quán)限,必須要使用recorderManager之前要調(diào)用一次硬件權(quán)限申請。這個(gè)在插件市場里面有一個(gè)https://ext.dcloud.net.cn/plugin?id=594 這個(gè)地址 App權(quán)限判斷和提示這樣的js,用于判斷或申請某個(gè)硬件權(quán)限使用的是native.js的功能。這個(gè)插件引入項(xiàng)目之后會在當(dāng)前項(xiàng)目目錄的js_sdk這樣一個(gè)文件夾。在里面會出現(xiàn)wa-permission文件 夾下面會有一個(gè)permission.js,
3.相關(guān)代碼
uniapp端代碼?
<view class="popup-content" > <view>{{msg}}</view> <view>你在說{{voicetext}}</view> <button class="uni-btn" type="warn" @touchstart="startvoice" @touchend="endvoice">按說語話松開停止</button> <button class="uni-btn" type="warn" @tap="playvoice" >播放錄音</button> </view> <script> import permision from "@/js_sdk/wa-permission/permission.js" const recorderManager = uni.getRecorderManager(); const innerAudioContext = uni.createInnerAudioContext(); export default { data() { return { voicetext:"", msg:"", voicepath:"" } }, onLoad() { this.initaudio() }, methods: { async initaudio(){ //注意此處必須為 await 因?yàn)闀|發(fā)異步事件,手機(jī)上會彈出權(quán)限申請對話框處理完才能走下一步錄音 let recordauth = await permision.requestAndroidPermission("android.permission.RECORD_AUDIO") console.log("判斷有沒有錄音權(quán)限>>>>>>"+recordauth) if(recordauth==1){ recorderManager.onStart((res)=>{ console.log("開始 錄音>>>>>>>>>...") }); recorderManager.onStop((res)=>{ console.log("recorderstop....res.tempFilePath>>>"+res.tempFilePath) this.voicepath = res.tempFilePath this.uploadvoicefile() // 使用uni.uploadFile上傳到服務(wù)器上,此時(shí)是mp3格式 }); recorderManager.onError( (res)=> { console.log('onError'+JSON.stringify(res)); }); } }, //initaudio 方法結(jié)束 startvoice(){ console.log("開始錄音") recorderManager.start({ format:"mp3", sampleRate: 16000 // 必須設(shè)置是后臺設(shè)置的參數(shù),不然百度語音識別不了 }); }, endvoice(){ console.log("結(jié)束錄音") //注意為了避免說話時(shí)間太短導(dǎo)致這個(gè)api出現(xiàn)bug要加一些延時(shí) setTimeout(()=>{ recorderManager.stop() },1000) }, playvoice(){ console.log("點(diǎn)擊playvoice") if (this.voicepath) { console.log("播放聲音") innerAudioContext.src = this.voicepath; innerAudioContext.play(); } }, uploadvoicefile(){ // this.msg = "調(diào)用java端服務(wù)文件路徑"+this.voicepath uni.uploadFile({ url: 'http://ip:端口/uploadFile(java端接收文件接口名)', filePath: this.voicepath,//錄音結(jié)束后返回的臨時(shí)路徑, name: 'file', formData: { dev_id:1537 //中文帶標(biāo)點(diǎn) }, success: (uploadFileRes) => { let word = uploadFileRes.data console.log("上傳音頻成功"+word); }, fail: (res) => { console.log("上傳音頻失敗"+JSON.stringify(res)); } }); } } } </script> ``` //注意uploadFile 的url屬性 這個(gè)地方ip不能是localhost或127,如果自已電腦啟動java服務(wù)必須 是本機(jī)的真實(shí)ip如192.xxx這種,或者域名什么的,并且java端接口一定要支持跨域,很多人卡到這個(gè)ip上,我也是網(wǎng)上很難找到解決問題的貼子 注意filePath這個(gè)路徑就是recorderManager的onStop事件就得到的_doc這種開頭的路徑,不需要加什么file:不是像網(wǎng)上某些人說的加這種東西
Java端
pom里面需要引用兩個(gè)包??
<dependency> <groupId>com.baidu.aip</groupId> <artifactId>java-sdk</artifactId> <version>4.16.3</version> </dependency> <dependency> <groupId>com.googlecode.soundlibs</groupId> <artifactId>mp3spi</artifactId> <version>1.9.5.4</version> </dependency> ``` import com.baidu.aip.speech.AipSpeech; import javazoom.spi.mpeg.sampled.file.MpegAudioFileReader; import org.apache.commons.io.IOUtils; import org.json.JSONArray; import org.json.JSONObject; import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; import javax.sound.sampled.AudioFormat; import javax.sound.sampled.AudioInputStream; import javax.sound.sampled.AudioSystem; import java.io.IOException; import java.io.InputStream; import java.util.HashMap; @RestController @CrossOrigin(origins = "*") public class BaiduSpeech { //設(shè)置APPID/AK/SK public static final String APP_ID = ""; //去百度語音服務(wù)申請 public static final String API_KEY = "";//去百度語音服務(wù)申請 public static final String SECRET_KEY = "";//去百度語音服務(wù)申請 @RequestMapping(value = "/uploadFile") public String uploadFile( @RequestParam("dev_id") int dev_id, @RequestParam("file") MultipartFile file) throws Exception { byte[] pcmbytedata = mp3Convert2pcm(file.getInputStream()); HashMap<String,Object> options = new HashMap<String,Object>(); options.put("dev_pid",dev_id);// JSONObject jsonfrombaidu = basicBydata(pcmbytedata,"pcm",options); JSONArray jsonArray = jsonfrombaidu.getJSONArray("result"); String result = jsonArray.getString(0); System.out.println(result); //解析完的結(jié)果 return result; } // 獲取AipSpeech對象,建議單例使用 public static AipSpeech getClient() { AipSpeech client = new AipSpeech(APP_ID, API_KEY, SECRET_KEY); // 可選:設(shè)置網(wǎng)絡(luò)連接參數(shù) client.setConnectionTimeoutInMillis(2000); client.setSocketTimeoutInMillis(60000); return client; } // 語音識別(來自文件) public static JSONObject basicBydata(byte[] voicedata, String fileType,HashMap<String,Object> options) { AipSpeech client = getClient(); return client.asr(voicedata, fileType, 16000, options); } /** * MP3轉(zhuǎn)換PCM * @param inputStream MP3輸入流 * @throws Exception */ public static byte[] mp3Convert2pcm(InputStream inputStream) throws Exception { //轉(zhuǎn)換PCM audioInputStream 數(shù)據(jù) AudioInputStream audioInputStream = getPcmAudioInputStream(inputStream); byte[] pcmBytes = IOUtils.toByteArray(audioInputStream); return pcmBytes; } /** * 獲取PCM AudioInputStream 數(shù)據(jù) * @param inputStream MP3輸入流 * @return AudioInputStream PCM輸入流 */ private static AudioInputStream getPcmAudioInputStream(InputStream inputStream) { AudioInputStream audioInputStream = null; AudioFormat targetFormat = null; try { AudioInputStream in = null; MpegAudioFileReader mp = new MpegAudioFileReader(); in = mp.getAudioInputStream(inputStream); AudioFormat baseFormat = in.getFormat(); targetFormat = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED, baseFormat.getSampleRate(), 16, baseFormat.getChannels(), baseFormat.getChannels() * 2, baseFormat.getSampleRate(), false); audioInputStream = AudioSystem.getAudioInputStream(targetFormat, in); } catch (Exception e) { e.printStackTrace(); } return audioInputStream; } } ```
到此這篇關(guān)于uniapp調(diào)用百度語音實(shí)現(xiàn)錄音轉(zhuǎn)文字功能的文章就介紹到這了,更多相關(guān)uniapp錄音轉(zhuǎn)文字內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
各瀏覽器對link標(biāo)簽onload/onreadystatechange事件支持的差異分析
各瀏覽器對link標(biāo)簽onload/onreadystatechange事件支持的差異分析,需要的朋友可以參考下。2011-04-04完美實(shí)現(xiàn)js選項(xiàng)卡切換效果(一)
這篇文章主要為大家詳細(xì)介紹如何完美實(shí)現(xiàn)js選項(xiàng)卡切換效果,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-03-03js實(shí)現(xiàn)瀏覽器窗口大小被改變時(shí)觸發(fā)事件的方法
這篇文章主要介紹了js實(shí)現(xiàn)瀏覽器窗口大小被改變時(shí)觸發(fā)事件的方法,實(shí)例分析了window.onresize方法的使用技巧,需要的朋友可以參考下2015-02-02利用JavaScript實(shí)現(xiàn)拖拽改變元素大小
本文主要介紹了JavaScript實(shí)現(xiàn)拖拽改變元素大小的原理及具體實(shí)例分析,具有很好的參考價(jià)值,需要的朋友一起來看下吧2016-12-12js 右鍵菜單,支持不同對象不同菜單(兼容IE、Firefox)
版本雖然很老也不符合標(biāo)準(zhǔn)了,不過代碼是值得參考的,需要右鍵菜單的朋友可以參考下。2010-01-01javascript實(shí)現(xiàn)框架高度隨內(nèi)容改變的方法
這篇文章主要介紹了javascript實(shí)現(xiàn)框架高度隨內(nèi)容改變的方法,實(shí)例分析了通過父頁面及內(nèi)容改變框架高度兩種實(shí)現(xiàn)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-07-07