HTML用javascrip在瀏覽器上實現語音輸入和語義理解功能(speex壓縮)

基於javascript用olamisdk實現web端語音識別語義理解(speex壓縮)

轉載請註明原文地址:傳送javascript

olami 開放平臺 sdk 除了支持語音識別功能外,更強大的在於支持語義理解功能,在 Android 平臺和 iOS 平臺都有示例 demo 供你們下載。html

語音在線聽書demo:傳送java

語音記帳demo:傳送jquery

在 web 端,基於 JavaScript 用 olami 開放平臺 sdk 也能夠實現語音識別語義理解。本文就實現了這樣一個小程序,web 客戶端本地用麥克風錄音,錄音的數據用 speex 壓縮,而後跨域向服務器發送請求,返回識別的語音和語義字符串並顯示。android

先上圖:git

以下圖剛載入的時候,未錄音前界面github

圖片描述

點擊開始錄音button後web

圖片描述

一句話說完自動檢測尾音結束標誌而後壓縮上傳給服務器進行識別chrome

圖片描述

將從服務器獲取的識別結果顯示到界面上json

圖片描述

本例中說的語音是:「我要聽三國演義這本書」,用的是 android 平臺聽書 app 創建的語法。
返回的json字串以下:

{
    「data」: {
        「asr」: {
            「result」: 「我要聽三國演義這本書」,
            「speech_status」: 0,
            「final」: true,
            「status」: 0
        },
        「nli」: [
            {
                「desc_obj」: {
                    「result」: 「正在努力搜索中,請稍等」,
                    「status」: 0
                },
                「semantic」: [
                    {
                        「app」: 「musiccontrol」,
                        「input」: 「我要聽三國演義這本書」,
                        「slots」: [
                            {
                                「name」: 「songname」,
                                「value」: 「三國演義」
                            }
                        ],
                        「modifier」: [
                            「play」
                        ],
                        「customer」: 「58df512384ae11f0bb7b487e」
                    }
                ],
                「type」: 「musiccontrol」
            }
        ]
    },
    「status」: 「ok」
}

經過解析這段 json,能夠獲得 app 類型,songname (用於查詢書名),modifier 是 play 表示行爲是播放。

這段 json 的語法固然是用戶自定義的,得到了 json 字串就能夠解析獲得程序須要的字段用於對應的操做,從而實現了語義理解功能。olami 開放平臺語法編寫介紹

下面來看看實現的 code,用 eclipse 創建 J2EE 工程 WebVoiceRecognize

初次搭建能夠參考以下網站: 傳送

下面是創建的工程目錄結構,發佈後,網頁打開運行在chrome或者QQ瀏覽器都可。

圖片描述

下面講述下 voiceRecognize.html 這個文件,其餘都是 min.js,只需知道如何調用就能夠了。

