|
|
|
@ -17,6 +17,13 @@ import '../../../data/models/events/voice_interaction_event.dart'; |
|
|
|
import '../../../data/services/asr_service.dart'; |
|
|
|
import '../../../data/services/ble_manager.dart'; |
|
|
|
|
|
|
|
// 切换音频输出设备的枚举 |
|
|
|
enum AudioOutputDevice { |
|
|
|
defaultDevice, // 默认(如有耳机优先耳机,否则扬声器) |
|
|
|
headphones, // 强制耳机 |
|
|
|
speaker, // 强制扬声器 |
|
|
|
} |
|
|
|
|
|
|
|
class TranslationController extends GetxController { |
|
|
|
// 服务 |
|
|
|
final AsrService _asrService = Get.find<AsrService>(); |
|
|
|
@ -55,6 +62,7 @@ class TranslationController extends GetxController { |
|
|
|
final appDocDir = getApplicationDocumentsDirectory(); |
|
|
|
var appDir; |
|
|
|
var dir; |
|
|
|
|
|
|
|
Future<void> changeTranslationMode(String mode) async { |
|
|
|
currentMode.value = mode; |
|
|
|
currentModeTitle.value = _getModeTitle(mode); |
|
|
|
@ -104,7 +112,7 @@ class TranslationController extends GetxController { |
|
|
|
//_setupEventListeners(); |
|
|
|
// 加载上次保存的语言设置 |
|
|
|
_loadSavedLanguages(); |
|
|
|
_requestStoragePermission(); |
|
|
|
|
|
|
|
// 初始化语言代码 |
|
|
|
final sourceAsrCode = |
|
|
|
_languageManager.getAsrCodeByChineseName(sourceLanguage.value); |
|
|
|
@ -175,25 +183,27 @@ class TranslationController extends GetxController { |
|
|
|
} |
|
|
|
|
|
|
|
// 请求存储权限 |
|
|
|
void _requestStoragePermission() async { |
|
|
|
Future<bool> _requestStoragePermission() async { |
|
|
|
// final BuildContext context = Get.overlayContext!; |
|
|
|
|
|
|
|
PermissionUtil.instance |
|
|
|
.requestPermission( |
|
|
|
// context: context, |
|
|
|
try { |
|
|
|
final bool granted = await PermissionUtil.instance.requestPermission( |
|
|
|
permissionType: Permission.storage, |
|
|
|
permissionName: "存储", |
|
|
|
explanationText: "我们需要访问存储权限,以便您可以选择并上传音频文件。", |
|
|
|
permanentDenialText: "检测到您已永久拒绝存储权限。如需继续使用此功能,请前往应用设置中手动开启存储权限。", |
|
|
|
) |
|
|
|
.then((granted) { |
|
|
|
); |
|
|
|
|
|
|
|
if (granted) { |
|
|
|
Logger.d("Permission", "用户授予了存储权限"); |
|
|
|
return true; |
|
|
|
} else { |
|
|
|
Logger.d("Permission", "用户未授予存储权限"); |
|
|
|
// 可以提示用户无法进行文件操作 |
|
|
|
return false; |
|
|
|
} |
|
|
|
} catch (e) { |
|
|
|
Logger.e("Permission", "请求存储权限时出错: $e"); |
|
|
|
return false; |
|
|
|
} |
|
|
|
}); |
|
|
|
} |
|
|
|
// /// 设置事件监听器 |
|
|
|
// void _setupEventListeners() { |
|
|
|
@ -224,6 +234,11 @@ class TranslationController extends GetxController { |
|
|
|
await _asrService.initialize( |
|
|
|
supportedLanguages: asrSupportedLanguages, |
|
|
|
); |
|
|
|
final bool storage = await _requestStoragePermission(); |
|
|
|
if (!storage) { |
|
|
|
Logger.d("Permission", "未授予存储权限,无法提供录音功能"); |
|
|
|
return; |
|
|
|
} |
|
|
|
appDir = await appDocDir; // 先 await 获取目录 |
|
|
|
dir = Directory("${appDir.path}/TranslatAudio"); |
|
|
|
if (!await dir.exists()) { |
|
|
|
@ -266,10 +281,10 @@ class TranslationController extends GetxController { |
|
|
|
Future<void> startRecognition() async { |
|
|
|
Logger.info('开始语音识别'); |
|
|
|
// 等待权限请求完成并获取结果 |
|
|
|
final bool granted = await _requestRecordPermission(); |
|
|
|
final bool record = await _requestRecordPermission(); |
|
|
|
|
|
|
|
// 如果权限被拒绝,直接返回 |
|
|
|
if (!granted) { |
|
|
|
if (!record) { |
|
|
|
Logger.d("Permission", "录音权限被拒绝,无法开始录音"); |
|
|
|
return; |
|
|
|
} |
|
|
|
@ -328,6 +343,11 @@ class TranslationController extends GetxController { |
|
|
|
await _asrService.startContinuousRecognition(_audioSourceType); |
|
|
|
isRecognizing.value = true; |
|
|
|
if (isRecording.value && isRecognizing.value) { |
|
|
|
final bool storage = await _requestStoragePermission(); |
|
|
|
if (!storage) { |
|
|
|
Logger.d("Permission", "未授予存储权限,无法提供录音功能"); |
|
|
|
return; |
|
|
|
} |
|
|
|
final formattedTime = |
|
|
|
DateFormat('yyyyMMdd_HHmmss').format(DateTime.now()); |
|
|
|
await _asrService.enableRecord( |
|
|
|
@ -516,6 +536,20 @@ class TranslationController extends GetxController { |
|
|
|
detectedSourceLanguageCode; |
|
|
|
translationHistory[index].targetLanguageCode = |
|
|
|
detectedTargetLanguageCode; |
|
|
|
print("判断是否是面对面模式且语言一致: ${detectedSourceLanguageCode}"); |
|
|
|
// 判断是否是面对面模式且语言一致 |
|
|
|
final bool isFaceToFaceSameLang = |
|
|
|
detectedSourceLanguageCode == sourceLanguageCode.value && |
|
|
|
currentMode.value == "faceToFace"; |
|
|
|
|
|
|
|
// 设置音频输出设备 |
|
|
|
var isSuccess = await _ttsService.setAudioOutputDevice( |
|
|
|
isFaceToFaceSameLang |
|
|
|
? AudioOutputDevice.speaker.index |
|
|
|
: AudioOutputDevice.headphones.index, |
|
|
|
); |
|
|
|
if (isSuccess) { |
|
|
|
print('设置音频输出设备成功'); |
|
|
|
translationHistory.refresh(); |
|
|
|
saveTranslationHistory(); |
|
|
|
// 更新后滚动到底部 |
|
|
|
@ -526,6 +560,9 @@ class TranslationController extends GetxController { |
|
|
|
// Logger.info('播放翻译文本: ${translationResult}'); |
|
|
|
await playTranslatedText(translationResult); |
|
|
|
} |
|
|
|
} else { |
|
|
|
print('设置音频输出设备失败'); |
|
|
|
} |
|
|
|
} else { |
|
|
|
Logger.info( |
|
|
|
'未找到匹配的历史项 ${sourceText} ${timestamp.toIso8601String() ?? "无时间戳"}'); |
|
|
|
|