AIUIWrapper.java 8.7 KB
package com.ys.yslibrary.aiui;

import android.content.Context;
import android.text.TextUtils;
import android.util.Log;

import com.iflytek.aiui.AIUIAgent;
import com.iflytek.aiui.AIUIConstant;
import com.iflytek.aiui.AIUIEvent;
import com.iflytek.aiui.AIUIListener;
import com.iflytek.aiui.AIUIMessage;
import com.ys.yslibrary.bean.RawMessage;
import com.ys.yslibrary.callback.OnVoiceIdentifyResultListener;
import com.ys.yslibrary.bean.VoiceMsgType;
import com.ys.yslibrary.control.MsgAction;
import com.ys.yslibrary.paraser.AbsVoiceMsgParser;
import com.ys.yslibrary.paraser.DefaultVoiceMsgParaserFactory;

public class AIUIWrapper implements AIUIListener {
    private static Context mContext;
    private AIUIAgent aiuiAgent;
    private AIUIConfiguration mConfigManager;
    private int mCurrentState;
    private String TAG = getClass().getName();
    private static volatile AIUIWrapper instance;
    //AIUI当前录音状态,避免连续两次startRecordAudio时的录音失败
    private boolean mAudioRecording = false;
    private AbsVoiceMsgParser voiceMsgParser;
    private MsgAction msgAction;
    private CheckForNotSpeak checkForNotSpeak;
    private boolean hasSpeak;
    private OnVoiceIdentifyResultListener onVoiceIdentifyResultListener;

    public static AIUIWrapper getInstance() {
        if (instance == null) {
            synchronized (AIUIWrapper.class) {
                if (instance == null) {
                    instance = new AIUIWrapper();

                }
            }
        }
        return instance;
    }

    //是否是唤醒状态
    public AIUIWrapper() {
        if (voiceMsgParser == null) {
            voiceMsgParser = new DefaultVoiceMsgParaserFactory().getMsgParser();
        }
        if (mConfigManager == null) {
            this.mConfigManager = new AIUIConfiguration(mContext);
            aiuiAgent = AIUIAgent.createAgent(mContext, mConfigManager.getCurrentAssetConfig(), this);
        }
        if (msgAction == null) {
            msgAction = new MsgAction();
        }
        if (checkForNotSpeak == null) {
            checkForNotSpeak = new CheckForNotSpeak();
        }
    }

    public static void init(Context context) {
        if (context == null) {
            throw new NullPointerException("context can't be null");
        }
        mContext = context;
    }

