From 9065c39ef57003d0e604492d866c09608b5552c1 Mon Sep 17 00:00:00 2001 From: lxm <1274844347@qq.com> Date: Wed, 31 Dec 2025 16:08:18 +0800 Subject: [PATCH] =?UTF-8?q?feat(asr):=20=E6=B7=BB=E5=8A=A0=E8=AE=AF?= =?UTF-8?q?=E9=A3=9EASR=E6=94=AF=E6=8C=81=E5=B9=B6=E8=AE=B0=E5=BD=95ASR?= =?UTF-8?q?=E6=8F=90=E4=BE=9B=E5=95=86=E4=BF=A1=E6=81=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 在Azure ASR服务中集成讯飞ASR支持,添加ASR提供商字段并记录日志 修改各平台代码以传递和记录ASR提供商信息 添加讯飞ASR相关配置参数传递逻辑 --- lib/data/services/asr_service.dart | 7 ++++- lib/data/services/ble_manager.dart | 15 ++++++++-- .../speech_impl/azure_asr_service.dart | 24 ++++++++++++++- .../speech_impl/azure_ast_service.dart | 4 +-- .../agent/controllers/agent_controller.dart | 2 ++ .../controllers/translation_controller.dart | 2 ++ .../agent_service/AgentService.kt | 28 +++++++++++++++-- .../agent_service/AgentServicePlugin.kt | 3 ++ .../agent_service/BleMediaService.kt | 9 ++++++ .../agent_service/AgentServiceImpl.swift | 30 +++++++++++++++++-- .../azure_speech/AzureAsrHelper.kt | 4 +++ .../azure_speech/AzureSpeechPlugin.kt | 8 +++-- .../Sources/azure_speech/AzureAsrHelper.swift | 4 +++ .../azure_speech/AzureSpeechPlugin.swift | 14 +++++++-- 14 files changed, 138 insertions(+), 16 deletions(-) diff --git a/lib/data/services/asr_service.dart b/lib/data/services/asr_service.dart index 35c263e34..8bb7892c6 100644 --- a/lib/data/services/asr_service.dart +++ b/lib/data/services/asr_service.dart @@ -112,6 +112,8 @@ class RecognitionEvent { /// 检测到的语言 final String detectedLanguage; + final String provider; + /// 角色 final String role; @@ -125,6 +127,7 @@ class RecognitionEvent { required this.type, this.text = '', this.detectedLanguage = '', + this.provider = '', this.role = '', this.audio, this.error = '', @@ -134,11 +137,13 @@ class RecognitionEvent { factory RecognitionEvent.finalResult({ required String text, String detectedLanguage = '', + String provider = '', }) { return RecognitionEvent( type: RecognitionEventType.finalResult, text: text, detectedLanguage: detectedLanguage, + provider: provider, ); } @@ -160,6 +165,6 @@ class RecognitionEvent { @override String toString() { - return 'RecognitionEvent{type: $type, text: $text, detectedLanguage: $detectedLanguage, error: $error}'; + return 'RecognitionEvent{type: $type, provider: $provider, text: $text, detectedLanguage: $detectedLanguage, error: $error}'; } } diff --git a/lib/data/services/ble_manager.dart b/lib/data/services/ble_manager.dart index 1d7df2f6e..c0afa44cf 100644 --- a/lib/data/services/ble_manager.dart +++ b/lib/data/services/ble_manager.dart @@ -875,6 +875,10 @@ class BleManager extends GetxService { } final navigationMode = AppConfig.env('APP_NAVIGATION_MODE') ?? 'external_auto'; + final xunfeiAppId = AppConfig.env('XUNFEI_ASR_APP_ID') ?? ''; + final xunfeiAccessKeyId = AppConfig.env('XUNFEI_ASR_ACCESS_KEY_ID') ?? ''; + final xunfeiAccessKeySecret = + AppConfig.env('XUNFEI_ASR_ACCESS_KEY_SECRET') ?? ''; // 从Flutter资源包中加载.mcp.json final jsonData = AppConfig.mcpConfig(); Logger.info('启动BLE服务,musicServiceType: ${musicServiceType}'); @@ -939,6 +943,9 @@ class BleManager extends GetxService { // 语音代理配置参数 'azureSpeechKey': azureSpeechKey, 'azureSpeechRegion': azureSpeechRegion, + 'xunfeiAppId': xunfeiAppId, + 'xunfeiAccessKeyId': xunfeiAccessKeyId, + 'xunfeiAccessKeySecret': xunfeiAccessKeySecret, 'openaiApiKey': openaiApiKey, 'openaiBaseUrl': openaiBaseUrl, 'openaiModel': openaiModel, @@ -958,8 +965,12 @@ class BleManager extends GetxService { "insufficientIntegralText": "insufficientIntegral".tr, }; - // 记录日志(不记录敏感信息) - Logger.info('启动BLE服务,配置参数键名: ${config}'); + Logger.info('启动BLE服务,配置参数键名: ${config.keys.toList()}'); + if (xunfeiAppId.isEmpty || + xunfeiAccessKeyId.isEmpty || + xunfeiAccessKeySecret.isEmpty) { + Logger.warning('XUNFEI_ASR_* 未完整配置,ASR 将不会切到讯飞'); + } if (azureSpeechKey.isEmpty || openaiApiKey.isEmpty) { Logger.warning('缺少必要的API密钥,请检查.env文件配置'); diff --git a/lib/data/services/speech_impl/azure_asr_service.dart b/lib/data/services/speech_impl/azure_asr_service.dart index cec7285a1..e3d66e411 100644 --- a/lib/data/services/speech_impl/azure_asr_service.dart +++ b/lib/data/services/speech_impl/azure_asr_service.dart @@ -50,6 +50,9 @@ class AzureAsrService extends GetxService implements AsrService { String _latestDetectedLanguage = ''; String get latestDetectedLanguage => _latestDetectedLanguage; + String _latestAsrProvider = ''; + String get latestAsrProvider => _latestAsrProvider; + // 音频数据事件订阅 StreamSubscription? _audioDataEventSubscription; // 音频数据流控制器 @@ -74,7 +77,8 @@ class AzureAsrService extends GetxService implements AsrService { _serviceRegion = AppConfig.env('AZURE_SPEECH_REGION') ?? ''; _xunfeiAppId = AppConfig.env('XUNFEI_ASR_APP_ID') ?? ''; _xunfeiAccessKeyId = AppConfig.env('XUNFEI_ASR_ACCESS_KEY_ID') ?? ''; - _xunfeiAccessKeySecret = AppConfig.env('XUNFEI_ASR_ACCESS_KEY_SECRET') ?? ''; + _xunfeiAccessKeySecret = + AppConfig.env('XUNFEI_ASR_ACCESS_KEY_SECRET') ?? ''; if (_subscriptionKey.isEmpty || _serviceRegion.isEmpty) { throw Exception( @@ -334,6 +338,17 @@ class AzureAsrService extends GetxService implements AsrService { final Map eventMap = event; final String eventType = eventMap['type'] as String? ?? ''; + final String provider = eventMap['provider'] as String? ?? ''; + if (provider.isNotEmpty) { + if (provider != _latestAsrProvider) { + _latestAsrProvider = provider; + Logger.info('ASR provider: $_latestAsrProvider'); + } + } else { + if (eventType == 'sessionStarted') { + Logger.warning('ASR provider missing in event'); + } + } // 添加日志帮助调试 @@ -348,6 +363,7 @@ class AzureAsrService extends GetxService implements AsrService { type: RecognitionEventType.finalResult, text: text, detectedLanguage: detectedLanguage, + provider: _latestAsrProvider, )); break; case 'result1': @@ -360,6 +376,7 @@ class AzureAsrService extends GetxService implements AsrService { type: RecognitionEventType.finalResult1, text: text, detectedLanguage: detectedLanguage, + provider: _latestAsrProvider, )); break; @@ -371,11 +388,13 @@ class AzureAsrService extends GetxService implements AsrService { type: RecognitionEventType.intermediateResult, text: text, detectedLanguage: detectedLanguage, + provider: _latestAsrProvider, )); break; case 'sessionStarted': _eventStreamController?.add(RecognitionEvent( type: RecognitionEventType.sessionStarted, + provider: _latestAsrProvider, )); break; @@ -383,6 +402,7 @@ class AzureAsrService extends GetxService implements AsrService { _isContinuousRecognitionActive = false; _eventStreamController?.add(RecognitionEvent( type: RecognitionEventType.sessionStopped, + provider: _latestAsrProvider, )); break; @@ -398,6 +418,7 @@ class AzureAsrService extends GetxService implements AsrService { _eventStreamController?.add(RecognitionEvent( type: RecognitionEventType.canceled, error: '$reason: $errorDetails', + provider: _latestAsrProvider, )); break; @@ -407,6 +428,7 @@ class AzureAsrService extends GetxService implements AsrService { _eventStreamController?.add(RecognitionEvent( type: RecognitionEventType.error, error: error, + provider: _latestAsrProvider, )); break; } diff --git a/lib/data/services/speech_impl/azure_ast_service.dart b/lib/data/services/speech_impl/azure_ast_service.dart index 97cb98335..a806adc6d 100644 --- a/lib/data/services/speech_impl/azure_ast_service.dart +++ b/lib/data/services/speech_impl/azure_ast_service.dart @@ -78,8 +78,6 @@ class AzureAstService extends GetxService implements AstService { final Map eventMap = event; final String eventType = eventMap['type'] as String? ?? ''; - // 添加日志帮助调试 - switch (eventType) { case 'result': final String text = eventMap['text'] as String? ?? ''; @@ -105,6 +103,7 @@ class AzureAstService extends GetxService implements AstService { )); break; case 'sessionStarted': + Logger.info('AST provider: azure'); _eventStreamController?.add(RecognitionEvent1( type: RecognitionEventType1.sessionStarted, )); @@ -309,6 +308,7 @@ class AzureAstService extends GetxService implements AstService { _isInitialized = result; _setupEventChannel(); Logger.info('Azure 语音识别服务初始化${result ? '成功' : '失败'}'); + if (result) Logger.info('AST provider: azure'); return result; } catch (e) { Logger.error('Azure 语音识别服务初始化失败: ${e.toString()}'); diff --git a/lib/modules/agent/controllers/agent_controller.dart b/lib/modules/agent/controllers/agent_controller.dart index 2de128daf..f4af0edf5 100644 --- a/lib/modules/agent/controllers/agent_controller.dart +++ b/lib/modules/agent/controllers/agent_controller.dart @@ -569,6 +569,8 @@ class AgentController extends GetxController with WidgetsBindingObserver { // 订阅代理服务事件 void _subscribeToEvents() { _eventSubscription = AgentService.events.listen((event) { + final String asrProvider = (event.data['provider'] ?? '').toString(); + if (asrProvider.isNotEmpty) Logger.i(TAG, 'ASR provider: $asrProvider'); switch (event.type) { case AgentServiceEventType.recognitionStarted: isListening.value = true; diff --git a/lib/modules/translation/controllers/translation_controller.dart b/lib/modules/translation/controllers/translation_controller.dart index 1b6a57edd..fad6dfda9 100644 --- a/lib/modules/translation/controllers/translation_controller.dart +++ b/lib/modules/translation/controllers/translation_controller.dart @@ -1034,6 +1034,8 @@ class TranslationController extends GetxController with WidgetsBindingObserver { /// [event] 识别事件 void _handleRecognitionEvent(RecognitionEvent event) { // Logger.info("处理识别事件:${event}"); + final String asrProvider = event.provider; + if (asrProvider.isNotEmpty) Logger.info('ASR provider: $asrProvider'); switch (event.type) { case RecognitionEventType.finalResult: if (event.text.isEmpty) break; diff --git a/local_plugins/agent_service/android/src/main/kotlin/com/yunqiinnovation/agent_service/AgentService.kt b/local_plugins/agent_service/android/src/main/kotlin/com/yunqiinnovation/agent_service/AgentService.kt index 22c510c59..7b71a8058 100644 --- a/local_plugins/agent_service/android/src/main/kotlin/com/yunqiinnovation/agent_service/AgentService.kt +++ b/local_plugins/agent_service/android/src/main/kotlin/com/yunqiinnovation/agent_service/AgentService.kt @@ -73,6 +73,9 @@ object AgentService : CoroutineScope { private var azureSpeechKey: String = "" private var azureSpeechRegion: String = "" + private var xunfeiAppId: String = "" + private var xunfeiAccessKeyId: String = "" + private var xunfeiAccessKeySecret: String = "" // 协程相关 private val job = SupervisorJob() @@ -238,6 +241,9 @@ object AgentService : CoroutineScope { //保存配置 this.azureSpeechKey = config["azureSpeechKey"]?.toString() ?: "" this.azureSpeechRegion = config["azureSpeechRegion"]?.toString() ?: "" + this.xunfeiAppId = config["xunfeiAppId"]?.toString() ?: "" + this.xunfeiAccessKeyId = config["xunfeiAccessKeyId"]?.toString() ?: "" + this.xunfeiAccessKeySecret = config["xunfeiAccessKeySecret"]?.toString() ?: "" if (!customSystemPrompt.isNullOrBlank()) { systemPrompt = customSystemPrompt } else { @@ -257,7 +263,10 @@ object AgentService : CoroutineScope { region = config["azureSpeechRegion"]?.toString() ?: "", supportedLanguages = supportedLanguages, audioSourceType = if (isExternalActive) AzureAsrHelper.AudioSourceType.EXTERNAL - else AzureAsrHelper.AudioSourceType.MICROPHONE + else AzureAsrHelper.AudioSourceType.MICROPHONE, + xunfeiAppId = config["xunfeiAppId"]?.toString() ?: "", + xunfeiAccessKeyId = config["xunfeiAccessKeyId"]?.toString() ?: "", + xunfeiAccessKeySecret = config["xunfeiAccessKeySecret"]?.toString() ?: "" ) if (asrInitSuccess) { @@ -306,6 +315,9 @@ object AgentService : CoroutineScope { vipExptime = config["vipexptime"]?.toString()?.toIntOrNull() ?: vipExptime; navigationMode = config["navigationMode"]?.toString() ?: navigationMode musicServiceType = config["musicServiceType"]?.toString() ?: "" + xunfeiAppId = config["xunfeiAppId"]?.toString() ?: xunfeiAppId + xunfeiAccessKeyId = config["xunfeiAccessKeyId"]?.toString() ?: xunfeiAccessKeyId + xunfeiAccessKeySecret = config["xunfeiAccessKeySecret"]?.toString() ?: xunfeiAccessKeySecret chatApiService.initialize( config["openaiApiKey"]?.toString() ?: "", config["openaiBaseUrl"]?.toString() ?: "", @@ -1407,7 +1419,10 @@ object AgentService : CoroutineScope { subscriptionKey = this.azureSpeechKey, region = this.azureSpeechRegion, supportedLanguages = languages.toTypedArray(), - audioSourceType = audioSourceType + audioSourceType = audioSourceType, + xunfeiAppId = this.xunfeiAppId, + xunfeiAccessKeyId = this.xunfeiAccessKeyId, + xunfeiAccessKeySecret = this.xunfeiAccessKeySecret ) ?: false if (asrSuccess) { recognizeCallback() @@ -1631,11 +1646,18 @@ object AgentService : CoroutineScope { * 发送事件 */ private fun sendEvent(eventName: String, data: Map) { + val shouldAttachAsrProvider = eventName == "recognizing" || eventName.startsWith("recognition_") + val finalData: Map = if (shouldAttachAsrProvider && !data.containsKey("provider")) { + val provider = azureAsrHelper?.getAsrProvider() ?: "unknown" + data.toMutableMap().apply { put("provider", provider) } + } else { + data + } // 切换到主线程执行监听器回调,避免 UI 更新问题 launch(Dispatchers.Main) { listeners.forEach { listener -> try { - listener.onEvent(eventName, data) + listener.onEvent(eventName, finalData) } catch (e: Exception) { Log.e(TAG, "向监听器发送事件失败", e) } diff --git a/local_plugins/agent_service/android/src/main/kotlin/com/yunqiinnovation/agent_service/AgentServicePlugin.kt b/local_plugins/agent_service/android/src/main/kotlin/com/yunqiinnovation/agent_service/AgentServicePlugin.kt index d53768ecd..e3b464226 100644 --- a/local_plugins/agent_service/android/src/main/kotlin/com/yunqiinnovation/agent_service/AgentServicePlugin.kt +++ b/local_plugins/agent_service/android/src/main/kotlin/com/yunqiinnovation/agent_service/AgentServicePlugin.kt @@ -80,6 +80,9 @@ class AgentServicePlugin : FlutterPlugin, MethodCallHandler, EventChannel.Stream config["isttsinterrupt"]?.toString()?.let { intent.putExtra("isttsinterrupt", it) } config["callingToolText"]?.toString()?.let { intent.putExtra("callingToolText", it) } config["insufficientIntegralText"]?.toString()?.let { intent.putExtra("insufficientIntegralText", it) } + config["xunfeiAppId"]?.toString()?.let { intent.putExtra("xunfeiAppId", it) } + config["xunfeiAccessKeyId"]?.toString()?.let { intent.putExtra("xunfeiAccessKeyId", it) } + config["xunfeiAccessKeySecret"]?.toString()?.let { intent.putExtra("xunfeiAccessKeySecret", it) } config["vipexptime"]?.toString()?.let { intent.putExtra("vipexptime", it) //打印日志 diff --git a/local_plugins/agent_service/android/src/main/kotlin/com/yunqiinnovation/agent_service/BleMediaService.kt b/local_plugins/agent_service/android/src/main/kotlin/com/yunqiinnovation/agent_service/BleMediaService.kt index 6c992fdd3..26e9cf2b9 100644 --- a/local_plugins/agent_service/android/src/main/kotlin/com/yunqiinnovation/agent_service/BleMediaService.kt +++ b/local_plugins/agent_service/android/src/main/kotlin/com/yunqiinnovation/agent_service/BleMediaService.kt @@ -71,6 +71,9 @@ class BleMediaService : Service(), CoroutineScope { private const val APP_CALLING_TOOL_TEXT = "callingToolText" // 工具调用提示 private const val APP_INSUFFICIENT_INTEGRAL_TEXT = "insufficientIntegralText" // 积分不足提示 private const val KEY_VIP_EXPTIME = "vipexptime" // 会员到期时间 + private const val KEY_XUNFEI_APP_ID = "xunfeiAppId" // 讯飞AppID + private const val KEY_XUNFEI_ACCESS_KEY_ID = "xunfeiAccessKeyId" // 讯飞AccessKeyID + private const val KEY_XUNFEI_ACCESS_KEY_SECRET = "xunfeiAccessKeySecret" // 讯飞AccessKeySecret // 用于跟踪服务是否正在运行 private val isRunning = AtomicBoolean(false) @@ -591,6 +594,9 @@ private var companionManager: BleCompanionManager? = null it.getStringExtra(APP_INSUFFICIENT_INTEGRAL_TEXT)?.let { value -> config[APP_INSUFFICIENT_INTEGRAL_TEXT] = value } it.getStringExtra(KEY_VIP_EXPTIME)?.let { value -> config[KEY_VIP_EXPTIME] = value } it.getStringExtra("isttsinterrupt")?.let { value -> config["isttsinterrupt"] = value } + it.getStringExtra(KEY_XUNFEI_APP_ID)?.let { value -> config[KEY_XUNFEI_APP_ID] = value } + it.getStringExtra(KEY_XUNFEI_ACCESS_KEY_ID)?.let { value -> config[KEY_XUNFEI_ACCESS_KEY_ID] = value } + it.getStringExtra(KEY_XUNFEI_ACCESS_KEY_SECRET)?.let { value -> config[KEY_XUNFEI_ACCESS_KEY_SECRET] = value } Log.d(TAG, "liwei-------vipexptime 3-1 ${ config[KEY_VIP_EXPTIME]}") // 提取 supportedLanguages 参数 it.getStringArrayListExtra(KEY_SUPPORTED_LANGUAGES)?.let { languages -> @@ -655,6 +661,9 @@ private var companionManager: BleCompanionManager? = null config[APP_CALLING_TOOL_TEXT] = getConfigString(prefs, APP_CALLING_TOOL_TEXT, "") config[APP_INSUFFICIENT_INTEGRAL_TEXT] = getConfigString(prefs, APP_INSUFFICIENT_INTEGRAL_TEXT, "") config[KEY_VIP_EXPTIME] = getConfigString(prefs, KEY_VIP_EXPTIME, "") + config[KEY_XUNFEI_APP_ID] = getConfigString(prefs, KEY_XUNFEI_APP_ID, "") + config[KEY_XUNFEI_ACCESS_KEY_ID] = getConfigString(prefs, KEY_XUNFEI_ACCESS_KEY_ID, "") + config[KEY_XUNFEI_ACCESS_KEY_SECRET] = getConfigString(prefs, KEY_XUNFEI_ACCESS_KEY_SECRET, "") Log.d(TAG, "liwei-------vipexptime 3-0 ${ config[KEY_VIP_EXPTIME]}") // 添加 supportedLanguages 参数处理 val supportedLanguagesStr = getConfigString(prefs, KEY_SUPPORTED_LANGUAGES, "") diff --git a/local_plugins/agent_service/ios/agent_service/Sources/agent_service/AgentServiceImpl.swift b/local_plugins/agent_service/ios/agent_service/Sources/agent_service/AgentServiceImpl.swift index 09a71692e..10d2d58e1 100644 --- a/local_plugins/agent_service/ios/agent_service/Sources/agent_service/AgentServiceImpl.swift +++ b/local_plugins/agent_service/ios/agent_service/Sources/agent_service/AgentServiceImpl.swift @@ -36,6 +36,9 @@ class AgentServiceImpl: NSObject { private var azureSpeechKey: String = "" private var azureSpeechRegion: String = "" + private var xunfeiAppId: String = "" + private var xunfeiAccessKeyId: String = "" + private var xunfeiAccessKeySecret: String = "" private var config: [String: Any] = [:] // 添加音乐播放状态记录 @@ -145,12 +148,17 @@ class AgentServiceImpl: NSObject { } internal func sendEvent(name eventName: String, data: [String: Any]) { + var eventData = data + let shouldAttachAsrProvider = eventName == "recognizing" || eventName.hasPrefix("recognition_") + if shouldAttachAsrProvider && eventData["provider"] == nil { + eventData["provider"] = azureAsrHelper?.asrProvider() ?? "unknown" + } listenersLock.lock() let currentListeners = self.listeners listenersLock.unlock() for listener in currentListeners { - listener.onEvent(eventName: eventName, data: data) + listener.onEvent(eventName: eventName, data: eventData) } } @@ -252,6 +260,16 @@ class AgentServiceImpl: NSObject { sendError("Azure语音区域缺失", code: "CONFIG_ERROR") return false } + + if let xunfeiAppId = config["xunfeiAppId"] as? String { + self.xunfeiAppId = xunfeiAppId + } + if let xunfeiAccessKeyId = config["xunfeiAccessKeyId"] as? String { + self.xunfeiAccessKeyId = xunfeiAccessKeyId + } + if let xunfeiAccessKeySecret = config["xunfeiAccessKeySecret"] as? String { + self.xunfeiAccessKeySecret = xunfeiAccessKeySecret + } //启动定位服务 NotificationCenter.default.post(name: .locationstartEvent, object: nil) @@ -298,7 +316,10 @@ class AgentServiceImpl: NSObject { subscriptionKey: azureSpeechKey, region: azureSpeechRegion, supportedLanguages: supportedLanguages, - audioSourceType: .microphone + audioSourceType: .microphone, + xunfeiAppId: xunfeiAppId, + xunfeiAccessKeyId: xunfeiAccessKeyId, + xunfeiAccessKeySecret: xunfeiAccessKeySecret ), asrSuccess else { sendError("初始化语音识别服务失败", code: "ASR_INIT_ERROR") return false @@ -1459,7 +1480,10 @@ private func jsonToString(_ json: [String: Any]) -> String? { subscriptionKey: azureSpeechKey, region: azureSpeechRegion, supportedLanguages: languages, - audioSourceType: .microphone + audioSourceType: .microphone, + xunfeiAppId: xunfeiAppId, + xunfeiAccessKeyId: xunfeiAccessKeyId, + xunfeiAccessKeySecret: xunfeiAccessKeySecret ), asrSuccess else { sendError("初始化语音识别服务失败", code: "ASR_INIT_ERROR") return false 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 75d42962b..ee0cbd907 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 @@ -48,6 +48,10 @@ class AzureAsrHelper(private val context: Context) { private var xunfeiAccessKeyId: String = "" private var xunfeiAccessKeySecret: String = "" + fun getAsrProvider(): String { + return if (useXunfei) "xunfei" else "azure" + } + // 音频源配置 var audioSourceType = AudioSourceType.MICROPHONE diff --git a/local_plugins/azure_speech/android/src/main/kotlin/com/yunqiinnovation/azure_speech/AzureSpeechPlugin.kt b/local_plugins/azure_speech/android/src/main/kotlin/com/yunqiinnovation/azure_speech/AzureSpeechPlugin.kt index e684d456f..a2d922b2e 100644 --- a/local_plugins/azure_speech/android/src/main/kotlin/com/yunqiinnovation/azure_speech/AzureSpeechPlugin.kt +++ b/local_plugins/azure_speech/android/src/main/kotlin/com/yunqiinnovation/azure_speech/AzureSpeechPlugin.kt @@ -280,6 +280,7 @@ class AzureSpeechPlugin : BleService.Callback, FlutterPlugin { mapOf( "type" to "result", "sessionid" to sessionid, + "provider" to azureAsrHelper.getAsrProvider(), "text" to text, "detectedLanguage" to detectedLanguage ) @@ -297,6 +298,7 @@ class AzureSpeechPlugin : BleService.Callback, FlutterPlugin { mapOf( "type" to "recognizing", "sessionid" to sessionid, + "provider" to azureAsrHelper.getAsrProvider(), "text" to recognizing, "detectedLanguage" to detectedLanguage ) @@ -304,11 +306,11 @@ class AzureSpeechPlugin : BleService.Callback, FlutterPlugin { } override fun onSessionStarted(sessionid:String) { - sendAsrEvent(mapOf("type" to "sessionStarted","sessionid" to sessionid,)) + sendAsrEvent(mapOf("type" to "sessionStarted","sessionid" to sessionid, "provider" to azureAsrHelper.getAsrProvider())) } override fun onSessionStopped(sessionid:String) { - sendAsrEvent(mapOf("type" to "sessionStopped","sessionid" to sessionid,)) + sendAsrEvent(mapOf("type" to "sessionStopped","sessionid" to sessionid, "provider" to azureAsrHelper.getAsrProvider())) } @@ -318,6 +320,7 @@ class AzureSpeechPlugin : BleService.Callback, FlutterPlugin { mapOf( "type" to "canceled", "sessionid" to sessionid, + "provider" to azureAsrHelper.getAsrProvider(), "reason" to reason, "errorDetails" to errorDetails ) @@ -331,6 +334,7 @@ class AzureSpeechPlugin : BleService.Callback, FlutterPlugin { mapOf( "type" to "error", "sessionid" to sessionid, + "provider" to azureAsrHelper.getAsrProvider(), "code" to code, "message" to error ) diff --git a/local_plugins/azure_speech/ios/azure_speech/Sources/azure_speech/AzureAsrHelper.swift b/local_plugins/azure_speech/ios/azure_speech/Sources/azure_speech/AzureAsrHelper.swift index ababec198..3b1017217 100644 --- a/local_plugins/azure_speech/ios/azure_speech/Sources/azure_speech/AzureAsrHelper.swift +++ b/local_plugins/azure_speech/ios/azure_speech/Sources/azure_speech/AzureAsrHelper.swift @@ -80,6 +80,10 @@ public class AzureAsrHelper: NSObject { // 音频处理 public var audioStream: SimpleAudioReceiver? + public func asrProvider() -> String { + return useXunfei ? "xunfei" : "azure" + } + /** * 初始化Azure语音服务 * diff --git a/local_plugins/azure_speech/ios/azure_speech/Sources/azure_speech/AzureSpeechPlugin.swift b/local_plugins/azure_speech/ios/azure_speech/Sources/azure_speech/AzureSpeechPlugin.swift index c0f88a996..2484ab79e 100644 --- a/local_plugins/azure_speech/ios/azure_speech/Sources/azure_speech/AzureSpeechPlugin.swift +++ b/local_plugins/azure_speech/ios/azure_speech/Sources/azure_speech/AzureSpeechPlugin.swift @@ -224,6 +224,10 @@ internal func sendAsrEvent(_ event: [String: Any]) { sendEvent(event, type: .asr) } +internal func currentAsrProvider() -> String { + return azureAsrHelper.asrProvider() +} + private func sendTtsEvent(_ event: [String: Any]) { sendEvent(event, type: .tts) } @@ -1289,6 +1293,7 @@ private class AsrCallbackWrapper: AzureAsrHelper.ContinuousRecognizeCallback { plugin?.sendAsrEvent([ "type": "result", "sessionid": sessionid, + "provider": plugin?.currentAsrProvider() ?? "", "text": text, "detectedLanguage": detectedLanguage ]) @@ -1303,6 +1308,7 @@ private class AsrCallbackWrapper: AzureAsrHelper.ContinuousRecognizeCallback { plugin?.sendAsrEvent([ "type": "recognizing", "sessionid": sessionid, + "provider": plugin?.currentAsrProvider() ?? "", "text": text, "detectedLanguage": detectedLanguage ]) @@ -1314,7 +1320,8 @@ private class AsrCallbackWrapper: AzureAsrHelper.ContinuousRecognizeCallback { func onSessionStarted(sessionid:String) { plugin?.sendAsrEvent([ "type": "sessionStarted", - "sessionid": sessionid + "sessionid": sessionid, + "provider": plugin?.currentAsrProvider() ?? "" ]) } @@ -1324,7 +1331,8 @@ private class AsrCallbackWrapper: AzureAsrHelper.ContinuousRecognizeCallback { func onSessionStopped(sessionid:String) { plugin?.sendAsrEvent([ "type": "sessionStopped", - "sessionid": sessionid + "sessionid": sessionid, + "provider": plugin?.currentAsrProvider() ?? "" ]) } @@ -1337,6 +1345,7 @@ private class AsrCallbackWrapper: AzureAsrHelper.ContinuousRecognizeCallback { plugin?.sendAsrEvent([ "type": "canceled", "sessionid": sessionid, + "provider": plugin?.currentAsrProvider() ?? "", "reason": reason, "errorDetails": errorDetails ]) @@ -1351,6 +1360,7 @@ private class AsrCallbackWrapper: AzureAsrHelper.ContinuousRecognizeCallback { plugin?.sendAsrEvent([ "type": "error", "sessionid": sessionid, + "provider": plugin?.currentAsrProvider() ?? "", "code": errorCode, "message": error ])