总结一篇热乎的【科大讯飞】SDK集成 常见问题!

版权声明:本博客为博主原创,欢迎大佬批评指点! https://blog.csdn.net/qq_31332467/article/details/79409258
总结一篇热乎的【科大讯飞】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()回调初始化成功之后在开始设置参数、调用合成、调用识别;

猜你喜欢

转载自blog.csdn.net/qq_31332467/article/details/79409258