[Feat]TTS支持按优先级排队和打断机制
This commit is contained in:
@@ -90,6 +90,17 @@ public class AIAssist {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 等级由低到高为0、1、2、3,分别对应p3、p2、p1、p0
|
||||
* @param text
|
||||
* @param level
|
||||
*/
|
||||
public void speakTTSVoiceWithLevel(String text, int level) {
|
||||
if (mTTS != null) {
|
||||
mTTS.speakTTSVoiceWithLevel(text, level);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 语音播报
|
||||
*
|
||||
|
||||
@@ -39,6 +39,8 @@ interface IMogoTTS extends IProvider {
|
||||
*/
|
||||
void speakTTSVoice( String tts );
|
||||
|
||||
void speakTTSVoiceWithLevel( String tts, int level);
|
||||
|
||||
/**
|
||||
* 播放 tts 语音
|
||||
*
|
||||
|
||||
@@ -8,6 +8,9 @@ import android.os.Build;
|
||||
import android.os.Environment;
|
||||
import android.provider.Settings;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Pair;
|
||||
|
||||
import androidx.annotation.MainThread;
|
||||
|
||||
import com.aispeech.AIError;
|
||||
import com.aispeech.DUILiteConfig;
|
||||
@@ -20,8 +23,6 @@ import com.aispeech.export.engines.AILocalTTSEngine;
|
||||
import com.aispeech.export.intent.AILocalTTSIntent;
|
||||
import com.aispeech.export.listeners.AITTSListener;
|
||||
import com.aispeech.lite.AuthType;
|
||||
import com.alibaba.android.arouter.facade.annotation.Route;
|
||||
import com.mogo.cloud.commons.BuildConfig;
|
||||
import com.mogo.cloud.passport.MoGoAiCloudClientConfig;
|
||||
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger;
|
||||
import com.mogo.eagle.core.utilcode.util.ThreadUtils;
|
||||
@@ -39,6 +40,7 @@ import com.zhidao.voicesdk.callback.OnTtsListener;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
@@ -59,6 +61,10 @@ public class PadTTS implements IMogoTTS, VoiceClient.VoiceCmdCallBack, OnTtsList
|
||||
private boolean mInitReady = true;
|
||||
private Context mContext;
|
||||
|
||||
// 等级由低到高为0、1、2、3,默认为-1表示没有正在tts的
|
||||
private int curTtsLevel = -1;
|
||||
private LinkedList<Pair<String, Integer>> linkedList = new LinkedList<>();
|
||||
|
||||
public void release() {
|
||||
CallerLogger.INSTANCE.d(TAG, "release");
|
||||
ThreadUtils.runOnUiThread(() -> {
|
||||
@@ -73,6 +79,7 @@ public class PadTTS implements IMogoTTS, VoiceClient.VoiceCmdCallBack, OnTtsList
|
||||
}
|
||||
mQAndAMap.clear();
|
||||
mVoiceClient.release();
|
||||
curTtsLevel = -1;
|
||||
if (mEngine != null) {
|
||||
mEngine.destroy();
|
||||
mEngine = null;
|
||||
@@ -344,12 +351,15 @@ public class PadTTS implements IMogoTTS, VoiceClient.VoiceCmdCallBack, OnTtsList
|
||||
if (mSpeakVoiceMap.containsKey(text)) {
|
||||
mSpeakVoiceMap.remove(text);
|
||||
}
|
||||
curTtsLevel = -1;
|
||||
mEngine.stop();
|
||||
}
|
||||
}
|
||||
|
||||
public void stopTts() {
|
||||
if (mEngine != null && mHasAuth) {
|
||||
// tts过程中调用stop不会有回调事件
|
||||
curTtsLevel = -1;
|
||||
mEngine.stop();
|
||||
}
|
||||
}
|
||||
@@ -367,6 +377,67 @@ public class PadTTS implements IMogoTTS, VoiceClient.VoiceCmdCallBack, OnTtsList
|
||||
}
|
||||
}
|
||||
|
||||
@MainThread
|
||||
public void speakTTSVoiceWithLevel(String text, int ttsLevel) {
|
||||
if (mEngine != null) {
|
||||
if (ttsLevel == curTtsLevel) {
|
||||
// 对应p3、p2级别的排队
|
||||
if (ttsLevel == 0 || ttsLevel == 1) {
|
||||
CallerLogger.INSTANCE.d(TAG, "===================");
|
||||
CallerLogger.INSTANCE.d(TAG, "插入消息:" + text + ",level为:" + ttsLevel);
|
||||
insertTts(text, ttsLevel);
|
||||
return;
|
||||
} else {
|
||||
// 打断并合成新的
|
||||
stopTts();
|
||||
CallerLogger.INSTANCE.d(TAG, "非Level1同级别打断!");
|
||||
}
|
||||
} else {
|
||||
// 将要TTS的比现在正在TTS的优先级高
|
||||
if (ttsLevel > curTtsLevel) {
|
||||
if (curTtsLevel >= 0) {
|
||||
// 打断并合成高优先级的
|
||||
stopTts();
|
||||
}
|
||||
CallerLogger.INSTANCE.d(TAG, "高优先级打断低级别的!");
|
||||
} else {
|
||||
if (ttsLevel == 0 || ttsLevel == 1) {
|
||||
CallerLogger.INSTANCE.d(TAG, "===================");
|
||||
CallerLogger.INSTANCE.d(TAG, "插入消息:" + text + ",level为:" + ttsLevel);
|
||||
insertTts(text, ttsLevel);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
curTtsLevel = ttsLevel;
|
||||
// 合成并播放
|
||||
CallerLogger.INSTANCE.d(TAG, "tts准备合成:" + text + ",curTtsLevel为:" + curTtsLevel);
|
||||
mEngine.speak(text, text, mAILocalTTSIntent);
|
||||
}
|
||||
}
|
||||
|
||||
// 降序插入Tts(目前Level0、1可排队)
|
||||
private void insertTts(String text, int level) {
|
||||
int index = -1;
|
||||
for (int i = linkedList.size() - 1; i >= 0; i--) {
|
||||
int nodeLevel = linkedList.get(i).second;
|
||||
// 只有高优先级才插入到前面,等于的情况下是插到后面
|
||||
if (level > nodeLevel) {
|
||||
index = i;
|
||||
}
|
||||
}
|
||||
if (index >= 0) {
|
||||
linkedList.add(index, new Pair(text, level));
|
||||
} else {
|
||||
linkedList.addLast(new Pair(text, level));
|
||||
}
|
||||
for (Pair<String, Integer> ttsPair:
|
||||
linkedList) {
|
||||
CallerLogger.INSTANCE.d(TAG, "tts文本为:" + ttsPair.first + ",level为:" + ttsPair.second);
|
||||
}
|
||||
CallerLogger.INSTANCE.d(TAG, "===================");
|
||||
}
|
||||
|
||||
/**
|
||||
* 语音播报
|
||||
*
|
||||
@@ -669,6 +740,7 @@ public class PadTTS implements IMogoTTS, VoiceClient.VoiceCmdCallBack, OnTtsList
|
||||
@Override
|
||||
public void onError(String utteranceId, AIError aiError) {
|
||||
CallerLogger.INSTANCE.d(TAG, "检测到错误:" + aiError.toString());
|
||||
curTtsLevel = -1;
|
||||
IMogoTTSCallback callBack = PadTTS.this.mSpeakVoiceMap.remove(utteranceId);
|
||||
if (callBack != null) {
|
||||
callBack.onSpeakError(utteranceId, aiError.getError());
|
||||
@@ -682,7 +754,9 @@ public class PadTTS implements IMogoTTS, VoiceClient.VoiceCmdCallBack, OnTtsList
|
||||
|
||||
@Override
|
||||
public void onCompletion(String utteranceId) {
|
||||
curTtsLevel = -1;
|
||||
CallerLogger.INSTANCE.d(TAG, "播放完成");
|
||||
ttsNext();
|
||||
IMogoTTSCallback callBack = PadTTS.this.mSpeakVoiceMap.remove(utteranceId);
|
||||
if (callBack != null) {
|
||||
callBack.onSpeakEnd(utteranceId);
|
||||
@@ -711,6 +785,18 @@ public class PadTTS implements IMogoTTS, VoiceClient.VoiceCmdCallBack, OnTtsList
|
||||
}
|
||||
}
|
||||
|
||||
@MainThread
|
||||
private void ttsNext() {
|
||||
if (!linkedList.isEmpty()) {
|
||||
Pair<String, Integer> ttsPair = linkedList.removeFirst();
|
||||
CallerLogger.INSTANCE.i(TAG, "排队播放的下一条文本为:" + ttsPair.first + ",级别为:" + ttsPair.second);
|
||||
curTtsLevel = ttsPair.second;
|
||||
speakTTSVoice(ttsPair.first);
|
||||
} else {
|
||||
CallerLogger.INSTANCE.i(TAG, "队列为空");
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isProcessRunning(Context context, int uid) {
|
||||
if (context == null) {
|
||||
return false;
|
||||
|
||||
Reference in New Issue
Block a user