您的位置:首頁>正文

基於騰訊雲智慧語音的即時語音辨識微信小程式的開發

更多騰訊海量技術文章, 請關注雲加社區:https://cloud.tencent.com/developer

作者:Jason

微信小程式的基礎庫升級到了 1.6.0 之後, 提供了許多新的 API, 其中新增了錄音管理的 API, 不同於以前只有wx.startRecord和wx.stopRecord兩個簡單的錄音功能, 新的wx.getRecorderManager介面提供了包括擴展時長、取樣速率、錄音通道、碼率、格式等在內的許多配置項。 基於此, 我們能更加輕鬆的控制錄音, 新提供的onFrameRecorded的事件, 甚至可以實現流式語音辨識。

本文就介紹一下使用 Wafer Node.js SDK 提供的騰訊雲智慧語音辨識介面來實現錄音轉文字的功能。 請您先從 Github 下載語音辨識 Demo, 本文會根據 Demo 來介紹 SDK 中語音辨識介面的使用。

使用語音辨識需要開通騰訊雲智慧語音。

打開server/config.js, 添加上qcloudAppId, qcloudSecretId, qcloudSecretKey三個配置項, 並在代碼目錄中打開 CMD, 運行如下代碼:

cd server && npm i

安裝完成依賴, 選擇小程式開發者工具右上角的【騰訊雲】按鈕, 點擊【上傳測試環境】上傳代碼到測試環境中, 一鍵部署程式。 你也可以自行部署代碼, 部署過程同《自行部署 Node.js Demo》, 這裡不再介紹。

最終實現的效果如下:

具體是如何實現的呢?接下來我們來分析一下 Demo 裡的有關代碼。

首先查閱 SDK API 文檔可知, SDK 提供的語音辨識介面是分片識別介面, 原理是將語音檔切分成一個個分片, 將每個分片以buffer格式傳入介面, 最後一個分片調用介面時需要將isEnd參數置為true, 最後會返回完整的識別結果, 以此來流式識別語音。

由於智慧語音辨識只支援以下幾種編碼格式的音訊檔:

pcm

adpcm

feature

speex

amr

silk

wav

所以小程式端通過recorderManager獲取到的錄音檔需要提前轉換為這幾種格式中的一種, 然後才能識別。 Demo 裡選擇了將mp3格式轉換為wav格式檔的形式。

Demo 中採用了ffmpeg對語音檔進行轉碼, 使用ffmpeg的前提是需要在環境中安裝ffmpeg, 然後在 Node.js 中使用fluent-ffmpeg調用ffmpeg實現轉碼。

注意:ffmpeg
並沒有默認預裝在開發環境和生產環境中, 如果您需要使用語音辨識的轉碼功能, 可以提交工單, 我們會為您配置好環境。

打開 Demo 中的server/controllers/recognize.js檔, 首先調用了multiparty從請求體中讀取出上傳上來的音訊資料, 接著對語音的類型進行一些判斷。

...const { files } = await resolveUploadFileFromRequest(ctx.req);...if (!resultType || !['audio/mpeg', 'audio/mp3'].includes(resultType.mime)) {throw new Error('上傳的檔案格式不是 mp3')}...

第 46 行開始對音訊檔進行處理, 首先先生成了voiceId, voiceId告訴了語音辨識介面每個語音分片屬於哪個語音, 每個語音的voiceId應當是唯一的。

接著調用了convertMp3ToWav函數對語音進行轉換, convertMp3ToWav 函數的實現如下:

/*** mp3 轉 wav* @param {string} srcPath 原始檔案地址* @param {string} newPath 新文件地址*/function convertMp3ToWav (srcPath, newPath) {return new Promise((resolve, reject) => {ffmpeg(srcPath).format('wav').on('error', reject).on('end', function () {resolve(newPath)}).save(newPath)})}

由於每次識別的檔大小最好不要超過 10K byte, 所以需要對音訊檔進行切片, 原理就是將音訊檔讀取為 buffer, 然後按每 9K byte 大小切片識別。

// 將文件讀取為 Bufferconst voiceBuffer = fs.readFileSync(newVoicePath);const taskList = [];let leftBufferSize = 0;let idx = 0;// 按 9K 大小切分分片並識別while (leftBufferSize < voiceBuffer.length) {const newBufferSize = leftBufferSize + 9 * 1024;// 切分分片const chunk = voiceBuffer.slice(leftBufferSize,newBufferSize > voiceBuffer.length ? voiceBuffer.length : newBufferSize )// 提交每個切片去識別,
並將任務推入任務列表taskList.push(voice.recognize(chunk,newBufferSize > voiceBuffer.length,voiceId,idx ));leftBufferSize = newBufferSize;idx++;}

以上就是語音辨識 Demo 代碼的分析, 您可以直接運行 Demo, 在手機端真機調試體驗。

注意:開發者工具的錄音介面返回的資料不是 MP3 格式, 與真機行為不完全相同, 所以錄音相關的測試請直接使用真機調試。

同類文章
Next Article
喜欢就按个赞吧!!!
点击关闭提示