You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
163 lines
4.5 KiB
163 lines
4.5 KiB
import 'package:get/get.dart';
|
|
import '../../../data/services/flutter_tts_service.dart';
|
|
import '../../../core/utils/logger.dart';
|
|
import 'dart:async';
|
|
|
|
/// Flutter TTS测试控制器,演示如何使用FlutterTtsService
|
|
class FlutterTtsTestController extends GetxController {
|
|
// 获取TTS服务实例
|
|
final FlutterTtsService _ttsService = Get.find<FlutterTtsService>();
|
|
|
|
// 当前TTS状态 - 使用Rx包装以便UI可以响应变化
|
|
final Rx<TtsState> _ttsState = TtsState.stopped.obs;
|
|
TtsState get ttsState => _ttsState.value;
|
|
|
|
// 当前正在播放的文本 - 使用Rx包装以便UI可以响应变化
|
|
final RxString _currentText = ''.obs;
|
|
String get currentText => _currentText.value;
|
|
|
|
// 是否正在播放 - 计算属性
|
|
bool get isPlaying => ttsState == TtsState.playing;
|
|
|
|
// 队列中的文本 - 使用Rx包装以便UI可以响应变化
|
|
final RxList<String> _textQueue = <String>[].obs;
|
|
List<String> get textQueue => _textQueue;
|
|
|
|
// 可用的语音列表 - 使用Rx包装以便UI可以响应变化
|
|
final RxList<Map<String, String>> _voices = <Map<String, String>>[].obs;
|
|
List<Map<String, String>> get voices => _voices;
|
|
|
|
// 当前选择的语音 - 使用Rx包装以便UI可以响应变化
|
|
final RxString _currentVoice = ''.obs;
|
|
String get currentVoice => _currentVoice.value;
|
|
|
|
// 定时器,用于定期更新状态
|
|
late Timer _updateTimer;
|
|
|
|
@override
|
|
void onInit() {
|
|
super.onInit();
|
|
|
|
// 初始化状态
|
|
_updateState();
|
|
|
|
// 设置定时器,每300毫秒更新一次状态,确保UI能够及时反映服务状态变化
|
|
_updateTimer = Timer.periodic(const Duration(milliseconds: 300), (_) {
|
|
_updateState();
|
|
});
|
|
}
|
|
|
|
/// 更新控制器状态,从服务获取最新状态
|
|
void _updateState() {
|
|
// 更新TTS状态
|
|
final serviceState = _ttsService.ttsState;
|
|
if (_ttsState.value != serviceState) {
|
|
_ttsState.value = serviceState;
|
|
}
|
|
|
|
// 更新当前播放文本
|
|
final serviceText = _ttsService.currentText;
|
|
if (_currentText.value != serviceText) {
|
|
_currentText.value = serviceText;
|
|
}
|
|
|
|
// 更新队列
|
|
final serviceQueue = _ttsService.textQueue;
|
|
if (!listEquals(_textQueue, serviceQueue)) {
|
|
_textQueue.value = List.from(serviceQueue);
|
|
}
|
|
|
|
// 更新可用语音列表
|
|
final serviceVoices = _ttsService.voices;
|
|
if (!listEquals(_voices, serviceVoices)) {
|
|
_voices.value = List.from(serviceVoices);
|
|
}
|
|
|
|
// 更新当前选择的语音
|
|
final serviceCurrentVoice = _ttsService.currentVoice;
|
|
if (_currentVoice.value != serviceCurrentVoice) {
|
|
_currentVoice.value = serviceCurrentVoice;
|
|
}
|
|
}
|
|
|
|
/// 比较两个列表是否相等
|
|
bool listEquals<T>(List<T> a, List<T> b) {
|
|
if (a.length != b.length) return false;
|
|
for (int i = 0; i < a.length; i++) {
|
|
if (a[i] != b[i]) return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
/// 添加文本到队列并开始播放(如果尚未开始)
|
|
Future<void> speak(String text) async {
|
|
if (text.isEmpty) {
|
|
Logger.warning('文本为空,无法播放');
|
|
return;
|
|
}
|
|
|
|
await _ttsService.speak(text);
|
|
_updateState();
|
|
}
|
|
|
|
/// 添加多条文本到队列并开始播放(如果尚未开始)
|
|
Future<void> speakTexts(List<String> texts) async {
|
|
if (texts.isEmpty) {
|
|
Logger.warning('文本列表为空,无法播放');
|
|
return;
|
|
}
|
|
|
|
await _ttsService.speakTexts(texts);
|
|
_updateState();
|
|
}
|
|
|
|
/// 停止播放并清空队列
|
|
Future<void> stop() async {
|
|
await _ttsService.stop();
|
|
_updateState();
|
|
}
|
|
|
|
/// 暂停播放
|
|
Future<void> pause() async {
|
|
await _ttsService.pause();
|
|
_updateState();
|
|
}
|
|
|
|
/// 设置语音
|
|
Future<void> setVoice(String voiceName) async {
|
|
await _ttsService.setVoice(voiceName);
|
|
_updateState();
|
|
}
|
|
|
|
/// 设置语言
|
|
Future<void> setLanguage(String language) async {
|
|
await _ttsService.setLanguage(language);
|
|
}
|
|
|
|
/// 设置语速
|
|
Future<void> setRate(double rate) async {
|
|
await _ttsService.setRate(rate);
|
|
}
|
|
|
|
/// 设置音量
|
|
Future<void> setVolume(double volume) async {
|
|
await _ttsService.setVolume(volume);
|
|
}
|
|
|
|
/// 设置音调
|
|
Future<void> setPitch(double pitch) async {
|
|
await _ttsService.setPitch(pitch);
|
|
}
|
|
|
|
/// 清空队列并停止播放
|
|
Future<void> clearQueue() async {
|
|
await _ttsService.clearQueue();
|
|
_updateState();
|
|
}
|
|
|
|
@override
|
|
void onClose() {
|
|
_updateTimer.cancel();
|
|
super.onClose();
|
|
}
|
|
}
|