【Android】灵云在线语音识别使用说明

来源:互联网 发布:香水时代淘宝店真假 编辑:程序博客网 时间:2024/04/29 03:22

注册

使用灵云的语音识别功能需要先在官网上进行注册应用。官网地址

注册比较简单,就不做过多介绍了,注册完应用以后,在后台创建自己的应用,创建完应用以后需要给应用开通对应的语音能力。
这里写图片描述

capKey说明:

  • asr.cloud.freetalk 云端自由说识别功能
  • asr.cloud.dialog 云端自由说+语义理解功能
  • asr.cloud.grammar 云端语法识别功能
  • asr.local.grammar.v4 本地的语法识别功能

使用asr.cloud.dialog功能时,需要勾选对应的领域,以下示例按照百科领域进行测试。
这里写图片描述

集成

下载灵云的Android版本语音识别功能,下载地址

源码

Github

灵云在线语音识别功能

需要加入的so和jar包有:

  • libhci_curl.so
  • libhci_sys.so
  • libhci_sys_jni.so
  • libhci_asr.so
  • libhci_asr_jni.so
  • libhci_asr_cloud_recog.so
  • libspeex.so
  • libstlport_shared.so
  • hcicloud-5.0.jar
  • hcicloud_recorder-5.0.jar

需要使用的权限

<uses-permission android:name="android.permission.INTERNET" /><uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /><uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /><uses-permission android:name="android.permission.RECORD_AUDIO" /><uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" /><uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/><uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>

加载配置类

