最近爲小程序增長語音識別轉文字的功能,坑路不斷,特此記錄。html
開發者工具上的錄音文件與移動端格式不一樣,暫時只可在工具上進行播放調試,沒法直接播放或者在客戶端上播放java
debug的時候發現,工具上錄音的路徑是http://tmp/xxx.mp3
,客戶端上錄音是wxfile://xxx.mp3
。 忽悠呢,不是格式不一樣,是映射路徑不一樣。
其實作個兼容也不難,每次提示一行文字,很醜。git
每種採樣率有對應的編碼碼率範圍有效值,設置不合法的採樣率或編碼碼率會致使錄音失敗。詳細看這個
https://developers.weixin.qq.com/miniprogram/dev/api/media/recorder/RecorderManager.start.htmlgithub
一開始沒有留意,致使錄音不成功。
試過幾回後,採用這樣的配置,感受錄音識別率和體積之間比較好平衡:json
1 |
sampleRate: 16000, //採樣率 |
單通道基本是必選的。由於asr只支持單通道。frameSize也是能夠的,可是要考慮截斷對識別的影響。暫時沒有用上。小程序
由於可能誤按,因而對小於500ms的錄音直接忽略。
另外,鬆開錄音按鍵後,再延遲一點時間才真正stop錄音。api
微信錄音文件支持mp3和aac。這2種格式文件都比較小,aac文件體積更小。這對上傳來講是件好事情,速度更快。
可是對語音識別轉文字就不友好了。由於百度、阿里雲ASR、訊飛的語音轉文字接口都不支持aac和mp3,一般要求是pcm或者wav格式。
若是微信錄音能提供wav格式,那麼就不用服務器作格式轉換了,可是wav格式體積是mp三、aac的5到10倍,至少短時間是沒戲了,這也是不少人吐槽的地方。數組
能夠用java第三方庫轉換,也能夠用Process調用ffmpeg轉換。要注意的是,根據識別API的要求來作轉換。好比阿里雲asr的要求是:緩存
支持音頻編碼格式:pcm(無壓縮的pcm文件或wav文件)、opus,16bit採樣位數的單聲道(mono);
支持音頻採樣率:8000Hz、16000Hz;服務器
轉換音視頻,習慣用ffmpeg。安裝完ffmpeg以後,用java新建進程調用。
1 |
Process = new ProcessBuilder("ffmpeg -i in.mp3 out.wav").start(); |
一直提示CreateProcess error
。 後來看文檔才發現,要以數組的形式傳入參數。
1 |
Process = new ProcessBuilder("ffmpeg", "-y", "-i", "in.mp3", "out.wav").start(); |
這樣就啓動成功了。
關於java啓動進程,不是本文重點,之後再寫篇文章總結。
這個問題困擾了一天時間,回想起來真是吐血。
問題表現是微信錄製的語音不少都識別不了。
最初是直接把錄音mp3文件轉換爲pcm文件,本地能播放,可是用阿里雲asr sdk卻識別不了。 一開始覺得是文件編碼問題。特地查了asr支持的文件格式,用ffprobe檢查,potplayer看屬性,都沒有看出問題。
甚至把啓動ffmpeg進程轉換也改了,用了java的庫去作,仍是不行。
後來爲了方便測試問題,用asr的restful接口測試錄音文件,都能識別! 彷佛是sdk的問題。因而打開官方文檔例子對比。發現用的是sdk 2.x,老鐵啊你複製粘貼過來的代碼居然少了!欲哭無淚。
1 |
// TODO 重要提示:這裏是用讀取本地文件的形式模擬實時獲取語音流併發送的,由於read很快,因此這裏須要sleep |
也少了對sampleRate的設置。
由於用的是免費版asr,沒有給福報廠充值,所以token一天失效,致使聯調的時候忽然報錯。
最後實在受不了,寫了個定時任務每小時更新token。
這,就是beggar VIP😎
封裝了一個接口parseResponse,統一解析查詢結果(文本、語音)。發現奇怪的問題:
只能console.log()
打印出來對比
第一行是wx.request()
發起文本查詢。
第二行是wx.uploadFile()
上傳語音文件後直接語音轉文字,而且查詢。
wx.request
返回值是json對象。wx.uploadFile
返回值是「字符串」!wx.uploadFile
返回值是「字符串」!wx.uploadFile
返回值是「字符串」!
重要的事情要說3遍。儘管Content-Type: "application/json; charset=utf8"
,可是微信根本不作轉換!很是坑爹!
解決:對wx.uploadFile
返回值進行JSON.parse(res.data)
,獲得json對象。
由於正式小程序項目帳號一直拖着沒有申請,因此這段時間用的是我我的的appid和secret進行開發。
等正式帳號準備好了,更新了小程序項目的appid,而且發出內部體驗包。
此時已經深夜1點半,頭腦有點發懵。只更新了小程序appid,居然忘了更新服務器的appid和secret。。。
因而乎反覆報錯登陸失敗。
過了一會才反映過來,更新服務器的appi的secret,可是仍是用戶。纔想起忘了還有storage緩存沒有清除😂,裏面放着自定義的session。這下真機體驗沒問題了。
可是微信開發者工具又是登陸失敗。反覆摸索後發現:更換小程序appid後,清除全部數據,關閉開發者工具,從新打開,這就正常了。應該是微信開發者工具的bug。
結論:深夜不宜加班寫bug😭。
https://ycwu314.github.io/p/miniapp-speech-to-text-experience/