小程序實現語音識別到底要填多少坑?

前不久寫了個工具型微信小程序(Find周邊),裏面用到了語音識別技術。現將實現細節整理以下:php

接口預覽html

經過閱讀了解科大訊飛接口文檔小程序接口開發文檔以及對後端ThinkPhp框架的學習,我整理了以下開發步驟:java

  • 註冊科大訊飛帳號(國人的驕傲,全球領先的語音識別技術)
  • 進入AIUI開放平臺在應用管理建立應用並記錄APPID和ApiKey
  • 進入應用配置,配置符合本身的情景模式、識別方式和技能
  • 進行小程序開發錄製須要識別的音頻(下有詳述)
  • 後端轉碼錄製的音頻(科大訊飛支持pcm、wav),提交給識別接口(下有詳述)
  • 小程序接到識別結果進行接下來業務

音頻錄製接口node

  • wx.startRecord()和wx.stopRecord()

wx.startRecord()和wx.stopRecord()接口也能夠知足需求,但從1.6.0 版本開始再也不被微信團隊維護。建議使用能力更強的 wx.getRecorderManager 接口。該接口獲取到的音頻格式爲silk。
silk是webm格式經過base64編碼後的結果,咱們解碼後須要將webm轉換成pcm、wavpython

  • wx.getRecorderManager()

相對wx.startRecord()接口,該接口提供的能力更爲強大(詳情),能夠暫停錄音也能夠繼續錄音,根據本身需求設置編碼碼率,錄音通道數,採樣率。最讓人開心的是能夠指定音頻格式,有效值 aac/mp3。很差的是wx.getRecorderManager()在1.6.0纔開始被支持。固然若是你要兼容低端微信用戶須要使用wx.startRecord()作兼容處理。linux

  • 事件監聽細節
// wxjs:

const recorderManager = wx.getRecorderManager()
recorderManager.onStart(() => {
    //開始錄製的回調方法
})
//錄音中止函數
recorderManager.onStop((res) => {
  const { tempFilePath } = res;
  //上傳錄製的音頻
  wx.uploadFile({
    url: app.d.hostUrl + '/Api/Index/wxupload', //僅爲示例,非真實的接口地址
    filePath: tempFilePath,
    name: 'viceo',
    success: function (res) {
        console.log(res);
    }
  })
})

Page({
    //按下按鈕--錄音
  startHandel: function () {
    console.log("開始")
    recorderManager.start({
      duration: 10000
    })
  },
  //鬆開按鈕
  endHandle: function () {
    console.log("結束")
    //觸發錄音中止
    recorderManager.stop()
  }
})

//wxml:
<view bindtouchstart='startHandel' bindtouchend='endHandle' class="tapview">
    <text>{{text}}</text>
</view>
複製代碼

音頻轉換web

我這邊後端使用php的開源框架thinkphp,固然node、java、python等後端語言均可以,你根據本身的喜愛和能力來。想作好音頻轉碼咱們就要藉助音視頻轉碼工具ffmpeg、avconv,它們都依賴於gcc。安裝過程你們能夠自行百度,或者關注我後面的文章。thinkphp

<?php
namespace Api\Controller;
use Think\Controller;
class IndexController extends Controller {
	
    //音頻上傳編解碼
    public function wxupload(){
        $upload_res=$_FILES['viceo'];
        $tempfile = file_get_contents($upload_res['tmp_name']);
        $wavname = substr($upload_res['name'],0,strripos($upload_res['name'],".")).".wav";
        $arr = explode(",", $tempfile);
        $path = 'Aduio/'.$upload_res['name'];
        
        if ($arr && !empty(strstr($tempfile,'base64'))){
            //微信模擬器錄製的音頻文件能夠直接存儲返回
        	file_put_contents($path, base64_decode($arr[1]));
        	$data['path'] = $path;
        	apiResponse("success","轉碼成功!",$data);
        }else{
            //手機錄音文件
            $path = 'Aduio/'.$upload_res['name'];
            $newpath = 'Aduio/'.$wavname;
        	file_put_contents($path, $tempfile);
            chmod($path, 0777);
            $exec1 = "avconv -i /home/wwwroot/mapxcx.kanziqiang.top/$path -vn -f wav /home/wwwroot/mapxcx.kanziqiang.top/$newpath";
            exec($exec1,$info,$status);
            chmod($newpath, 0777);
	        if ( !empty($tempfile) && $status == 0 ) {
	        	$data['path'] = $newpath;
	        	apiResponse("success","轉碼成功!",$data);
	        }
        }
        apiResponse("error","發生未知錯誤!");
    }
    //json數據返回方法封裝
    function apiResponse($flag = 'error', $message = '',$data = array()){
        $result = array('flag'=>$flag,'message'=>$message,'data'=>$data);
        print json_encode($result);exit;
    }
}

複製代碼

調用識別接口json

當咱們把文件準備好以後,接下來咱們就能夠將base64編碼以後的音頻文件經過api接口請求傳輸過去。期間咱們要注意嚴格按照文檔中所說的規範傳輸,不然將形成不可知的結果。小程序

<?php
namespace Api\Controller;
use Think\Controller;
class IndexController extends Controller {
	public function _initialize(){
	}
	//封裝數據請求方法
	public function httpsRequest($url,$data = null,$xparam){
        $curl = curl_init();
        curl_setopt($curl, CURLOPT_URL, $url);
        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
        curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE);
        curl_setopt($curl, CURLOPT_HEADER, 0);
        $Appid = "";//開放平臺的appid
        $Appkey = "";//開放平臺的Appkey
        $curtime = time();
        $CheckSum = md5($Appkey.$curtime.$xparam.$data);
        $headers = array(
        	'X-Appid:'.$Appid,
        	'X-CurTime:'.$curtime,
        	'X-CheckSum:'.$CheckSum,
        	'X-Param:'.$xparam,
        	'Content-Type:'.'application/x-www-form-urlencoded; charset=utf-8'
        	);
        curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
        if (!empty($data)){
            curl_setopt($curl, CURLOPT_POST, 1);
            curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
        }
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
        $output = curl_exec($curl);
        curl_close($curl);
        return $output;
    }
    //請求接口數據處理
    public function getVoice($path){
        $d = base64_encode($path);
        $url = "https://api.xfyun.cn/v1/aiui/v1/voice_semantic";
        $xparam = base64_encode( json_encode(array('scene' => 'main','userid'=>'user_0001',"auf"=>"16k","aue"=>"raw","spx_fsize"=>"60" )));
    	$data = "data=".$d;
    	$res = $this->httpsRequest($url,$data,$xparam);
    	if(!empty($res) && $res['code'] == 00000){
    	    apiResponse("success","識別成功!",$res);
    	}else{
    	    apiResponse("error","識別失敗!");
    	}
    }
    //數據返回封裝
    function apiResponse($flag = 'error', $message = '',$data = array()){
        $result = array('flag'=>$flag,'message'=>$message,'data'=>$data);
        print json_encode($result);exit;
    }
}
複製代碼

到這裏基本就完成了。以上代碼是通過整理以後的,並不必定可以知足各位的實際開發需求。若是發現不當之處歡迎微信交流(xiaoqiang0672)。

想看實際案例的能夠微信掃碼

小程序碼

關於gcc安裝
關於FFmpeg安裝
關於ffmpeg/avconv安裝
相關文章
相關標籤/搜索