package com.miao.test.util;/** * 灵云配置信息 * Created by 10048 on 2016/12/3. */public class ConfigUtil {    /**     * 灵云APP_KEY     */    public static final String APP_KEY = "c85d54f1";    /**     * 开发者密钥     */    public static final String DEVELOPER_KEY = "712ddd892cf9163e6383aa169e0454e3";    /**     * 灵云云服务的接口地址     */    public static final String CLOUD_URL = "test.api.hcicloud.com:8888";    /**     * 需要运行的灵云能力     */    // 云端自由说    public static final String CAP_KEY_ASR_CLOUD_FREETALK = "asr.cloud.freetalk";    // 云端语音识别+语义    public static final String CAP_KEY_ASR_CLOUD_DIALOG = "asr.cloud.dialog";    // 离线命令词    public static final String CAP_KEY_ASR_LOCAL_GRAMMAR = "asr.local.grammar.v4";    // 在线命令词    public static final String CAP_KEY_ASR_CLOUD_GRAMMAR = "asr.cloud.grammar";}

封装灵云系统的初始化功能

package com.example.sinovoice.util;import android.content.Context;import android.os.Environment;import android.util.Log;import com.sinovoice.hcicloudsdk.api.HciCloudSys;import com.sinovoice.hcicloudsdk.common.AuthExpireTime;import com.sinovoice.hcicloudsdk.common.HciErrorCode;import com.sinovoice.hcicloudsdk.common.InitParam;import java.io.File;import java.text.SimpleDateFormat;import java.util.Date;import java.util.Locale;/** * Created by miaochangchun on 2016/11/28. */public class HciCloudSysHelper {    private static final String TAG = HciCloudSysHelper.class.getSimpleName();    private static HciCloudSysHelper mHciCloudSysHelper = null;    private HciCloudSysHelper(){    }    public static HciCloudSysHelper getInstance() {        if (mHciCloudSysHelper == null) {            return  new HciCloudSysHelper();        }        return  mHciCloudSysHelper;    }    /**     * 初始化函数     * @param context     * @return     */    public int init(Context context){        //配置串参数        String strConfig = getInitParam(context);        int errCode = HciCloudSys.hciInit(strConfig, context);        if (errCode != HciErrorCode.HCI_ERR_NONE){            Log.e(TAG, "hciInit Failed and return errcode = " + errCode);            return errCode;        }        errCode = checkAuthAndUpdateAuth();        if (errCode != HciErrorCode.HCI_ERR_NONE) {            Log.e(TAG, "checkAuthAndUpdateAuth Failed and return errcode = " + errCode);            return errCode;        }        return HciErrorCode.HCI_ERR_NONE;    }    /**     * 获取授权     * @return     */    private int checkAuthAndUpdateAuth() {        // 获取系统授权到期时间        AuthExpireTime objExpireTime = new AuthExpireTime();        int initResult = HciCloudSys.hciGetAuthExpireTime(objExpireTime);        if (initResult == HciErrorCode.HCI_ERR_NONE) {            // 显示授权日期,如用户不需要关注该值,此处代码可忽略            Date date = new Date(objExpireTime.getExpireTime() * 1000);            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd", Locale.CHINA);            Log.i(TAG, "expire time: " + sdf.format(date));            if (objExpireTime.getExpireTime() * 1000 > System.currentTimeMillis()) {                // 已经成功获取了授权,并且距离授权到期有充足的时间(>7天)                Log.i(TAG, "checkAuth success");                return initResult;            }        }        // 获取过期时间失败或者已经过期        initResult = HciCloudSys.hciCheckAuth();        if (initResult == HciErrorCode.HCI_ERR_NONE) {            Log.i(TAG, "checkAuth success");            return initResult;        } else {            Log.e(TAG, "checkAuth failed: " + initResult);            return initResult;        }    }    /**     * 获取配置传参数     * @param context     * @return     */    private String getInitParam(Context context) {        InitParam initParam = new InitParam();        //灵云云服务的接口地址,此项必填        initParam.addParam(InitParam.AuthParam.PARAM_KEY_APP_KEY, ConfigUtil.APP_KEY);        //灵云云服务的接口地址,此项必填        initParam.addParam(InitParam.AuthParam.PARAM_KEY_DEVELOPER_KEY, ConfigUtil.DEVELOPER_KEY);        //灵云云服务的接口地址,此项必填        initParam.addParam(InitParam.AuthParam.PARAM_KEY_CLOUD_URL, ConfigUtil.CLOUD_URL);        String authPath = context.getFilesDir().getAbsolutePath();        //授权文件所在路径,此项必填        initParam.addParam(InitParam.AuthParam.PARAM_KEY_AUTH_PATH, authPath);        //日志数目,默认保留多少个日志文件,超过则覆盖最旧的日志        initParam.addParam(InitParam.LogParam.PARAM_KEY_LOG_FILE_COUNT, "5");        String logPath = Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator                + "sinovoice" + File.separator                + context.getPackageName() + File.separator                + "log" + File.separator;        File file = new File(logPath);        if (!file.exists()) {            file.mkdirs();        }        //日志的路径,可选,如果不传或者为空则不生成日志        initParam.addParam(InitParam.LogParam.PARAM_KEY_LOG_FILE_PATH, logPath);        Log.d(TAG, "logPath = " + logPath);        //日志大小,默认一个日志文件写多大,单位为K        initParam.addParam(InitParam.LogParam.PARAM_KEY_LOG_FILE_SIZE, "1024");        //日志等级,0=无,1=错误,2=警告,3=信息,4=细节,5=调试,SDK将输出小于等于logLevel的日志信息        initParam.addParam(InitParam.LogParam.PARAM_KEY_LOG_LEVEL, "5");        return initParam.getStringConfig();    }    /**     * 反初始化     * @return     */    public int release(){        return HciCloudSys.hciRelease();    }}

封装灵云语音识别功能

package com.miao.test.util;import android.content.Context;import android.os.Bundle;import android.os.Handler;import android.os.Message;import com.sinovoice.hcicloudsdk.android.asr.recorder.ASRRecorder;import com.sinovoice.hcicloudsdk.common.asr.AsrConfig;import com.sinovoice.hcicloudsdk.common.asr.AsrInitParam;import com.sinovoice.hcicloudsdk.common.asr.AsrRecogResult;import com.sinovoice.hcicloudsdk.recorder.ASRRecorderListener;import com.sinovoice.hcicloudsdk.recorder.RecorderEvent;/** * Created by miaochangchun on 2016/11/28. */public class HciCloudAsrHelper {    private static final String TAG = HciCloudAsrHelper.class.getSimpleName();    public static final int RECORDER_STATE = 3;    public static final int RECORDER_ERROR = 2;    public static final int RECORDER_RESULT = 1;    private static HciCloudAsrHelper mHciCloudAsrHelper = null;    private ASRRecorder mASRRecorder;    private Handler myHander;//    private String voicePath;   //音频文件保存路径//    public void setVoicePath(String voicePath) {//        this.voicePath = voicePath;//    }//    public String getVoicePath() {//        return voicePath;//    }    private HciCloudAsrHelper() {    }    public static HciCloudAsrHelper getInstance() {        if (mHciCloudAsrHelper == null) {            return new HciCloudAsrHelper();        }        return mHciCloudAsrHelper;    }    public Handler getMyHander() {        return myHander;    }    public void setMyHander(Handler myHander) {        this.myHander = myHander;    }    /**     * 录音机初始化     *     * @param context     上下文     * @param initCapkeys 初始化录音机时设置的capkey,可以设置为多个。     * @return true录音机初始化成功,false录音机初始化失敗     */    public boolean initAsrRecorder(Context context, String initCapkeys) {        mASRRecorder = new ASRRecorder();        String strConfig = getAsrInitParam(context, initCapkeys);        // 语法相关的配置,若使用自由说能力可以不必配置该项//        String grammarData = "";//        String grammarConfigString = "capkey=" + initCapkeys + ",isFile=no,grammarType=jsgf";        mASRRecorder.init(strConfig, "", "", new ASRRecorderCallback());        if (mASRRecorder.getRecorderState() == ASRRecorder.RECORDER_STATE_IDLE) {            return true;        } else {            return false;        }    }    /**     * 获取初始化时的参数配置     *     * @param context     上下文     * @param initCapkeys 需要初始化的capkey,可以设置为多个     * @return     */    private String getAsrInitParam(Context context, String initCapkeys) {        AsrInitParam asrInitParam = new AsrInitParam();        asrInitParam.addParam(AsrInitParam.PARAM_KEY_INIT_CAP_KEYS, initCapkeys);        asrInitParam.addParam(AsrInitParam.PARAM_KEY_FILE_FLAG, "android_so");        String dataPath = context.getFilesDir().getAbsolutePath().replace("files", "lib");        asrInitParam.addParam(AsrInitParam.PARAM_KEY_DATA_PATH, dataPath);        return asrInitParam.getStringConfig();    }    /**     * 开启录音机识别     *     * @param capkey 开启录音机时使用的capkey     * @param domain 设置识别的领域,没有特殊设置,domain=common     * @param isContinue 设置是否为连续识别,yes为是连续识别,no是非连续识别     */    public void startAsrRecorder(String capkey, String domain, String isContinue) {        if (mASRRecorder.getRecorderState() == mASRRecorder.RECORDER_STATE_RECOGING) {            mASRRecorder.cancel();        }        if (mASRRecorder.getRecorderState() == ASRRecorder.RECORDER_STATE_IDLE) {            String strConfig = getAsrConfigParam(capkey, domain, isContinue);            mASRRecorder.start(strConfig);        }    }    /**     * 取消录音识别功能     */    public void CancelAsrRecorder() {        if (mASRRecorder.getRecorderState() == mASRRecorder.RECORDER_STATE_RECOGING) {            mASRRecorder.cancel();        }    }    /**     * 获取asr识别时的配置参数     *     * @param capkey 录音机识别是的配置参数capkey     * @param domain 设置的领域值     * @param isContinue 设置是否为连续识别     * @return     */    private String getAsrConfigParam(String capkey, String domain, String isContinue) {        AsrConfig asrConfig = new AsrConfig();        asrConfig.addParam(AsrConfig.AudioConfig.PARAM_KEY_AUDIO_FORMAT, "pcm16k16bit");        asrConfig.addParam(AsrConfig.AudioConfig.PARAM_KEY_ENCODE, "speex");        asrConfig.addParam(AsrConfig.SessionConfig.PARAM_KEY_CAP_KEY, capkey);        asrConfig.addParam(AsrConfig.SessionConfig.PARAM_KEY_REALTIME, "yes");        asrConfig.addParam(AsrConfig.ResultConfig.PARAM_KEY_ADD_PUNC, "yes");        asrConfig.addParam(AsrConfig.ResultConfig.PARAM_KEY_DOMAIN, domain);        asrConfig.addParam("continue", isContinue);        if ("asr.cloud.dialog".equals(capkey)) {            //intention需要在开发者社区勾选,必须要设置对应的asr.cloud.dialog才可以使用,默认使用baike的领域            asrConfig.addParam("intention", "baike");        }        return asrConfig.getStringConfig();    }    /**     * 录音机release接口     */    public void releaseAsrRecorder() {        if (mASRRecorder != null) {            mASRRecorder.release();        }    }    /**     * ASR录音机回调类     */    private class ASRRecorderCallback implements ASRRecorderListener {        String result = "";        @Override        public void onRecorderEventStateChange(RecorderEvent recorderEvent) {            String state = "初始状态";            if (recorderEvent == RecorderEvent.RECORDER_EVENT_BEGIN_RECORD) {                state = "开始录音";            } else if (recorderEvent == RecorderEvent.RECORDER_EVENT_BEGIN_RECOGNIZE) {                state = "开始识别";            } else if (recorderEvent == RecorderEvent.RECORDER_EVENT_NO_VOICE_INPUT) {                state = "无音频输入";            } else if (recorderEvent == RecorderEvent.RECORDER_EVENT_HAVING_VOICE) {                state = "录音中";            } else if (recorderEvent == RecorderEvent.RECORDER_EVENT_END_RECORD) {                state = "录音结束";            } else if (recorderEvent == RecorderEvent.RECORDER_EVENT_RECOGNIZE_COMPLETE) {                state = "识别结束";            } else if (recorderEvent == RecorderEvent.RECORDER_EVENT_VOICE_BUFFER_FULL) {                state = "缓冲满";            }            //把录音机状态传递到Activity上            Message message = new Message();            message.arg1 = RECORDER_STATE;            Bundle bundle = new Bundle();            bundle.putString("state", "录音机状态:" + state);            message.setData(bundle);            myHander.sendMessage(message);        }        @Override        public void onRecorderEventRecogFinsh(RecorderEvent recorderEvent, AsrRecogResult asrRecogResult) {            if (asrRecogResult != null) {                if (asrRecogResult.getRecogItemList().size() > 0) {                    //识别结果                    result = asrRecogResult.getRecogItemList().get(0).getRecogResult();                    //置信度                    int score = asrRecogResult.getRecogItemList().get(0).getScore();                    //把识别结果传递到Activity上                    Message message = new Message();                    message.arg1 = RECORDER_RESULT;                    Bundle bundle = new Bundle();                    bundle.putString("result", "识别结果是:" + result);                    message.setData(bundle);                    myHander.sendMessage(message);                }            }        }        @Override        public void onRecorderEventRecogProcess(RecorderEvent recorderEvent, AsrRecogResult asrRecogResult) {        }        @Override        public void onRecorderEventError(RecorderEvent recorderEvent, int i) {            String error = "" + i;            //把错误信息传递到Activity上            Message message = new Message();            message.arg1 = RECORDER_ERROR;            Bundle bundle = new Bundle();            bundle.putString("error", "错误码:" + error);            message.setData(bundle);            myHander.sendMessage(message);        }        @Override        public void onRecorderRecording(byte[] bytes, int i) {//            File file = new File(voicePath);//            if (!file.exists()) {//                file.getParentFile().mkdirs();//                try {//                    file.createNewFile();//                } catch (IOException e) {//                    e.printStackTrace();//                }//            }//            try {//                FileOutputStream outputStream = new FileOutputStream(file);//                outputStream.write(bytes);//                outputStream.close();//            } catch (FileNotFoundException e) {//                e.printStackTrace();//            } catch (IOException e) {//                e.printStackTrace();//            }        }    }}

在MainActivity中使用语音识别的功能

package com.miao.test.util;import android.content.Context;import android.os.Bundle;import android.os.Handler;import android.os.Message;import com.sinovoice.hcicloudsdk.android.asr.recorder.ASRRecorder;import com.sinovoice.hcicloudsdk.common.asr.AsrConfig;import com.sinovoice.hcicloudsdk.common.asr.AsrInitParam;import com.sinovoice.hcicloudsdk.common.asr.AsrRecogResult;import com.sinovoice.hcicloudsdk.recorder.ASRRecorderListener;import com.sinovoice.hcicloudsdk.recorder.RecorderEvent;/** * Created by miaochangchun on 2016/11/28. */public class HciCloudAsrHelper {    private static final String TAG = HciCloudAsrHelper.class.getSimpleName();    public static final int RECORDER_STATE = 3;    public static final int RECORDER_ERROR = 2;    public static final int RECORDER_RESULT = 1;    private static HciCloudAsrHelper mHciCloudAsrHelper = null;    private ASRRecorder mASRRecorder;    private Handler myHander;//    private String voicePath;   //音频文件保存路径//    public void setVoicePath(String voicePath) {//        this.voicePath = voicePath;//    }//    public String getVoicePath() {//        return voicePath;//    }    private HciCloudAsrHelper() {    }    public static HciCloudAsrHelper getInstance() {        if (mHciCloudAsrHelper == null) {            return new HciCloudAsrHelper();        }        return mHciCloudAsrHelper;    }    public Handler getMyHander() {        return myHander;    }    public void setMyHander(Handler myHander) {        this.myHander = myHander;    }    /**     * 录音机初始化     *     * @param context     上下文     * @param initCapkeys 初始化录音机时设置的capkey,可以设置为多个。     * @return true录音机初始化成功,false录音机初始化失敗     */    public boolean initAsrRecorder(Context context, String initCapkeys) {        mASRRecorder = new ASRRecorder();        String strConfig = getAsrInitParam(context, initCapkeys);        // 语法相关的配置,若使用自由说能力可以不必配置该项//        String grammarData = "";//        String grammarConfigString = "capkey=" + initCapkeys + ",isFile=no,grammarType=jsgf";        mASRRecorder.init(strConfig, "", "", new ASRRecorderCallback());        if (mASRRecorder.getRecorderState() == ASRRecorder.RECORDER_STATE_IDLE) {            return true;        } else {            return false;        }    }    /**     * 获取初始化时的参数配置     *     * @param context     上下文     * @param initCapkeys 需要初始化的capkey,可以设置为多个     * @return     */    private String getAsrInitParam(Context context, String initCapkeys) {        AsrInitParam asrInitParam = new AsrInitParam();        asrInitParam.addParam(AsrInitParam.PARAM_KEY_INIT_CAP_KEYS, initCapkeys);        asrInitParam.addParam(AsrInitParam.PARAM_KEY_FILE_FLAG, "android_so");        String dataPath = context.getFilesDir().getAbsolutePath().replace("files", "lib");        asrInitParam.addParam(AsrInitParam.PARAM_KEY_DATA_PATH, dataPath);        return asrInitParam.getStringConfig();    }    /**     * 开启录音机识别     *     * @param capkey 开启录音机时使用的capkey     * @param domain 设置识别的领域,没有特殊设置,domain=common     * @param isContinue 设置是否为连续识别,yes为是连续识别,no是非连续识别     */    public void startAsrRecorder(String capkey, String domain, String isContinue) {        if (mASRRecorder.getRecorderState() == mASRRecorder.RECORDER_STATE_RECOGING) {            mASRRecorder.cancel();        }        if (mASRRecorder.getRecorderState() == ASRRecorder.RECORDER_STATE_IDLE) {            String strConfig = getAsrConfigParam(capkey, domain, isContinue);            mASRRecorder.start(strConfig);        }    }    /**     * 取消录音识别功能     */    public void CancelAsrRecorder() {        if (mASRRecorder.getRecorderState() == mASRRecorder.RECORDER_STATE_RECOGING) {            mASRRecorder.cancel();        }    }    /**     * 获取asr识别时的配置参数     *     * @param capkey 录音机识别是的配置参数capkey     * @param domain 设置的领域值     * @param isContinue 设置是否为连续识别     * @return     */    private String getAsrConfigParam(String capkey, String domain, String isContinue) {        AsrConfig asrConfig = new AsrConfig();        asrConfig.addParam(AsrConfig.AudioConfig.PARAM_KEY_AUDIO_FORMAT, "pcm16k16bit");        asrConfig.addParam(AsrConfig.AudioConfig.PARAM_KEY_ENCODE, "speex");        asrConfig.addParam(AsrConfig.SessionConfig.PARAM_KEY_CAP_KEY, capkey);        asrConfig.addParam(AsrConfig.SessionConfig.PARAM_KEY_REALTIME, "yes");        asrConfig.addParam(AsrConfig.ResultConfig.PARAM_KEY_ADD_PUNC, "yes");        asrConfig.addParam(AsrConfig.ResultConfig.PARAM_KEY_DOMAIN, domain);        asrConfig.addParam("continue", isContinue);        if ("asr.cloud.dialog".equals(capkey)) {            //intention需要在开发者社区勾选,必须要设置对应的asr.cloud.dialog才可以使用,默认使用baike的领域            asrConfig.addParam("intention", "baike");        }        return asrConfig.getStringConfig();    }    /**     * 录音机release接口     */    public void releaseAsrRecorder() {        if (mASRRecorder != null) {            mASRRecorder.release();        }    }    /**     * ASR录音机回调类     */    private class ASRRecorderCallback implements ASRRecorderListener {        String result = "";        @Override        public void onRecorderEventStateChange(RecorderEvent recorderEvent) {            String state = "初始状态";            if (recorderEvent == RecorderEvent.RECORDER_EVENT_BEGIN_RECORD) {                state = "开始录音";            } else if (recorderEvent == RecorderEvent.RECORDER_EVENT_BEGIN_RECOGNIZE) {                state = "开始识别";            } else if (recorderEvent == RecorderEvent.RECORDER_EVENT_NO_VOICE_INPUT) {                state = "无音频输入";            } else if (recorderEvent == RecorderEvent.RECORDER_EVENT_HAVING_VOICE) {                state = "录音中";            } else if (recorderEvent == RecorderEvent.RECORDER_EVENT_END_RECORD) {                state = "录音结束";            } else if (recorderEvent == RecorderEvent.RECORDER_EVENT_RECOGNIZE_COMPLETE) {                state = "识别结束";            } else if (recorderEvent == RecorderEvent.RECORDER_EVENT_VOICE_BUFFER_FULL) {                state = "缓冲满";            }            //把录音机状态传递到Activity上            Message message = new Message();            message.arg1 = RECORDER_STATE;            Bundle bundle = new Bundle();            bundle.putString("state", "录音机状态:" + state);            message.setData(bundle);            myHander.sendMessage(message);        }        @Override        public void onRecorderEventRecogFinsh(RecorderEvent recorderEvent, AsrRecogResult asrRecogResult) {            if (asrRecogResult != null) {                if (asrRecogResult.getRecogItemList().size() > 0) {                    //识别结果                    result = asrRecogResult.getRecogItemList().get(0).getRecogResult();                    //置信度                    int score = asrRecogResult.getRecogItemList().get(0).getScore();                    //把识别结果传递到Activity上                    Message message = new Message();                    message.arg1 = RECORDER_RESULT;                    Bundle bundle = new Bundle();                    bundle.putString("result", "识别结果是:" + result);                    message.setData(bundle);                    myHander.sendMessage(message);                }            }        }        @Override        public void onRecorderEventRecogProcess(RecorderEvent recorderEvent, AsrRecogResult asrRecogResult) {        }        @Override        public void onRecorderEventError(RecorderEvent recorderEvent, int i) {            String error = "" + i;            //把错误信息传递到Activity上            Message message = new Message();            message.arg1 = RECORDER_ERROR;            Bundle bundle = new Bundle();            bundle.putString("error", "错误码:" + error);            message.setData(bundle);            myHander.sendMessage(message);        }        @Override        public void onRecorderRecording(byte[] bytes, int i) {//            File file = new File(voicePath);//            if (!file.exists()) {//                file.getParentFile().mkdirs();//                try {//                    file.createNewFile();//                } catch (IOException e) {//                    e.printStackTrace();//                }//            }//            try {//                FileOutputStream outputStream = new FileOutputStream(file);//                outputStream.write(bytes);//                outputStream.close();//            } catch (FileNotFoundException e) {//                e.printStackTrace();//            } catch (IOException e) {//                e.printStackTrace();//            }        }    }}

注:灵云的在线识别功能需要联网才能使用。

0 0
原创粉丝点击