import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'dart:async'; import 'package:flutter/foundation.dart'; import '../../../data/services/volcano_tts_api_service.dart'; class TtsTestController extends GetxController { final VolcanoTtsApiService _ttsService = Get.find(); // 可观察状态 final isSpeaking = false.obs; final errorMessage = ''.obs; final isLoading = false.obs; final statusMessage = '未连接'.obs; // 当前播放的索引 final currentPlayingIndex = RxInt(-1); // 固定的播报内容 final RxList speechTexts = [ '这是第一条播报测试,请听取合成效果。', '这是第二条播报测试,火山语音合成支持连续多条播报。', '这是第三条播报测试,可以测试语音合成的流畅度和连贯性。', '这是第四条播报测试,感谢您的使用。', ].obs; // 事件订阅 StreamSubscription? _eventSubscription; @override void onInit() { super.onInit(); // 初始化UI状态 isSpeaking.value = false; errorMessage.value = ''; isLoading.value = false; // 监听TTS服务状态 ever(_ttsService.isConnected, (bool connected) { if (connected) { statusMessage.value = '已连接'; } else { statusMessage.value = '未连接'; isSpeaking.value = false; } }); // 监听TTS合成状态 ever(_ttsService.isSynthesizing, (bool synthesizing) { isSpeaking.value = synthesizing; }); // 监听TTS播放状态 ever(_ttsService.isPlaying.obs, (bool playing) { isSpeaking.value = playing; if (!playing && currentPlayingIndex.value >= 0) { // 如果播放结束,重置当前播放索引 currentPlayingIndex.value = -1; } }); // 设置事件监听 _setupEventListener(); // 连接到TTS服务 _connectToTtsService(); } // 设置事件监听 void _setupEventListener() { _eventSubscription?.cancel(); _eventSubscription = _ttsService.eventStream.listen(_handleEvent); } // 处理事件 void _handleEvent(Map event) { final eventType = event['eventType']; switch (eventType) { case 'connectionStarted': statusMessage.value = '连接成功'; errorMessage.value = ''; break; case 'connectionFailed': statusMessage.value = '连接失败'; errorMessage.value = event['error'] ?? '未知错误'; break; case 'sessionStarted': statusMessage.value = '会话开始'; errorMessage.value = ''; break; case 'sessionFailed': statusMessage.value = '会话失败'; errorMessage.value = event['error'] ?? '未知错误'; currentPlayingIndex.value = -1; break; case 'ttsSentenceStart': statusMessage.value = '开始合成'; break; case 'ttsSentenceEnd': statusMessage.value = '合成完成'; break; case 'sessionFinished': statusMessage.value = '会话结束'; currentPlayingIndex.value = -1; break; case 'connectionFinished': statusMessage.value = '连接关闭'; currentPlayingIndex.value = -1; break; case 'error': statusMessage.value = '错误'; errorMessage.value = event['error'] ?? '未知错误'; break; case 'disconnected': statusMessage.value = '连接已断开'; currentPlayingIndex.value = -1; break; default: statusMessage.value = '事件: $eventType'; break; } // 强制更新UI update(); } // 连接到TTS服务 Future _connectToTtsService() async { try { isLoading.value = true; statusMessage.value = '正在连接...'; final success = await _ttsService.connect(); if (!success) { statusMessage.value = '连接失败'; errorMessage.value = '无法连接到火山语音服务'; } } catch (e) { statusMessage.value = '连接错误'; errorMessage.value = e.toString(); } finally { isLoading.value = false; } } /// 更新UI状态 void updateUIState() { // 强制更新UI update(); } /// 播放单条文本 Future speakText(int index) async { if (index < 0 || index >= speechTexts.length || isSpeaking.value) { return; } try { isLoading.value = true; errorMessage.value = ''; currentPlayingIndex.value = index; final text = speechTexts[index]; const speaker = 'zh_female_shuangkuaisisi_moon_bigtts'; // 确保TTS服务已连接 if (!_ttsService.isConnected.value) { await _connectToTtsService(); } // 开始会话 await _ttsService.startSession(speaker); // 播放文本 await _ttsService.speak(text, speaker: speaker); // 等待播放完成 while (_ttsService.isActuallyPlaying()) { await Future.delayed(const Duration(milliseconds: 100)); } // 结束会话 await _ttsService.endSession(); } catch (e) { errorMessage.value = '播放出错'; if (kDebugMode) { print('播放出错: $e'); } } finally { isLoading.value = false; currentPlayingIndex.value = -1; } } /// 连续播放所有文本 Future speakContinuousTexts() async { if (isSpeaking.value || isLoading.value) { return; } try { isLoading.value = true; isSpeaking.value = true; errorMessage.value = ''; // 确保TTS服务已连接 if (!_ttsService.isConnected.value) { await _connectToTtsService(); } const speaker = 'zh_female_shuangkuaisisi_moon_bigtts'; // 停止之前的播放 await _ttsService.stop(); // 开始会话 await _ttsService.startSession(speaker); // 连续播放所有文本 for (int i = 0; i < speechTexts.length; i++) { // 如果播放被中断,退出循环 if (!isSpeaking.value) break; currentPlayingIndex.value = i; statusMessage.value = '正在播放第 ${i + 1}/${speechTexts.length} 条文本'; // 播放当前文本 await _ttsService.speak(speechTexts[i], speaker: speaker); } // 结束会话 await _ttsService.endSession(); statusMessage.value = '播放完成'; } catch (e) { errorMessage.value = '播放出错'; if (kDebugMode) { print('连续播放出错: $e'); } // 尝试结束会话,忽略可能的错误 try { await _ttsService.endSession(); } catch (_) { // 忽略结束会话时的错误 } } finally { currentPlayingIndex.value = -1; isSpeaking.value = false; isLoading.value = false; } } /// 停止播放 void stopSpeaking() async { try { isSpeaking.value = false; statusMessage.value = '正在停止播放...'; // 停止播放 await _ttsService.stop(); // 结束会话 await _ttsService.endSession(); // 重置UI状态 currentPlayingIndex.value = -1; statusMessage.value = '已停止播放'; } catch (e) { if (kDebugMode) { print('停止播放出错: $e'); } errorMessage.value = '停止播放出错'; } finally { isSpeaking.value = false; isLoading.value = false; } } @override void onClose() { // 取消事件订阅 _eventSubscription?.cancel(); // 断开TTS服务连接 _ttsService.disconnect(); super.onClose(); } }