diff --git a/local_plugins/azure_speech/android/src/main/kotlin/com/yunqiinnovation/azure_speech/AzureTtsHelper.kt b/local_plugins/azure_speech/android/src/main/kotlin/com/yunqiinnovation/azure_speech/AzureTtsHelper.kt index 05223bd8d..5b0770249 100644 --- a/local_plugins/azure_speech/android/src/main/kotlin/com/yunqiinnovation/azure_speech/AzureTtsHelper.kt +++ b/local_plugins/azure_speech/android/src/main/kotlin/com/yunqiinnovation/azure_speech/AzureTtsHelper.kt @@ -14,6 +14,7 @@ import com.deep_voice.speech.tts.TtsEventType import kotlinx.coroutines.* import java.io.ByteArrayInputStream import java.io.InputStream +import java.util.concurrent.atomic.AtomicInteger import com.yunqiinnovation.azure_speech.tools.SimpleAudioPlayer /** * Azure TTS Helper @@ -51,6 +52,9 @@ class AzureTtsHelper(private val context: Context) : ITtsService { private val streamBuffer = StringBuilder() private var lastSpeakTime = 0L + // 待完成的合成任务计数:只有全部完成才触发 PLAYBACK_COMPLETED + private val pendingSpeakCount = AtomicInteger(0) + private var enableVoiceFlocking = false private var speakerProfileId: String = "" @@ -310,8 +314,11 @@ class AzureTtsHelper(private val context: Context) : ITtsService { ) isSpeaking = false notifyEvent(TtsEventType.SYNTHESIS_COMPLETED) - // Azure TTS 合成完成即播放完成 - notifyEvent(TtsEventType.PLAYBACK_COMPLETED) + // 所有句子都播完后才触发 PLAYBACK_COMPLETED,避免多句流式合成时重复触发 + if (pendingSpeakCount.decrementAndGet() <= 0) { + pendingSpeakCount.set(0) + notifyEvent(TtsEventType.PLAYBACK_COMPLETED) + } } // 合成取消事件 @@ -561,8 +568,9 @@ class AzureTtsHelper(private val context: Context) : ITtsService { val ssml = generateOptimizedSsml(text) isSpeaking = true + pendingSpeakCount.incrementAndGet() - FileLogger.d(TAG, "开始语音合成,文本长度: ${text.length}") + FileLogger.d(TAG, "开始语音合成,文本长度: ${text.length},当前待完成任务: ${pendingSpeakCount.get()}") // 直接调用SpeakSsmlAsync,SDK内部已经是异步的 synthesizer?.SpeakSsmlAsync(ssml) @@ -700,6 +708,7 @@ class AzureTtsHelper(private val context: Context) : ITtsService { synthesizer?.StopSpeakingAsync() streamBuffer.clear() isSpeaking = false + pendingSpeakCount.set(0) recreateSynthesizer() return true } catch (e: Exception) {