diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro index 5da3d57d2c..2dd53bbe9e 100644 --- a/app/proguard-rules.pro +++ b/app/proguard-rules.pro @@ -426,6 +426,6 @@ -keep class com.squareup.haha.guava.collect.*{*;} -keep class **.zego.**{*;} - - +#-----科大讯飞语音合成----- +-keep class com.iflytek.**{*;} diff --git a/config.gradle b/config.gradle index d71b4c64df..2d4c6d6ddc 100644 --- a/config.gradle +++ b/config.gradle @@ -142,6 +142,7 @@ ext { ttszhi : "com.mogo.tts:tts-zhi:${TTS_ZHI_VERSION}", ttspad : "com.mogo.tts:tts-pad:${TTS_ZHI_VERSION}", ttsnoop : "com.mogo.tts:tts-noop:${TTS_NOOP_VERSION}", + ttsiflytek : "com.mogo.tts:tts-iflytek :${TTS_IFLYTEK_VERSION}", //========================= 网约车 Maven 版本管理 ========================= mogooch : "com.mogo.och:och:${MOGO_OCH_VERSION}", 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 e8d509617b..39ed751afa 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 @@ -6,6 +6,7 @@ import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger; import com.mogo.eagle.core.utilcode.util.ToastUtils; import com.mogo.tts.base.IMogoTTS; import com.mogo.tts.base.IMogoTTSCallback; +import com.mogo.tts.base.MultiLangTtsEntity; import com.mogo.tts.base.PreemptType; /** @@ -52,7 +53,9 @@ public class AIAssist { private AIAssist(Context context) { try { // 暂时换成反射,解决死锁问题 + // TODO:("支持切换思必驰和科大讯飞") Class clazz = Class.forName("com.mogo.tts.pad.PadTTS"); +// Class clazz = Class.forName("com.mogo.tts.iflytek.IFlyTekTts"); mTTS = (IMogoTTS) clazz.getConstructor().newInstance(); mTTS.init(context); // mTTS = (IMogoTTS) ARouter.getInstance().build(MogoTTSConstants.API_PATH).navigation(context.getApplicationContext()); @@ -122,6 +125,18 @@ public class AIAssist { } } + /** + * 支持多语言的Tts + * @param ttsEntity: 多语言Entity + * @param level: 等级由低到高为0、1、2、3,分别对应p3、p2、p1、p0 + * @param callback + */ + public void speakMultiLangTTSWithLevel(MultiLangTtsEntity ttsEntity, int level, IMogoTTSCallback callback) { + if (mTTS != null) { + mTTS.speakMultiLangTTSWithLevel(ttsEntity, level, callback); + } + } + /** * 语音播报 * diff --git a/gradle.properties b/gradle.properties index 76086a15f4..621da04292 100644 --- a/gradle.properties +++ b/gradle.properties @@ -123,6 +123,7 @@ TTS_DI_VERSION=2.1.16.10 TTS_ZHI_VERSION=2.1.16.10 TTS_PAD_VERSION=2.1.16.10 TTS_NOOP_VERSION=2.1.16.10 +TTS_IFLYTEK_VERSION=2.1.16.10 # 自研地图 MAP_CUSTOM_VERSION=2.1.16.10 diff --git a/settings.gradle b/settings.gradle index b04aa2b3f4..253517d62f 100644 --- a/settings.gradle +++ b/settings.gradle @@ -50,6 +50,7 @@ include ':libraries:mogo-obu' // 语音 include ':tts:tts-base' include ':tts:tts-pad' +include ':tts:tts-iflytek' // 测试DEBUG include ':test:crashreport' 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 c6940c17a7..03334594db 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 @@ -64,6 +64,12 @@ interface IMogoTTS extends IProvider { */ void speakTTSVoice( String tts, PreemptType type, IMogoTTSCallback callback ); + void speakMultiLangTTSWithLevel( + MultiLangTtsEntity ttsEntity, + int level, + IMogoTTSCallback callback + ); + void stopSpeakTts(String text); void stopTts(); diff --git a/tts/tts-base/src/main/java/com/mogo/tts/base/LanguageType.kt b/tts/tts-base/src/main/java/com/mogo/tts/base/LanguageType.kt new file mode 100644 index 0000000000..887dadc17e --- /dev/null +++ b/tts/tts-base/src/main/java/com/mogo/tts/base/LanguageType.kt @@ -0,0 +1,7 @@ +package com.mogo.tts.base + +enum class LanguageType(val langName: String) { + CHINESE("chinese"), + ENGLISH("english"), + KOREAN("korean") +} \ No newline at end of file diff --git a/tts/tts-base/src/main/java/com/mogo/tts/base/MultiLangTtsEntity.kt b/tts/tts-base/src/main/java/com/mogo/tts/base/MultiLangTtsEntity.kt new file mode 100644 index 0000000000..eec6615703 --- /dev/null +++ b/tts/tts-base/src/main/java/com/mogo/tts/base/MultiLangTtsEntity.kt @@ -0,0 +1,42 @@ +package com.mogo.tts.base + +data class MultiLangTtsEntity( + private var ttsList: List +) { + private val stringBuffer by lazy { + StringBuffer() + } + + private var ttsIndex = 0 + + fun ttsNext(): LangTtsEntity? { + return if (ttsIndex in ttsList.indices) { + ttsList[ttsIndex++] + } else { + null + } + } + + override fun toString(): String { + return stringBuffer.let { + it.setLength(0) + ttsList.forEachIndexed { index, langTtsEntity -> + if (index != ttsList.size - 1) { + it.append("${langTtsEntity};") + } else { + it.append(langTtsEntity) + } + } + it.toString() + } + } +} + +data class LangTtsEntity( + var ttsContent: String, + var language: LanguageType +) { + override fun toString(): String { + return "ttsContent is:$ttsContent,language is:${language.langName}" + } +} \ No newline at end of file diff --git a/tts/tts-iflytek/.gitignore b/tts/tts-iflytek/.gitignore new file mode 100644 index 0000000000..42afabfd2a --- /dev/null +++ b/tts/tts-iflytek/.gitignore @@ -0,0 +1 @@ +/build \ No newline at end of file diff --git a/tts/tts-iflytek/build.gradle b/tts/tts-iflytek/build.gradle new file mode 100644 index 0000000000..5b3aae988a --- /dev/null +++ b/tts/tts-iflytek/build.gradle @@ -0,0 +1,62 @@ +plugins { + id 'com.android.library' + id 'kotlin-android' + id 'kotlin-android-extensions' + id 'kotlin-kapt' + id 'com.alibaba.arouter' +} + +android { + compileSdkVersion rootProject.ext.android.compileSdkVersion + // buildToolsVersion rootProject.ext.android.buildToolsVersion + defaultConfig { + minSdkVersion rootProject.ext.android.minSdkVersion + targetSdkVersion rootProject.ext.android.targetSdkVersion + versionCode Integer.valueOf(VERSION_CODE) + versionName getValueFromRootProperties("${project.name.replace("-", "_").toUpperCase()}_VERSION") + + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + consumerProguardFiles "consumer-rules.pro" + + //ARouter apt 参数 + kapt { + useBuildCache = false + arguments { + arg("AROUTER_MODULE_NAME", project.getName()) + } + } + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } +} + +dependencies { + implementation fileTree(dir: "libs", include: ["*.jar"]) + implementation rootProject.ext.dependencies.androidxappcompat + + implementation rootProject.ext.dependencies.arouter + kapt rootProject.ext.dependencies.aroutercompiler + + api rootProject.ext.dependencies.aiassist + api rootProject.ext.dependencies.aiassistReplace + + if (Boolean.valueOf(USE_MAVEN_PACKAGE)) { + implementation rootProject.ext.dependencies.ttsbase + implementation rootProject.ext.dependencies.mogo_core_utils + } else { + implementation project(":tts:tts-base") + implementation project(':core:mogo-core-utils') + } +} + +apply from: new File(rootProject.rootDir, "gradle/upload.gradle").toString() \ No newline at end of file diff --git a/tts/tts-iflytek/consumer-rules.pro b/tts/tts-iflytek/consumer-rules.pro new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tts/tts-iflytek/gradle.properties b/tts/tts-iflytek/gradle.properties new file mode 100644 index 0000000000..42e1ef3b19 --- /dev/null +++ b/tts/tts-iflytek/gradle.properties @@ -0,0 +1,3 @@ +GROUP=com.mogo.tts +POM_ARTIFACT_ID=tts-iflytek +VERSION_CODE=1 diff --git a/tts/tts-iflytek/libs/Msc.jar b/tts/tts-iflytek/libs/Msc.jar new file mode 100644 index 0000000000..fe502fb3e5 Binary files /dev/null and b/tts/tts-iflytek/libs/Msc.jar differ diff --git a/tts/tts-iflytek/proguard-rules.pro b/tts/tts-iflytek/proguard-rules.pro new file mode 100644 index 0000000000..481bb43481 --- /dev/null +++ b/tts/tts-iflytek/proguard-rules.pro @@ -0,0 +1,21 @@ +# Add project specific ProGuard rules here. +# You can control the set of applied configuration files using the +# proguardFiles setting in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} + +# Uncomment this to preserve the line number information for +# debugging stack traces. +#-keepattributes SourceFile,LineNumberTable + +# If you keep the line number information, uncomment this to +# hide the original source file name. +#-renamesourcefileattribute SourceFile \ No newline at end of file diff --git a/tts/tts-iflytek/src/main/AndroidManifest.xml b/tts/tts-iflytek/src/main/AndroidManifest.xml new file mode 100644 index 0000000000..098e30a5d9 --- /dev/null +++ b/tts/tts-iflytek/src/main/AndroidManifest.xml @@ -0,0 +1,4 @@ + + + \ No newline at end of file diff --git a/tts/tts-iflytek/src/main/java/com/mogo/tts/iflytek/IFlyTekTts.kt b/tts/tts-iflytek/src/main/java/com/mogo/tts/iflytek/IFlyTekTts.kt new file mode 100644 index 0000000000..56f891b3c1 --- /dev/null +++ b/tts/tts-iflytek/src/main/java/com/mogo/tts/iflytek/IFlyTekTts.kt @@ -0,0 +1,375 @@ +package com.mogo.tts.iflytek + +import android.content.Context +import android.os.Bundle +import android.os.Looper +import android.util.Pair +import androidx.annotation.Keep +import com.iflytek.cloud.* +import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger +import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger.d +import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger.i +import com.mogo.eagle.core.utilcode.util.UiThreadHandler +import com.mogo.tts.base.* +import java.util.* + +@Keep +class IFlyTekTts : IMogoTTS, InitListener { + companion object { + const val TAG = "IFlyTekTts" + } + + private var context: Context? = null + + private var ttsEngine: SpeechSynthesizer? = null + private var engineType = SpeechConstant.TYPE_CLOUD + + private var voicer: String = "xiaoyan" + private var voicerEntries: Array? = null + + // 等级由低到高为0、1、2、3,默认为-1表示没有正在tts的 + private var curTtsLevel = -1 + + // 由于主动打断不会有回调事件,所以主动打断时清掉map中被打断的text和callback + private var curTtsContent = "" + private var curTtsEntity: MultiLangTtsEntity? = null + private val linkedList = LinkedList>() + + // 上一次语音合成的语言 + private var lastLang = LanguageType.CHINESE + + private val speakVoiceMap by lazy { + HashMap() + } + + override fun init(context: Context) { + this.context = context + + // 应用程序入口处调用,避免手机内存过小,杀死后台进程后通过历史intent进入Activity造成SpeechUtility对象为null + // 如在Application中调用初始化,需要在Mainifest中注册该Applicaiton + // 注意:此接口在非主进程调用会返回null对象,如需在非主进程使用语音功能,请增加参数:SpeechConstant.FORCE_LOGIN+"=true" + // 参数间使用半角“,”分隔。 + // 设置你申请的应用appid,请勿在'='与appid之间添加空格及空转义符 + // 注意: appid 必须和下载的SDK保持一致,否则会出现10407错误 + SpeechUtility.createUtility(context, "appid=0c498b42") + ttsEngine = SpeechSynthesizer.createSynthesizer(context, this) + voicerEntries = context.resources?.getStringArray(R.array.voicer_cloud_values) + } + + override fun initTts(sn: String?) {} + + override fun onInit(code: Int) { + if (code != ErrorCode.SUCCESS) { + CallerLogger.e( + TAG, + "初始化失败,错误码为:$code,请点击网址https://www.xfyun.cn/document/error-code查询解决方案" + ) + } + } + + override fun release() { + ttsEngine?.stopSpeaking() + ttsEngine?.destroy() + } + + override fun flush() { + } + + override fun speakTTSVoice(tts: String?) { + + } + + override fun speakTTSVoice(tts: String?, callback: IMogoTTSCallback?) { + } + + override fun speakTTSVoice(tts: String?, type: PreemptType?, callback: IMogoTTSCallback?) { + } + + override fun speakTTSVoiceWithLevel(tts: String?, level: Int) { + } + + override fun speakTTSVoiceWithLevel(tts: String?, level: Int, callBack: IMogoTTSCallback?) { + } + + override fun speakMultiLangTTSWithLevel( + ttsEntity: MultiLangTtsEntity, + level: Int, + callBack: IMogoTTSCallback? + ) { + if (callBack != null) { + speakVoiceMap[ttsEntity.toString()] = callBack + } + speakMultiLangTTSWithLevel(ttsEntity, level) + } + + override fun stopSpeakTts(text: String?) { + stopTts() + } + + override fun stopTts() { + curTtsEntity?.let { + val string = it.toString() + if (speakVoiceMap.containsKey(string)) { + speakVoiceMap.remove(string) + } + curTtsEntity = null + } + curTtsContent = "" + curTtsLevel = -1 + ttsEngine?.stopSpeaking() + } + + override fun speakQAndACmd(tts: String?, callback: IMogoTTSCallback?) { + } + + override fun speakQAndACmd( + tts: String?, + okWords: Array?, + cancelWords: Array?, + callback: IMogoTTSCallback? + ) { + } + + override fun registerUnWakeupCommand( + cmd: String?, + cmdWords: Array?, + callback: IMogoTTSCallback? + ) { + } + + override fun unregisterUnWakeupCommand(cmd: String?) { + } + + override fun unregisterUnWakeupCommand(cmd: String?, callback: IMogoTTSCallback?) { + } + + override fun startAIAssist(context: Context?) { + } + + override fun startAIAssist(context: Context?, status: Int) { + } + + override fun breakOffSpeak() { + } + + // 降序插入Tts(目前Level0、1可排队) + private fun insertTts(ttsEntity: MultiLangTtsEntity, level: Int) { + var index = -1 + for (i in linkedList.indices.reversed()) { + val nodeLevel = linkedList[i].second + // 只有高优先级才插入到前面,等于的情况下是插到后面 + if (level > nodeLevel) { + index = i + } + } + if (index >= 0) { + linkedList.add(index, Pair(ttsEntity, level)) + } else { + linkedList.addLast(Pair(ttsEntity, level)) + } + for (ttsPair in linkedList) { + d(TAG, "tts文本为:" + ttsPair.first + ",level为:" + ttsPair.second) + } + d(TAG, "===================") + } + + private fun speakMultiLangTTSWithLevel(ttsEntity: MultiLangTtsEntity, ttsLevel: Int) { + ttsEngine?.let { + if (ttsLevel == curTtsLevel) { + // 对应p3、p2级别的排队 + if (ttsLevel == 0 || ttsLevel == 1) { + d(TAG, "===================") + d(TAG, "插入消息:$ttsEntity,level为:$ttsLevel") + insertTts(ttsEntity, ttsLevel) + return + } else { + // 打断并合成新的 + stopTts() + d(TAG, "非Level1同级别打断!") + } + } else { + // 将要TTS的比现在正在TTS的优先级高 + if (ttsLevel > curTtsLevel) { + if (curTtsLevel >= 0) { + // 打断并合成高优先级的 + stopTts() + } + d(TAG, "高优先级打断低级别的!") + } else { + if (ttsLevel == 0 || ttsLevel == 1) { + d(TAG, "===================") + d(TAG, "插入消息:$ttsEntity,level为:$ttsLevel") + insertTts(ttsEntity, ttsLevel) + } + return + } + } + curTtsLevel = ttsLevel + curTtsEntity = ttsEntity + // 合成并播放 + d(TAG, "tts准备合成:$ttsEntity,curTtsLevel为:$curTtsLevel") + startSpeak(ttsEntity.ttsNext()) + } + } + + private fun startSpeak(langTtsEntity: LangTtsEntity?) { + langTtsEntity?.let { + if (it.language != lastLang) { + updateVoicer(it.language) + updateTtsParam() + lastLang = it.language + } + ttsEngine?.startSpeaking(it.ttsContent, ttsListener) + } + } + + private fun handleCompleteEvent() { + curTtsLevel = -1 + if (curTtsEntity != null) {// 多语言 + val langTtsEntity = curTtsEntity!!.ttsNext() + if (langTtsEntity != null) { + speakVoiceMap[curTtsEntity.toString()]?.onSpeakEnd(curTtsEntity.toString()) + ttsNextLanguage(langTtsEntity) + } else { + speakVoiceMap.remove(curTtsEntity.toString())?.onSpeakEnd(curTtsEntity.toString()) + curTtsEntity = null + ttsNextMultiLangEntity() + } + } else {// 单语言 + speakVoiceMap.remove(curTtsContent)?.onSpeakEnd(curTtsContent) + curTtsContent = "" + ttsNextMultiLangEntity() + } + } + + private fun handleErrorEvent(error: SpeechError) { + curTtsLevel = -1 + if (curTtsEntity != null) { + speakVoiceMap.remove(curTtsEntity.toString()) + ?.onSpeakError(curTtsEntity.toString(), error.message) + } else { + speakVoiceMap.remove(curTtsContent)?.onSpeakError(curTtsContent, error.message) + } + curTtsEntity = null + curTtsContent = "" + } + + private val ttsListener = object : SynthesizerListener { + override fun onSpeakBegin() { + + } + + override fun onBufferProgress(p0: Int, p1: Int, p2: Int, p3: String?) { + } + + override fun onSpeakPaused() { + } + + override fun onSpeakResumed() { + } + + override fun onSpeakProgress(p0: Int, p1: Int, p2: Int) { + } + + override fun onEvent(p0: Int, p1: Int, p2: Int, p3: Bundle?) { + + } + + /** + * error - 错误信息,若为null,则没有出现错误。 + * 在音频播放完成,或会话出现错误时,将回调此函数。 + * 若应用主动调用SpeechSynthesizer.stopSpeaking()停止会话,则不会回调此函数。 + */ + override fun onCompleted(error: SpeechError?) { + if (Thread.currentThread() == Looper.getMainLooper().thread) { + if (error == null) {// 播放完成 + handleCompleteEvent() + } else {// 播放出错 + handleErrorEvent(error) + } + } else { + UiThreadHandler.post { + if (error == null) { + handleCompleteEvent() + } else { + handleErrorEvent(error) + } + } + } + } + } + + /** + * 语音合成下一个MultiLangTtsEntity + */ + private fun ttsNextMultiLangEntity() { + if (!linkedList.isEmpty()) { + val ttsPair = linkedList.removeFirst() + i(TAG, "排队播放的下一条文本为:" + ttsPair.first + ",级别为:" + ttsPair.second) + curTtsLevel = ttsPair.second + startSpeak(ttsPair.first.ttsNext()) + } else { + i(TAG, "队列为空") + } + } + + /** + * 语音合成下一个MultiLangTtsEntity中的语言 + */ + private fun ttsNextLanguage(langTtsEntity: LangTtsEntity) { + startSpeak(langTtsEntity) + } + + private fun updateVoicer(language: LanguageType) { + voicerEntries?.let { + voicer = when (language) { + LanguageType.ENGLISH -> it[5] + LanguageType.KOREAN -> it[6] + else -> it[0] + } + } + } + + private fun updateTtsParam() { + // 清空参数 + ttsEngine?.setParameter(SpeechConstant.PARAMS, null) + // 根据合成引擎设置相应参数 + if (engineType == SpeechConstant.TYPE_CLOUD) { + ttsEngine?.setParameter(SpeechConstant.ENGINE_TYPE, SpeechConstant.TYPE_CLOUD) + // 支持实时音频返回,仅在 synthesizeToUri 条件下支持 + ttsEngine?.setParameter(SpeechConstant.TTS_DATA_NOTIFY, "1") + // ttsEngine?.setParameter(SpeechConstant.TTS_BUFFER_TIME,"1"); + // 设置在线合成发音人 + ttsEngine?.setParameter(SpeechConstant.VOICE_NAME, voicer) + //设置合成语速 + ttsEngine?.setParameter( + SpeechConstant.SPEED, "50" + ) + //设置合成音调 + ttsEngine?.setParameter( + SpeechConstant.PITCH, "50" + ) + //设置合成音量 + ttsEngine?.setParameter( + SpeechConstant.VOLUME, "50" + ) + } else { + ttsEngine?.setParameter(SpeechConstant.ENGINE_TYPE, SpeechConstant.TYPE_LOCAL) + ttsEngine?.setParameter(SpeechConstant.VOICE_NAME, "") + } + + //设置播放器音频流类型 + ttsEngine?.setParameter( + SpeechConstant.STREAM_TYPE, "3" + ) + // 设置播放合成音频打断音乐播放,默认为true + ttsEngine?.setParameter(SpeechConstant.KEY_REQUEST_FOCUS, "false") + + // 设置音频保存路径,保存音频格式支持pcm、wav,设置路径为sd卡请注意WRITE_EXTERNAL_STORAGE权限 + ttsEngine?.setParameter(SpeechConstant.AUDIO_FORMAT, "pcm") + ttsEngine?.setParameter( + SpeechConstant.TTS_AUDIO_PATH, + context?.getExternalFilesDir("msc")?.absolutePath + "/tts.pcm" + ) + } +} \ No newline at end of file diff --git a/tts/tts-iflytek/src/main/jniLibs/arm64-v8a/libmsc.so b/tts/tts-iflytek/src/main/jniLibs/arm64-v8a/libmsc.so new file mode 100644 index 0000000000..6a8f3f8862 Binary files /dev/null and b/tts/tts-iflytek/src/main/jniLibs/arm64-v8a/libmsc.so differ diff --git a/tts/tts-iflytek/src/main/res/values/strings.xml b/tts/tts-iflytek/src/main/res/values/strings.xml new file mode 100644 index 0000000000..b0dbcd1930 --- /dev/null +++ b/tts/tts-iflytek/src/main/res/values/strings.xml @@ -0,0 +1,17 @@ + + + + + xiaoyan + aisjiuxu + aisxping + aisjinger + aisbabyxu + + + x2_enus_catherine + + + zhimin + + \ No newline at end of file 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 ced07980ba..382f00303a 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 @@ -29,6 +29,7 @@ import com.mogo.eagle.core.utilcode.util.ThreadUtils; import com.mogo.eagle.core.utilcode.util.ToastUtils; import com.mogo.tts.base.IMogoTTS; import com.mogo.tts.base.IMogoTTSCallback; +import com.mogo.tts.base.MultiLangTtsEntity; import com.mogo.tts.base.PreemptType; import com.zhidao.auto.platform.voice.VoiceClient; import com.zhidao.voicesdk.MogoVoiceManager; @@ -505,6 +506,11 @@ public class PadTTS implements IMogoTTS, VoiceClient.VoiceCmdCallBack, OnTtsList } } + @Override + public void speakMultiLangTTSWithLevel(MultiLangTtsEntity ttsEntity, int level, IMogoTTSCallback callback) { + + } + /** * 问答类型语音注册:默认确认和取消 *