Android集成訊飛語音、百度語音、阿里語音識別

1、引言

demo下載地址:https://fir.im/jy28
demo源碼查看:https://github.com/wapchief/android-CollectionDemo
效果圖:android

選這幾個平臺的主要也是從多方面考慮。
大概從這幾個git

  • 識別精準度
  • 免費限制
  • 穩定程度
  • 包體積
  • 拓展性

目前只有百度的語音服務支持長語音(60秒以上),和離線語音識別。
固然語音的庫(.so)文件也是最大的。足足10多M。github

2、申請應用

在集成以前,須要去相應的平臺去申請應用。
拿到key等密鑰。目前這幾個平臺都在測試免費層限制中。json

百度是徹底免費,訊飛有免費層日調用次數限制。網絡

3、集成

首先去各大平臺下載對於的語音文件庫
通常都包含.so和libs兩部分。這兩部分都須要加入到項目中。架構

不過這裏只須要注意一點是,每一個平臺的文檔不同,有些是使用libs集成第三方庫,有些是使用jnilibs加載。app

若是都按照第三方文檔來集成,一定會出錯。
這裏統一使用jniLibs來集成(只適用於AndroidStudio)。若是是eclipse,則須要使用libs集成eclipse

若是在集成中遇到了問題,能夠參考我之前寫過的解決方案
Android關於libs,jniLibs庫的基本使用說明及衝突解決ide

一、(必須)將下載後的全部so庫文件(以.so結尾的文件)拷貝至項目下/app/src/main目錄,若是沒有則建立一個,裏面的名字是固定的,注意不能修改,必須按照這樣的架構目錄集成。測試

二、(必須)將jar文件拷貝到libs目錄中

 

image.png

 

而後將jar添加到項目。
可使用右鍵對應的jar包,add-libs手動添加

三、(必須)在AndroidManifest.xml添加權限

以訊飛的權限文檔說明爲例

<!--鏈接網絡權限,用於執行雲端語音能力 -->
<uses-permission android:name="android.permission.INTERNET"/>
<!--獲取手機錄音機使用權限,聽寫、識別、語義理解須要用到此權限 -->
<uses-permission android:name="android.permission.RECORD_AUDIO"/>
<!--讀取網絡信息狀態 -->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<!--獲取當前wifi狀態 -->
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<!--容許程序改變網絡鏈接狀態 -->
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"/>
<!--讀取手機信息權限 -->
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
<!--讀取聯繫人權限,上傳聯繫人須要用到此權限 -->
<uses-permission android:name="android.permission.READ_CONTACTS"/>
<!--外存儲寫權限,構建語法須要用到此權限 -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<!--外存儲讀權限,構建語法須要用到此權限 -->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<!--配置權限,用來記錄應用配置信息 -->
<uses-permission android:name="android.permission.WRITE_SETTINGS"/>
<!--手機定位信息,用來爲語義等功能提供定位,提供更精準的服務-->
<!--定位信息是敏感信息,可經過Setting.setLocationEnable(false)關閉定位請求 -->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<!--如需使用人臉識別,還要添加:攝相頭權限,拍照須要用到 -->
<uses-permission android:name="android.permission.CAMERA" />

若是SDK版本在6.0以上須要在項目中手動獲取錄音權限

/*動態權限申請*/
    private void initPermission() {
        String permission[] = {Manifest.permission.RECORD_AUDIO,
                Manifest.permission.ACCESS_NETWORK_STATE,
                Manifest.permission.INTERNET,
                Manifest.permission.WRITE_EXTERNAL_STORAGE};
        ArrayList<String> applyList = new ArrayList<>();

        for (String per : permission) {
            if (PackageManager.PERMISSION_GRANTED != ContextCompat.checkSelfPermission(this, per)) {
                applyList.add(per);
            }
        }

        String tmpList[] = new String[applyList.size()];
        if (!applyList.isEmpty()) {
            ActivityCompat.requestPermissions(this, applyList.toArray(tmpList), 123);
        }
    }

4、初始化服務

各個平臺的初始化方法都不同。
但大多數都是在本身項目的Application中初始化。

//初始化訊飛語音
        SpeechUtility.createUtility(mContext, SpeechConstant.APPID +"=59daecea," + SpeechConstant.FORCE_LOGIN +"=true");
        //訊飛調試日誌開啓
        Setting.setShowLog(true);
        //初始化阿里語音
        NlsClient.openLog(true);
        NlsClient.configure(mContext);

