android项目接入科大讯飞语音评测功能过程

前言

最近项目需要接入语音评测功能,公司有做过这方面的同事推荐了科大讯飞语音评测,于是根据官网的开发指南接入了sdk,可以成功评测用户的口语能力,并给出合适的分数,但是期间遇到了很多小问题,于是写在这篇文章记录一下开发及填坑的过程。

正文

1.接入sdk:

如何接入sdk请去看科大讯飞官网提供的接入指南,这里就不做介绍了

传送门:https://doc.xfyun.cn/msc_android/%E8%AF%AD%E9%9F%B3%E8%AF%84%E6%B5%8B.html

2.编写语音评测工具类:

因为有两个地方用到了这个评测功能,所以为了使用方便,写了一个工具类,直接上代码:

/**
 * @ClassName: SpeechEvaluatorUtil
 * @Desciption: //语音评测工具类
 * @author: jesse
 * @date: 2018-06-29
 */
public class SpeechEvaluatorUtil {

    private static final String TAG = SpeechEvaluatorUtil.class.getSimpleName();
    public static final String EVA_RECORD_PATH = Environment.getExternalStorageDirectory().getAbsolutePath() + "/msc/ise.wav";

    private static SpeechEvaluator mIse;

    public static void init(Context context) {
        if (mIse == null) {
            mIse = SpeechEvaluator.createEvaluator(context, null);
        }
    }

    /**
     * @param evaText            评测用句
     * @param mEvaluatorListener 语音评测回调接口
     * @return 评测录音存储路径
     */
    public static void startSpeechEva(String evaText, EvaluatorListener mEvaluatorListener) {
        setParams();
        // 设置音频保存路径,保存音频格式支持pcm、wav,设置路径为sd卡请注意WRITE_EXTERNAL_STORAGE权限
        // 注:AUDIO_FORMAT参数语记需要更新版本才能生效
        mIse.startEvaluating(evaText, null, mEvaluatorListener);
    }

    //通过写入音频文件进行评测
    public static void startEva(byte[] audioData,String evaText,EvaluatorListener mEvaluatorListener){
        setParams();
        //通过writeaudio方式直接写入音频时才需要此设置
        mIse.setParameter(SpeechConstant.AUDIO_SOURCE,"-1");

        int ret = mIse.startEvaluating(evaText, null, mEvaluatorListener);
        //在startEvaluating接口调用之后,加入以下方法,即可通过直接
        //写入音频的方式进行评测业务
        if (ret != ErrorCode.SUCCESS) {
            Log.i(TAG,"识别失败,错误码:" + ret);
        } else {
            if(audioData != null) {
                //防止写入音频过早导致失败
                try{
                    new Thread().sleep(100);
                }catch (InterruptedException e) {
                    Log.d(TAG,"InterruptedException :"+e);
                }
                mIse.writeAudio(audioData,0,audioData.length);
                mIse.stopEvaluating();
            }else{
                Log.i(TAG,"audioData == null");
            }
        }
    }

    private static void setParams() {
        Log.i(TAG, "setParams()");
        // 设置评测语种:英语
        mIse.setParameter(SpeechConstant.LANGUAGE, "en_us");
        // 设置评测题型:句子
        mIse.setParameter(SpeechConstant.ISE_CATEGORY, "read_sentence");
        mIse.setParameter(SpeechConstant.RESULT_LEVEL,"plain");
        mIse.setParameter(SpeechConstant.ISE_AUDIO_PATH, EVA_RECORD_PATH);
        mIse.setParameter(SpeechConstant.AUDIO_FORMAT, "wav");
    }

    //停止评测
    public static void stopSpeechEva() {
        if (mIse.isEvaluating()) {
            mIse.stopEvaluating();
        }
    }

    //取消评测
    public static void cancelSpeechEva() {
        mIse.cancel();
    }

}

这里写了两种评测方式:

第一种是“直接根据mic录到的音频进行评测”(startSpeechEva()),这种方式会在EVA_RECORD_PATH路径下生成一个约44kb的wav格式音频文件,但是这里有一个巨大的坑--音频文件不会立即刷新覆盖上一次录音,大概会延迟0.7-1.2s的时间,这样就造成了一个问题:如果想要录音完后立即播放这次的录音的话,会发现播放的录音是上一次的录音!而很不巧,我就需要做这样的一个功能,所以我弃用了第一种方式,改用了第二种方式。

第二种是“先自己把音频录下来,生成wav格式文件,然后再转换成byte数组进行评测”(startEva()),这种方式因为是自己录音,所以没有刷新录音文件的延迟,可以实现录音完后立即播放录音音频的效果,这就解决了第一种方式里的大坑。但是还有个坑就是,较之第一种方式,这种方式的评分偏低很多(第一种方式能得90分的发音,第二种方式大概得70分)。如果有人能够解决这个坑的话,希望你能给我留言告知一下方法。(此坑已填,文中代码已修改)

3.编写录音工具类

这里我写了两个工具类,一个用的是MediaRecorder进行录音,一个是用AudioRecord,第2步里的第二种方式用到的是AudioRecorder这个工具类。这里两种都奉上。

MediaRecorder工具类:

/**
 * @ClassName: MediaRecordUtil
 * @Desciption: //录音工具类
 * @author: jesse
 * @date: 2018-06-15
 */
public class MediaRecordUtil {

    //文件路径
    private String filePath;
    //文件夹路径
    private String FolderPath;

    private MediaRecorder mMediaRecorder;
    private final String TAG = MediaRecordUtil.class.getSimpleName();
    public static final int MAX_LENGTH = 1000 * 60 * 10;// 最大录音时长1000*60*10;

    private OnAudioStatusUpdateListener audioStatusUpdateListener;

    /**
     * 文件存储默认sdcard/record
     */
    public MediaRecordUtil(){

    
  • 4
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 15
    评论
回答: 在Unity中使用科大语音过程中,有一些常见问题需要注意。首先,关于路径的问题,需要确保ivw_res_path路径中不包含中文字符,否则会报错10102。此外,路径中的斜杠需要替换为反斜杠,否则也会报错10102。\[1\] 其次,关于QIVWAudioWrite接口需要调用两次的问题,这是因为在写入音频数据时,需要先调用一次MSP_AUDIO_SAMPLE_CONTINUE表示音频数据的中间部分,然后再调用一次MSP_AUDIO_SAMPLE_LAST表示音频数据的最后一部分。这样做是为了确保音频数据的完整性。\[2\] 最后,关于QIVWRegisterNotify接口后面需要使用Sleep的问题,这是因为在注册通知后,需要给科大语音一些时间来处理注册的操作。使用Sleep函数可以暂停程序的执行,让科大语音有足够的时间来完成注册。具体的等待时间可以根据实际情况进行调整。\[2\] 总结起来,在Unity中使用科大语音时,需要注意路径中不包含中文字符,斜杠需要替换为反斜杠;在写入音频数据时,需要调用两次接口来表示音频数据的中间部分和最后一部分;在注册通知后,需要使用Sleep函数给科大语音足够的时间来完成注册操作。 #### 引用[.reference_title] - *1* *2* [Unity 科大语音唤醒](https://blog.csdn.net/weixin_42208093/article/details/107364588)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 15
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

JesseAndroid

每一份支持都是我创作的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值