1. 程式人生 > >總結一篇熱乎的【科大訊飛】SDK整合 常見問題!

總結一篇熱乎的【科大訊飛】SDK整合 常見問題!

總結一篇熱乎的【科大訊飛】SDK整合 常見問題! 【離線喚醒】+【離線命令詞 近日,業務需要增加語音輔助功能到APP 上,於是就找到了2家比較好一點的SDK 【科大訊飛】和【百度語音】! 先說說各自的優缺點吧!各位新入手的小白能稍微從我這裡得到一點資訊!第一點最最重要的是錢!【科大訊飛】要錢,價格不是個人所能承擔的!【百度語音】免費!免費!(個別功能)下面來看圖把!


OK!大家可以自由選擇平臺SDK!
首先要說的!百度的API 文件特別相信,所有常量引數以及Demo  錯誤碼 都特別好找!
http://ai.baidu.com/docs#/ASR-Android-SDK/top
,全部都在這個【離線上語音識別】,官方的Demo 也是下載後就能 在 Android studio 上執行!基礎檔案也只有WakeUp.bin ;baidu_speech_grammar.bsg ;和bdasr_V3_20171108_9800a2a.jar 包!不做過多贅述! 科大訊飛使用中容易忽視的幾個坑!! 因為博主只是用到了【離線喚醒】+【離線命令詞】2個功能!所以其他的不再本文中出現解釋!另外訊飛官方Demo 根本就跑不起來,自己整理了一套【絕對的完整】,有需要的郵件
[email protected]
【準備】 匯入jar包 Msc.jar ,Sunflower.jar其實沒有多大作用!可不用! 【離線喚醒】
這個也沒太大問題,主要問題有2處! 1.設定喚醒資源路徑(在科大控制檯後臺設定喚醒詞)
	private String getResource() {
		final String resPath = ResourceUtil.generateResourcePath(WakeDemo.this, RESOURCE_TYPE.assets, "iflytek/5a950c38.jet");
		return resPath;
	}

2.設定喚醒模式
 // 設定持續進行喚醒(一般不要設定持續喚醒,配合UI 喚醒一次 停止一次)
            mIvw.setParameter(SpeechConstant.KEEP_ALIVE, "0");

// 持續喚醒模式
            mIvw.setParameter(SpeechConstant.KEEP_ALIVE, "1");
另外這裡還有三個引數需要注意下,就是語音識別超時識別
        // 設定語音前端點:靜音超時時間,即使用者多長時間不說話則當做超時處理
        mAsr.setParameter(SpeechConstant.VAD_BOS,  "4000");
        // 設定語音後端點:後端點靜音檢測時間,即使用者停止說話多長時間內即認為不再輸入, 自動停止錄音
        mAsr.setParameter(SpeechConstant.VAD_EOS,  "2000");
所謂的前端點 :通俗的意思就是從你開始啟動監聽器開始,如果4000未有語音錄入 就暫停識別/結束識別 所謂的後端點:意思就是你說完了命令詞或者一段話,系統監聽等待2000後 再無錄入,就表示識別結束。

3.啟動喚醒 沒多大問題,在WakeuperListener 的onResult 回撥資訊就行了!
我步建議設定持續喚醒,官方Demo 寫的就是持續喚醒,但是它是一個功能一個功能使用的!如果一旦搭配使用就會出現問題,後面講解!

【離線命令詞】
1.要增添資源包【common.jet】,【command_cn.bnf】------這是我的中文離線包 ;【command_en.bnf】----英文離線包! 2.初始化配置
  /**
     * <P>初始化配置</P>
     */
    private void initConfig() {
        if (mAsr == null) {
            mAsr = SpeechRecognizer.createRecognizer(activity, mInitListener);
            mLocalGrammar_CN = FucUtil.readFile(activity, "iflytek/command_cn.bnf", "utf-8");
            mLocalGrammar_EN = FucUtil.readFile(activity, "iflytek/command_en.bnf", "utf-8");
        }
}

