|
|
|
@ -25,7 +25,7 @@ enum TimerStatus { |
|
|
|
/// 负责会议记录的状态管理、音频处理、语音识别和UI交互 |
|
|
|
class MeetingRecordController extends GetxController |
|
|
|
with GetTickerProviderStateMixin { |
|
|
|
// Services |
|
|
|
// 服务 |
|
|
|
final AsrService _asrService = Get.find<AsrService>(); |
|
|
|
final BleManager _bleManager = Get.find<BleManager>(); |
|
|
|
|
|
|
|
@ -45,7 +45,7 @@ class MeetingRecordController extends GetxController |
|
|
|
|
|
|
|
final RecorderController waveformController = RecorderController(); |
|
|
|
|
|
|
|
// Transcription content |
|
|
|
// 转写内容 |
|
|
|
final RxString intermediateContent = ''.obs; |
|
|
|
final RxString finalContent = ''.obs; |
|
|
|
|
|
|
|
@ -57,7 +57,7 @@ class MeetingRecordController extends GetxController |
|
|
|
late FocusNode titleFocusNode; |
|
|
|
final Future<Directory> appDocDir = getApplicationDocumentsDirectory(); |
|
|
|
|
|
|
|
// Timing variables |
|
|
|
// 计时变量 |
|
|
|
Timer? _timer; |
|
|
|
int _elapsedMilliseconds = 0; |
|
|
|
int? _lastStartTime; |
|
|
|
@ -107,19 +107,19 @@ class MeetingRecordController extends GetxController |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
/// Initializes UI controllers and focus nodes |
|
|
|
/// 初始化 UI 控制器和焦点节点 |
|
|
|
void _initializeComponents() { |
|
|
|
titleEditingController = TextEditingController(text: fileName.value); |
|
|
|
titleFocusNode = FocusNode(); |
|
|
|
titleFocusNode.addListener(_handleTitleFocusChange); |
|
|
|
} |
|
|
|
|
|
|
|
/// Sets up initial state from navigation arguments |
|
|
|
/// 根据路由参数设置初始状态 |
|
|
|
void _setupFromArguments() { |
|
|
|
final Map<String, dynamic> args = Get.arguments ?? {}; |
|
|
|
audioType.value = args['audioTypes'] ?? 0; |
|
|
|
|
|
|
|
// Set default filename based on audio type |
|
|
|
// 根据音频类型设置默认文件名 |
|
|
|
switch (audioType.value) { |
|
|
|
case 0: |
|
|
|
fileName.value = "liveRecording".tr; //对应中文:现场录音 |
|
|
|
@ -134,7 +134,7 @@ class MeetingRecordController extends GetxController |
|
|
|
newName.value = fileName.value; |
|
|
|
} |
|
|
|
|
|
|
|
/// Cleans up resources when controller is disposed |
|
|
|
/// 控制器销毁时清理资源 |
|
|
|
void _cleanupResources() { |
|
|
|
_timer?.cancel(); |
|
|
|
_stopWaveformTimer(); |
|
|
|
@ -156,14 +156,14 @@ class MeetingRecordController extends GetxController |
|
|
|
waveformController.dispose(); |
|
|
|
} |
|
|
|
|
|
|
|
/// Handles focus changes in title text field |
|
|
|
/// 处理标题输入框焦点变化 |
|
|
|
void _handleTitleFocusChange() { |
|
|
|
if (!titleFocusNode.hasFocus && isEditingTitle.value) { |
|
|
|
saveTitleChange(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
/// Starts title editing mode |
|
|
|
/// 开始标题编辑模式 |
|
|
|
void startTitleEditing() { |
|
|
|
isEditingTitle.value = true; |
|
|
|
titleEditingController.text = fileName.value; |
|
|
|
@ -173,7 +173,7 @@ class MeetingRecordController extends GetxController |
|
|
|
}); |
|
|
|
} |
|
|
|
|
|
|
|
/// Saves new title and exits editing mode |
|
|
|
/// 保存新标题后退出编辑状态 |
|
|
|
Future<void> saveTitleChange() async { |
|
|
|
isEditingTitle.value = true; |
|
|
|
if (isEditingTitle.value) { |
|
|
|
@ -183,12 +183,12 @@ class MeetingRecordController extends GetxController |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
/// Toggles visibility of transcribed text content |
|
|
|
/// 切换转写文本内容的显示状态 |
|
|
|
Future<void> toggleTextDisplay() async { |
|
|
|
showTextContent.toggle(); |
|
|
|
} |
|
|
|
|
|
|
|
/// Toggles important mark status |
|
|
|
/// 切换重要标记状态 |
|
|
|
void toggleMarked() => isMarked.toggle(); |
|
|
|
|
|
|
|
/// 格式化时间为 MM:SS.S 显示格式 |
|
|
|
@ -204,7 +204,7 @@ class MeetingRecordController extends GetxController |
|
|
|
'.${centiseconds.toString()}'; |
|
|
|
} |
|
|
|
|
|
|
|
/// Starts/resumes recording based on current state |
|
|
|
/// 根据当前状态开始或恢复录音 |
|
|
|
Future<void> toggleRecording() async { |
|
|
|
// 等待权限请求完成并获取结果 |
|
|
|
final bool granted = await _requestRecordPermission(); |
|
|
|
@ -229,7 +229,7 @@ class MeetingRecordController extends GetxController |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
/// Starts recording session |
|
|
|
/// 开始录音会话 |
|
|
|
Future<void> _startRecording() async { |
|
|
|
// Prepare storage directory |
|
|
|
final appDir = await appDocDir; |
|
|
|
@ -260,7 +260,7 @@ class MeetingRecordController extends GetxController |
|
|
|
}); |
|
|
|
|
|
|
|
isRecording.value = true; |
|
|
|
// Update state |
|
|
|
// 更新录音状态 |
|
|
|
fileName.value = fullFileName; |
|
|
|
newName.value = fullFileName; |
|
|
|
titleEditingController.text = fullFileName; |
|
|
|
@ -272,7 +272,7 @@ class MeetingRecordController extends GetxController |
|
|
|
startTimer(); |
|
|
|
} |
|
|
|
|
|
|
|
/// Activates appropriate hardware service based on audio type |
|
|
|
/// 根据音频类型启动对应的硬件服务 |
|
|
|
void _startHardwareServices() { |
|
|
|
switch (audioType.value) { |
|
|
|
case 0: |
|
|
|
@ -289,7 +289,7 @@ class MeetingRecordController extends GetxController |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
/// Pauses current recording session |
|
|
|
/// 暂停当前录音会话 |
|
|
|
Future<void> _pauseRecording() async { |
|
|
|
await _asrService.pauseRecord(); |
|
|
|
_stopWaveformTimer(); |
|
|
|
@ -297,7 +297,7 @@ class MeetingRecordController extends GetxController |
|
|
|
pauseTimer(); |
|
|
|
} |
|
|
|
|
|
|
|
/// Resumes paused recording session |
|
|
|
/// 恢复已暂停的录音会话 |
|
|
|
Future<void> _resumeRecording() async { |
|
|
|
await _asrService.resumeRecord(); |
|
|
|
_startWaveformTimer(); |
|
|
|
@ -370,7 +370,7 @@ class MeetingRecordController extends GetxController |
|
|
|
return (rms / 32768.0).clamp(0.0, 1.0); |
|
|
|
} |
|
|
|
|
|
|
|
/// Saves recording and cleans up resources |
|
|
|
/// 保存录音并清理相关资源 |
|
|
|
Future<void> saveRecording() async { |
|
|
|
resetTimer(); |
|
|
|
_stopWaveformTimer(); |
|
|
|
@ -380,7 +380,7 @@ class MeetingRecordController extends GetxController |
|
|
|
if (!isRecording.value) return; |
|
|
|
await _asrService.stopRecord(true); |
|
|
|
|
|
|
|
// Rename file if title was edited |
|
|
|
// 如果标题被修改则重命名文件 |
|
|
|
if (fileName.value != newName.value) { |
|
|
|
final appDir = await appDocDir; |
|
|
|
final dir = Directory("${appDir.path}/MeetingAudio/"); |
|
|
|
@ -408,7 +408,7 @@ class MeetingRecordController extends GetxController |
|
|
|
_resetWaveform(); |
|
|
|
} |
|
|
|
|
|
|
|
/// Resets controller to initial state |
|
|
|
/// 将控制器重置到初始状态 |
|
|
|
void _resetToDefaultState() { |
|
|
|
switch (audioType.value) { |
|
|
|
case 0: |
|
|
|
@ -427,7 +427,7 @@ class MeetingRecordController extends GetxController |
|
|
|
isMarked.value = false; |
|
|
|
} |
|
|
|
|
|
|
|
/// TIMER CONTROL SECTION /// |
|
|
|
/// 计时器控制部分 /// |
|
|
|
|
|
|
|
/// 启动定时器 |
|
|
|
void startTimer() { |
|
|
|
@ -449,7 +449,7 @@ class MeetingRecordController extends GetxController |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
/// Pauses active timer |
|
|
|
/// 暂停当前计时器 |
|
|
|
void pauseTimer() { |
|
|
|
if (timerStatus.value == TimerStatus.running) { |
|
|
|
timerStatus.value = TimerStatus.paused; |
|
|
|
@ -462,7 +462,7 @@ class MeetingRecordController extends GetxController |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
/// Resets timer to initial state |
|
|
|
/// 将计时器重置到初始状态 |
|
|
|
void resetTimer() { |
|
|
|
_timer?.cancel(); |
|
|
|
_timer = null; |
|
|
|
|