DefaultVoiceMsgParser.java 7.55 KB
package com.ys.yslibrary.paraser;

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

import com.iflytek.aiui.AIUIEvent;
import com.ys.yslibrary.callback.OnVoiceIdentifyResultListener;
import com.ys.yslibrary.bean.RawMessage;

import org.json.JSONArray;
import org.json.JSONObject;

import java.nio.ByteBuffer;
import java.util.LinkedList;
import java.util.List;

import static com.ys.yslibrary.bean.RawMessage.FromType.AIUI;
import static com.ys.yslibrary.bean.RawMessage.FromType.USER;
import static com.ys.yslibrary.bean.RawMessage.MsgType.TEXT;
import static com.ys.yslibrary.bean.RawMessage.MsgType.Voice;

public class DefaultVoiceMsgParser implements AbsVoiceMsgParser {
    private final String TAG = getClass().getName();
    private OnVoiceIdentifyResultListener onVoiceIdentifyResultListener;
    //处理PGS听写(流式听写)的数组
    private String[] mIATPGSStack = new String[256];
    private List<String> mInterResultStack = new LinkedList<>();
    private DefaultVoiceMsgParser voiceMsgParser;
    //当前未结束的语音交互消息,更新语音消息的听写内容时使用
    private RawMessage mAppendVoiceMsg = null;

    /**
     * 重置流式识别的信息
     */
    @Override
    public void resetAppendVoiceMsg() {
        mAppendVoiceMsg = new RawMessage(USER, Voice, null);
        mAppendVoiceMsg.cacheContent = "";
        //语音消息msgData为录音时长
        mAppendVoiceMsg.msgData = ByteBuffer.allocate(4).putFloat(0).array();
        mInterResultStack.clear();
    }

    @Override
    public boolean isHasUserCache() {
        return (mAppendVoiceMsg != null && !TextUtils.isEmpty(mAppendVoiceMsg.cacheContent));
    }

    /**
     * 处理AIUI结果事件(听写结果和语义结果)
     *
     * @param event 结果事件
     */
    @Override
    public RawMessage processResult(AIUIEvent event) {
        RawMessage rawMessage = null;
        try {
            JSONObject bizParamJson = new JSONObject(event.info);
            JSONObject data = bizParamJson.getJSONArray("data").getJSONObject(0);
            JSONObject params = data.getJSONObject("params");
            JSONObject content = data.getJSONArray("content").getJSONObject(0);

            long rspTime = event.data.getLong("eos_rslt", -1);  //响应时间
            String sub = params.optString("sub");
            if (content.has("cnt_id") && !sub.equals("tts")) {
                String cnt_id = content.getString("cnt_id");
                JSONObject cntJson = new JSONObject(new String(event.data.getByteArray(cnt_id), "utf-8"));
                //听写结束语义结果
                if ("nlp".equals(sub)) {
                    JSONObject semanticResult = cntJson.optJSONObject("intent");
                    if (semanticResult != null && semanticResult.length() != 0) {
                        //解析得到语义结果,将语义结果作为消息插入到消息列表中
                        rawMessage = new RawMessage(AIUI, TEXT,
                                semanticResult.toString().getBytes(), null, rspTime);
//                        addChatMessage(rawMessage);
                        Log.e(TAG, "processResult: " + rawMessage);
                        if (onVoiceIdentifyResultListener != null) {
                            onVoiceIdentifyResultListener.onResult(false, rawMessage);
                        }
                    }
                    return rawMessage;
                }
                //流式响应数据
                else if ("iat".equals(sub)) {
                    return processIATResult(cntJson);
                }
            }
        } catch (Exception e) {
        }
        return rawMessage;
    }


    /**
     * 解析听写结果更新当前语音消息的听写内容
     */
    @Override
    public RawMessage processIATResult(JSONObject cntJson) {
        RawMessage rawMessage = null;
        if (mAppendVoiceMsg == null) return rawMessage;
        try {
            JSONObject text = cntJson.optJSONObject("text");
            // 解析拼接此次听写结果
            StringBuilder iatText = new StringBuilder();
            JSONArray words = text.optJSONArray("ws");
            boolean lastResult = text.optBoolean("ls");
            for (int index = 0; index < words.length(); index++) {
                JSONArray charWord = words.optJSONObject(index).optJSONArray("cw");
                for (int cIndex = 0; cIndex < charWord.length(); cIndex++) {
                    iatText.append(charWord.optJSONObject(cIndex).opt("w"));
                }
            }

            String voiceIAT = "";
            String pgsMode = text.optString("pgs");
            //非PGS模式结果
            if (TextUtils.isEmpty(pgsMode)) {
                if (TextUtils.isEmpty(iatText)) return rawMessage;

                //和上一次结果进行拼接
                if (!TextUtils.isEmpty(mAppendVoiceMsg.cacheContent)) {
                    voiceIAT = mAppendVoiceMsg.cacheContent;//+ "\n";
                }
                voiceIAT += iatText;
            } else {
                int serialNumber = text.optInt("sn");
                mIATPGSStack[serialNumber] = iatText.toString();
                //pgs结果两种模式rpl和apd模式(替换和追加模式)
                if ("rpl".equals(pgsMode)) {
                    //根据replace指定的range,清空stack中对应位置值
                    JSONArray replaceRange = text.optJSONArray("rg");
                    int start = replaceRange.getInt(0);
                    int end = replaceRange.getInt(1);

                    for (int index = start; index <= end; index++) {
                        mIATPGSStack[index] = null;
                    }
                }

                StringBuilder PGSResult = new StringBuilder();
                //汇总stack经过操作后的剩余的有效结果信息
                for (int index = 0; index < mIATPGSStack.length; index++) {
                    if (TextUtils.isEmpty(mIATPGSStack[index])) continue;

//                if(!TextUtils.isEmpty(PGSResult.toString())) PGSResult.append("\n");
                    PGSResult.append(mIATPGSStack[index]);
                    //如果是最后一条听写结果,则清空stack便于下次使用
                    if (lastResult) {
                        mIATPGSStack[index] = null;
                    }
                }
                voiceIAT = join(mInterResultStack) + PGSResult.toString();

                if (lastResult) {
                    mInterResultStack.add(PGSResult.toString());
                }
            }

            if (!TextUtils.isEmpty(voiceIAT)) {
                mAppendVoiceMsg.cacheContent = voiceIAT;
                if (onVoiceIdentifyResultListener != null) {
                    onVoiceIdentifyResultListener.onResult(true, mAppendVoiceMsg);
                }
                Log.e(TAG, "processIATResult: 流式结果" + mAppendVoiceMsg);
                return mAppendVoiceMsg;
            }
        } catch (Exception e) {
        }
        return rawMessage;
    }

    @Override
    public String getUserSpeakContent() {
        if (mAppendVoiceMsg == null) {
            return "";
        }
        return mAppendVoiceMsg.cacheContent;
    }

    private String join(List<String> data) {
        StringBuilder builder = new StringBuilder();
        for (int index = 0; index < data.size(); index++) {
            builder.append(data.get(index));
        }

        return builder.toString();
    }

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