3. 載入本地資源
    /**
     * <P>初始化本地識別物件</P>
     * <P>構建語法</P>
     */
    public void initLocalAsrEvent() {
        // 初始化識別物件
        //全部載入是防止在已經開啟實施控制頁面的時候切換語言情況
        mAsr.setParameter(SpeechConstant.PARAMS, null);
        // 設定文字編碼格式
        mAsr.setParameter(SpeechConstant.TEXT_ENCODING, "utf-8");
        // 設定引擎型別
        mAsr.setParameter(SpeechConstant.ENGINE_TYPE, SpeechConstant.TYPE_LOCAL);
        // 設定引擎模式
        mAsr.setParameter(SpeechConstant.ENGINE_MODE, SpeechConstant.MODE_MSC);
        // 設定語法構建路徑  【重點!<1>】
        mAsr.setParameter(ResourceUtil.GRM_BUILD_PATH, grmPath);
//        // 設定資源路徑   【重點!<2>】
        mAsr.setParameter(ResourceUtil.ASR_RES_PATH, getResourcePath());
        // 設定返回結果格式  【重點!<3>】可以設定 json 和 xml 2種
        mAsr.setParameter(SpeechConstant.RESULT_TYPE, "json");

        mAsr.buildGrammar(GRAMMAR_TYPE_BNF, mLocalGrammar_CN, grammarListener);
    }

4. 重點! 重點!【回撥 】我就是在這裡栽了下!
   /**
     * <P>構建語法監聽器</P>
     * <P>獲取雲端識別使用的語法id</P>
     * <P>這個回撥很重要!需要準確的獲取到 grammarId </P>
     * <P>    mAsr.setParameter(SpeechConstant.LOCAL_GRAMMAR, KEY_GRAMMAR_BNF_ID);  </P>
     */
    private String KEY_GRAMMAR_BNF_ID;//反饋的 編譯ID
  
    private GrammarListener grammarListener = new GrammarListener() {

        @Override
        public void onBuildFinish(String grammarId, SpeechError speechError) {
            if (speechError == null) {
              if (mEngineType.equals(SpeechConstant.TYPE_LOCAL)) {
                    if (!TextUtils.isEmpty(grammarId)) {
                        KEY_GRAMMAR_BNF_ID = grammarId;
                        BBLog.LogI("AsrHelper——initCloudAsrEvent", "語法構建成功:" + KEY_GRAMMAR_BNF_ID);
                    }
                }
            } else {
                BBLog.LogI("AsrHelper——語法構建失敗,錯誤碼:", speechError.getErrorCode() + "");
            }
        }
    };

就如我的註釋一樣,這個KEY_GRAMMAR_BNF_ID  很重要,是在下一步開始識別的時候使用的!之前的都是   配置 +構建語法!
5.開始識別(也就是開始錄音) 這裡會出現2個問題! 問題一: 配置都沒問題,許可權也沒問題,但是開始錄音就報錯!可能是“APP 正在錄音,APP暫時無法錄音”,也可能是 “20006”,問題就出現喚醒。當你使用完喚醒後就開始識別,就會導致此類問題!

  如果你喚醒模式設定的是持續喚醒,就需要在喚醒成功後,自己手動stopAwake(); 如果設定的不是持續喚醒,就沒有這個問題了,是喚醒錄音影響了離線詞識別!
