diff --git a/lib/core/translations/language/en_us.dart b/lib/core/translations/language/en_us.dart index 1ea125f22..a5b86bc55 100644 --- a/lib/core/translations/language/en_us.dart +++ b/lib/core/translations/language/en_us.dart @@ -305,8 +305,20 @@ const Map enUS = { "loadFailedClickRetry": "Load failed, click to retry", "swipeUpForMore": "Swipe up for more", - // Agent Controller - 'welcomeMessage': 'Hello! I\'m **XiaoYan**, I can help you:\n\n' + // Preset prompts + "presetMusic": "Play some music", // Play some music + "presetNavigation": "Navigation to", // Navigation + "presetWeather": "Today's weather", // Weather + "presetNews": "Today's news", // News + "presetFood": "Nearby food", // Food + "playSomeMusic": "Play some popular music", // 播放一些流行音乐 + "navigationTo": "Please help me navigate to", // 导航到 + "todayWeather": "How's the weather today?", // 今日天气 + "todayNews": "What's the news today?", // 今日新闻 + "nearbyFood": "What delicious food is nearby?", // 美食 + + // Agent controller + 'welcomeMessage': 'Hello! I\'m **Xiaoyan**, I can help you:\n\n' '• Answer questions and provide information\n\n' '• Real-time voice translation\n\n' '• Recommend music and podcasts\n\n' diff --git a/lib/core/translations/language/zh_cn.dart b/lib/core/translations/language/zh_cn.dart index f52ebd4ab..2dc75a89b 100644 --- a/lib/core/translations/language/zh_cn.dart +++ b/lib/core/translations/language/zh_cn.dart @@ -295,6 +295,18 @@ const Map zhCN = { "loadFailedClickRetry": "加载失败,点击重试", "swipeUpForMore": "向上滑动查看更多", + // 预设提示词 + "presetMusic": "来点音乐", // 来点音乐 + "presetNavigation": "导航到", // 导航 + "presetWeather": "今日天气", // 今日天气 + "presetNews": "今日新闻", // 今日新闻 + "presetFood": "附近美食", // 美食 + "playSomeMusic": "播放一些流行音乐", // 播放一些流行音乐 + "navigationTo": "请帮我导航到", // 导航到 + "todayWeather": "今天天气如何?", // 今日天气 + "todayNews": "今天有哪些新闻?", // 今日新闻 + "nearbyFood": "附近有哪些美食?", // 美食 + // Agent controller 'welcomeMessage': '你好!我是**小言**,我能帮你:\n\n' '• 答问题和提供信息\n\n' diff --git a/lib/data/services/meeting/meeting_task_service.dart b/lib/data/services/meeting/meeting_task_service.dart index e4603a4ad..ccae12596 100644 --- a/lib/data/services/meeting/meeting_task_service.dart +++ b/lib/data/services/meeting/meeting_task_service.dart @@ -26,7 +26,7 @@ class MeetingTaskService extends GetxService { final String _appid = '2316081933'; final String _token = 'mcJTh6OelBqU_L78lgGd77Nyrc_-5-En'; - final String _cluster = 'volc_auc_common_flash'; + final String _cluster = 'volc_auc_tele_flash'; final String _serviceUrl = 'https://openspeech.bytedance.com/api/v1/auc'; Map _headers = {}; diff --git a/lib/modules/agent/controllers/agent_controller.dart b/lib/modules/agent/controllers/agent_controller.dart index e786100ac..f8e64bd27 100644 --- a/lib/modules/agent/controllers/agent_controller.dart +++ b/lib/modules/agent/controllers/agent_controller.dart @@ -1287,6 +1287,41 @@ class AgentController extends GetxController { useImagePrompt('请翻译这张图片中的文字'); } + // 预设提示词处理(文本输入模式) + void preSetPromptAction(String presetType) { + // 确保在文本输入模式下 + if (!isTextInputMode.value) { + // 如果不在文本模式,先切换到文本模式 + isTextInputMode.value = true; + } + + switch (presetType) { + case 'Music': + textController.text = 'playSomeMusic'.tr; + break; + case 'Navigation': + textController.text = 'navigationTo'.tr; + break; + case 'Weather': + textController.text = 'todayWeather'.tr; + break; + case 'News': + textController.text = 'todayNews'.tr; + break; + case 'Food': + textController.text = 'nearbyFood'.tr; + break; + default: + textController.text = presetType; + break; + } + + // 自动发送消息 + if (presetType != 'Navigation') { + sendMessage(); + } + } + // 模式历史记录 VoiceInputMode? _previousInputMode; diff --git a/lib/modules/agent/views/agent_view.dart b/lib/modules/agent/views/agent_view.dart index da7e2bff0..dc39fe3c8 100644 --- a/lib/modules/agent/views/agent_view.dart +++ b/lib/modules/agent/views/agent_view.dart @@ -341,80 +341,127 @@ class _AgentViewState extends State with WidgetsBindingObserver { child: Column( children: [ // 图片预览区域 - 仅在图片输入模式下显示 - Obx(() { - if (controller.isImageInputActive.value && - controller.selectedImagePath.value != null) { - return Column( - children: [ - // 图片预览和关闭按钮 - Stack( - children: [ - ClipRRect( - borderRadius: BorderRadius.circular(12.w), - child: Image.file( - File(controller.selectedImagePath.value!), - height: 150.h, - width: double.infinity, - fit: BoxFit.cover, + Obx( + () { + if (controller.isImageInputActive.value && + controller.selectedImagePath.value != null) { + return Column( + children: [ + // 图片预览和关闭按钮 + Stack( + children: [ + ClipRRect( + borderRadius: BorderRadius.circular(12.w), + child: Image.file( + File(controller.selectedImagePath.value!), + height: 150.h, + width: double.infinity, + fit: BoxFit.cover, + ), ), - ), - Positioned( - top: 8.h, - right: 8.w, - child: GestureDetector( - onTap: () => controller.clearImageInput(), - child: Container( - padding: EdgeInsets.all(4.w), - decoration: BoxDecoration( - color: Colors.black.withOpacity(0.6), - shape: BoxShape.circle, - ), - child: Icon( - Icons.close, - color: Colors.white, - size: 16.sp, + Positioned( + top: 8.h, + right: 8.w, + child: GestureDetector( + onTap: () => controller.clearImageInput(), + child: Container( + padding: EdgeInsets.all(4.w), + decoration: BoxDecoration( + color: Colors.black.withOpacity(0.6), + shape: BoxShape.circle, + ), + child: Icon( + Icons.close, + color: Colors.white, + size: 16.sp, + ), ), ), ), - ), - ], - ), - - // 预设提示选项 - SizedBox(height: 12.h), - SingleChildScrollView( - scrollDirection: Axis.horizontal, - child: Row( - children: [ - _buildPromptChip( - context: context, - label: 'summarizeImageContent'.tr, //总结图片内容 - onTap: () => controller.summarizeImage(), - ), - SizedBox(width: 8.w), - _buildPromptChip( - context: context, - label: 'extractImageText'.tr, //抽取图像文字 - onTap: () => - controller.extractTextFromImage(), - ), - SizedBox(width: 8.w), - _buildPromptChip( - context: context, - label: 'translateImageText'.tr, //翻译图像文字 - onTap: () => - controller.translateImageText(), - ), ], ), - ), - SizedBox(height: 12.h), - ], - ); - } else { - return const SizedBox.shrink(); - } - }), + + // 预设提示选项 + SizedBox(height: 12.h), + SingleChildScrollView( + scrollDirection: Axis.horizontal, + child: Row( + children: [ + _buildPromptChip( + context: context, + label: + 'summarizeImageContent'.tr, //总结图片内容 + onTap: () => controller.summarizeImage(), + ), + SizedBox(width: 8.w), + _buildPromptChip( + context: context, + label: 'extractImageText'.tr, //抽取图像文字 + onTap: () => + controller.extractTextFromImage(), + ), + SizedBox(width: 8.w), + _buildPromptChip( + context: context, + label: 'translateImageText'.tr, //翻译图像文字 + onTap: () => + controller.translateImageText(), + ), + ], + ), + ), + SizedBox(height: 12.h), + ], + ); + } else if (controller.isTextInputMode.value && + !controller.hasTextInput.value) { + // 文本输入模式下,且输入框为空 + return Column( + children: [ + SingleChildScrollView( + scrollDirection: Axis.horizontal, + child: Row( + children: [ + _buildPromptChip( + context: context, + label: 'presetMusic'.tr, // 来点音乐 + onTap: () => controller + .preSetPromptAction('Music')), + SizedBox(width: 8.w), + _buildPromptChip( + context: context, + label: 'presetNavigation'.tr, // 导航 + onTap: () => + controller.preSetPromptAction( + 'Navigation')), + SizedBox(width: 8.w), + _buildPromptChip( + context: context, + label: 'presetWeather'.tr, // 天气 + onTap: () => controller + .preSetPromptAction('Weather')), + SizedBox(width: 8.w), + _buildPromptChip( + context: context, + label: 'presetNews'.tr, // 新闻 + onTap: () => controller + .preSetPromptAction('News')), + SizedBox(width: 8.w), + _buildPromptChip( + context: context, + label: 'presetFood'.tr, // 美食 + onTap: () => controller + .preSetPromptAction('Food')), + ], + )), + SizedBox(height: 12.h), + ], + ); + } else { + return const SizedBox.shrink(); + } + }, + ), // 输入控件区域 - 包含输入行和展开的选项 Column( diff --git a/lib/modules/meeting/controllers/meeting_record_controller.dart b/lib/modules/meeting/controllers/meeting_record_controller.dart index b30651e28..47e656df3 100644 --- a/lib/modules/meeting/controllers/meeting_record_controller.dart +++ b/lib/modules/meeting/controllers/meeting_record_controller.dart @@ -61,10 +61,10 @@ class MeetingRecordController extends GetxController StreamSubscription? _audioDataSubscription; // 添加波形放大倍数变量 - final double waveAmplifyFactor = 100.0; // 增加波动幅度 + final double waveAmplifyFactor = 250.0; // 增加波动幅度 final RxDouble ursorPosition = 0.0.obs; // 当前播放位置 final RxInt _currentPosition = 0.obs; // 原始位置索引 - int maxPoints = 500; // 最大显示点数(根据屏幕宽度优化) + int maxPoints = 300; // 最大显示点数(根据屏幕宽度优化) int sampleRate = 16000; // 假设音频采样率(根据实际情况调整) // 波形流动动画控制器 @@ -72,7 +72,7 @@ class MeetingRecordController extends GetxController late Animation waveformAnimation; // 设置最大点数(根据屏幕宽度) void setMaxPoints(double screenWidth) { - maxPoints = screenWidth ~/ 2; // 每2像素一个数据点 + maxPoints = screenWidth ~/ 3; // 增加数据点密度以填满整个区域 } @override @@ -377,7 +377,7 @@ class MeetingRecordController extends GetxController return _currentPosition.value / waveData.length; } - /// 添加处理后的音频数据 - 优化流动效果 + /// 添加处理后的音频数据 - 优化全屏流动效果 void _addAudioData(Float32List newAudio) { if (!isRecording.value) return; @@ -389,8 +389,8 @@ class MeetingRecordController extends GetxController for (final sample in downsampled) { waveData.add(sample); - //维护合理的数据长度 - 保持滑动窗口效果 - if (waveData.length > maxPoints) { + // 维护合理的数据长度 - 保持足够的数据以填满整个屏幕 + if (waveData.length > maxPoints * 2) { waveData.removeAt(0); // 移除最旧的数据 } } diff --git a/lib/modules/meeting/views/meeting_record_view.dart b/lib/modules/meeting/views/meeting_record_view.dart index 3784e9673..6ddb25a75 100644 --- a/lib/modules/meeting/views/meeting_record_view.dart +++ b/lib/modules/meeting/views/meeting_record_view.dart @@ -477,10 +477,10 @@ class RealTimeWaveformPainter extends CustomPainter { } } - /// 绘制中央时间参考线 + /// 绘制中央时间参考线(只保留水平线) void _drawCenterLine( Canvas canvas, Size size, double centerX, double centerY) { - // 绘制水平中线 + // 只绘制水平中线 final horizontalLinePaint = Paint() ..color = (isDarkMode ? Colors.white : Colors.black).withValues(alpha: 0.15) @@ -492,51 +492,25 @@ class RealTimeWaveformPainter extends CustomPainter { horizontalLinePaint, ); - // 绘制垂直时间参考线(红色,更醒目) - final centerLinePaint = Paint() - ..color = Colors.red.withValues(alpha: 0.8) - ..strokeWidth = 2.0 - ..style = PaintingStyle.stroke; - - canvas.drawLine( - Offset(centerX, centerY - size.height * 0.4), - Offset(centerX, centerY + size.height * 0.4), - centerLinePaint, - ); - - // 在参考线顶部绘制小三角形指示器 - final trianglePath = Path(); - final triangleSize = 4.0; - trianglePath.moveTo(centerX, centerY - size.height * 0.4); - trianglePath.lineTo( - centerX - triangleSize, centerY - size.height * 0.4 - triangleSize); - trianglePath.lineTo( - centerX + triangleSize, centerY - size.height * 0.4 - triangleSize); - trianglePath.close(); - - final trianglePaint = Paint() - ..color = Colors.red - ..style = PaintingStyle.fill; - - canvas.drawPath(trianglePath, trianglePaint); + // 移除垂直时间参考线和三角形指示器 } - /// 绘制实时流动波形 + /// 绘制实时流动波形(扩散到整个区域) void _drawWaveform(Canvas canvas, Size size, double centerX, double centerY) { final barWidth = 2.5; // 波形条宽度 final barSpacing = 0.5; // 波形条间距 final totalBarWidth = barWidth + barSpacing; - // 计算中央参考线左侧可以显示多少个波形条 - final maxBarsOnLeft = (centerX / totalBarWidth).floor(); + // 计算整个宽度可以显示多少个波形条 + final maxBars = (size.width / totalBarWidth).floor(); - // 绘制左侧流动波形(历史数据,从右向左流动) - _drawLeftWaveform( - canvas, centerX, centerY, barWidth, totalBarWidth, maxBarsOnLeft); + // 绘制扩散到整个区域的波形 + _drawFullWaveform( + canvas, size, centerY, barWidth, totalBarWidth, maxBars); } - /// 绘制左侧历史波形(从右向左流动) - void _drawLeftWaveform(Canvas canvas, double centerX, double centerY, + /// 绘制扩散到整个区域的波形 + void _drawFullWaveform(Canvas canvas, Size size, double centerY, double barWidth, double totalBarWidth, int maxBars) { final dataLength = waveData.length; if (dataLength == 0) return; @@ -544,24 +518,25 @@ class RealTimeWaveformPainter extends CustomPainter { // 计算流动偏移量 final flowOffset = animationValue * totalBarWidth; - // 绘制最近的波形条(最多显示maxBars个) + // 绘制波形条,从左到右填满整个区域 final displayCount = min(dataLength, maxBars); for (int i = 0; i < displayCount; i++) { - // 计算波形条的x位置:从参考线开始,向左排列,加上流动偏移 - final x = centerX - (i + 1) * totalBarWidth + flowOffset; + // 计算波形条的x位置:从左边开始排列,加上流动偏移 + final x = i * totalBarWidth + flowOffset; + // 如果波形条完全移出屏幕右侧,跳过绘制 + if (x > size.width) continue; // 如果波形条完全移出屏幕左侧,跳过绘制 if (x + barWidth < 0) continue; - // 获取对应的音频数据(最新的数据在数组末尾) - final dataIndex = dataLength - 1 - i; - if (dataIndex < 0) continue; - + // 获取对应的音频数据(循环使用数据以填满整个区域) + final dataIndex = (dataLength - 1 - (i % dataLength)) % dataLength; final amplitude = waveData[dataIndex]; - // 计算透明度:越远的波形条越透明 - final opacity = (1.0 - (i / displayCount) * 0.6).clamp(0.2, 1.0); + // 计算透明度:中央区域更亮,边缘渐暗 + final distanceFromCenter = (x - size.width / 2).abs() / (size.width / 2); + final opacity = (1.0 - distanceFromCenter * 0.4).clamp(0.3, 1.0); _drawWaveBar(canvas, x, centerY, barWidth, amplitude, opacity); } diff --git a/lib/modules/ota_upgrade/controllers/ota_core_contropller.dart b/lib/modules/ota_upgrade/controllers/ota_core_contropller.dart index 2d02acd1c..5692515e2 100644 --- a/lib/modules/ota_upgrade/controllers/ota_core_contropller.dart +++ b/lib/modules/ota_upgrade/controllers/ota_core_contropller.dart @@ -53,6 +53,123 @@ class OtaCoreService { // ==================== 设备检查功能 ==================== + /// 检查BLE设备连接状态 + /// 返回true表示设备已连接,可以进行升级 + /// 返回false表示设备未连接,不能进行升级 + bool checkBleConnectionStatus() { + try { + // 检查BLE管理器的连接状态 + if (!_bleManager.isConnected) { + //_showBleDisconnectedDialog(); + return false; + } + + // 检查设备信息是否可用 + final deviceInfo = _bleManager.deviceInfo.value; + if (deviceInfo == null) { + _showDeviceInfoUnavailableDialog(); + return false; + } + + return true; + } catch (e) { + _showBleCheckFailedSnackbar('检查BLE连接状态时发生错误:$e'); + return false; + } + } + + /// 显示BLE设备未连接对话框 + void _showBleDisconnectedDialog() { + Get.dialog( + AlertDialog( + title: Text( + 'BLE设备未连接', + style: TextStyle( + color: Colors.red[700], + fontWeight: FontWeight.w600, + ), + ), + content: Text( + '固件升级需要连接BLE设备\n请确保设备已正确连接后再试', + style: TextStyle( + color: Colors.red[600], + ), + ), + actions: [ + TextButton( + onPressed: () => Get.back(), + style: TextButton.styleFrom( + foregroundColor: Colors.red[700], + ), + child: const Text('确定'), + ), + ], + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(12), + side: BorderSide( + color: Colors.red.withValues(alpha: 0.3), + width: 1, + ), + ), + backgroundColor: Colors.red[50], + ), + ); + } + + /// 显示设备信息不可用对话框 + void _showDeviceInfoUnavailableDialog() { + Get.dialog( + AlertDialog( + title: Text( + '设备信息不可用', + style: TextStyle( + color: Colors.orange[700], + fontWeight: FontWeight.w600, + ), + ), + content: Text( + '无法获取设备信息\n请重新连接设备或稍后再试', + style: TextStyle( + color: Colors.orange[600], + ), + ), + actions: [ + TextButton( + onPressed: () => Get.back(), + style: TextButton.styleFrom( + foregroundColor: Colors.orange[700], + ), + child: const Text('确定'), + ), + ], + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(12), + side: BorderSide( + color: Colors.orange.withValues(alpha: 0.3), + width: 1, + ), + ), + backgroundColor: Colors.orange[50], + ), + ); + } + + /// 显示BLE连接检查失败提示 + /// [message] 错误信息 + void _showBleCheckFailedSnackbar(String message) { + Get.snackbar( + 'BLE连接检查失败', + message, + snackPosition: SnackPosition.BOTTOM, + backgroundColor: Colors.red[600], + colorText: Colors.white, + icon: const Icon( + Icons.bluetooth_disabled, + color: Colors.white, + ), + ); + } + /// 检查设备电量是否满足升级条件 /// 返回true表示电量充足,可以进行升级 /// 返回false表示电量不足,不能进行升级 diff --git a/lib/modules/ota_upgrade/controllers/ota_upgrade_controller.dart b/lib/modules/ota_upgrade/controllers/ota_upgrade_controller.dart index 50d9385b4..9e56c02d8 100644 --- a/lib/modules/ota_upgrade/controllers/ota_upgrade_controller.dart +++ b/lib/modules/ota_upgrade/controllers/ota_upgrade_controller.dart @@ -27,11 +27,12 @@ class OtaUpgradeController extends GetxController { final RxDouble downloadProgress = 0.0.obs; final RxDouble progress = 0.0.obs; final RxInt type = OtaCoreService.NOT_STARTED.obs; - final RxBool isUpdateAvailable = true.obs; + final RxBool isUpdateAvailable = false.obs; final RxBool isDownloading = false.obs; final RxBool isUpgrade = false.obs; - final RxBool isFetchingDeviceInfo = true.obs; + final RxBool isFetchingDeviceInfo = false.obs; final RxBool showDetailedStatus = false.obs; + final RxBool isBleConnected = true.obs; String _address = ''; String _updatePackageAddress = ''; @@ -53,6 +54,14 @@ class OtaUpgradeController extends GetxController { /// 初始化控制器 /// 设置事件监听并加载版本信息 Future _initializeController() async { + // 首先检查BLE设备连接状态 + if (!_coreService.checkBleConnectionStatus()) { + //isFetchingDeviceInfo.value = false; + //errorMessage.value = 'unconnected'.tr; + isBleConnected.value = false; + + return; + } _listenToOtaEvents(); await _loadVersionInfo(); } diff --git a/lib/modules/ota_upgrade/views/ota_upgrade_view.dart b/lib/modules/ota_upgrade/views/ota_upgrade_view.dart index 922964c9d..e9011531a 100644 --- a/lib/modules/ota_upgrade/views/ota_upgrade_view.dart +++ b/lib/modules/ota_upgrade/views/ota_upgrade_view.dart @@ -397,7 +397,8 @@ class OtaUpgradeView extends GetView { ), // 版本状态指示器 SizedBox(height: 14.h), - _buildVersionStatusIndicator(isDarkMode), + if (controller.isBleConnected.value) + _buildVersionStatusIndicator(isDarkMode), ], ); } @@ -836,7 +837,9 @@ class OtaUpgradeView extends GetView { label: Text( controller.isUpdateAvailable.value ? 'ota_updateNow'.tr - : 'latestVersion'.tr, // 立即更新 : 已是最新版本 + : controller.isBleConnected.value + ? 'latestVersion'.tr // 立即更新 : 已是最新版本 + : 'unconnected'.tr, style: TextStyle( fontSize: 16.sp, fontWeight: FontWeight.w600, diff --git a/lib/modules/settings/views/settings_view.dart b/lib/modules/settings/views/settings_view.dart index 24aff0513..47d859ba3 100644 --- a/lib/modules/settings/views/settings_view.dart +++ b/lib/modules/settings/views/settings_view.dart @@ -515,22 +515,22 @@ class SettingsView extends GetView { // ? Colors.white.withOpacity(0.1) // : Colors.grey[200]), //BLE测试 - _buildSimpleNavigationSetting( - title: 'opus解码测试', - subtitle: '测试opus解码', - icon: Icons.bluetooth_searching, - iconBgColor: isDarkMode - ? Colors.green[900]!.withOpacity(0.3) - : Colors.green[100]!, - iconColor: - isDarkMode ? Colors.green[300]! : Colors.green[600]!, - titleColor: isDarkMode ? Colors.white : null, - subtitleColor: isDarkMode ? Colors.white70 : null, - onTap: () { - Get.toNamed(Routes.opusTest); - }, - isDarkMode: isDarkMode, - ), + // _buildSimpleNavigationSetting( + // title: 'opus解码测试', + // subtitle: '测试opus解码', + // icon: Icons.bluetooth_searching, + // iconBgColor: isDarkMode + // ? Colors.green[900]!.withOpacity(0.3) + // : Colors.green[100]!, + // iconColor: + // isDarkMode ? Colors.green[300]! : Colors.green[600]!, + // titleColor: isDarkMode ? Colors.white : null, + // subtitleColor: isDarkMode ? Colors.white70 : null, + // onTap: () { + // Get.toNamed(Routes.opusTest); + // }, + // isDarkMode: isDarkMode, + // ), // Divider( // height: 1, // color: isDarkMode diff --git a/lib/modules/translation/views/translation_view.dart b/lib/modules/translation/views/translation_view.dart index a5d4fbde3..bf11fd7bd 100644 --- a/lib/modules/translation/views/translation_view.dart +++ b/lib/modules/translation/views/translation_view.dart @@ -523,63 +523,63 @@ class TranslationView extends GetView { ), // 添加间距 - SizedBox(height: 16.h), + //SizedBox(height: 16.h), // 语音识别结果显示框 - Container( - width: double.infinity, - padding: EdgeInsets.all(12.w), - decoration: BoxDecoration( - color: isDarkMode ? Colors.grey[800] : Colors.grey[100], - borderRadius: BorderRadius.circular(8.r), - border: Border.all( - color: isDarkMode ? Colors.grey[600]! : Colors.grey[300]!, - width: 1, - ), - ), - child: Obx(() { - // 显示最新的语音识别结果 - final recognitionText = controller.latestRecognitionText.value; - final detectedLanguage = controller.detectedLanguageCode1.value; + // Container( + // width: double.infinity, + // padding: EdgeInsets.all(12.w), + // decoration: BoxDecoration( + // color: isDarkMode ? Colors.grey[800] : Colors.grey[100], + // borderRadius: BorderRadius.circular(8.r), + // border: Border.all( + // color: isDarkMode ? Colors.grey[600]! : Colors.grey[300]!, + // width: 1, + // ), + // ), + // child: Obx(() { + // // 显示最新的语音识别结果 + // final recognitionText = controller.latestRecognitionText.value; + // final detectedLanguage = controller.detectedLanguageCode1.value; - return Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - // 标题 - Text( - '麦头语音识别结果', - style: TextStyle( - fontSize: 12.sp, - color: isDarkMode ? Colors.grey[400] : Colors.grey[600], - fontWeight: FontWeight.w500, - ), - ), - SizedBox(height: 4.h), - // 识别文本 - 这里显示 finalResult1 的内容 - Text( - recognitionText.isEmpty ? '等待语音输入...' : recognitionText, - style: TextStyle( - fontSize: 14.sp, - color: isDarkMode ? Colors.white : Colors.black87, - height: 1.3, - ), - ), - // 检测到的语言(如果有) - if (detectedLanguage.isNotEmpty) ...[ - SizedBox(height: 4.h), - Text( - '检测语言: $detectedLanguage', - style: TextStyle( - fontSize: 10.sp, - color: - isDarkMode ? Colors.grey[500] : Colors.grey[500], - ), - ), - ], - ], - ); - }), - ), + // return Column( + // crossAxisAlignment: CrossAxisAlignment.start, + // children: [ + // // 标题 + // Text( + // '麦头语音识别结果', + // style: TextStyle( + // fontSize: 12.sp, + // color: isDarkMode ? Colors.grey[400] : Colors.grey[600], + // fontWeight: FontWeight.w500, + // ), + // ), + // SizedBox(height: 4.h), + // // 识别文本 - 这里显示 finalResult1 的内容 + // Text( + // recognitionText.isEmpty ? '等待语音输入...' : recognitionText, + // style: TextStyle( + // fontSize: 14.sp, + // color: isDarkMode ? Colors.white : Colors.black87, + // height: 1.3, + // ), + // ), + // // 检测到的语言(如果有) + // if (detectedLanguage.isNotEmpty) ...[ + // SizedBox(height: 4.h), + // Text( + // '检测语言: $detectedLanguage', + // style: TextStyle( + // fontSize: 10.sp, + // color: + // isDarkMode ? Colors.grey[500] : Colors.grey[500], + // ), + // ), + // ], + // ], + // ); + // }), + // ), ], ); }), diff --git a/local_plugins/azure_speech/android/src/main/kotlin/com/yunqiinnovation/azure_speech/AzureAsrHelper.kt b/local_plugins/azure_speech/android/src/main/kotlin/com/yunqiinnovation/azure_speech/AzureAsrHelper.kt index afc9e0409..519dd42e8 100644 --- a/local_plugins/azure_speech/android/src/main/kotlin/com/yunqiinnovation/azure_speech/AzureAsrHelper.kt +++ b/local_plugins/azure_speech/android/src/main/kotlin/com/yunqiinnovation/azure_speech/AzureAsrHelper.kt @@ -321,6 +321,7 @@ class AzureAsrHelper(private val context: Context) { isContinuousRecognitionActive = true return true } catch (e: Exception) { + Log.e(tag, "开始连续识别失败: ${e.message}") audioStream!!.stopMicrophoneCapture() isContinuousRecognitionActive = false return false diff --git a/local_plugins/azure_speech/android/src/main/kotlin/com/yunqiinnovation/azure_speech/tools/SimpleAudioReceiver.kt b/local_plugins/azure_speech/android/src/main/kotlin/com/yunqiinnovation/azure_speech/tools/SimpleAudioReceiver.kt index f2e39abcb..8da18ef18 100644 --- a/local_plugins/azure_speech/android/src/main/kotlin/com/yunqiinnovation/azure_speech/tools/SimpleAudioReceiver.kt +++ b/local_plugins/azure_speech/android/src/main/kotlin/com/yunqiinnovation/azure_speech/tools/SimpleAudioReceiver.kt @@ -236,7 +236,7 @@ class SimpleAudioReceiver(private val context: Context) { private fun runMicrophoneCapture() { try { // 首先设置通话音频模式 - setupCommunicationAudioMode() + //setupCommunicationAudioMode() val supportedSampleRates = intArrayOf(16000, 8000, 11025, 22050, 44100) val sampleRate = supportedSampleRates.firstOrNull { rate -> val bufferSize = AudioRecord.getMinBufferSize(rate, channelConfig, audioFormat) @@ -329,7 +329,7 @@ class SimpleAudioReceiver(private val context: Context) { audioRecord?.stop() // 恢复音频模式 这里会导致关闭麦克风卡住待优化 - restoreCommunicationAudioMode() + //restoreCommunicationAudioMode() } catch (e: Exception) { Log.e(TAG, "停止麦克风捕获失败: ${e.message}") diff --git a/local_plugins/ble_service/android/src/main/kotlin/com/yunqiinnovation/ble_service/BleService.kt b/local_plugins/ble_service/android/src/main/kotlin/com/yunqiinnovation/ble_service/BleService.kt index 1aa4eeca8..46568bf9c 100644 --- a/local_plugins/ble_service/android/src/main/kotlin/com/yunqiinnovation/ble_service/BleService.kt +++ b/local_plugins/ble_service/android/src/main/kotlin/com/yunqiinnovation/ble_service/BleService.kt @@ -1415,9 +1415,9 @@ startBytesStatistics() // 将新数据添加到缓冲区 audioBuffer.addAll(data.toList()) - // 当缓冲区达到80字节时,发送数据 + // 当缓冲区达到120字节时,发送数据 while (audioBuffer.size >= AUDIO_CHUNK_SIZE) { - // 取出80字节数据 + // 取出120字节数据 val chunk = ByteArray(AUDIO_CHUNK_SIZE) for (i in 0 until AUDIO_CHUNK_SIZE) { chunk[i] = audioBuffer.removeAt(0)