讯飞声纹验证

作者: 涛涛123759 | 来源:发表于2018-02-05 17:17 被阅读617次

    公司要做门禁其中用到了声纹识别,最后选用了科大讯飞的声纹验证。下面我们就学习一下声纹验证吧!

    目前 MSC SDK 支持两种类型的声纹密码:数字密码和文本密码。文本密码的效果在优化中,建议使用数字密码。密码类型的取值说明如下表所示:


    第一步 注册讯飞账号

    注册账号——创建新应用——立即开通(开通需要的服务)—— 选中对应SDK、平台、你创建的应用 ;

    第二步集成SDK

    把我们从讯飞平台上集成的SDK导入我们项目的libs目录下(注意我们集成的SDK要和我们在讯飞平台上创建的应用里的APPID保持一致,否则无法使用),如图所示:


    最好在build.gradle里面加上一句话

    sourceSets{
        main{
            jniLibs.srcDirs=['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" />
    

    然后在application中导入:

        <!-- 移动统计分析 -->
        <meta-data
            android:name="IFLYTEK_APPKEY"
            android:value="自己的app_id" />
        <meta-data
            android:name="IFLYTEK_CHANNEL"
            android:value="Android_Demo" />
    
        <activity android:name=".MainActivity">
    

    第四步然后我们就该写代码了

    1、 初始化

    初始化即创建语音配置对象,只有初始化后才可以使用MSC的各项服务。建议将初始化放在程序入口处(如Application、Activity的onCreate方法),初始化代码如下:

    SpeechUtility.createUtility(this, "appid=" + getString(R.string.app_id));
    

    2、在Activity中实现具体的内容
    实现声纹注册可以分为四步:
    1、获得密码
    2、注册声纹
    3、验证声纹
    4、查询和删除声纹

    然后就是Activity中的实现代码了:

    public class Main2Activity extends AppCompatActivity implements View.OnClickListener {
    
    private static final String TAG = Main2Activity.class.getSimpleName();
    
    private static final int PWD_TYPE_TEXT = 1;
    //自由说密码。用户通过读一段文字来进行声纹注册和验证,注册时要求声音长度为20秒左右,
    // 验证时要求声音长度为15秒左右,内容不限。
    private static final int PWD_TYPE_FREE = 2;
    private static final int PWD_TYPE_NUM = 3;
    // 当前声纹密码类型,1、2、3分别为文本、自由说和数字密码
    private int mPwdType = PWD_TYPE_TEXT;
    
    // 数字声纹密码
    private String mNumPwd = "";
    // 数字声纹密码段,默认有5段
    private String[] mNumPwdSegs;
    // 用于验证的数字密码
    private String mVerifyNumPwd = "";
    // 文本声纹密码
    private String mTextPwd = "";
    
    // 会话类型
    private int mSST = 0;
    // 注册
    private static final int SST_ENROLL = 0;
    // 验证
    private static final int SST_VERIFY = 1;
    
    // 是否可以录音
    private boolean isStartWork = false;
    
    // 用户id,唯一标识
    private String mAuthId;
    
    private TextView mResultText;
    private Button mBtnStartRecord;
    private EditText mAuthidEditText;
    private RadioGroup mPwdTypeGroup;
    private TextView mErrorResult;
    
    private Toast mToast;
    private ProgressDialog mProDialog;
    private AlertDialog mTextPwdSelectDialog;
    private SpeakerVerifier mSpeakerVerifier;
    
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main2);
    
        setUI();
        // 初始化SpeakerVerifier,InitListener为初始化完成后的回调接口
        mSpeakerVerifier = SpeakerVerifier.createVerifier(this, new InitListener() {
            @Override
            public void onInit(int i) {
                if (ErrorCode.SUCCESS == i) {
                    showTip("引擎初始化成功");
                } else {
                    showTip("引擎初始化失败,错误码:" + i);
                }
            }
        });
    }
    
    
    private void setUI() {
        mToast = Toast.makeText(this, "", Toast.LENGTH_SHORT);
        mToast.setGravity(Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL, 0, 0);
    
        mResultText = (TextView) findViewById(R.id.edt_result);
        mErrorResult = (TextView) findViewById(R.id.error_result);
        mAuthidEditText = (EditText) findViewById(R.id.set_authId);
        mBtnStartRecord = (Button) findViewById(R.id.isv_reocrd);
        mBtnStartRecord.setOnClickListener(this);
    
        findViewById(R.id.isv_getpassword).setOnClickListener(this);
        findViewById(R.id.isv_search).setOnClickListener(this);
        findViewById(R.id.isv_delete).setOnClickListener(this);
        findViewById(R.id.isv_identity).setOnClickListener(this);
    
        mProDialog = new ProgressDialog(this);
        mProDialog.setCancelable(true);
        mProDialog.setTitle("请稍候");
        // cancel进度框时,取消正在进行的操作
        mProDialog.setOnCancelListener(new DialogInterface.OnCancelListener() {
            @Override
            public void onCancel(DialogInterface dialog) {
                if (null != mSpeakerVerifier) {
                    mSpeakerVerifier.cancel();
                }
            }
        });
    
        mPwdTypeGroup = (RadioGroup) findViewById(R.id.radioGroup);
        mPwdTypeGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(RadioGroup group, int checkedId) {
                switch (checkedId) {
                    case R.id.radioText:
                        mTextPwd = null;
                        isStartWork = false;
                        mPwdType = PWD_TYPE_TEXT;
                        break;
    
                    case R.id.radioFree:
                        isStartWork = false;
                        mPwdType = PWD_TYPE_FREE;
                        break;
    
                    case R.id.radioNumber:
                        mNumPwdSegs = null;
                        isStartWork = false;
                        mPwdType = PWD_TYPE_NUM;
                        break;
                    default:
                        break;
                }
            }
        });
    
    }
    
    
    private void showTip(final String str) {
        mToast.setText(str);
        mToast.show();
    }
    
    
    
    @Override
    public void onClick(View v) {
        if (!checkInstance()) {
            return;
        }
    
        mAuthId = getAuthid();
        if (TextUtils.isEmpty(mAuthId)) {
            showTip("用户id为空,请重新输入");
            return;
        }
        // 取消先前操作
        cancelOperation();
        switch (v.getId()) {
            case R.id.isv_getpassword:
                // 获取密码之前先终止之前的注册或验证过程
                // 首次注册密码为空时,调用下载密码
                if (mTextPwd == null || mNumPwdSegs == null && mPwdType != PWD_TYPE_FREE) {
                    downloadPwd();
                }
                break;
    
            case R.id.isv_reocrd:
                mAuthId = getAuthid();
                if (TextUtils.isEmpty(mAuthId)) {
                    showTip("请输入authid");
                    break;
                }
                vocalEnroll();
                break;
    
            case R.id.isv_search:
                //查询模型
                performModelOperation("que", mModelOperationListener);
                break;
    
            case R.id.isv_delete:
                //删除模型
                performModelOperation("del", mModelOperationListener);
                break;
    
            case R.id.isv_identity:
                //验证
                // 清空参数
                mSpeakerVerifier.setParameter(SpeechConstant.PARAMS, null);
                mSpeakerVerifier.setParameter(SpeechConstant.ISV_AUDIO_PATH,
                        Environment.getExternalStorageDirectory().getAbsolutePath() + "/msc/verify.pcm");
                mSpeakerVerifier = SpeakerVerifier.getVerifier();
                // 设置业务类型为验证
                mSpeakerVerifier.setParameter(SpeechConstant.ISV_SST, "verify");
                // 对于某些麦克风非常灵敏的机器,如nexus、samsung i9300等,建议加上以下设置对录音进行消噪处理
    

    // mVerify.setParameter(SpeechConstant.AUDIO_SOURCE, "" + MediaRecorder.AudioSource.VOICE_RECOGNITION);

                if (mPwdType == PWD_TYPE_TEXT) {
                    // 文本密码注册需要传入密码
                    if (TextUtils.isEmpty(mTextPwd)) {
                        showTip("请获取密码后进行操作");
                        return;
                    }
                    mSpeakerVerifier.setParameter(SpeechConstant.ISV_PWD, mTextPwd);
                    mResultText.setText("请读出:" + mTextPwd);
    
                } else if (mPwdType == PWD_TYPE_NUM) {
                    // 数字密码注册需要传入密码
                    String verifyPwd = mSpeakerVerifier.generatePassword(8);
                    mSpeakerVerifier.setParameter(SpeechConstant.ISV_PWD, verifyPwd);
                    mResultText.setText("请读出:" + verifyPwd);
    
                } else if (mPwdType == PWD_TYPE_FREE) {
                    mSpeakerVerifier.setParameter(SpeechConstant.SAMPLE_RATE, "8000");
                    mResultText.setText("请随便说些用于验证");
    
                }
                // 设置auth_id,不能设置为空
                mSpeakerVerifier.setParameter(SpeechConstant.AUTH_ID, mAuthId);
                mSpeakerVerifier.setParameter(SpeechConstant.ISV_PWDT, "" + mPwdType);
                // 开始验证
                mSpeakerVerifier.startListening(mVerifyListener);
                break;
            default:
                break;
        }
    
    }
    
    /**
     * 执行模型操作
     *
     * @param operation 操作命令
     * @param listener  操作结果回调对象
     */
    private void performModelOperation(String operation, SpeechListener listener) {
        // 清空参数
        mSpeakerVerifier.setParameter(SpeechConstant.PARAMS, null);
    
    
        //设置密码类型(就是咱要读的)
        mSpeakerVerifier.setParameter(SpeechConstant.ISV_PWDT, "" + mPwdType);
    
        if (mPwdType == PWD_TYPE_TEXT) {
            // 文本密码删除需要传入密码
            if (TextUtils.isEmpty(mTextPwd)) {
                showTip("请获取密码后进行操作");
                return;
            }
    
            // 对于文本密码和数字密码,必须设置密码的文本内容,pwdText的取值为“芝麻开门”或者是从云端拉取的数字密码(每8位用“-”隔开,如“62389704-45937680-32758406-29530846-58206497”)。自由说略过此步
    
            mSpeakerVerifier.setParameter(SpeechConstant.ISV_PWD, mTextPwd);
        } else if (mPwdType == PWD_TYPE_NUM) {
    
        } else if (mPwdType == PWD_TYPE_FREE) {
    
        }
        // 设置auth_id,不能设置为空
        mSpeakerVerifier.sendRequest(operation, mAuthId, listener);
    }
    
    /**
     * 下载密码
     */
    private void downloadPwd() {
        mAuthId = getAuthid();
        if (TextUtils.isEmpty(mAuthId)) {
            showTip("请输入authid");
            return;
        }
        // 获取密码之前先终止之前的操作
        mSpeakerVerifier.cancel();
        // 下载密码时,按住说话触摸无效
        mBtnStartRecord.setClickable(false);
    
        mProDialog.setMessage("下载中...");
        mProDialog.show();
        // 清空参数
        mSpeakerVerifier.setParameter(SpeechConstant.PARAMS, null);
        // 设置会话场景
        mSpeakerVerifier.setParameter(SpeechConstant.MFV_SCENES, "ivp");
        // 当前声纹密码类型,1、2、3分别为文本、自由说和数字密码
        mSpeakerVerifier.setParameter(SpeechConstant.ISV_PWDT, "" + mPwdType);
        if (mPwdType != PWD_TYPE_FREE) {
            //本地的监听参数
            mSpeakerVerifier.getPasswordList(mPwdListenter);
        }
    
    }
    
    /**
     * 注册
     */
    private void vocalEnroll() {
        mSpeakerVerifier.setParameter(SpeechConstant.PARAMS, null);
        mSpeakerVerifier.setParameter(SpeechConstant.ASR_AUDIO_PATH,
                Environment.getExternalStorageDirectory().getAbsolutePath() + "/msc/test.pcm");
        // 对于某些麦克风非常灵敏的机器,如nexus、samsung i9300等,建议加上以下设置对录音进行消噪处理
        // mSpeakerVerifier.setParameter(SpeechConstant.AUDIO_SOURCE, "" + MediaRecorder.AudioSource.VOICE_RECOGNITION);
        if (mPwdType == PWD_TYPE_TEXT){
            if (TextUtils.isEmpty(mTextPwd)){
                showTip("请获取密码后进行操作");
                return;
            }
            StringBuffer strBuffer = new StringBuffer();
            strBuffer.append("请长按“按住说话”按钮!\n");
            strBuffer.append("请读出:" + mTextPwd + "\n");
            strBuffer.append("训练 第" + 1 + "遍,剩余4遍\n");
            mResultText.setText(strBuffer.toString());
            mSpeakerVerifier.setParameter(SpeechConstant.ISV_PWD, mTextPwd);
        } else if (mPwdType == PWD_TYPE_NUM){
            // 数字密码注册需要传入密码
            if (TextUtils.isEmpty(mNumPwd)) {
                showTip("请获取密码后进行操作");
                return;
            }
            StringBuffer strBuffer = new StringBuffer();
            strBuffer.append("请长按“按住说话”按钮!\n");
            strBuffer.append("请读出:" + mNumPwdSegs[0] + "\n");
            strBuffer.append("训练 第" + 1 + "遍,剩余4遍\n");
            mResultText.setText(strBuffer.toString());
            mSpeakerVerifier.setParameter(SpeechConstant.ISV_PWD, mNumPwd);
    
        } else if (mPwdType == PWD_TYPE_FREE){
            //这里插一句嘴,自由说的注册参数之次数 设置为“1” 音质的的设置“8000
            mSpeakerVerifier.setParameter(SpeechConstant.ISV_RGN, "1");
            mSpeakerVerifier.setParameter(SpeechConstant.SAMPLE_RATE, "8000");
    
        }
    
        mSpeakerVerifier.setParameter(SpeechConstant.AUTH_ID, mAuthId);
        // 设置业务类型为注册
        mSpeakerVerifier.setParameter(SpeechConstant.ISV_SST, "train");
        // 设置声纹密码类型
        mSpeakerVerifier.setParameter(SpeechConstant.ISV_PWDT, "" + mPwdType);
        // 开始注册
        mSpeakerVerifier.startListening(mRegisterListener);
    }
    
    
    //    第一步的监听参数:
    //    通过解析获得密码,注意 这里自由说不需要密码,所以这里没有它的case
    private String[] items;
    private SpeechListener mPwdListenter = new SpeechListener() {
        @Override
        public void onEvent(int i, Bundle bundle) {
    
        }
    
        @Override
        public void onBufferReceived(byte[] bytes) {
            mAuthidEditText.setEnabled(false);//密码获取成功后,authid不可再变动
            mProDialog.dismiss();
            mBtnStartRecord.setClickable(true);
    
            String result = new String(bytes);
            switch (mPwdType) {
                case PWD_TYPE_TEXT:
                    try {
                        JSONObject object = new JSONObject(result);
                        if (!object.has("txt_pwd")) {
                            mResultText.setText("");
                            return;
                        }
    
                        JSONArray pwdArray = object.optJSONArray("txt_pwd");
                        items = new String[pwdArray.length()];
                        for (int i = 0; i < pwdArray.length(); i++) {
                            items[i] = pwdArray.getString(i);
                        }
                        mTextPwdSelectDialog = new AlertDialog.Builder(Main2Activity.this)
                                .setTitle("请选择密码文本")
                                .setCancelable(false)
                                .setItems(items, new DialogInterface.OnClickListener() {
                                    @Override
                                    public void onClick(DialogInterface dialog, int which) {
                                        mTextPwd = items[which];
                                        mResultText.setText("您的注册密码:\n" + mTextPwd +
                                                "\n请长按“按住说话”按钮进行注册\n");
                                    }
                                }).create();
                        mTextPwdSelectDialog.show();
    
                    } catch (JSONException e) {
                        e.printStackTrace();
                    }
                    break;
    
                case PWD_TYPE_NUM:
                    StringBuffer numberString = new StringBuffer();
                    try {
                        JSONObject object = new JSONObject(result);
                        if (!object.has("num_pwd")) {
                            mResultText.setText("");
                            return;
                        }
                        JSONArray pwdArray = object.optJSONArray("num_pwd");
                        numberString.append(pwdArray.get(0));
                        for (int i = 1; i < pwdArray.length(); i++) {
                            numberString.append("-" + pwdArray.get(i));
                        }
                    } catch (JSONException e) {
                        e.printStackTrace();
                    }
                    mNumPwd = numberString.toString();
                    mNumPwdSegs = mNumPwd.split("-");
                    mResultText.setText("您的注册密码:\n" + mNumPwd +
                            "\n请长按“按住说话”按钮进行注册\n");
                    break;
                default:
                    break;
            }
    
        }
    
        @Override
        public void onCompleted(SpeechError speechError) {
            if (null != speechError && ErrorCode.SUCCESS != speechError.getErrorCode()) {
                showTip("获取失败:" + speechError.getErrorCode());
            }
        }
    };
    
    //第二步的监听参数,通过调用result的参数获取结果
    private VerifierListener mRegisterListener = new VerifierListener() {
        @Override
        public void onResult(VerifierResult verifierResult) {
          if (verifierResult.ret == ErrorCode.SUCCESS){
              switch (verifierResult.err){
                  case VerifierResult.MSS_ERROR_IVP_GENERAL:
                      mErrorResult.setText("内核异常");
                      break;
                  case VerifierResult.MSS_ERROR_IVP_EXTRA_RGN_SOPPORT:
                      mErrorResult.setText("训练达到最大次数");
                      break;
                  case VerifierResult.MSS_ERROR_IVP_TRUNCATED:
                      mErrorResult.setText("出现截幅");
                      break;
                  case VerifierResult.MSS_ERROR_IVP_MUCH_NOISE:
                      mErrorResult.setText("太多噪音");
                      break;
                  case VerifierResult.MSS_ERROR_IVP_UTTER_TOO_SHORT:
                      mErrorResult.setText("录音太短");
                      break;
                  case VerifierResult.MSS_ERROR_IVP_TEXT_NOT_MATCH:
                      mErrorResult.setText("训练失败,您所读的文本不一致");
                      break;
                  case VerifierResult.MSS_ERROR_IVP_TOO_LOW:
                      mErrorResult.setText("音量太低");
                      break;
                  case VerifierResult.MSS_ERROR_IVP_NO_ENOUGH_AUDIO:
                      mErrorResult.setText("音频长达不到自由说的要求");
                      break;
                  default:
                      showTip("");
                      break;
              }
    
              if (verifierResult.suc == verifierResult.rgn){
                  mResultText.setText("注册成功");
                  if (PWD_TYPE_TEXT == mPwdType) {
                      mErrorResult.setText("您的文本密码声纹ID:\n" + verifierResult.vid);
                      Log.e(TAG, "onResult:文字 " + verifierResult.vid);
    
                  } else if (PWD_TYPE_NUM == mPwdType) {
                      mErrorResult.setText("您的数字密码声纹ID:\n" + verifierResult.vid);
                      Log.e(TAG, "onResult:数字 " + verifierResult.vid);
    
                  } else if (mPwdType == PWD_TYPE_FREE) {
                      mErrorResult.setText("您的数字密码声纹ID:\n" + verifierResult.vid);
                      Log.e(TAG, "onResult: 自由" + verifierResult.vid);
    
                  }
                  isStartWork = false;
                  if (mSpeakerVerifier != null) {
                      mSpeakerVerifier.stopListening();
                  }
    
              } else {
                  int nowTimes = verifierResult.suc + 1;
                  int leftTimes = verifierResult.rgn - nowTimes;
    
                  StringBuffer strBuffer = new StringBuffer();
                  strBuffer.append("请长按“按住说话”按钮!\n");
                  if (PWD_TYPE_TEXT == mPwdType) {
                      strBuffer.append("请读出:" + mTextPwd + "\n");
                  } else if (PWD_TYPE_NUM == mPwdType) {
                      strBuffer.append("请读出:" + mNumPwdSegs[nowTimes - 1] + "\n");
                  }
                  strBuffer.append("训练 第" + nowTimes + "遍,剩余" + leftTimes + "遍");
                  mResultText.setText(strBuffer.toString());
              }
    
          } else {
              mResultText.setText("注册失败,请重新开始。");
    
          }
        }
    
        @Override
        public void onVolumeChanged(int i, byte[] bytes) {
            showTip("当前正在说话,音量大小:" + i);
            Log.d(TAG, "返回音频数据:" + bytes.length);
        }
    
        @Override
        public void onBeginOfSpeech() {
            showTip("开始说话");
        }
    
        @Override
        public void onEndOfSpeech() {
            showTip("结束说话");
        }
    
        @Override
        public void onError(SpeechError speechError) {
            if (speechError.getErrorCode() == ErrorCode.MSP_ERROR_ALREADY_EXIST) {
                showTip("模型已存在,如需重新注册,请先删除");
            } else {
                showTip("onError Code:" + speechError.getPlainDescription(true));
            }
        }
    
        // 保留方法,暂不用
        @Override
        public void onEvent(int i, int i1, int i2, Bundle bundle) {
            // 以下代码用于获取与云端的会话id,当业务出错时将会话id提供给技术支持人员,可用于查询会话日志,定位出错原因
             if (SpeechEvent.EVENT_SESSION_ID == i) {
                String sid = bundle.getString(SpeechEvent.KEY_EVENT_SESSION_ID);
                Log.d(TAG, "session id =" + sid);
             }
        }
    };
    
    //第三步 监听参数
    private VerifierListener mVerifyListener = new VerifierListener() {
    
        @Override
        public void onVolumeChanged(int volume, byte[] data) {
            showTip("当前正在说话,音量大小:" + volume);
            Log.d(TAG, "返回音频数据:" + data.length);
        }
    
        @Override
        public void onResult(VerifierResult result) {
            mErrorResult.setText("");
    
            if (result.ret == 0) {
                // 验证通过 这里就意味着通过了!!!
                mResultText.setText("验证通过,打开****");
    
            } else {
                // 验证不通过
                switch (result.err) {
                    case VerifierResult.MSS_ERROR_IVP_GENERAL:
                        mErrorResult.setText("内核异常");
                        break;
                    case VerifierResult.MSS_ERROR_IVP_TRUNCATED:
                        mErrorResult.setText("出现截幅");
                        break;
                    case VerifierResult.MSS_ERROR_IVP_MUCH_NOISE:
                        mErrorResult.setText("太多噪音");
                        break;
                    case VerifierResult.MSS_ERROR_IVP_UTTER_TOO_SHORT:
                        mErrorResult.setText("录音太短");
                        break;
                    case VerifierResult.MSS_ERROR_IVP_TEXT_NOT_MATCH:
                        mErrorResult.setText("验证不通过,您所读的文本不一致");
                        break;
                    case VerifierResult.MSS_ERROR_IVP_TOO_LOW:
                        mErrorResult.setText("音量太低");
                        break;
                    case VerifierResult.MSS_ERROR_IVP_NO_ENOUGH_AUDIO:
                        mErrorResult.setText("音频长达不到自由说的要求");
                        break;
                    default:
                        mErrorResult.setText("验证不通过,相似度仅为" + result.score + "%。");
                        break;
                }
            }
        }
    
        // 保留方法,暂不用
        @Override
        public void onEvent(int eventType, int arg1, int arg2, Bundle arg3) {
            // 以下代码用于获取与云端的会话id,当业务出错时将会话id提供给技术支持人员,可用于查询会话日志,定位出错原因
            // if (SpeechEvent.EVENT_SESSION_ID == eventType) {
            //    String sid = obj.getString(SpeechEvent.KEY_EVENT_SESSION_ID);
            //    Log.d(TAG, "session id =" + sid);
            // }
        }
    
        @Override
        public void onError(SpeechError error) {
    
            switch (error.getErrorCode()) {
                case ErrorCode.MSP_ERROR_NOT_FOUND:
                    mResultText.setText("模型不存在,请先注册");
                    break;
    
                default:
                    showTip("onError Code:" + error.getPlainDescription(true));
                    break;
            }
        }
    
        @Override
        public void onEndOfSpeech() {
            // 此回调表示:检测到了语音的尾端点,已经进入识别过程,不再接受语音输入
            showTip("结束说话");
        }
    
        @Override
        public void onBeginOfSpeech() {
            // 此回调表示:sdk内部录音机已经准备好了,用户可以开始语音输入
            showTip("开始说话");
        }
    };
    
    
    private SpeechListener mModelOperationListener = new SpeechListener() {
    
        @Override
        public void onEvent(int eventType, Bundle params) {
        }
    
        @Override
        public void onBufferReceived(byte[] buffer) {
    
            String result = new String(buffer);
            try {
                JSONObject object = new JSONObject(result);
                String cmd = object.getString("cmd");
                int ret = object.getInt("ret");
    
                if ("del".equals(cmd)) {
                    if (ret == ErrorCode.SUCCESS) {
                        showTip("删除成功");
                        mResultText.setText("");
                    } else if (ret == ErrorCode.MSP_ERROR_FAIL) {
                        showTip("删除失败,模型不存在");
                    }
    
                } else if ("que".equals(cmd)) {
                    if (ret == ErrorCode.SUCCESS) {
                        showTip("模型存在");
                    } else if (ret == ErrorCode.MSP_ERROR_FAIL) {
                        showTip("模型不存在");
                    }
                }
            } catch (JSONException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    
        @Override
        public void onCompleted(SpeechError error) {
            if (null != error && ErrorCode.SUCCESS != error.getErrorCode()) {
                showTip("操作失败:" + error.getPlainDescription(true));
            }
        }
    };
    
    private boolean checkInstance() {
        if (null == mSpeakerVerifier) {
            // 创建单例失败,与 21001 错误为同样原因,
            this.showTip("创建对象失败,请确认 libmsc.so 放置正确,\n 且有调用 createUtility 进行初始化");
            return false;
        } else {
            return true;
        }
    }
    
    private void cancelOperation() {
        mSpeakerVerifier.cancel();
    }
    
    private String getAuthid() {
        String id = mAuthidEditText.getText() == null ? null : mAuthidEditText.getText().toString();
        return id;
    }
    
    
    @Override
    public void finish() {
        if (null != mTextPwdSelectDialog) {
            mTextPwdSelectDialog.dismiss();
        }
        super.finish();
    }
    
    }
    

    源代码

    相关文章

      网友评论

        本文标题:讯飞声纹验证

        本文链接:https://www.haomeiwen.com/subject/erabzxtx.html