有些是在AndroidManifest.xml中初始化

<!--******************************百度語音**********************************-->
        <meta-data android:name="com.baidu.speech.APP_ID"
            android:value="8172882" />
        <meta-data
            android:name="com.baidu.speech.API_KEY"
            android:value="R3crsZhvpqQSrLGUvG7kuG0pCnpTbXvb" />
        <meta-data
            android:name="com.baidu.speech.SECRET_KEY"
            android:value="6MafqZkSLoNYUML1YduHPDYBg1kkPLHj" />

        <service android:name="com.baidu.speech.VoiceRecognitionService" android:exported="false"/>

5、開啓識別服務

以訊飛爲例:
在開始識別前須要初始化識別對象,

SpeechRecognizer  recognizer = SpeechRecognizer.createRecognizer(this, null);

而後配置聽寫參數

/**
     * 參數設置
     */
    public void setParam() {
        //2.設置聽寫參數,詳見《科大訊飛MSC API手冊(Android)》SpeechConstant類
        recognizer.setParameter(SpeechConstant.DOMAIN, "iat");
        recognizer.setParameter(SpeechConstant.LANGUAGE, "zh_cn");
        recognizer.setParameter(SpeechConstant.ACCENT, "mandarin ");
        //設置音頻保存路徑
        recognizer.setParameter(SpeechConstant.AUDIO_FORMAT, "wav");
        recognizer.setParameter(SpeechConstant.ASR_AUDIO_PATH, Environment.getExternalStorageDirectory() + "/msc/iat.wav");

    }

開始識別的開始和終止,及識別過程的內容回調

//開啓
    private void startXF() {
        setParam();
        recognizer.startListening(recognizerListener);
    }

    //中止
    private void stopXF() {

        recognizer.stopListening();
    }


    /*監聽*/
    private RecognizerListener recognizerListener = new RecognizerListener() {
        @Override
        public void onVolumeChanged(int i, byte[] bytes) {
            //音量變化
        }

        @Override
        public void onBeginOfSpeech() {
            //開始說話
            Log.e(TAG, "XF開始說話");
        }

        @Override
        public void onEndOfSpeech() {
            //結束說話
            Log.e(TAG, "XF結束說話");

        }

        @Override
        public void onResult(RecognizerResult recognizerResult, boolean b) {
            //返回結果須要判斷null
            text = JsonParser.parseIatResult(recognizerResult.getResultString());
            Log.e(TAG, "XFResult:" + text + "\n" + recognizerResult.getResultString());
            mVoiceTv.setText(recognizerResult.getResultString());
            printResult(recognizerResult);
        }

        @Override
        public void onError(SpeechError speechError) {
            //錯誤回調
            Log.e(TAG, "XFError:" + speechError.toString());

        }

        @Override
        public void onEvent(int i, int i1, int i2, Bundle bundle) {
            //事件拓展
        }
    };

解析語音識別的結果。

//儲存聽寫結果
    private HashMap<String, String> mIatResults = new LinkedHashMap<String, String>();

 /*解析器*/
    private void printResult(RecognizerResult results) {
        String text = JsonParser.parseIatResult(results.getResultString());

        String sn = null;
        // 讀取json結果中的sn字段
        try {
            JSONObject resultJson = new JSONObject(results.getResultString());
            sn = resultJson.optString("sn");
        } catch (JSONException e) {
            e.printStackTrace();
        }

        mIatResults.put(sn, text);

        StringBuffer resultBuffer = new StringBuffer();
        for (String key : mIatResults.keySet()) {
            resultBuffer.append(mIatResults.get(key));
        }

        mVoiceEt.setText("訊飛識別結果:" + resultBuffer.toString());
        mVoiceEt.setSelection(mVoiceEt.length());
//        mVoiceTv.setText(resultBuffer.toString());
    }

6、異常及其餘

SecurityException異常:
若是是在6.0以上版本的sdk可能會出現該問題,主要是臨時權限調用,好比調用系統的錄音文件播放,或者調用系統的圖庫。
能夠參考調用圖庫的解決方案,原理同樣
Android版本相機適配問題集合(不斷整理更新中)

demo下載地址:
https://fir.im/jy28
demo源碼:
https://github.com/wapchief/android-CollectionDemo

做者:八怪不姓醜 連接:https://www.jianshu.com/p/950d73234991 來源:簡書 簡書著做權歸做者全部,任何形式的轉載都請聯繫做者得到受權並註明出處。

相關文章
相關標籤/搜索