From 6e0e117e0ee16d8e376b65381dffb1d95c23ed75 Mon Sep 17 00:00:00 2001 From: chenfufeng Date: Fri, 21 Oct 2022 11:18:51 +0800 Subject: [PATCH] =?UTF-8?q?[Feat]TTS=E6=94=AF=E6=8C=81=E6=8C=89=E4=BC=98?= =?UTF-8?q?=E5=85=88=E7=BA=A7=E6=8E=92=E9=98=9F=E5=92=8C=E6=89=93=E6=96=AD?= =?UTF-8?q?=E6=9C=BA=E5=88=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/mogo/commons/voice/AIAssist.java | 11 +++ .../main/java/com/mogo/tts/base/IMogoTTS.java | 2 + .../main/java/com/mogo/tts/pad/PadTTS.java | 90 ++++++++++++++++++- 3 files changed, 101 insertions(+), 2 deletions(-) diff --git a/foudations/mogo-commons/src/main/java/com/mogo/commons/voice/AIAssist.java b/foudations/mogo-commons/src/main/java/com/mogo/commons/voice/AIAssist.java index 2ccb0e63da..90866ce120 100644 --- a/foudations/mogo-commons/src/main/java/com/mogo/commons/voice/AIAssist.java +++ b/foudations/mogo-commons/src/main/java/com/mogo/commons/voice/AIAssist.java @@ -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); + } + } + /** * 语音播报 * diff --git a/tts/tts-base/src/main/java/com/mogo/tts/base/IMogoTTS.java b/tts/tts-base/src/main/java/com/mogo/tts/base/IMogoTTS.java index 51b49b3377..bb0da53d07 100644 --- a/tts/tts-base/src/main/java/com/mogo/tts/base/IMogoTTS.java +++ b/tts/tts-base/src/main/java/com/mogo/tts/base/IMogoTTS.java @@ -39,6 +39,8 @@ interface IMogoTTS extends IProvider { */ void speakTTSVoice( String tts ); + void speakTTSVoiceWithLevel( String tts, int level); + /** * 播放 tts 语音 * diff --git a/tts/tts-pad/src/main/java/com/mogo/tts/pad/PadTTS.java b/tts/tts-pad/src/main/java/com/mogo/tts/pad/PadTTS.java index fd253070e1..a2530a1286 100644 --- a/tts/tts-pad/src/main/java/com/mogo/tts/pad/PadTTS.java +++ b/tts/tts-pad/src/main/java/com/mogo/tts/pad/PadTTS.java @@ -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> 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 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 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;