Browse Source

feat(语音支持): 新增多种语言和方言的语音支持

添加葡萄牙语(葡萄牙)、保加利亚语、斯洛伐克语、斯洛文尼亚语、立陶宛语、拉脱维亚语、爱沙尼亚语、塞尔维亚语、冰岛语、阿拉伯语(沙特)和菲律宾语的语音支持
统一处理语言代码大小写转换,特别处理菲律宾语(tl-PH)映射为fil-PH
weicu
lxm 9 months ago
parent
commit
b663b04b20
  1. 37
      lib/data/services/ble_manager.dart
  2. 19
      lib/modules/settings/controllers/settings_controller.dart
  3. 11
      local_plugins/agent_service/android/src/main/kotlin/com/yunqiinnovation/agent_service/AgentService.kt
  4. 22
      local_plugins/agent_service/ios/agent_service/Sources/agent_service/AgentServiceImpl.swift

37
lib/data/services/ble_manager.dart

@ -2,8 +2,6 @@ import 'dart:async';
import 'dart:convert';
import 'dart:io';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter_dotenv/flutter_dotenv.dart';
import 'package:get_storage/get_storage.dart';
import 'package:get/get.dart';
import 'package:ble_service/ble_service.dart';
@ -882,7 +880,7 @@ class BleManager extends GetxService {
AppConfig.env('XUNFEI_ASR_ACCESS_KEY_SECRET') ?? '';
// 从Flutter资源包中加载.mcp.json
final jsonData = AppConfig.mcpConfig();
Logger.info('启动BLE服务,musicServiceType: ${musicServiceType}');
Logger.info('启动BLE服务,musicServiceType: $musicServiceType');
final isTtsInterruptEnabled = await _loadTtsInterrupe();
final vipExpiryTime = userInfo.User.instance.vipexptime;
@ -901,26 +899,24 @@ class BleManager extends GetxService {
// 用户设置了特定语言
final parts = savedLanguage.split('_');
if (parts.length == 2) {
final lang = parts[0];
final lang = parts[0].toLowerCase();
final country = parts[1].toUpperCase();
if (lang == 'zh' &&
(country == 'HK' || country == 'TW' || country == 'CN')) {
supportedLanguages.add('zh-$country');
} else if (lang == 'tl' && country == 'PH') {
// 菲律宾语特殊处理,映射为azure语言码
supportedLanguages.add('fil-PH');
} else {
final asrCode = languageManager.getAsrCodeByShortCode(lang);
if (asrCode != null) {
supportedLanguages.add(asrCode);
} else {
supportedLanguages.add('$lang-$country');
}
supportedLanguages.add('$lang-$country');
}
}
} else {
// 跟随系统语言或未设置
final appLocale = Get.locale ?? AppTranslations.deviceLocale();
if (appLocale != null) {
final lang = appLocale.languageCode;
final lang = appLocale.languageCode.toLowerCase();
final country = appLocale.countryCode;
if (lang.toLowerCase() == 'zh' &&
@ -931,13 +927,20 @@ class BleManager extends GetxService {
country.toUpperCase() == 'CN')) {
supportedLanguages.add('zh-${country.toUpperCase()}');
} else {
final asrCode = languageManager.getAsrCodeByShortCode(lang);
if (asrCode != null) {
supportedLanguages.add(asrCode);
} else if (country != null && country.isNotEmpty) {
supportedLanguages.add('$lang-$country');
if (country != null && country.isNotEmpty) {
final normalizedCountry = country.toUpperCase();
if (lang == 'tl' && normalizedCountry == 'PH') {
supportedLanguages.add('fil-PH');
} else {
supportedLanguages.add('$lang-$normalizedCountry');
}
} else {
supportedLanguages.add('en-US');
final asrCode = languageManager.getAsrCodeByShortCode(lang);
if (asrCode != null) {
supportedLanguages.add(asrCode);
} else {
supportedLanguages.add('en-US');
}
}
}
}

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

@ -165,7 +165,13 @@ class SettingsController extends GetxController {
final lang = matchedLocale.languageCode;
final country = matchedLocale.countryCode;
if (country != null && country.isNotEmpty) {
supportedLanguages.add('$lang-$country');
final normalizedLang = lang.toLowerCase();
final normalizedCountry = country.toUpperCase();
if (normalizedLang == 'tl' && normalizedCountry == 'PH') {
supportedLanguages.add('fil-PH');
} else {
supportedLanguages.add('$normalizedLang-$normalizedCountry');
}
} else {
// 根据语言代码映射到对应的ASR代码
final asrCode = languageManager.getAsrCodeByShortCode(lang);
@ -182,19 +188,16 @@ class SettingsController extends GetxController {
// 根据选择的语言值映射到ASR代码
final parts = languageModel.value.split('_');
if (parts.length == 2) {
final lang = parts[0];
final lang = parts[0].toLowerCase();
final country = parts[1].toUpperCase();
if (lang == 'zh' &&
(country == 'HK' || country == 'TW' || country == 'CN')) {
supportedLanguages.add('zh-$country');
} else if (lang == 'tl' && country == 'PH') {
supportedLanguages.add('fil-PH');
} else {
final asrCode = languageManager.getAsrCodeByShortCode(lang);
if (asrCode != null) {
supportedLanguages.add(asrCode);
} else {
supportedLanguages.add('$lang-$country');
}
supportedLanguages.add('$lang-$country');
}
}
}

11
local_plugins/agent_service/android/src/main/kotlin/com/yunqiinnovation/agent_service/AgentService.kt

@ -1547,6 +1547,7 @@ object AgentService : CoroutineScope {
"fr-FR" -> "fr-FR-DeniseNeural"
"es-ES" -> "es-ES-ElviraNeural"
"pt-BR" -> "pt-BR-FranciscaNeural"
"pt-PT" -> "pt-PT-RaquelNeural"
"it-IT" -> "it-IT-ElsaNeural"
"de-DE" -> "de-DE-KatjaNeural"
"ru-RU" -> "ru-RU-SvetlanaNeural"
@ -1563,10 +1564,20 @@ object AgentService : CoroutineScope {
"nb-NO" -> "nb-NO-IselinNeural"
"hr-HR" -> "hr-HR-GabrijelaNeural"
"ca-ES" -> "ca-ES-JoanaNeural"
"bg-BG" -> "bg-BG-KalinaNeural"
"sk-SK" -> "sk-SK-ViktoriaNeural"
"sl-SI" -> "sl-SI-PetraNeural"
"lt-LT" -> "lt-LT-OnaNeural"
"lv-LV" -> "lv-LV-EveritaNeural"
"et-EE" -> "et-EE-AnuNeural"
"sr-RS" -> "sr-RS-SophieNeural"
"is-IS" -> "is-IS-GudrunNeural"
// 阿拉伯语和非洲语言
"ar-EG" -> "ar-EG-SalmaNeural"
"ar-SA" -> "ar-SA-ZariyahNeural"
"sw-KE" -> "sw-KE-ZuriNeural"
"fil-PH" -> "fil-PH-BlessicaNeural"
else -> {
Log.w(TAG, "未支持的语言代码: $asrCode,使用默认英语语音")

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

@ -1608,6 +1608,8 @@ private func jsonToString(_ json: [String: Any]) -> String? {
return "es-ES-ElviraNeural"
case "pt-BR":
return "pt-BR-FranciscaNeural"
case "pt-PT":
return "pt-PT-RaquelNeural"
case "it-IT":
return "it-IT-ElsaNeural"
case "de-DE":
@ -1640,12 +1642,32 @@ private func jsonToString(_ json: [String: Any]) -> String? {
return "hr-HR-GabrijelaNeural"
case "ca-ES":
return "ca-ES-JoanaNeural"
case "bg-BG":
return "bg-BG-KalinaNeural"
case "sk-SK":
return "sk-SK-ViktoriaNeural"
case "sl-SI":
return "sl-SI-PetraNeural"
case "lt-LT":
return "lt-LT-OnaNeural"
case "lv-LV":
return "lv-LV-EveritaNeural"
case "et-EE":
return "et-EE-AnuNeural"
case "sr-RS":
return "sr-RS-SophieNeural"
case "is-IS":
return "is-IS-GudrunNeural"
// 阿拉伯语和非洲语言
case "ar-EG":
return "ar-EG-SalmaNeural"
case "ar-SA":
return "ar-SA-ZariyahNeural"
case "sw-KE":
return "sw-KE-ZuriNeural"
case "fil-PH":
return "fil-PH-BlessicaNeural"
default:
os_log("未支持的语言代码: %{public}@,使用默认英语语音", log: logger, type: .error, asrCode)

Loading…
Cancel
Save