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.

194 lines
5.5 KiB

import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'dart:async';
import 'package:flutter/foundation.dart';
import '../../../data/services/volcano_tts_service.dart';
import '../../../core/utils/logger.dart';
class VolcanoTtsTestController extends GetxController {
// 使用 VolcanoTtsService 替代 VolcanoTtsApiService
final VolcanoTtsService _ttsService = Get.put(VolcanoTtsService());
// 可观察状态
final isSpeaking = false.obs;
final errorMessage = ''.obs;
final isLoading = false.obs;
final statusMessage = '未连接'.obs;
// 添加实际音频播放状态
final isAudioPlaying = false.obs;
// 播放状态检查定时器
Timer? _playbackCheckTimer;
// 当前播放的索引
final currentPlayingIndex = RxInt(-1);
// 当前使用的语音 - 使用预定义的值
final currentVoice = 'zh_female_meilinvyou_moon_bigtts'.obs;
// 可用的语音列表
final List<Map<String, String>> availableVoices = [
{'id': 'zh_female_meilinvyou_moon_bigtts', 'name': '魅力女友'},
{'id': 'zh_male_shaonianzixin_moon_bigtts', 'name': '少年梓辛/Brayan'},
{'id': 'zh_male_beijingxiaoye_moon_bigtts', 'name': '北京小爷'},
{'id': 'zh_female_daimengchuanmei_moon_bigtts', 'name': '呆萌川妹'},
{'id': 'zh_female_wanqudashu_moon_bigtts', 'name': '湾区大叔'},
{'id': 'zh_female_sajiaonvyou_moon_bigtts', 'name': '撒娇女友'},
{'id': 'zh_male_shenyeboke_moon_bigtts', 'name': '深夜播客'},
];
// 固定的播报内容
final RxList<String> speechTexts = <String>[
'这是第一条播报测试,请听取合成效果。',
'这是第二条播报测试,火山语音合成支持连续多条播报。',
'这是第三条播报测试,可以测试语音合成的流畅度和连贯性。',
'这是第四条播报测试,感谢您的使用。',
].obs;
@override
void onInit() {
super.onInit();
// 初始化UI状态
isSpeaking.value = false;
isAudioPlaying.value = false;
errorMessage.value = '';
isLoading.value = false;
// 监听TTS播放状态
ever(_ttsService.isPlaying, (bool playing) {
isAudioPlaying.value = playing;
if (!playing && currentPlayingIndex.value >= 0) {
// 如果播放结束,重置当前播放索引
currentPlayingIndex.value = -1;
}
});
// 启动播放状态检查定时器
_startPlaybackCheckTimer();
}
/// 更新UI状态
void updateUIState() {
// 强制更新UI
update();
}
/// 播放单条文本
Future<void> playSingle(int index) async {
if (index < 0 || index >= speechTexts.length) {
return;
}
try {
isSpeaking.value = true;
isAudioPlaying.value = true;
errorMessage.value = '';
currentPlayingIndex.value = index;
statusMessage.value = '正在合成...';
final text = speechTexts[index];
// 播放文本
await _ttsService.speak(text);
statusMessage.value = '合成完成';
} catch (e) {
errorMessage.value = '播放出错';
statusMessage.value = '错误';
Logger.error('播放出错: $e');
} finally {
isSpeaking.value = false;
if (!_ttsService.isPlaying.value) {
isAudioPlaying.value = false;
currentPlayingIndex.value = -1;
}
}
}
// 启动播放状态检查定时器
void _startPlaybackCheckTimer() {
_playbackCheckTimer?.cancel();
_playbackCheckTimer = Timer.periodic(const Duration(milliseconds: 200), (timer) {
// 更新实际播放状态
final actuallyPlaying = _ttsService.isPlaying.value;
isAudioPlaying.value = actuallyPlaying;
// 如果不再播放,确保重置状态
if (!actuallyPlaying && isSpeaking.value) {
// 播放已完成,重置状态
isSpeaking.value = false;
currentPlayingIndex.value = -1;
// 更新UI
update();
}
});
}
/// 连续播放所有文本
Future<void> speakContinuousTexts() async {
if (isAudioPlaying.value || isLoading.value) {
return;
}
try {
isSpeaking.value = true;
errorMessage.value = '';
statusMessage.value = '开始连续播放';
// 连接所有文本
final allText = speechTexts.join('');
// 播放所有文本
await _ttsService.speak(allText);
statusMessage.value = '连续播放完成';
} catch (e) {
errorMessage.value = '连续播放出错';
statusMessage.value = '错误';
Logger.error('连续播放出错: $e');
} finally {
isSpeaking.value = false;
}
}
/// 停止播放
Future<void> stopSpeaking() async {
try {
await _ttsService.stop();
isSpeaking.value = false;
isAudioPlaying.value = false;
currentPlayingIndex.value = -1;
statusMessage.value = '已停止';
} catch (e) {
errorMessage.value = '停止播放出错';
Logger.error('停止播放出错: $e');
}
}
/// 切换语音
void changeVoice(String voiceId) {
currentVoice.value = voiceId;
// VolcanoTtsService 不需要显式设置发音人,在 speak 时会使用环境变量中的默认发音人
}
/// 切换启用状态
void toggleEnabled() {
_ttsService.isEnabled.toggle();
statusMessage.value = _ttsService.isEnabled.value ? '已启用' : '已禁用';
}
@override
void onClose() {
// 取消定时器
_playbackCheckTimer?.cancel();
// 停止播放
_ttsService.stop();
super.onClose();
}
}