問題二: 一直提示23002,無線的引數值!其實一開始一直不懂,這是啥!你想,我特麼都構建成功了,這是啥!百度語音就沒有這一步蛋疼的操作!需要將反饋的KEY_GRAMMAR_BNF_ID  再次載入使用!通過Demo 我們還是可以看出,在開啟監聽之前,還要判斷下是否構建成功,並在設定一次引數!
  /**
     * 引數設定
     *
     * @return
     */
    public boolean setParam() {
        // 清空引數
        mAsr.setParameter(SpeechConstant.PARAMS, null);
        // 設定識別引擎
        mAsr.setParameter(SpeechConstant.ENGINE_TYPE, SpeechConstant.TYPE_LOCAL);

        if (TextUtils.isEmpty(KEY_GRAMMAR_BNF_ID)) {
            return false;
        }
        // 設定本地識別資源            !!!這裡很重要!是我們重要資源配置之一                
        mAsr.setParameter(ResourceUtil.ASR_RES_PATH, getResourcePath());
        // 設定語法構建路徑
        mAsr.setParameter(ResourceUtil.GRM_BUILD_PATH, grmPath);
        // 設定返回結果格式
        mAsr.setParameter(SpeechConstant.RESULT_TYPE, "json");
        // 設定本地識別使用語法id(反饋 !grammar drone;)----這裡就是我說的 KEY_GRAMMAR_BNF_ID
        mAsr.setParameter(SpeechConstant.LOCAL_GRAMMAR, KEY_GRAMMAR_BNF_ID);
        // 設定識別的門限值
        mAsr.setParameter(SpeechConstant.MIXED_THRESHOLD, "30");

//      設定音訊儲存路徑,儲存音訊格式支援pcm、wav,設定路徑為sd卡請注意WRITE_EXTERNAL_STORAGE許可權
//      注:AUDIO_FORMAT引數語記需要更新版本才能生效
        mAsr.setParameter(SpeechConstant.AUDIO_FORMAT, "wav");
        mAsr.setParameter(SpeechConstant.ASR_AUDIO_PATH, wav_path);
        return true;
    }

如上,第一個關鍵就是設定本地資源
 /**
     * <P>獲取訊飛重要資源(必不可少)</P>
     * <P>使用下載組合包之後 資原始檔中的  common.jet</P>
     *
     * @return
     */
    private String getResourcePath() {
        //識別通用資源
        StringBuffer tempBuffer = new StringBuffer();
        tempBuffer.append(ResourceUtil.generateResourcePath(activity, ResourceUtil.RESOURCE_TYPE.assets, "iflytek/asr/common.jet"));
        return tempBuffer.toString();
    }

第二個:就是路徑,ResourceUtil.GRM_BUILD_PATH   就是語法構建成功後 在本地生成的路徑,這個要放在自己APP 路徑下就行,同樣的 SpeechConstant.ASR_AUDIO_PATH 也是一樣,是錄音 音訊路徑
第三個:就是上文提到的回撥到的!KEY_GRAMMAR_BNF_ID 值!其實我也也可以手動去 填寫了, 不需要回調!在你的  command_cn.bnf  中,第二行 其實就是你自己定義的 key

最後:
mAsr.startListening(mRecognizerListener);

一定要加入錄音許可權!!!!!! ok,我太渣了,在這幾個問題上沒注意,栽了下又下!
另外附上我在論壇上找的易錯碼!
https://shimo.im/sheet/w3yUy39uNKs0J7DT


錯誤碼:意義:產生原因及解決辦法

20004:無有效的結果:一般轉寫產生,在沒有說話的時候就停止識別監聽,會產生這個錯誤;

20005:無匹配的結果:使用命令詞識別或者語法檔案識別出現,檢視所說的話是否在語法檔案或者命令詞識別中,若不在其中會有這個錯誤碼;

20006:錄音失敗:該問題經常出現,主要是因為麥克風不能使用,解決辦法:1、重啟手機,2、檢視是否使用的虛擬機器,建議真機除錯,虛擬機器很多時候不能識別到麥克風裝置,3、檢視工程是否添加了錄音許可權,4、檢視是否有其他程序正在佔用麥克風;5.喚醒監聽佔用!

20017:被異常打斷:在使用麥克風錄音的過程中,有其他程序搶佔麥克風資源,導致錄音中斷(經常在迴圈識別的時候產生,請在一次錄音會話結束之後再開始下一次會話,一般是在onEnd裡面呼叫下一次識別);

21001:沒有安裝語音元件:請檢查是否安裝了訊飛語音+;

21002:引擎不支援:您所呼叫的功能,這個版本的語音+是否支援,部分功能只在內測版本的語音+中提供,內測結束之後才會正式上線;

21003:初始化失敗:這個錯誤經常出現,主要是在呼叫過程中剛開始初始化就開始設定引數、開始識別或開始合成,解決辦法:初始化是相對非同步進行的,初始化的時候在InitListener裡面的onInit()回撥初始化成功之後在開始設定引數、呼叫合成、呼叫識別;