Browse Source

Merge branch 'new_dev' of https://github.com/deepcloud2048/deep_voice into new_dev

newdev_shunjiawei
fdp 1 year ago
parent
commit
fd9489b77e
  1. 27
      lib/core/translations/language/en_us.dart
  2. 27
      lib/core/translations/language/zh_cn.dart
  3. 2
      lib/modules/agent/views/music_card.dart
  4. 57
      lib/modules/devices/views/devices_view.dart
  5. 10
      lib/modules/meeting/controllers/meeting_connect_controller.dart
  6. 35
      lib/modules/meeting/controllers/meeting_home_controller.dart
  7. 9
      lib/modules/meeting/views/tabs/overview_tab.dart
  8. 70
      lib/modules/settings/controllers/settings_controller.dart
  9. 131
      lib/modules/translation/views/translation_view.dart
  10. 5
      local_plugins/agent_service/ios/agent_service/Sources/agent_service/AgentServiceImpl.swift
  11. 1
      local_plugins/ble_service/android/src/main/kotlin/com/yunqiinnovation/ble_service/BleCompanionManager.kt
  12. 6
      local_plugins/music_service/ios/music_service/Sources/music_service/MusicService.swift

27
lib/core/translations/language/en_us.dart

@ -485,11 +485,11 @@ const Map<String, String> enUS = {
'networkErrorRetry': 'Network error, please try again later',
// 设备管理相关
'clearPairedDevices': 'Clear Paired Devices',
'clearPairedDevicesConfirm':
'Are you sure you want to clear all paired devices?',
'clearPairedDevicesSuccess': 'Clear paired devices successfully',
'clearPairedDevicesFailed': 'Clear paired devices failed',
// 'clearPairedDevices': 'Clear Paired Devices',
// 'clearPairedDevicesConfirm':
// 'Are you sure you want to clear all paired devices?',
// 'clearPairedDevicesSuccess': 'Clear paired devices successfully',
// 'clearPairedDevicesFailed': 'Clear paired devices failed',
// 设置页面 - 实时语音对话
'realtimeVoiceChat': 'Real-time Voice Chat',
@ -498,11 +498,20 @@ const Map<String, String> enUS = {
'loading': 'Loading...',
//设备管理页面
"earphone": "Earphone", // 耳机
"voicerecorder": "Voice Recorder", // 录音笔
"notBound": "Not Bound", // 未绑定
"deviceNotBoundYet": "Device not bound yet", // 还未绑定设备
"deviceTypeUnknown": "Unknown Device",
"deviceTypeClassicBluetoothHeadset": "Classic Bluetooth Headset",
"deviceTypeBleBluetoothHeadset": "BLE Bluetooth Headset",
"deviceTypeSmartVoiceRecorder": "Smart Voice Recorder",
"deviceTypeSmartEye": "Smart Glasses",
"unbind": "Unbind", // 解绑
"noDevicesBound": "No devices bound yet",
"pleaseBindDeviceFirst": "Please bind a device first to manage",
"noMacAddress": "No MAC Address",
"licenseCode": "License Code",
"confirmUnbind": "Confirm Unbind",
"confirmUnbindMessage":
"Are you sure you want to unbind device \"{deviceName}\"?",
"confirmUnbindAction": "Confirm Unbind",
// Agent模块
//Agent View

27
lib/core/translations/language/zh_cn.dart

@ -399,7 +399,8 @@ const Map<String, String> zhCN = {
// Meeting模块 - 云端同步相关
'syncToCloud': '同步到云端',
'syncToCloudTip': '自动将你的录音同步到云端,你可以通过任意VOITRANS APP或VOITRANS Web(web.voitrans.com)播放、管理和分享录音。',
'syncToCloudTip':
'自动将你的录音同步到云端,你可以通过任意VOITRANS APP或VOITRANS Web(web.voitrans.com)播放、管理和分享录音。',
'syncToVoitransApp': '同步VOITRANS APP',
'transcriptionRecord': '转写记录',
@ -458,10 +459,10 @@ const Map<String, String> zhCN = {
'networkErrorRetry': '网络错误,请稍后重试',
// 设备管理相关
'clearPairedDevices': '清除配对设备',
'clearPairedDevicesConfirm': '确定要清除所有配对设备吗?',
'clearPairedDevicesSuccess': '清除配对设备成功',
'clearPairedDevicesFailed': '清除配对设备失败',
// 'clearPairedDevices': '清除配对设备',
// 'clearPairedDevicesConfirm': '确定要清除所有配对设备吗?',
// 'clearPairedDevicesSuccess': '清除配对设备成功',
// 'clearPairedDevicesFailed': '清除配对设备失败',
// 设置页面 - 实时语音对话
"realtimeVoiceChat": "实时语音对话",
@ -469,11 +470,19 @@ const Map<String, String> zhCN = {
"loading": "加载中...",
//设备管理页面
"earphone": "耳机",
"voicerecorder": "录音笔",
"notBound": "未绑定",
"deviceNotBoundYet": "还未绑定设备",
"deviceTypeUnknown": "未知设备",
"deviceTypeClassicBluetoothHeadset": "经典蓝牙耳机",
"deviceTypeBleBluetoothHeadset": "BLE蓝牙耳机",
"deviceTypeSmartVoiceRecorder": "智能录音笔",
"deviceTypeSmartEye": "智能眼镜",
"unbind": "解绑",
"noDevicesBound": "暂未绑定任何设备",
"pleaseBindDeviceFirst": "请先绑定设备后再进行管理",
"noMacAddress": "无MAC地址",
"licenseCode": "授权码",
"confirmUnbind": "确认解绑",
"confirmUnbindMessage": "确定要解绑设备 \"{deviceName}\" 吗?",
"confirmUnbindAction": "确认解绑",
//Agent 模块
// agent View

2
lib/modules/agent/views/music_card.dart

@ -233,7 +233,7 @@ Widget buildMusicContent(
final id = item["id"];
final name = item["name"] ?? "未知歌曲";
final url = item["url"] ?? "";
final singer = item["sgener"] ?? "未知歌手";
final singer = item["singer"] ?? "未知歌手";
final image = item["image"] ?? "";
final ts = item["ts"] ?? 0;
return Column(

57
lib/modules/devices/views/devices_view.dart

@ -10,15 +10,30 @@ import '../controllers/devices_controller.dart';
// 设备类型枚举
enum DeviceType {
Unknown(0, "未知设备"),
Classic_bluetooth_Headset(1, "经典蓝牙耳机"),
BLE_Bluetooth_Headset(2, "BLE蓝牙耳机"),
Smart_Voice_Recorder(3, "智能录音笔"),
SmartEye(4, "智能眼镜");
Unknown(0),
Classic_bluetooth_Headset(1),
BLE_Bluetooth_Headset(2),
Smart_Voice_Recorder(3),
SmartEye(4);
const DeviceType(this.value, this.displayName);
const DeviceType(this.value);
final int value;
final String displayName;
// 使用getter获取多语言显示名称
String get displayName {
switch (this) {
case DeviceType.Unknown:
return "deviceTypeUnknown".tr;
case DeviceType.Classic_bluetooth_Headset:
return "deviceTypeClassicBluetoothHeadset".tr;
case DeviceType.BLE_Bluetooth_Headset:
return "deviceTypeBleBluetoothHeadset".tr;
case DeviceType.Smart_Voice_Recorder:
return "deviceTypeSmartVoiceRecorder".tr;
case DeviceType.SmartEye:
return "deviceTypeSmartEye".tr;
}
}
static DeviceType fromValue(int value) {
return DeviceType.values.firstWhere(
@ -168,7 +183,7 @@ class DevicesView extends GetView<DevicesController> {
),
SizedBox(height: 20.h),
Text(
"暂未绑定任何设备",
"noDevicesBound".tr,
style: TextStyle(
fontSize: 16.sp,
color: isDarkMode ? Colors.white70 : Colors.grey[600],
@ -176,7 +191,7 @@ class DevicesView extends GetView<DevicesController> {
),
SizedBox(height: 12.h),
Text(
"请先绑定设备后再进行管理",
"pleaseBindDeviceFirst".tr,
style: TextStyle(
fontSize: 14.sp,
color: isDarkMode ? Colors.white54 : Colors.grey[500],
@ -230,7 +245,9 @@ class DevicesView extends GetView<DevicesController> {
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
device.devicename.isNotEmpty ? device.devicename : "未知设备",
device.devicename.isNotEmpty
? device.devicename
: "deviceTypeUnknown".tr,
style: TextStyle(
fontSize: 16.sp,
fontWeight: FontWeight.w500,
@ -239,7 +256,9 @@ class DevicesView extends GetView<DevicesController> {
),
SizedBox(height: 4.h),
Text(
device.devicemac.isNotEmpty ? device.devicemac : "无MAC地址",
device.devicemac.isNotEmpty
? device.devicemac
: "noMacAddress".tr,
style: TextStyle(
fontSize: 14.sp,
color: isDarkMode ? Colors.white70 : Colors.grey[600],
@ -248,7 +267,7 @@ class DevicesView extends GetView<DevicesController> {
if (device.license.isNotEmpty) ...[
SizedBox(height: 4.h),
Text(
"授权码: ${device.license}",
"${"licenseCode".tr}: ${device.license}",
style: TextStyle(
fontSize: 12.sp,
color: isDarkMode ? Colors.white54 : Colors.grey[500],
@ -294,13 +313,15 @@ class DevicesView extends GetView<DevicesController> {
AlertDialog(
backgroundColor: isDarkMode ? AppColors.cardBackground : Colors.white,
title: Text(
"确认解绑",
"confirmUnbind".tr,
style: TextStyle(
color: isDarkMode ? Colors.white : Colors.black87,
),
),
content: Text(
"确定要解绑设备 \"${device.devicename}\" 吗?",
"confirmUnbindMessage"
.tr
.replaceAll('{deviceName}', device.devicename),
style: TextStyle(
color: isDarkMode ? Colors.white70 : Colors.black54,
),
@ -309,7 +330,7 @@ class DevicesView extends GetView<DevicesController> {
TextButton(
onPressed: () => Get.back(),
child: Text(
"取消",
"cancel".tr,
style: TextStyle(
color: isDarkMode ? Colors.white70 : Colors.grey[600],
),
@ -320,9 +341,9 @@ class DevicesView extends GetView<DevicesController> {
Get.back();
controller.unbindearphone(device);
},
child: const Text(
"确认解绑",
style: TextStyle(color: Colors.red),
child: Text(
"confirmUnbindAction".tr,
style: const TextStyle(color: Colors.red),
),
),
],

10
lib/modules/meeting/controllers/meeting_connect_controller.dart

@ -227,8 +227,11 @@ class MeetingConnectController extends GetxController {
(sum, entry) => sum + (entry.size ?? 0),
);
for (var i = 0; i < listDirectory.length; i++) {
importedFilesStr.value =
'downloadingFileProgress'.trParams({'total': '${listDirectory.length}', 'current': '${i + 1}'}); // 对应中文:共{total}个文件,正在下载第{current}个文件
importedFilesStr.value = 'downloadingFileProgress'
.tr
.replaceAll('{total}', '${listDirectory.length}')
.replaceAll('{current}',
'${i + 1}'); // 对应中文:共{total}个文件,正在下载第{current}个文件
int previousSize = i > 0 ? listDirectory[i - 1].size ?? 0 : 0;
FTPEntry element = listDirectory[i];
await _downloadFile(totalSize, previousSize, element);
@ -236,7 +239,8 @@ class MeetingConnectController extends GetxController {
}
await _disconnect();
stateStr.value = 'downloadComplete'.tr; // 对应中文:下载完成
importedFilesStr.value = 'downloadCompleteInfo'.trParams({'count': '${listDirectory.length}'}); // 对应中文:下载完成,共{count}个文件,2秒后自动返回
importedFilesStr.value = 'downloadCompleteInfo'.tr.replaceAll('{count}',
'${listDirectory.length}'); // 对应中文:下载完成,共{count}个文件,2秒后自动返回
Future.delayed(const Duration(seconds: 2), () {
_executeUpload();
Get.back();

35
lib/modules/meeting/controllers/meeting_home_controller.dart

@ -95,7 +95,7 @@ class MeetingHomeController extends GetxController {
final deviceInfo = DeviceInfoPlugin();
final androidInfo = await deviceInfo.androidInfo;
final sdkVersion = androidInfo.version.sdkInt;
// Android 11+ (API 30+) 不需要存储权限
if (sdkVersion >= 30) {
Logger.d("Permission", "Android 11+版本,无需请求存储权限");
@ -106,13 +106,15 @@ class MeetingHomeController extends GetxController {
// 如果获取版本失败,为了兼容性还是请求权限
}
}
PermissionUtil.instance
.requestPermission(
permissionType: Permission.storage,
permissionName: "meetingStoragePermission".tr, // 对应中文:存储
explanationText: "meetingStoragePermissionExplanation".tr, // 对应中文:我们需要访问存储权限,以便您可以选择并上传音频文件。
permanentDenialText: "meetingStoragePermissionPermanentDenial".tr, // 对应中文:检测到您已永久拒绝存储权限。如需继续使用此功能,请前往应用设置中手动开启存储权限。
explanationText: "meetingStoragePermissionExplanation"
.tr, // 对应中文:我们需要访问存储权限,以便您可以选择并上传音频文件。
permanentDenialText: "meetingStoragePermissionPermanentDenial"
.tr, // 对应中文:检测到您已永久拒绝存储权限。如需继续使用此功能,请前往应用设置中手动开启存储权限。
)
.then((granted) {
if (granted) {
@ -169,7 +171,9 @@ class MeetingHomeController extends GetxController {
EasyLoading.showToast('shareComplete'.tr); // 对应中文:分享完成!
} catch (e) {
EasyLoading.showToast('shareFailed'.trParams({'error': e.toString()})); // 对应中文:分享失败: {error}
EasyLoading.showToast('shareFailed'
.tr
.replaceAll('{error}', e.toString())); // 对应中文:分享失败: {error}
}
}
@ -258,12 +262,21 @@ class MeetingHomeController extends GetxController {
addUp++;
}
} catch (e) {
print('fileProcessingFailed'.trParams({'filePath': fileEntity.path, 'error': e.toString()})); // 对应中文:文件处理失败: {filePath}, 错误: {error}
print('fileProcessingFailed'
.tr
.replaceAll('{filePath}', fileEntity.path)
.replaceAll('{error}',
e.toString())); // 对应中文:文件处理失败: {filePath}, 错误: {error}
}
}
if (addUp > 0) EasyLoading.showSuccess('importSuccess'.trParams({'count': '$addUp'})); // 对应中文:成功导入本地 {count} 条录音
if (addUp > 0)
EasyLoading.showSuccess('importSuccess'
.tr
.replaceAll('{count}', '$addUp')); // 对应中文:成功导入本地 {count} 条录音
} catch (e) {
EasyLoading.showError('importError'.trParams({'error': e.toString()})); // 对应中文:导入失败: {error}
EasyLoading.showError('importError'
.tr
.replaceAll('{error}', e.toString())); // 对应中文:导入失败: {error}
} finally {
EasyLoading.dismiss();
}
@ -308,7 +321,11 @@ class MeetingHomeController extends GetxController {
}
}
} catch (e) {
Logger.error('importFailed'.trParams({'filePath': filePath, 'error': e.toString()})); // 对应中文:导入文件失败: {filePath}, error: {error}
Logger.error('importFailed'
.tr
.replaceAll('{filePath}', filePath)
.replaceAll('{error}',
e.toString())); // 对应中文:导入文件失败: {filePath}, error: {error}
}
}
EasyLoading.dismiss();

9
lib/modules/meeting/views/tabs/overview_tab.dart

@ -71,7 +71,8 @@ class _OverviewTabState extends State<OverviewTab> {
Padding(
padding: EdgeInsets.symmetric(vertical: 10.w),
child: Text(
'keyEventsAnalyzed'.trParams({'count': '${_dataList.length}'}), // 对应中文:分析出{count}个关键事件。
'keyEventsAnalyzed'.tr.replaceAll('{count}',
'${_dataList.length}'), // 对应中文:分析出{count}个关键事件。
style: TextStyle(
color: isDarkMode ? Colors.grey[400] : Colors.grey,
fontSize: 12.sp,
@ -106,7 +107,8 @@ class _OverviewTabState extends State<OverviewTab> {
Get.bottomSheet(
const AIBottomSheet(),
isScrollControlled: true,
backgroundColor: isDarkMode ? Colors.grey[800] : Colors.white,
backgroundColor:
isDarkMode ? Colors.grey[800] : Colors.white,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.vertical(
top: Radius.circular(12.r),
@ -125,7 +127,8 @@ class _OverviewTabState extends State<OverviewTab> {
Get.bottomSheet(
const GenerateBottomSheet(),
isScrollControlled: true,
backgroundColor: isDarkMode ? Colors.grey[800] : Colors.grey[100],
backgroundColor:
isDarkMode ? Colors.grey[800] : Colors.grey[100],
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.vertical(
top: Radius.circular(12.r),

70
lib/modules/settings/controllers/settings_controller.dart

@ -466,42 +466,42 @@ class SettingsController extends GetxController {
}
/// 清除BLE配对设备
Future<void> clearBleDevices() async {
// 显示确认对话框
final confirmed = await Get.dialog<bool>(
AlertDialog(
title: const Text('清除配对设备'),
content: const Text('确定要清除所有BLE配对设备吗?此操作不可撤销。'),
actions: [
TextButton(
onPressed: () => Get.back(result: false),
child: Text('cancel'.tr),
),
TextButton(
onPressed: () => Get.back(result: true),
style: TextButton.styleFrom(
foregroundColor: Colors.red,
),
child: Text('confirm'.tr), //确认
),
],
),
);
// Future<void> clearBleDevices() async {
// // 显示确认对话框
// final confirmed = await Get.dialog<bool>(
// AlertDialog(
// title: const Text('清除配对设备'),
// content: const Text('确定要清除所有BLE配对设备吗?此操作不可撤销。'),
// actions: [
// TextButton(
// onPressed: () => Get.back(result: false),
// child: Text('cancel'.tr),
// ),
// TextButton(
// onPressed: () => Get.back(result: true),
// style: TextButton.styleFrom(
// foregroundColor: Colors.red,
// ),
// child: Text('confirm'.tr), //确认
// ),
// ],
// ),
// );
if (confirmed == true) {
try {
final bleManager = Get.find<BleManager>();
final result = await bleManager.clearPairedDevices();
if (result) {
Get.snackbar('成功', 'BLE配对设备已清除');
} else {
Get.snackbar('失败', '清除BLE配对设备失败');
}
} catch (e) {
Get.snackbar('错误', '清除BLE配对设备时发生错误');
}
}
}
// if (confirmed == true) {
// try {
// final bleManager = Get.find<BleManager>();
// final result = await bleManager.clearPairedDevices();
// if (result) {
// Get.snackbar('成功', 'BLE配对设备已清除');
// } else {
// Get.snackbar('失败', '清除BLE配对设备失败');
// }
// } catch (e) {
// Get.snackbar('错误', '清除BLE配对设备时发生错误');
// }
// }
// }
/// 手动检查版本更新
Future<void> checkForUpdate() async {

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

@ -206,16 +206,35 @@ class TranslationView extends GetView<TranslationController> {
: Colors.grey[100],
borderRadius: BorderRadius.circular(16.r),
),
child: Obx(() => Text(
'${controller.targetLanguage.value.split(' ')[0]}'
.tr, // Just show the English part
style: TextStyle(
fontSize: 16.sp,
fontWeight: FontWeight.w600,
color: isDarkMode ? Colors.white : Colors.black,
),
textAlign: TextAlign.center,
overflow: TextOverflow.ellipsis,
child: Obx(() => Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Flexible(
child: Text(
'${controller.targetLanguage.value.split(' ')[0]}'
.tr,
style: TextStyle(
fontSize: 16.sp,
fontWeight: FontWeight.w600,
color:
isDarkMode ? Colors.white : Colors.black,
),
textAlign: TextAlign.center,
overflow: TextOverflow.ellipsis,
),
),
//只在通话翻译模式下显示电话图标
if (controller.currentMode.value == 'call') ...[
SizedBox(width: 4.w),
Icon(
Icons.phone_in_talk,
size: 20.sp,
color: isDarkMode
? Colors.white70
: Colors.grey[600],
),
],
],
)),
),
),
@ -418,23 +437,27 @@ class TranslationView extends GetView<TranslationController> {
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
// 耳机图标按钮 (说话者1)
_buildHoldToTalkButton(
isDarkMode: isDarkMode,
speakerId: 1,
activeSpeaker: controller.activeSpeaker.value,
icon: Icons.headset,
label: "headsetUser".tr,
),
SizedBox(width: 40.w),
// 手机图标按钮 (说话者2)
_buildHoldToTalkButton(
isDarkMode: isDarkMode,
speakerId: 2,
activeSpeaker: controller.activeSpeaker.value,
icon: Icons.phone_android,
label: "phoneUser".tr,
),
// 耳机图标按钮 (说话者1)-显示源语言
Obx(() => _buildHoldToTalkButton(
isDarkMode: isDarkMode,
speakerId: 1,
activeSpeaker: controller.activeSpeaker.value,
icon: Icons.mic_none,
label: controller.sourceLanguage.value
.split(' ')[0]
.tr, // 源语言名称
)),
SizedBox(width: 16.w),
// 手机图标按钮 (说话者2)-显示目标语言
Obx(() => _buildHoldToTalkButton(
isDarkMode: isDarkMode,
speakerId: 2,
activeSpeaker: controller.activeSpeaker.value,
icon: Icons.mic_none,
label: controller.targetLanguage.value
.split(' ')[0]
.tr, // 目标语言名称
)),
],
)
else
@ -569,15 +592,15 @@ class TranslationView extends GetView<TranslationController> {
},
child: AnimatedContainer(
duration: const Duration(milliseconds: 200),
width: 80.w,
height: 80.w,
width: 160.w, // 长条形宽度
height: 54.h, // 长条形高度
decoration: BoxDecoration(
color: isActive
? (isDarkMode ? Colors.green[700] : Colors.green)
: (isDisabled
? (isDarkMode ? Colors.grey[800] : Colors.grey[300])
: (isDarkMode ? AppColors.primary : Colors.blue)),
shape: BoxShape.circle,
borderRadius: BorderRadius.circular(25.r), // 圆角长条形
boxShadow: isActive
? [
BoxShadow(
@ -586,32 +609,42 @@ class TranslationView extends GetView<TranslationController> {
spreadRadius: 3,
)
]
: null,
: [
BoxShadow(
color: (isDarkMode ? Colors.black : Colors.grey)
.withOpacity(0.2),
blurRadius: 8,
spreadRadius: 1,
offset: Offset(0, 2),
)
],
),
child: Column(
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Stack(
alignment: Alignment.center,
children: [
// 设备类型图标
Icon(
icon,
// 左边图标
Icon(
icon,
color: isActive
? Colors.white
: Colors.white.withOpacity(isDisabled ? 0.3 : 0.9),
size: 20.sp,
),
SizedBox(width: 8.w), // 图标和文字间距
// 右边语言名称
Flexible(
child: Text(
label,
style: TextStyle(
fontSize: 12.sp,
fontWeight: FontWeight.w500,
color: isActive
? Colors.white
: Colors.white.withOpacity(isDisabled ? 0.3 : 0.9),
size: 24.sp,
),
],
),
SizedBox(height: 4.h),
Text(
label,
style: TextStyle(
fontSize: 12.sp,
color: isActive
? Colors.white
: Colors.white.withOpacity(isDisabled ? 0.3 : 0.9),
textAlign: TextAlign.center,
maxLines: 1,
overflow: TextOverflow.ellipsis, // 防止文本溢出
),
),
],

5
local_plugins/agent_service/ios/agent_service/Sources/agent_service/AgentServiceImpl.swift

@ -1450,6 +1450,7 @@ extension AgentServiceImpl: TtsEventListener {
restartIdleCheck()
sendEvent(name: "tts_started", data: ["status": "started"])
audioPlayer?.stopAwaitSound()
case .synthesisCompleted:
isSpeaking = false
restartIdleCheck()
@ -1458,11 +1459,11 @@ extension AgentServiceImpl: TtsEventListener {
case .playbackStarted:
restartIdleCheck()
sendEvent(name: "playback_started", data: ["status": "playback_started"])
MusicService.shared.reduceVolume()
case .playbackCompleted:
restartIdleCheck()
sendEvent(name: "playback_completed", data: ["status": "playback_completed"])
MusicService.shared.restoreVolume()
case .synthesisCanceled:
isSpeaking = false
restartIdleCheck()

1
local_plugins/ble_service/android/src/main/kotlin/com/yunqiinnovation/ble_service/BleCompanionManager.kt

@ -395,6 +395,7 @@ class BleCompanionManager(private val context: Context) {
// 构建过滤器
val filter = ScanFilter.Builder()
.setDeviceAddress(mac)
// .setServiceUuid(ParcelUuid(java.util.UUID.fromString("0000FEAA-0000-1000-8000-00805F9B34FB")))
.setManufacturerData(0xEFAB, byteArrayOf(0xA0.toByte(), 0x01))
.build()

6
local_plugins/music_service/ios/music_service/Sources/music_service/MusicService.swift

@ -273,10 +273,10 @@ public class MusicService: NSObject {
}
/// 降低音量(AI说话时)
func reduceVolume() {
public func reduceVolume() {
if !isVolumeReduced {
originalVolume = currentVolume
let reducedVolume = max(0.0, min(1.0, currentVolume * 0.3)) // 降低到30%
let reducedVolume = max(0.0, min(1.0, currentVolume * 0.2)) // 降低到30%
setVolume(volume: reducedVolume)
isVolumeReduced = true
print("AI说话开始,音量从 \(originalVolume) 降低到 \(reducedVolume)")
@ -284,7 +284,7 @@ public class MusicService: NSObject {
}
/// 恢复原始音量(AI说话结束时)
func restoreVolume() {
public func restoreVolume() {
if isVolumeReduced {
setVolume(volume: originalVolume)
isVolumeReduced = false

Loading…
Cancel
Save