diff --git a/libraries/mogo-tts/app/src/main/AndroidManifest.xml b/libraries/mogo-tts/app/src/main/AndroidManifest.xml
index 53a64e0..8364116 100644
--- a/libraries/mogo-tts/app/src/main/AndroidManifest.xml
+++ b/libraries/mogo-tts/app/src/main/AndroidManifest.xml
@@ -31,6 +31,15 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/libraries/mogo-tts/app/src/main/java/com/mogo/tts/MainActivity.kt b/libraries/mogo-tts/app/src/main/java/com/mogo/tts/MainActivity.kt
index 6206685..68fd248 100644
--- a/libraries/mogo-tts/app/src/main/java/com/mogo/tts/MainActivity.kt
+++ b/libraries/mogo-tts/app/src/main/java/com/mogo/tts/MainActivity.kt
@@ -5,8 +5,18 @@ import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.widget.AppCompatButton
import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat
+import com.mogo.tts.common.IMogoTTSCallback
+import com.mogo.tts.common.log.TtsLogManager
+import kotlin.random.Random
class MainActivity : AppCompatActivity() {
+
+ private val ttsManager = TtsManager()
+
+ private val TAG = "MainActivity"
+
+ private val ranx = Random(10)
+
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
@@ -17,10 +27,31 @@ class MainActivity : AppCompatActivity() {
}
findViewById(R.id.actv_test_tts1).setOnClickListener {
- TtsManager.speakTTSVoice("此时每个单兵要负责自己的一个视线防区")
+ //TtsInnerManager.speakTTSVoice("此时每个单兵要负责自己的一个视线防区")
+ val info = "此时每个单兵要负责自己的一个视线防区${ranx.nextInt()}"
+ TtsLogManager.d(TAG,"要播放的语音:${info}")
+ ttsManager.speakTTSVoice(info,object :IMogoTTSCallback{
+ override fun onSpeakStart(speakText: String?) {
+ TtsLogManager.d(TAG,"onSpeakStart:${speakText}")
+ }
+
+ override fun onSpeakComple(speakText: String?) {
+ TtsLogManager.d(TAG,"onSpeakComple:${speakText}")
+ }
+
+ override fun onStopTts(speakText: String?) {
+ TtsLogManager.d(TAG,"onStopTts:${speakText}")
+ }
+
+ override fun onSpeakError(speakText: String?, errorMsg: String?) {
+ TtsLogManager.d(TAG,"onSpeakError:${speakText}")
+ }
+ })
}
findViewById(R.id.actv_test_tts2).setOnClickListener {
- TtsManager.stopTTS()
+ ttsManager.stopTTS()
}
+
+ ttsManager.bindService(this)
}
}
\ No newline at end of file
diff --git a/libraries/mogo-tts/app/src/main/java/com/mogo/tts/MoGoApplication.kt b/libraries/mogo-tts/app/src/main/java/com/mogo/tts/MoGoApplication.kt
index 70601d4..5851846 100644
--- a/libraries/mogo-tts/app/src/main/java/com/mogo/tts/MoGoApplication.kt
+++ b/libraries/mogo-tts/app/src/main/java/com/mogo/tts/MoGoApplication.kt
@@ -30,7 +30,7 @@ class MoGoApplication : Application() {
}
private fun initTts() {
- TtsManager.init(this)
+ TTSService.start(this)
}
diff --git a/libraries/mogo-tts/app/src/main/java/com/mogo/tts/utils/PhoneUtilsExtend.kt b/libraries/mogo-tts/app/src/main/java/com/mogo/tts/utils/PhoneUtilsExtend.kt
index 4fcb04c..2945920 100644
--- a/libraries/mogo-tts/app/src/main/java/com/mogo/tts/utils/PhoneUtilsExtend.kt
+++ b/libraries/mogo-tts/app/src/main/java/com/mogo/tts/utils/PhoneUtilsExtend.kt
@@ -8,6 +8,6 @@ import android.os.Build
object PhoneUtilsExtend {
fun getDevicesSn(): String {
- return Build.getSerial()
+ return "name"
}
}
diff --git a/libraries/mogo-tts/tts-base/src/main/aidl/com/mogo/tts/ICoreBinder.aidl b/libraries/mogo-tts/tts-base/src/main/aidl/com/mogo/tts/ICoreBinder.aidl
new file mode 100644
index 0000000..d9f6bbb
--- /dev/null
+++ b/libraries/mogo-tts/tts-base/src/main/aidl/com/mogo/tts/ICoreBinder.aidl
@@ -0,0 +1,24 @@
+package com.mogo.tts;
+
+import com.mogo.tts.ITTSCallbackBinder;
+
+interface ICoreBinder {
+
+ void speakTTSVoice1(String tts);
+
+ void speakTTSVoice2(String tts,in ITTSCallbackBinder callback);
+
+ void speakTTSVoic3(String tts, int languageType,in ITTSCallbackBinder callback);
+
+ void registerTtsListener(String tag,in ITTSCallbackBinder callback);
+
+ void unRegisterTtsListener(String tag);
+
+ void clearTtsListener();
+
+ void stopTts();
+
+ void stopTtsByText(String tts);
+
+}
+
diff --git a/libraries/mogo-tts/tts-base/src/main/aidl/com/mogo/tts/ITTSCallbackBinder.aidl b/libraries/mogo-tts/tts-base/src/main/aidl/com/mogo/tts/ITTSCallbackBinder.aidl
new file mode 100644
index 0000000..f1a6fb5
--- /dev/null
+++ b/libraries/mogo-tts/tts-base/src/main/aidl/com/mogo/tts/ITTSCallbackBinder.aidl
@@ -0,0 +1,10 @@
+package com.mogo.tts;
+
+
+oneway interface ITTSCallbackBinder {
+ void onSpeakStart(String speakText);
+ void onSpeakComple(String speakText);
+ void onStopTts(String speakText);
+ void onSpeakError(String speakText,String errorMsg);
+}
+
diff --git a/libraries/mogo-tts/tts-base/src/main/java/com/mogo/tts/TTSService.kt b/libraries/mogo-tts/tts-base/src/main/java/com/mogo/tts/TTSService.kt
new file mode 100644
index 0000000..377ed7f
--- /dev/null
+++ b/libraries/mogo-tts/tts-base/src/main/java/com/mogo/tts/TTSService.kt
@@ -0,0 +1,254 @@
+package com.mogo.tts
+
+import android.app.Notification
+import android.app.NotificationChannel
+import android.app.NotificationManager
+import android.app.Service
+import android.content.Context
+import android.content.Intent
+import android.os.Build
+import android.os.IBinder
+import androidx.core.app.NotificationCompat
+import com.mogo.tts.common.IMogoTTSCallback
+import com.mogo.tts.common.LangTtsEntity
+import com.mogo.tts.common.R
+import com.mogo.tts.common.log.TtsLogManager
+import java.util.concurrent.ConcurrentHashMap
+
+class TTSService : Service() {
+
+ private val TAG = "TTSService"
+
+ private val globalStart = "global_"
+
+ // 🔥 最佳方案:ConcurrentHashMap 管理回调(key = tag,value = 回调)
+ private val callbackMap = ConcurrentHashMap()
+
+
+ private val iCorebinder = object : ICoreBinder.Stub() {
+ override fun speakTTSVoice1(tts: String?) {
+ // 防御空字符串
+ val text = tts?.takeIf { it.isNotEmpty() } ?: return
+ TtsInnerManager.speakTTSVoice(tts)
+ }
+
+ override fun speakTTSVoice2(tts: String?, callback: ITTSCallbackBinder?) {
+ // 防御空字符串
+ val text = tts?.takeIf { it.isNotEmpty() } ?: return
+ if(callback==null){
+ TtsInnerManager.speakTTSVoice(tts)
+ return
+ }
+ // 先缓存 callback
+ callbackMap[text] = callback
+
+ TtsInnerManager.speakTTSVoice(tts,object :IMogoTTSCallback{
+ override fun onSpeakStart(speakText: String?) {
+ val cb = callbackMap[speakText] ?: return
+ safeCallback {
+ cb.onSpeakStart(speakText)
+ }
+ }
+
+ override fun onSpeakComple(speakText: String?){
+ val cb = callbackMap[speakText] ?: return
+ safeCallback {
+ cb.onSpeakComple(speakText)
+ }
+ // ✅ 执行完自动销毁 callback
+ callbackMap.remove(speakText)
+ }
+
+ override fun onStopTts(speakText: String?) {
+ val cb = callbackMap[speakText] ?: return
+ safeCallback {
+ cb.onStopTts(speakText)
+ }
+ // ✅ 执行完自动销毁 callback
+ callbackMap.remove(speakText)
+ }
+
+ override fun onSpeakError(speakText: String?, errorMsg: String?) {
+ val cb = callbackMap[speakText] ?: return
+ safeCallback {
+ cb.onSpeakError(speakText,errorMsg)
+ }
+ // ✅ 执行完自动销毁 callback
+ callbackMap.remove(speakText)
+ }
+ })
+ }
+
+ override fun speakTTSVoic3(tts: String?, languageType: Int, callback: ITTSCallbackBinder?) {
+ // 防御空字符串
+ val text = tts?.takeIf { it.isNotEmpty() } ?: return
+ if(callback==null){
+ TtsInnerManager.speakTTSVoice(tts)
+ return
+ }
+ // 先缓存 callback
+ callbackMap[text] = callback
+
+ val langTtsEntity = LangTtsEntity.getLangTtsEntity(tts, languageType)
+
+ TtsInnerManager.speakTTSVoice(langTtsEntity,object :IMogoTTSCallback{
+ override fun onSpeakStart(speakText: String?) {
+ val cb = callbackMap[speakText] ?: return
+ safeCallback {
+ cb.onSpeakStart(speakText)
+ }
+ }
+
+ override fun onSpeakComple(speakText: String?) {
+ val cb = callbackMap[speakText] ?: return
+ safeCallback {
+ cb.onSpeakComple(speakText)
+ }
+ // ✅ 执行完自动销毁 callback
+ callbackMap.remove(speakText)
+ }
+
+ override fun onStopTts(speakText: String?) {
+ val cb = callbackMap[speakText] ?: return
+ safeCallback {
+ cb.onStopTts(speakText)
+ }
+ // ✅ 执行完自动销毁 callback
+ callbackMap.remove(speakText)
+ }
+
+ override fun onSpeakError(speakText: String?, errorMsg: String?) {
+ val cb = callbackMap[speakText] ?: return
+ safeCallback {
+ cb.onSpeakError(speakText,errorMsg)
+ }
+ // ✅ 执行完自动销毁 callback
+ callbackMap.remove(speakText)
+ }
+ })
+ }
+
+ override fun registerTtsListener(tag: String?, callback: ITTSCallbackBinder?) {
+ if(tag.isNullOrEmpty()){
+ return
+ }
+ if(callback==null){
+ return
+ }
+ val key = "${globalStart}${tag}"
+ callbackMap[key] = callback
+ }
+
+ override fun unRegisterTtsListener(tag: String?) {
+ if(tag.isNullOrEmpty()){
+ return
+ }
+ val key = "${globalStart}${tag}"
+ callbackMap.remove(key)
+ }
+
+ override fun clearTtsListener() {
+ callbackMap.clear()
+ }
+
+ override fun stopTts() {
+ TtsInnerManager.stopTTS()
+ }
+
+ override fun stopTtsByText(tts: String?) {
+ // TODO: 如果正在播放直接停止、如果在排队播放从队伍中移除
+ }
+
+ }
+
+ companion object{
+ fun start(context: Context) {
+ val serviceIntent = Intent(context, TTSService::class.java)
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
+ context.startForegroundService(serviceIntent)
+ } else {
+ context.startService(serviceIntent)
+ }
+ }
+ }
+
+ override fun onCreate() {
+ super.onCreate()
+ TtsLogManager.d(TAG,"onCreate")
+ TtsInnerManager.init(applicationContext)
+ TtsInnerManager.registerTtsListener(object :IMogoTTSCallback{
+ override fun onSpeakStart(speakText: String?) {
+ callbackMap.forEach {
+ if (it.key.startsWith(globalStart)) {
+ safeCallback {
+ it.value.onSpeakStart(speakText)
+ }
+ }
+ }
+ }
+
+
+ override fun onSpeakComple(speakText: String?) {
+ callbackMap.forEach {
+ if (it.key.startsWith(globalStart)) {
+ safeCallback {
+ it.value.onSpeakComple(speakText)
+ }
+ }
+ }
+ }
+
+ override fun onSpeakError(speakText: String?, errorMsg: String) {
+ callbackMap.forEach {
+ if (it.key.startsWith(globalStart)) {
+ safeCallback {
+ it.value.onSpeakError(speakText,errorMsg)
+ }
+ }
+ }
+ }
+
+ })
+ }
+
+ override fun onBind(intent: Intent?): IBinder? {
+ TtsLogManager.d(TAG,"onBind")
+ return iCorebinder
+ }
+
+ override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
+ TtsLogManager.d(TAG,"onStartCommand")
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
+ val manager = getSystemService(NOTIFICATION_SERVICE) as NotificationManager
+ if (manager != null) {
+ val nc = NotificationChannel("Voice", "语音服务", NotificationManager.IMPORTANCE_HIGH)
+ manager.createNotificationChannel(nc)
+ }
+ }
+ val notification: Notification = NotificationCompat.Builder(applicationContext, "Voice")
+ .setContentTitle("语音服务运行中")
+ .setSmallIcon(R.drawable.voice_manager_icon)
+ .build()
+
+ startForeground(1, notification)
+ return START_STICKY
+ }
+
+ override fun onDestroy() {
+ TtsLogManager.d(TAG,"onDestroy")
+ super.onDestroy()
+ TtsInnerManager.unRegisterTtsListener()
+ TtsInnerManager.release()
+ }
+
+
+ // 跨进程回调安全工具方法
+ private inline fun safeCallback(call: () -> Unit) {
+ try {
+ call()
+ } catch (e: Exception) {
+ TtsLogManager.e(TAG,e.toString(),e)
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/libraries/mogo-tts/tts-base/src/main/java/com/mogo/tts/TtsInnerManager.kt b/libraries/mogo-tts/tts-base/src/main/java/com/mogo/tts/TtsInnerManager.kt
new file mode 100644
index 0000000..64d4721
--- /dev/null
+++ b/libraries/mogo-tts/tts-base/src/main/java/com/mogo/tts/TtsInnerManager.kt
@@ -0,0 +1,71 @@
+package com.mogo.tts
+
+import android.content.Context
+import com.mogo.tts.common.IMogoTTS
+import com.mogo.tts.common.IMogoTTSCallback
+import com.mogo.tts.common.LangTtsEntity
+import com.mogo.tts.common.LanguageType
+import com.mogo.tts.common.log.TtsLogManager
+
+object TtsInnerManager {
+
+ private const val TAG = "TtsManager"
+
+ private var mTTS: IMogoTTS? = null
+
+ fun init(context: Context) {
+ try {
+ // 暂时换成反射,解决死锁问题
+ var clazz1: Class<*>? = null
+ try {
+// clazz1 = Class.forName("com.mogo.tts.iflytek.offline.IFlyTekOfflineTts")
+ clazz1 = Class.forName("com.k2fsa.sherpa.onnx.MogoOfflineTTS")
+ } catch (ignored: Exception) {
+ }
+
+ if (clazz1 != null) {
+ mTTS = clazz1.getConstructor().newInstance() as IMogoTTS
+ }
+ mTTS?.initTts(context)
+ } catch (e: Exception) {
+ e.printStackTrace()
+ TtsLogManager.d(TAG, "TTS 模块初始化异常")
+ }
+ }
+
+ fun speakTTSVoice(tts: String?) {
+ if(tts.isNullOrEmpty()) return
+ speakTTSVoice(tts,null)
+ }
+
+
+ fun speakTTSVoice(tts: String?, callBack: IMogoTTSCallback?) {
+ if(tts.isNullOrEmpty()) return
+ speakTTSVoice(LangTtsEntity(tts, LanguageType.CHINESE), callBack);
+ }
+
+ fun speakTTSVoice(ttsEntity: LangTtsEntity, callBack: IMogoTTSCallback?) {
+ if(ttsEntity.ttsContent.isEmpty()){
+ return
+ }
+ mTTS?.speakTTSVoice(ttsEntity, callBack)
+ }
+
+ fun registerTtsListener(callback: IMogoTTSCallback) {
+ mTTS?.registerTtsListener(callback)
+ }
+
+ fun unRegisterTtsListener() {
+ mTTS?.unRegisterTtsListener()
+ }
+
+ fun stopTTS() {
+ mTTS?.stopTts()
+ }
+
+ fun release() {
+ mTTS?.release()
+ }
+
+
+}
\ No newline at end of file
diff --git a/libraries/mogo-tts/tts-base/src/main/java/com/mogo/tts/TtsManager.kt b/libraries/mogo-tts/tts-base/src/main/java/com/mogo/tts/TtsManager.kt
index b46a105..d943c45 100644
--- a/libraries/mogo-tts/tts-base/src/main/java/com/mogo/tts/TtsManager.kt
+++ b/libraries/mogo-tts/tts-base/src/main/java/com/mogo/tts/TtsManager.kt
@@ -1,42 +1,33 @@
package com.mogo.tts
+import android.content.ComponentName
import android.content.Context
-import com.mogo.tts.common.IGlobalTtsCallback
-import com.mogo.tts.common.IMogoTTS
+import android.content.Intent
+import android.content.ServiceConnection
+import android.content.pm.PackageManager
+import android.os.Build
+import android.os.IBinder
+import android.os.RemoteException
+import com.elegant.utils.UiThreadHandler
import com.mogo.tts.common.IMogoTTSCallback
import com.mogo.tts.common.LangTtsEntity
import com.mogo.tts.common.LanguageType
-import com.mogo.tts.common.log.TtsLogManager
+import java.util.concurrent.atomic.AtomicBoolean
-object TtsManager {
-
- private const val TAG = "TtsManager"
-
- private var mTTS: IMogoTTS? = null
-
- fun init(context: Context) {
- try {
- // 暂时换成反射,解决死锁问题
- var clazz1: Class<*>? = null
- try {
- //clazz1 = Class.forName("com.mogo.tts.iflytek.offline.IFlyTekOfflineTts")
- clazz1 = Class.forName("com.k2fsa.sherpa.onnx.MogoOfflineTTS")
- } catch (ignored: Exception) {
- }
-
- if (clazz1 != null) {
- mTTS = clazz1.getConstructor().newInstance() as IMogoTTS
- }
- mTTS?.initTts(context)
- } catch (e: Exception) {
- e.printStackTrace()
- TtsLogManager.d(TAG, "TTS 模块初始化异常")
- }
+class TtsManager {
+ companion object {
+ private const val SERVER_PACKAGE: String = "com.mogo.tts"
}
+ private val isBind = AtomicBoolean(false)
+ private val isServiceException = AtomicBoolean(false) //服务绑定成功后出现异常
+ protected var binder: ICoreBinder? = null
+
+ private var context: Context? = null
+
fun speakTTSVoice(tts: String?) {
if(tts.isNullOrEmpty()) return
- speakTTSVoice(tts,null)
+ speakTTSVoice(LangTtsEntity(tts, LanguageType.CHINESE), null);
}
@@ -49,24 +40,172 @@ object TtsManager {
if(ttsEntity.ttsContent.isEmpty()){
return
}
- mTTS?.speakTTSVoice(ttsEntity, callBack)
+ if(binder!=null){
+ try {
+ binder?.speakTTSVoic3(ttsEntity.ttsContent,ttsEntity.getLanguageDef(),object :
+ ITTSCallbackBinder.Stub() {
+ override fun onSpeakStart(speakText: String?) {
+ callBack?.onSpeakStart(speakText)
+ }
+
+ override fun onSpeakComple(speakText: String?) {
+ callBack?.onSpeakComple(speakText)
+ }
+
+ override fun onStopTts(speakText: String?) {
+ callBack?.onStopTts(speakText)
+ }
+
+ override fun onSpeakError(speakText: String?, errorMsg: String?) {
+ callBack?.onSpeakError(speakText,errorMsg)
+ }
+ })
+ } catch (e: RemoteException) {
+ e.printStackTrace()
+ }
+ }
}
- fun registerTtsListener(key: String, callback: IGlobalTtsCallback) {
- mTTS?.registerTtsListener(key, callback)
+ fun registerTtsListener(tag:String,callback: IMogoTTSCallback) {
+ if(binder!=null){
+ try {
+ binder?.registerTtsListener(tag,object :ITTSCallbackBinder.Stub(){
+ override fun onSpeakStart(speakText: String?) {
+ callback.onSpeakStart(speakText)
+ }
+
+ override fun onSpeakComple(speakText: String?) {
+ callback.onSpeakComple(speakText)
+ }
+
+ override fun onStopTts(speakText: String?) {
+ callback.onStopTts(speakText)
+ }
+
+ override fun onSpeakError(speakText: String?, errorMsg: String?) {
+ callback.onSpeakError(speakText,errorMsg)
+ }
+ })
+ } catch (e: RemoteException) {
+ e.printStackTrace()
+ }
+ }
}
- fun unRegisterTtsListener(key: String) {
- mTTS?.unRegisterTtsListener(key)
+ fun unRegisterTtsListener(tag: String) {
+ if(binder!=null){
+ try {
+ binder?.unRegisterTtsListener(tag)
+ } catch (e: RemoteException) {
+ e.printStackTrace()
+ }
+ }
}
fun stopTTS() {
- mTTS?.stopTts()
+ if(binder!=null){
+ try {
+ binder?.stopTts()
+ } catch (e: RemoteException) {
+ e.printStackTrace()
+ }
+ }
}
- fun release() {
- mTTS?.release()
+ fun stopTTS(tts:String) {
+ if(binder!=null){
+ try {
+ binder?.stopTtsByText(tts)
+ } catch (e: RemoteException) {
+ e.printStackTrace()
+ }
+ }
}
+ private val connection = object : ServiceConnection {
+ override fun onServiceConnected(name: ComponentName?, service: IBinder?) {
+ binder = ICoreBinder.Stub.asInterface(service);
+ }
+ override fun onServiceDisconnected(name: ComponentName?) {
+ isServiceException.set(true);
+ unbind()
+ delayBind()
+ }
+ }
+
+ fun bindService(
+ context: Context,
+ ) {
+ this.context = context
+ bindService()
+ }
+
+ private fun bindService() {
+ context?.let {
+ if (!isBind.get()) {
+ if (isServerInstalled()) {
+ isBind.set(true)
+ val intent = Intent("com.mogo.tts.ttsservice")
+ intent.setPackage(SERVER_PACKAGE)
+ val isSuccess: Boolean =
+ it.bindService(intent, connection, Context.BIND_AUTO_CREATE)
+ if (!isSuccess) {
+ unbind()
+ }
+ } else {
+
+ }
+ }
+ }
+ }
+
+ private fun unbind() {
+ if (binder != null) {
+ try {
+ binder?.clearTtsListener()
+ } catch (e: RemoteException) {
+ e.printStackTrace()
+ }
+ binder = null
+ }
+ context?.let {
+ if (isBind.get()) {
+ isBind.set(false)
+ try {
+ it.unbindService(connection)
+ } catch (e: Exception) {
+ e.printStackTrace()
+ }
+ }
+ }
+ }
+
+ private fun delayBind() {
+ if (isServiceException.get()) {
+ isServiceException.set(false)
+ UiThreadHandler.postDelayed({
+ bindService()
+ }, 4000L)
+ }
+ }
+
+ private fun isServerInstalled(): Boolean {
+ context?.let {
+ val pm: PackageManager = it.getPackageManager()
+ return try {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
+ pm.getApplicationInfo(
+ SERVER_PACKAGE,
+ PackageManager.ApplicationInfoFlags.of(0)
+ ).enabled
+ } else {
+ pm.getApplicationInfo(SERVER_PACKAGE, 0).enabled
+ }
+ } catch (e: PackageManager.NameNotFoundException) {
+ false
+ }
+ }
+ return false
+ }
}
\ No newline at end of file
diff --git a/libraries/mogo-tts/tts-base/src/main/java/com/mogo/tts/common/IGlobalTtsCallback.kt b/libraries/mogo-tts/tts-base/src/main/java/com/mogo/tts/common/IGlobalTtsCallback.kt
index bd2322b..ea7f6de 100644
--- a/libraries/mogo-tts/tts-base/src/main/java/com/mogo/tts/common/IGlobalTtsCallback.kt
+++ b/libraries/mogo-tts/tts-base/src/main/java/com/mogo/tts/common/IGlobalTtsCallback.kt
@@ -1,7 +1,11 @@
package com.mogo.tts.common
interface IGlobalTtsCallback {
- fun onTtsSpeakStart()
+ fun onTtsSpeakStart(speakText: String?)
- fun onTtsSpeakEnd()
+ fun onTtsSpeakEnd(speakText: String?)
+
+ fun onTtsSpeakComple(speakText: String?)
+
+ fun onTtsSpeakError(speakText: String?, errorMsg: String)
}
\ No newline at end of file
diff --git a/libraries/mogo-tts/tts-base/src/main/java/com/mogo/tts/common/IMogoTTS.java b/libraries/mogo-tts/tts-base/src/main/java/com/mogo/tts/common/IMogoTTS.java
index 699013a..fb7ba69 100644
--- a/libraries/mogo-tts/tts-base/src/main/java/com/mogo/tts/common/IMogoTTS.java
+++ b/libraries/mogo-tts/tts-base/src/main/java/com/mogo/tts/common/IMogoTTS.java
@@ -18,9 +18,9 @@ interface IMogoTTS {
*/
void release();
- void registerTtsListener(String key, IGlobalTtsCallback callback);
+ void registerTtsListener(IMogoTTSCallback callback);
- void unRegisterTtsListener(String key);
+ void unRegisterTtsListener();
void speakTTSVoice(LangTtsEntity ttsEntity, IMogoTTSCallback callBack);
diff --git a/libraries/mogo-tts/tts-base/src/main/java/com/mogo/tts/common/IMogoTTSCallback.java b/libraries/mogo-tts/tts-base/src/main/java/com/mogo/tts/common/IMogoTTSCallback.java
index 8dc8723..f7da63e 100644
--- a/libraries/mogo-tts/tts-base/src/main/java/com/mogo/tts/common/IMogoTTSCallback.java
+++ b/libraries/mogo-tts/tts-base/src/main/java/com/mogo/tts/common/IMogoTTSCallback.java
@@ -9,46 +9,10 @@ public
*/
interface IMogoTTSCallback {
- /**
- * 新SDK接口
- *
- * @param ttsId
- * @param tts
- */
- @Deprecated
- default void onTTSStart( String ttsId, String tts ) {
- }
-
- /**
- * 新SDK接口
- *
- * @param ttsId
- * @param tts
- */
- @Deprecated
- default void onTTSEnd( String ttsId, String tts ) {
- }
-
- /**
- * 新SDK接口
- *
- * @param ttsId
- * @param tts
- */
- @Deprecated
- default void onTTSError( String ttsId, String tts ) {
- }
-
-
default void onSpeakStart( String speakText ) {
}
- /**
- * 语音播报完毕
- *
- * @param speakText 播报内容
- */
- default void onSpeakEnd( String speakText ) {
+ default void onSpeakComple( String speakText ) {
}
default void onStopTts( String speakText ) {
diff --git a/libraries/mogo-tts/tts-base/src/main/java/com/mogo/tts/common/LangTtsEntity.kt b/libraries/mogo-tts/tts-base/src/main/java/com/mogo/tts/common/LangTtsEntity.kt
new file mode 100644
index 0000000..0ddf3b2
--- /dev/null
+++ b/libraries/mogo-tts/tts-base/src/main/java/com/mogo/tts/common/LangTtsEntity.kt
@@ -0,0 +1,38 @@
+package com.mogo.tts.common
+
+data class LangTtsEntity(
+ var ttsContent: String,
+ var language: LanguageType
+) {
+ override fun toString(): String {
+ return "ttsContent is:$ttsContent,language is:${language.langName}"
+ }
+
+ fun getLanguageDef(): Int {
+ return when (language) {
+ LanguageType.CHINESE -> LanguageTypeDef.MODE_CHINESE
+ LanguageType.ENGLISH -> LanguageTypeDef.MODE_ENGLISH
+ LanguageType.KOREAN -> LanguageTypeDef.MODE_KOREAN
+ }
+ }
+
+
+ companion object {
+ fun getLangTtsEntity(tts: String, languageType: Int): LangTtsEntity {
+ val languageType = when (languageType) {
+ LanguageTypeDef.MODE_ENGLISH -> {
+ LanguageType.ENGLISH
+ }
+
+ LanguageTypeDef.MODE_KOREAN -> {
+ LanguageType.KOREAN
+ }
+
+ else -> {
+ LanguageType.CHINESE
+ }
+ }
+ return LangTtsEntity(tts, languageType)
+ }
+ }
+}
\ No newline at end of file
diff --git a/libraries/mogo-tts/tts-base/src/main/java/com/mogo/tts/common/LanguageTypeDef.java b/libraries/mogo-tts/tts-base/src/main/java/com/mogo/tts/common/LanguageTypeDef.java
new file mode 100644
index 0000000..31708c4
--- /dev/null
+++ b/libraries/mogo-tts/tts-base/src/main/java/com/mogo/tts/common/LanguageTypeDef.java
@@ -0,0 +1,14 @@
+package com.mogo.tts.common;
+
+import androidx.annotation.IntDef;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+@Retention(RetentionPolicy.SOURCE)
+public @interface LanguageTypeDef{
+ public static final int MODE_CHINESE = 0;
+ public static final int MODE_ENGLISH = 1;
+ public static final int MODE_KOREAN = 2;
+}
+
diff --git a/libraries/mogo-tts/tts-base/src/main/java/com/mogo/tts/common/MultiLangTtsEntity.kt b/libraries/mogo-tts/tts-base/src/main/java/com/mogo/tts/common/MultiLangTtsEntity.kt
deleted file mode 100644
index 2aaad26..0000000
--- a/libraries/mogo-tts/tts-base/src/main/java/com/mogo/tts/common/MultiLangTtsEntity.kt
+++ /dev/null
@@ -1,55 +0,0 @@
-package com.mogo.tts.common
-
-data class MultiLangTtsEntity(
- private var ttsList: List
-) {
- companion object {
- private const val TIMEOUT_MILLIS = 60000
- }
-
- private val stringBuffer by lazy {
- StringBuffer()
- }
-
- private var ttsIndex = 0
- private var timeStamp: Long = 0
-
- fun ttsNext(): LangTtsEntity? {
- return if (ttsIndex in ttsList.indices) {
- ttsList[ttsIndex++]
- } else {
- null
- }
- }
-
- fun markTime() {
- timeStamp = System.currentTimeMillis()
- }
-
- fun isTimeout():Boolean {
- return timeStamp > 0 && System.currentTimeMillis() - timeStamp >= TIMEOUT_MILLIS
- }
-
- 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/libraries/mogo-tts/tts-base/src/main/java/com/mogo/tts/common/impl/BaseMogoTTS.java b/libraries/mogo-tts/tts-base/src/main/java/com/mogo/tts/common/impl/BaseMogoTTS.java
index 20951e9..56a19c2 100644
--- a/libraries/mogo-tts/tts-base/src/main/java/com/mogo/tts/common/impl/BaseMogoTTS.java
+++ b/libraries/mogo-tts/tts-base/src/main/java/com/mogo/tts/common/impl/BaseMogoTTS.java
@@ -4,7 +4,6 @@ import android.content.Context;
import android.os.Looper;
import com.elegant.utils.UiThreadHandler;
-import com.mogo.tts.common.IGlobalTtsCallback;
import com.mogo.tts.common.IMogoTTS;
import com.mogo.tts.common.IMogoTTSCallback;
import com.mogo.tts.common.LangTtsEntity;
@@ -20,7 +19,7 @@ public abstract class BaseMogoTTS implements IMogoTTS {
protected volatile LangTtsEntity curTtsEntity = null;
protected HashMap speakVoiceMap = new HashMap<>();
- protected HashMap mGlobalTtsCallback = new HashMap<>();
+ protected IMogoTTSCallback mGlobalTtsCallback = null;
protected String getTAG() {
return "BaseMogoTTS";
@@ -31,14 +30,12 @@ public abstract class BaseMogoTTS implements IMogoTTS {
this.context = context;
}
- public void registerTtsListener(String key,IGlobalTtsCallback callback) {
- if (!mGlobalTtsCallback.containsKey(key)) {
- this.mGlobalTtsCallback.put(key,callback);
- }
+ public void registerTtsListener(IMogoTTSCallback callback) {
+ this.mGlobalTtsCallback = callback;
}
- public void unRegisterTtsListener(String key){
- this.mGlobalTtsCallback.remove(key);
+ public void unRegisterTtsListener(){
+ this.mGlobalTtsCallback = null;
}
@Override
@@ -59,7 +56,6 @@ public abstract class BaseMogoTTS implements IMogoTTS {
}
protected void speakMultiLangTTS(LangTtsEntity ttsEntity){
- this.curTtsEntity = ttsEntity;
// 合成并播放
TtsLogManager.d(getTAG(), "tts准备合成:"+ttsEntity);
}
@@ -80,7 +76,7 @@ public abstract class BaseMogoTTS implements IMogoTTS {
if (speakVoiceMap.containsKey(key)) {
IMogoTTSCallback remove = speakVoiceMap.remove(key);
if(remove!=null) {
- remove.onStopTts(key);
+ remove.onStopTts(curTtsEntity.getTtsContent());
}
}
curTtsEntity = null;
@@ -89,31 +85,27 @@ public abstract class BaseMogoTTS implements IMogoTTS {
}
public void onSpeakBegin() {
- if(!mGlobalTtsCallback.isEmpty()) {
- for (IGlobalTtsCallback callback : mGlobalTtsCallback.values()) {
- callback.onTtsSpeakStart();
- }
+ if(mGlobalTtsCallback != null) {
+ mGlobalTtsCallback.onSpeakStart(curTtsContent);
}
if (curTtsEntity!=null) {
String key = curTtsEntity.toString();
IMogoTTSCallback iMogoTTSCallback = speakVoiceMap.get(key);
if(iMogoTTSCallback!=null){
- iMogoTTSCallback.onSpeakStart(key);
+ iMogoTTSCallback.onSpeakStart(curTtsEntity.getTtsContent());
}
}
}
public void handleCompleteEvent() {
- if(!mGlobalTtsCallback.isEmpty()) {
- for (IGlobalTtsCallback callback : mGlobalTtsCallback.values()) {
- callback.onTtsSpeakEnd();
- }
+ if(mGlobalTtsCallback!=null) {
+ mGlobalTtsCallback.onSpeakComple(curTtsContent);
}
if (curTtsEntity!=null) {
String key = curTtsEntity.toString();
IMogoTTSCallback iMogoTTSCallback = speakVoiceMap.get(key);
if(iMogoTTSCallback!=null){
- iMogoTTSCallback.onSpeakEnd(key);
+ iMogoTTSCallback.onSpeakComple(curTtsEntity.getTtsContent());
}
}
curTtsEntity = null;
@@ -121,18 +113,19 @@ public abstract class BaseMogoTTS implements IMogoTTS {
}
public void handleErrorEvent(String error) {
+ if(mGlobalTtsCallback!=null) {
+ mGlobalTtsCallback.onSpeakError(curTtsContent,error);
+ }
if (curTtsEntity != null) {
String key = curTtsEntity.toString();
IMogoTTSCallback iMogoTTSCallback = speakVoiceMap.get(key);
if(iMogoTTSCallback!=null){
- iMogoTTSCallback.onSpeakError(key,
- error);
+ iMogoTTSCallback.onSpeakError(curTtsEntity.getTtsContent(), error);
}
} else {
IMogoTTSCallback iMogoTTSCallback = speakVoiceMap.get(curTtsContent);
if(iMogoTTSCallback!=null){
- iMogoTTSCallback.onSpeakError(curTtsContent,
- error);
+ iMogoTTSCallback.onSpeakError(curTtsContent, error);
}
}
curTtsEntity = null;
diff --git a/libraries/mogo-tts/tts-base/src/main/java/com/mogo/tts/common/log/TtsLogManager.kt b/libraries/mogo-tts/tts-base/src/main/java/com/mogo/tts/common/log/TtsLogManager.kt
index d96c9f7..7ef622e 100644
--- a/libraries/mogo-tts/tts-base/src/main/java/com/mogo/tts/common/log/TtsLogManager.kt
+++ b/libraries/mogo-tts/tts-base/src/main/java/com/mogo/tts/common/log/TtsLogManager.kt
@@ -48,4 +48,12 @@ object TtsLogManager {
}
logListener?.writeLog(LogLevel.error,tag,message)
}
+
+ @JvmStatic
+ fun e(tag: String, message: String,tr:Throwable?) {
+ if(isDebug) {
+ Log.e(tag, message,tr)
+ }
+ logListener?.writeLog(LogLevel.error,tag,message)
+ }
}
\ No newline at end of file
diff --git a/libraries/mogo-tts/tts-base/src/main/res/drawable/voice_manager_icon.xml b/libraries/mogo-tts/tts-base/src/main/res/drawable/voice_manager_icon.xml
new file mode 100644
index 0000000..6d4a792
--- /dev/null
+++ b/libraries/mogo-tts/tts-base/src/main/res/drawable/voice_manager_icon.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/libraries/mogo-tts/tts-iflytek-offline/src/main/java/com/mogo/tts/iflytek/offline/IFlyTekOfflineTts.kt b/libraries/mogo-tts/tts-iflytek-offline/src/main/java/com/mogo/tts/iflytek/offline/IFlyTekOfflineTts.kt
index a5f10eb..39715d3 100644
--- a/libraries/mogo-tts/tts-iflytek-offline/src/main/java/com/mogo/tts/iflytek/offline/IFlyTekOfflineTts.kt
+++ b/libraries/mogo-tts/tts-iflytek-offline/src/main/java/com/mogo/tts/iflytek/offline/IFlyTekOfflineTts.kt
@@ -129,6 +129,7 @@ class IFlyTekOfflineTts : BaseMogoTTS() {
private fun startSpeak(langTtsEntity: LangTtsEntity?) {
langTtsEntity?.let {
+ curTtsEntity = it
curTtsContent = it.ttsContent
realSpeak(it.ttsContent)
}
diff --git a/libraries/mogo-tts/tts-mogo/src/main/java/com/k2fsa/sherpa/onnx/MogoOfflineTTS.kt b/libraries/mogo-tts/tts-mogo/src/main/java/com/k2fsa/sherpa/onnx/MogoOfflineTTS.kt
index 0c80749..17f48fa 100644
--- a/libraries/mogo-tts/tts-mogo/src/main/java/com/k2fsa/sherpa/onnx/MogoOfflineTTS.kt
+++ b/libraries/mogo-tts/tts-mogo/src/main/java/com/k2fsa/sherpa/onnx/MogoOfflineTTS.kt
@@ -150,6 +150,7 @@ class MogoOfflineTTS : BaseMogoTTS() {
private fun startSpeak(langTtsEntity: LangTtsEntity?) {
stopTts()
langTtsEntity?.let {
+ this.curTtsEntity = langTtsEntity;
curTtsContent = it.ttsContent
realSpeak(it.ttsContent)
}