<!DOCTYPE HTML>
<html>
    <head>
    <meta charset="utf-8">
    <title>voice recognize test</title> 
    <script type="text/javascript" src="jquery-1.10.1.min.js"></script>
    <script type="text/javascript" src="jQuery.md5.js"></script> 
    <script src="speex.min.js"></script>  
    <script src="pcmdata.min.js"></script>      
    </head> 

    <body onload= "load()">
        <fieldset style="width:50%;margin:10px auto">
        <p align="center" >點擊開始button錄音,點擊中止button中止錄音並進行識別</p>
        <p align="center">
        <input type="button" id="recordbutton" value="開始錄音" onclick="StartRecording()"/>
        <input type="button" id="speexEncodebutton" value="中止錄音" onclick="speexEncode()"/>
      </p>
      <p id ="result" style="margin-bottom:100px;margin-top:50px">result:</p>
      </p>
      <script src="recorder.min.js"></script>   
      <script src="uploaddata.min.js"></script> 
      <script>


        window.AudioContext = window.AudioContext || window.webkitAudioContext;

        var audioContext = new AudioContext();
        var audioInput = null,
            realAudioInput = null,
            inputPoint = null,
            audioRecorder = null;
        var rafID = null;
        var analyserContext = null;
        var recIndex = 0;

        var recording = false;
        var bRecorded = false;

        function load(){
            initAudio();//初始化recorder
            setAuthorization("http://cn.olami.ai/cloudservice/api","51a4bb56ba954655a4fc834bfdc46af1","asr","68bff251789b426896e70e888f919a6d","nli");
            setCallBackFromServerResult(getResultFromServer);
        }

        function initAudio() {
                if (!navigator.getUserMedia)
                    navigator.getUserMedia = navigator.webkitGetUserMedia || navigator.mozGetUserMedia;
                if (!navigator.cancelAnimationFrame)
                    navigator.cancelAnimationFrame = navigator.webkitCancelAnimationFrame || navigator.mozCancelAnimationFrame;
                if (!navigator.requestAnimationFrame)
                    navigator.requestAnimationFrame = navigator.webkitRequestAnimationFrame || navigator.mozRequestAnimationFrame;

            navigator.getUserMedia({audio:true}, gotStream, function(e) {
                    alert('Error getting audio');
                    console.log(e);
                });
        }

        function gotStream(stream) {
            inputPoint = audioContext.createGain();

            // Create an AudioNode from the stream.
            realAudioInput = audioContext.createMediaStreamSource(stream);
            audioInput = realAudioInput;
            audioInput.connect(inputPoint);
            audioRecorder = new Recorder( inputPoint );
        }

        function StartRecording()
        {
            // start recording
            if (audioRecorder == null)
            {
               initAudio(); 
               alert("need initialize media");  
            }        
            audioRecorder.clear();
            audioRecorder.record();  
            recording = true;  
            bRecorded = false;
            ToggleLabels(); 
            RegisterCallBackToRecorder();           
        }

        function StopRecording()
        {
            audioRecorder.stop();
            audioRecorder.getBuffers( gotBuffers );     
        }

        function RegisterCallBackToRecorder()
        {//檢測語音結束後回調
            audioRecorder.setCallBack(speexEncode);
        }

        function ToggleLabels()
        {
            if(recording)
            {
                document .getElementById("recordbutton").value = "錄音中ֹ";    
                document .getElementById("speexEncodebutton").value = "中止錄音";       
                var btn = document .getElementById("recordbutton").value;   

            }else{
                document .getElementById("speexEncodebutton").value = "識別中";    
                document .getElementById("recordbutton").value = "中止錄音ֹ";                               
            }   

        }

        window.record = function(e)
        {
            if(!recording)
            {
                StartRecording();
                recording = true;
                bRecorded = false;
            }
            else
            {
                StopRecording();
                recording = false;
                bRecorded = true;
            }

            ToggleLabels();
        };

      window.speexEncode =  function()
      {
            exportSpeex();      
      };


     function exportSpeex()
     {
        recording = false;
        bRecorded = true;
        ToggleLabels();
        audioRecorder.stop();               
        audioRecorder.exportPCM(uploadSpeexData);
     }           

     function getResultFromServer()
     {
         document .getElementById('result').innerText = JSON.stringify(result);
         document .getElementById("speexEncodebutton").value = "中止錄音";  
         document .getElementById("recordbutton").value = "開始錄音ֹ"
     }
      </script>
    </body> 

</html>

瀏覽器載入的時候,先調用load()進行初始化

function load(){
setAuthorization(
                "http://cn.olami.ai/cloudservice/api",//serverurl
                "51a4bb56ba954655a4fc834bfdc46af1", //appkey             
                "asr",//api類型
                "68bff251789b426896e70e888f919a6d",//appSecret
                "nli");//seq
setCallBackFromServerResult(getResultFromServer);
}

initAudio()中初始化了recorder用於獲取麥克風資源作錄音使用。

setAuthorization函數,參數分別是

url :服務器地址
appkey:開放平臺註冊應用後得到的appkey
api:api類型選asr爲語音
appSecret:開放平臺註冊應用後得到的appSecret
nli:爲seq表示包含語音語義返回,爲stt表示只有語音返回

setCallBackFromServerResult(getResultFromServer) 註冊錄音介紹而且識別出結果後的回調,在回調函數中能夠把結果輸出到界面上。

當點擊開始錄音 button 後,調用

function StartRecording()
{
      // start recording
      if (audioRecorder == null)
      {
         initAudio();   
         alert("need initialize media");    
      }        
      audioRecorder.clear();
      audioRecorder.record();  
      recording = true;  
      bRecorded = false;
      ToggleLabels(); 
      RegisterCallBackToRecorder(); //註冊recoder回調        
}

當在錄音的js代碼中,會自動檢測尾音結束,而後回調註冊的函數speexEncode (),點擊中止錄音button同樣調用這個函數

window.speexEncode =  function()
 {
    exportSpeex();      
 };


  function exportSpeex()
{
    recording = false;
    bRecorded = true;
    ToggleLabels();//更新界面的button狀態
    audioRecorder.stop();               
    audioRecorder.exportPCM(uploadSpeexData);
}

audioRecorder.exportPCM(uploadSpeexData) 實現了將錄好的 16Kpcm 語音壓縮成 speex 格式並上傳到服務器,從服務器取得結果後調用註冊的

setCallBackFromServerResult(getResultFromServer)函數,而後再函數 getResultFromServer 中進行結果的輸出顯示。

代碼下載地址:

https://github.com/ls0609/Web...

相關網站連接:

olami開放平臺語法官方介紹:https://cn.olami.ai/wiki/?mp=...
olami開放平臺語法編寫簡介:http://blog.csdn.net/ls0609/a...

相關文章
相關標籤/搜索