Browse Source

优化ui等文件

weicu
fdp 1 year ago
parent
commit
cca3c4484b
  1. 31
      lib/modules/meeting/controllers/meeting_controller.dart
  2. 17
      lib/modules/meeting/controllers/meeting_record_controller.dart
  3. 62
      lib/modules/translation/controllers/translation_controller.dart
  4. 95
      lib/modules/translation/views/translation_view.dart

31
lib/modules/meeting/controllers/meeting_controller.dart

@ -182,27 +182,34 @@ class MeetingController extends GetxController {
void addMeetingAudio() async { void addMeetingAudio() async {
EasyLoading.show(status: '正在导入本地录音...'); EasyLoading.show(status: '正在导入本地录音...');
try { try {
int addUp = 0;
final appDir = await appDocDir; final appDir = await appDocDir;
final sourceDir = Directory("${appDir.path}/MeetingAudio/");
// 检查源目录是否存在 // 定义源目录列表
if (!await sourceDir.exists()) { final sourceDirs = [
EasyLoading.dismiss(); Directory("${appDir.path}/MeetingAudio/"),
return; Directory("${appDir.path}/DestAudio/"),
} ];
// 创建目标目录(如果不存在) // 创建目标目录(如果不存在)
final destDir = Directory("${appDir.path}/LocalAudio/"); final destDir = Directory("${appDir.path}/LocalAudio/");
if (!await destDir.exists()) { if (!await destDir.exists()) {
await destDir.create(recursive: true); await destDir.create(recursive: true);
} }
// 获取目录下所有文件 List<FileSystemEntity> allFiles = [];
final files =
await sourceDir.list().where((entity) => entity is File).toList();
int addUp = 0; for (final dir in sourceDirs) {
for (final fileEntity in files) { if (await dir.exists()) {
final files =
await dir.list().where((entity) => entity is File).toList();
allFiles.addAll(files);
}
}
// 此时 allFiles 包含 MeetingAudio 和 DestAudio 目录下所有的文件
for (final fileEntity in allFiles) {
try { try {
final file = File(fileEntity.path); final file = File(fileEntity.path);
final filePath = file.path; final filePath = file.path;

17
lib/modules/meeting/controllers/meeting_record_controller.dart

@ -335,10 +335,19 @@ class MeetingRecordController extends GetxController
final appDir = await appDocDir; final appDir = await appDocDir;
final dir = Directory("${appDir.path}/MeetingAudio/"); final dir = Directory("${appDir.path}/MeetingAudio/");
if (!await dir.exists()) await dir.create(recursive: true); if (!await dir.exists()) await dir.create(recursive: true);
await _asrService.renameFile( if (isMarked.value) {
"${dir.path}/${fileName.value}.wav", final Newdir = Directory("${appDir.path}/DestAudio/");
newName.value, if (!await Newdir.exists()) await Newdir.create(recursive: true);
); await _asrService.moveFile(
"${dir.path}/${fileName.value}.wav",
"${Newdir.path}/${fileName.value}.wav",
);
} else {
await _asrService.renameFile(
"${dir.path}/${fileName.value}.wav",
newName.value,
);
}
} }
await _asrService.stopContinuousRecognition(); await _asrService.stopContinuousRecognition();

62
lib/modules/translation/controllers/translation_controller.dart

@ -36,6 +36,11 @@ class TranslationController extends GetxController {
final bleManager = Get.find<BleManager>(); final bleManager = Get.find<BleManager>();
// 音频输入源 // 音频输入源
bool _audioSourceType = false; bool _audioSourceType = false;
// 倒计时器
final RxString recordDurationText = '00:00'.obs;
Timer? _recordTimer;
int _seconds = 0;
// 存储相关 // 存储相关
static const String _historyKey = 'translation_history'; static const String _historyKey = 'translation_history';
static const String _sourceLanguageKey = 'translation_source_language'; static const String _sourceLanguageKey = 'translation_source_language';
@ -198,7 +203,7 @@ class TranslationController extends GetxController {
return true; return true;
} else { } else {
Logger.d("Permission", "用户未授予存储权限"); Logger.d("Permission", "用户未授予存储权限");
return false; return true;
} }
} catch (e) { } catch (e) {
Logger.e("Permission", "请求存储权限时出错: $e"); Logger.e("Permission", "请求存储权限时出错: $e");
@ -267,16 +272,45 @@ class TranslationController extends GetxController {
Future<void> toggleisRecord() async { Future<void> toggleisRecord() async {
isRecording.toggle(); isRecording.toggle();
if (isRecording.value && isRecognizing.value) { if (isRecording.value && isRecognizing.value) {
// 使用可读性更好的时间格式 startRecording();
final formattedTime =
DateFormat('yyyyMMdd_HHmmss').format(DateTime.now());
await _asrService.enableRecord(
"${dir.path}/${currentModeTitle.value.tr}_$formattedTime.wav");
} else if (!isRecording.value) { } else if (!isRecording.value) {
await _asrService.stopRecord(true); stopRecording();
} else {} } else {}
} }
Future<void> startRecording() async {
final bool storage = await _requestStoragePermission();
if (!storage) {
Logger.d("Permission", "未授予存储权限,无法提供录音功能");
return;
}
//isRecording.value = true;
_seconds = 0;
recordDurationText.value = '00:00';
_recordTimer = Timer.periodic(Duration(seconds: 1), (_) {
_seconds++;
final minutes = (_seconds ~/ 60).toString().padLeft(2, '0');
final seconds = (_seconds % 60).toString().padLeft(2, '0');
recordDurationText.value = '$minutes:$seconds';
});
// 启动实际录音逻辑
// ...
final formattedTime = DateFormat('yyyyMMdd_HHmmss').format(DateTime.now());
await _asrService.enableRecord(
"${dir.path}/${currentModeTitle.value.tr}_$formattedTime.wav");
}
Future<void> stopRecording() async {
_recordTimer?.cancel();
_recordTimer = null;
isRecording.value = false;
recordDurationText.value = '00:00';
await _asrService.stopRecord(true);
// 停止实际录音逻辑
// ...
}
// 开始语音识别 // 开始语音识别
Future<void> startRecognition() async { Future<void> startRecognition() async {
Logger.info('开始语音识别'); Logger.info('开始语音识别');
@ -343,15 +377,7 @@ class TranslationController extends GetxController {
await _asrService.startContinuousRecognition(_audioSourceType); await _asrService.startContinuousRecognition(_audioSourceType);
isRecognizing.value = true; isRecognizing.value = true;
if (isRecording.value && isRecognizing.value) { if (isRecording.value && isRecognizing.value) {
final bool storage = await _requestStoragePermission(); startRecording();
if (!storage) {
Logger.d("Permission", "未授予存储权限,无法提供录音功能");
return;
}
final formattedTime =
DateFormat('yyyyMMdd_HHmmss').format(DateTime.now());
await _asrService.enableRecord(
"${dir.path}/${currentModeTitle.value.tr}_$formattedTime.wav");
} }
// 监听识别结果 // 监听识别结果
_recognitionSubscription?.cancel(); _recognitionSubscription?.cancel();
@ -411,7 +437,7 @@ class TranslationController extends GetxController {
saveTranslationHistory(); saveTranslationHistory();
} }
stopRecording();
currentSessionId = null; currentSessionId = null;
} catch (e) { } catch (e) {
Logger.error('停止语音识别失败: ${e.toString()}'); Logger.error('停止语音识别失败: ${e.toString()}');
@ -607,7 +633,7 @@ class TranslationController extends GetxController {
if (isRecognizing.value) { if (isRecognizing.value) {
await stopRecognition(); await stopRecognition();
} }
await _asrService.stopRecord(true); stopRecording();
_translationDebounceTimer?.cancel(); _translationDebounceTimer?.cancel();
await _ttsService.stop(); await _ttsService.stop();
} catch (e) { } catch (e) {

95
lib/modules/translation/views/translation_view.dart

@ -107,37 +107,70 @@ class TranslationView extends GetView<TranslationController> {
)), )),
centerTitle: true, centerTitle: true,
actions: [ actions: [
// TTS toggle button Obx(() {
Obx(() => IconButton( if (controller.isRecording.value) {
icon: Icon( // 录音中:显示红色计时器样式,点击可停止录音
controller.isRecording.value return Padding(
? Icons.mic padding: EdgeInsets.only(right: 16.w),
: Icons.fiber_manual_record, child: GestureDetector(
color: isDarkMode ? Colors.white : Colors.black, onTap: controller.toggleisRecord, // 点击结束录音
size: 24.sp, child: Container(
padding: EdgeInsets.symmetric(horizontal: 8.w, vertical: 4.h),
decoration: BoxDecoration(
color: Colors.red,
borderRadius: BorderRadius.circular(20.r),
),
child: Row(
children: [
Icon(
Icons.fiber_manual_record,
color: Colors.white,
size: 18.sp,
),
SizedBox(width: 4.w),
Text(
controller.recordDurationText.value,
style: TextStyle(
color: Colors.white,
fontSize: 14.sp,
fontWeight: FontWeight.bold,
),
),
],
),
),
), ),
// onPressed: controller.toggleTts,默认播放 );
onPressed: controller.toggleisRecord, } else {
tooltip: '是否开启录音', // 未录音:显示红色录音按钮 + 文件夹按钮
)), return Row(
children: [
// 历史记录按钮 IconButton(
IconButton( icon: Icon(
icon: Icon( Icons.radio_button_checked,
Icons.folder, color: Colors.red,
color: isDarkMode ? Colors.white : Colors.black, size: 24.sp,
size: 24.sp, ),
), onPressed: controller.toggleisRecord,
onPressed: () async { tooltip: '是否开启录音',
// 停止语音识别和TTS,释放资源 ),
await controller.stopAll(); IconButton(
Get.toNamed(Routes.translationList); icon: Icon(
Icons.folder,
// 返回时不自动开始翻译,只需重新设置滚动监听器 color: isDarkMode ? Colors.white : Colors.black,
controller.setupScrollListener(); size: 24.sp,
}, ),
tooltip: '查看录音文件', onPressed: () async {
), await controller.stopAll();
Get.toNamed(Routes.translationList);
controller.setupScrollListener();
},
tooltip: '查看录音文件',
),
],
);
}
}),
], ],
bottom: PreferredSize( bottom: PreferredSize(
preferredSize: Size.fromHeight(50.h), preferredSize: Size.fromHeight(50.h),
@ -328,7 +361,7 @@ class TranslationView extends GetView<TranslationController> {
onTap: () => controller.playTranslationItem(item), onTap: () => controller.playTranslationItem(item),
child: Icon( child: Icon(
Icons.volume_up, Icons.volume_up,
size: 18, size: 20,
color: Theme.of(context).colorScheme.primary, color: Theme.of(context).colorScheme.primary,
), ),
), ),

Loading…
Cancel
Save