    @Override
    public void onEvent(AIUIEvent event) {
        Log.e(TAG, "onEvent: " + event.eventType);
        switch (event.eventType) {

            case AIUIConstant.EVENT_CONNECTED_TO_SERVER: {
//                if (mPendingHistoryClear) {
//                    mPendingHistoryClear = false;
//                    //需要在CONNECT_TO_SERVER后才能发送清除历史指令,清除云端的交互历史
//                    sendMessage(new AIUIMessage(AIUIConstant.CMD_CLEAN_DIALOG_HISTORY, 0, 0, null, null));
//                }
//
//                mLiveUID.setValue(event.data.getString("uid"));
            }
            break;

            //唤醒事件
            case AIUIConstant.EVENT_WAKEUP: {

                break;
            }
            //休眠事件
            case AIUIConstant.EVENT_SLEEP: {
                break;
            }
            // 状态事件
            case AIUIConstant.EVENT_STATE: {
                mCurrentState = event.arg1;
                if (AIUIConstant.STATE_IDLE == mCurrentState) {
                    // 闲置状态,AIUI未开启
                    Log.e(TAG, "onEvent: 闲置");
                } else if (AIUIConstant.STATE_READY == mCurrentState) {
                    // AIUI已就绪,等待唤醒
                    Log.e(TAG, "onEvent: 等待唤醒");
                } else if (AIUIConstant.STATE_WORKING == mCurrentState) {
                    // AIUI工作中,可进行交互
                    Log.e(TAG, "onEvent: 可交互");
                }
            }
            break;
//            VAD事件
//            当检测到输入音频的前端点后,会抛出该事件,用arg1标识前后端点或者音量信息:0(前端点)、1(音量)、2(后端点)、3(前端点超时)。
//            当arg1取值为1时,arg2为音量大小。
            case AIUIConstant.EVENT_VAD:
//                Log.e(TAG, "onEvent: VAD");
                break;
            //错误事件
            case AIUIConstant.EVENT_ERROR: {
                Log.e(TAG, "onEvent: 错误");
                int errorCode = event.arg1;
//                if (errorCode == 20006) {
//                    mAudioRecording = false;
//                }
                break;
            }

            case AIUIConstant.EVENT_START_RECORD: {
                hasSpeak = false;
                msgAction.removeCallbacks(checkForNotSpeak);
                msgAction.postDelayed(checkForNotSpeak, AIUIConfiguration.TIME_CHECK_FIRST_NOT_SPEAK);
                Log.i(TAG, "on event: " + event.eventType);
                //开始录音
                Log.e(TAG, "onEvent: 开始录音");
            }
            break;

            case AIUIConstant.EVENT_STOP_RECORD: {
                msgAction.removeCallbacks(checkForNotSpeak);
                Log.i(TAG, "on event: " + event.eventType);
                // 停止录音
                Log.e(TAG, "onEvent: 停止录音");
            }
            break;
            //结果事件(包含听写,语义,离线语法结果)
            case AIUIConstant.EVENT_RESULT: {
                msgAction.removeCallbacks(checkForNotSpeak);
                //结果解析事件
                RawMessage rawMessage = voiceMsgParser.processResult(event);
                if (rawMessage == null) {
                    hasSpeak = false;
                } else {
                    hasSpeak = true;
                    //来自aiui的回应
                    //判断是否是用户刚说完的话,如果是,需要让云端解析
                    if (rawMessage.isFromUser()) {
                        msgAction.postDelayed(checkForNotSpeak, AIUIConfiguration.TIME_CHECK_NOT_SPEAK);
                    } else {
                        if (voiceMsgParser.isHasUserCache()) {
                            //从服务器获取响应,清空用户语音输入的临时数据
                            voiceMsgParser.resetAppendVoiceMsg();
                            if (!TextUtils.isEmpty(voiceMsgParser.getUserSpeakContent())) {
                                sendWriteMessage(voiceMsgParser.getUserSpeakContent());
                            }
                        } else {
                            //最终云端的结果
                        }
                    }

                }
            }
            break;
        }
    }


    /**
     * 发送AIUI消息
     *
     * @param message
     */
    public void sendMessage(AIUIMessage message) {
        if (aiuiAgent != null) {
            //确保AIUI处于唤醒状态
            if (mCurrentState != AIUIConstant.STATE_WORKING) {
                aiuiAgent.sendMessage(new AIUIMessage(AIUIConstant.CMD_WAKEUP, 0, 0, "", null));
            }

            aiuiAgent.sendMessage(message);
        }
    }

    public void sendWriteMessage(String msg) {
        if (TextUtils.isEmpty(msg)) {
            return;
        }
        sendMessage(new AIUIMessage(AIUIConstant.CMD_WRITE, 0, 0,
                AIUIConfiguration.CONFIG_WRITE_PARAMS, msg.getBytes()));
    }

    /**
     * 开始录音
     */
    public void startRecordAudio() {
        voiceMsgParser.resetAppendVoiceMsg();
        if (!mAudioRecording) {
            String params = AIUIConfiguration.CONFIG_START_RECORD_AND_PROGRESSIVE_PARAMS;
            sendMessage(new AIUIMessage(AIUIConstant.CMD_START_RECORD, 0, 0, params, null));
            mAudioRecording = true;
        }
    }
    /**
     * 停止说话
     */
    /**
     * 停止录音
     */
    public void stopRecordAudio() {
        if (mAudioRecording) {
            sendMessage(new AIUIMessage(AIUIConstant.CMD_STOP_RECORD, 0, 0, AIUIConfiguration.CONFIG_STOP_RECORD_PARAMS, null));
            mAudioRecording = false;
        }
    }

    public void setVoiceIdentifyResultListener(OnVoiceIdentifyResultListener onVoiceIdentifyResultListener) {
        this.onVoiceIdentifyResultListener = onVoiceIdentifyResultListener;
        voiceMsgParser.setOnVoiceIdentifyResultListener(onVoiceIdentifyResultListener);
    }

    /**
     * 检查是否没有说话
     */
    private final class CheckForNotSpeak implements Runnable {
        @Override
        public void run() {
            Log.e(TAG, "run: 长时间没有响应");
            stopRecordAudio();
            if (!hasSpeak) {
                Log.e(TAG, "run: 啥也没说");
                if (onVoiceIdentifyResultListener != null) {
                    onVoiceIdentifyResultListener.onResult(false, null);
                }
            }
        }
    }
}