diff --git a/lib/data/services/network/nw_api.dart b/lib/data/services/network/nw_api.dart index 69b0e9eef..c3b6a2f8b 100644 --- a/lib/data/services/network/nw_api.dart +++ b/lib/data/services/network/nw_api.dart @@ -1,5 +1,5 @@ class NWApi { // static const baseApi = "https://www.deapsound.com"; - // static const baseApi = "https://api.deapsound.com"; + //static const baseApi = "https://api.deapsound.com"; static const baseApi = "https://api.ideapsound.com"; } diff --git a/lib/modules/agent/controllers/agent_controller.dart b/lib/modules/agent/controllers/agent_controller.dart index adf43b71a..6c69ad897 100644 --- a/lib/modules/agent/controllers/agent_controller.dart +++ b/lib/modules/agent/controllers/agent_controller.dart @@ -93,7 +93,7 @@ class AgentController extends GetxController { final isPushToTalkActive = false.obs; // 是否正在按住说话 // 按住说话模式状态 - 用于区分是否处于按住说话模式(即使当前没有按住) - final isPushToTalkMode = false.obs; // 是否处于按住说话模式 + //final isPushToTalkMode = false.obs; // 是否处于按住说话模式 // 蓝牙唤醒状态 final isBleWakeupActive = false.obs; // 是否正在进行蓝牙唤醒对话 @@ -143,6 +143,7 @@ class AgentController extends GetxController { _initMusicStatus(); //初始化音乐状态 _setupMediaSessionCallbacks(); //设置媒体会话回调 _setupTextInputListener(); //设置文本输入监听器 + startVoiceInput(); //开启语音输入 } // 初始化音乐播放状态 @@ -355,6 +356,7 @@ class AgentController extends GetxController { case AgentServiceEventType.recognitionStarted: isListening.value = true; isTextInputMode.value = false; + print("订阅代理服务事件识别开始"); // isTextInputMode.refresh(); // 只标记识别开始,不添加消息 Logger.i(TAG, '识别开始'); @@ -371,7 +373,7 @@ class AgentController extends GetxController { } else { // 只有在非按住说话模式且非打电话模式下才自动切换到文字模式 // 按住说话模式下应该保持在语音模式,等待下次按住 - if (!isPushToTalkMode.value && !isPhoneCallMode.value) { + if (!isPhoneCallMode.value) { isTextInputMode.value = true; } } @@ -890,19 +892,18 @@ class AgentController extends GetxController { // 切换到文本模式时,禁用按住说话模式并停止任何正在进行的语音输入 if (isTextInputMode.value) { // 切换到文本模式 - isPushToTalkMode.value = false; - stopVoiceInput(); + isTextInputMode.value = true; + // stopVoiceInput(); } else { // 切换到语音模式,启用按住说话模式 - isPushToTalkMode.value = true; + isTextInputMode.value = false; } } // 开始语音输入 Future startVoiceInput() async { if (isListening.value) return; - - // 检查麦克风权限 + print("开始语音输入"); // 检查麦克风权限 final hasPermission = await PermissionUtil.instance.requestPermission( // context: Get.context!, permissionType: Permission.microphone, @@ -1129,13 +1130,14 @@ class AgentController extends GetxController { // 保存当前输入模式 void _saveCurrentInputMode() { - if (isPushToTalkMode.value) { + if (!isTextInputMode.value) { _previousInputMode = VoiceInputMode.pushToTalk; - } else if (isTextInputMode.value) { - _previousInputMode = VoiceInputMode.text; } else { - _previousInputMode = null; + _previousInputMode = VoiceInputMode.text; } + // else { + // _previousInputMode = null; + // } } // 恢复之前的输入模式 @@ -1143,16 +1145,16 @@ class AgentController extends GetxController { switch (_previousInputMode) { case VoiceInputMode.pushToTalk: isTextInputMode.value = false; - isPushToTalkMode.value = true; + //isPushToTalkMode.value = true; break; case VoiceInputMode.text: isTextInputMode.value = true; - isPushToTalkMode.value = false; + // isPushToTalkMode.value = false; break; default: // 默认恢复到文字模式 isTextInputMode.value = true; - isPushToTalkMode.value = false; + //isPushToTalkMode.value = false; break; } _previousInputMode = null; // 清除历史记录 @@ -1171,8 +1173,8 @@ class AgentController extends GetxController { // 进入打电话模式 isPhoneCallMode.value = true; - // 如果当前是文本模式,切换到语音模式 - if (isTextInputMode.value) { + // 如果当前是文本模式,切换到语音模式???? + if (isListening.value) { // 检查麦克风权限 final hasPermission = await PermissionUtil.instance.requestPermission( permissionType: Permission.microphone, @@ -1193,8 +1195,10 @@ class AgentController extends GetxController { // 切换到语音模式并开始语音输入 isTextInputMode.value = false; // 打电话模式不使用按住说话模式,而是持续语音输入 - isPushToTalkMode.value = false; - await startVoiceInput(); + //isPushToTalkMode.value = false; + // 开始语音识别 + print("开始打电话模式,开始语音输入"); + await AgentService.audioContinue(); } } @@ -1206,8 +1210,9 @@ class AgentController extends GetxController { isPhoneCallMode.value = false; // 停止语音输入 - await stopVoiceInput(); - + //await stopVoiceInput(); + // 开始语音识别 + await AgentService.audioPause(); // 恢复之前的输入模式,而不是强制切换到文字模式 _restorePreviousInputMode(); } @@ -1240,23 +1245,23 @@ class AgentController extends GetxController { // 验证语音输入状态一致性 void _validateVoiceInputStates() { // 检查状态冲突 - if (isPhoneCallMode.value && isPushToTalkMode.value) { - Logger.w(TAG, '状态冲突:同时启用打电话和按住说话模式,优先保持打电话模式'); - isPushToTalkMode.value = false; - } + // if (isPhoneCallMode.value && isPushToTalkMode.value) { + // Logger.w(TAG, '状态冲突:同时启用打电话和按住说话模式,优先保持打电话模式'); + // isPushToTalkMode.value = false; + // } - // 检查文字模式与语音模式的一致性 - if (isTextInputMode.value && - (isPushToTalkMode.value || isPhoneCallMode.value)) { - Logger.w(TAG, '状态冲突:文字模式与语音模式同时启用,优先保持语音模式'); - isTextInputMode.value = false; - } + // // 检查文字模式与语音模式的一致性 + // if (isTextInputMode.value && + // (isPushToTalkMode.value || isPhoneCallMode.value)) { + // Logger.w(TAG, '状态冲突:文字模式与语音模式同时启用,优先保持语音模式'); + // isTextInputMode.value = false; + // } - // 检查按住说话状态的合理性 - if (isPushToTalkActive.value && !isPushToTalkMode.value) { - Logger.w(TAG, '状态冲突:按住说话激活但未启用按住说话模式'); - isPushToTalkActive.value = false; - } + // // 检查按住说话状态的合理性 + // if (isPushToTalkActive.value && !isPushToTalkMode.value) { + // Logger.w(TAG, '状态冲突:按住说话激活但未启用按住说话模式'); + // isPushToTalkActive.value = false; + // } } // 安全的状态切换方法 @@ -1266,21 +1271,21 @@ class AgentController extends GetxController { switch (targetMode) { case VoiceInputMode.text: isTextInputMode.value = true; - isPushToTalkMode.value = false; + // isPushToTalkMode.value = false; isPhoneCallMode.value = false; isPushToTalkActive.value = false; break; case VoiceInputMode.pushToTalk: isTextInputMode.value = false; - isPushToTalkMode.value = true; + // isPushToTalkMode.value = true; isPhoneCallMode.value = false; isPushToTalkActive.value = false; break; case VoiceInputMode.phoneCall: isTextInputMode.value = false; - isPushToTalkMode.value = false; + // isPushToTalkMode.value = false; isPhoneCallMode.value = true; isPushToTalkActive.value = false; break; @@ -1295,7 +1300,7 @@ class AgentController extends GetxController { Logger.i(TAG, '🎤 开始按住说话'); // 只有在语音模式且按住说话模式下才能按住说话 - if (isTextInputMode.value || !isPushToTalkMode.value) return; + if (isTextInputMode.value) return; // 如果已经在按住说话,不重复开始 if (isPushToTalkActive.value) return; @@ -1303,8 +1308,10 @@ class AgentController extends GetxController { // 设置按住说话状态 isPushToTalkActive.value = true; + print("开始按住说话,状态已设置为true"); // 开始语音识别 - await startVoiceInput(); + await AgentService.audioContinue(); + // await startVoiceInput(); } // 结束按住说话 @@ -1316,9 +1323,9 @@ class AgentController extends GetxController { // 清除按住说话状态(但保持按住说话模式) isPushToTalkActive.value = false; - + await AgentService.audioPause(); // 停止语音识别 - await stopVoiceInput(); + // await stopVoiceInput(); } // 获取音乐播放状态 diff --git a/lib/modules/agent/views/agent_view.dart b/lib/modules/agent/views/agent_view.dart index c0abce98c..b4ab10ed8 100644 --- a/lib/modules/agent/views/agent_view.dart +++ b/lib/modules/agent/views/agent_view.dart @@ -1,3 +1,4 @@ +import 'dart:async'; import 'dart:io'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; @@ -374,7 +375,7 @@ class _AgentViewState extends State with WidgetsBindingObserver { final isTextMode = controller.isTextInputMode.value; - if (isTextMode) { + if (controller.isTextInputMode.value) { // 文本输入模式 - 限制最大高度并只向上扩展 return Container( constraints: const BoxConstraints( @@ -466,16 +467,44 @@ class _AgentViewState extends State with WidgetsBindingObserver { ), ); } else { + Timer? _holdTimer; // 增加延迟触发的计时器 // 语音输入模式 - 按住说话模式 return Listener( onPointerDown: (_) { - // 开始按住说话 - controller.startPushToTalk(); + // 设置300ms延迟防止误触 + _holdTimer = Timer( + const Duration(milliseconds: 200), + () { + controller.startPushToTalk(); + // if (activeSpeaker == 0) { + // if (speakerId == 1) { + // controller + // .restoreOriginalAudioState(); + // } else { + // controller + // .disableBluetoothAudio(); + // } + // controller + // .setActiveSpeaker(speakerId); + // } + }); }, onPointerUp: (_) { - // 结束按住说话 + _holdTimer?.cancel(); controller.endPushToTalk(); }, + onPointerCancel: (_) { + _holdTimer?.cancel(); + controller.endPushToTalk(); + }, + // onLongPressStart: (_) { + // // 开始按住说话 + // controller.startPushToTalk(); + // }, + // onLongPressEnd: (_) { + // // 结束按住说话 + // controller.endPushToTalk(); + // }, // onLongPressCancel: () { // // 取消按住说话 // controller.endPushToTalk(); @@ -517,7 +546,7 @@ class _AgentViewState extends State with WidgetsBindingObserver { // 语音波形图 - 只在按住时显示 if (isPushToTalkActive) ...[ const AgentSoundBarsWidget(), - //const Spacer(), + const Spacer(), ], // 状态文字和图标 @@ -526,7 +555,7 @@ class _AgentViewState extends State with WidgetsBindingObserver { mainAxisAlignment: isPushToTalkActive ? MainAxisAlignment - .center + .end : MainAxisAlignment .center, children: [ @@ -1020,13 +1049,13 @@ class _AgentViewState extends State with WidgetsBindingObserver { Obx(() { final isActive = controller.isListening.value; return GestureDetector( - onTap: () { - if (isActive) { - controller.stopVoiceInput(); - } else { - controller.startVoiceInput(); - } - }, + // onTap: () { + // if (isActive) { + // controller.stopVoiceInput(); + // } else { + // controller.startVoiceInput(); + // } + // }, child: Container( width: 80, height: 80, diff --git a/lib/modules/meeting/controllers/meeting_record_controller.dart b/lib/modules/meeting/controllers/meeting_record_controller.dart index 8b58e7378..8e9523d93 100644 --- a/lib/modules/meeting/controllers/meeting_record_controller.dart +++ b/lib/modules/meeting/controllers/meeting_record_controller.dart @@ -138,7 +138,6 @@ class MeetingRecordController extends GetxController _bleManager.closeCodec(); } _asrService.stopRecord(true); - _asrService.setPause(); _asrService.stopContinuousRecognition(); isRecording.value = false; } diff --git a/lib/modules/translation/controllers/translation_controller.dart b/lib/modules/translation/controllers/translation_controller.dart index b40408dbc..924bfa972 100644 --- a/lib/modules/translation/controllers/translation_controller.dart +++ b/lib/modules/translation/controllers/translation_controller.dart @@ -430,7 +430,7 @@ class TranslationController extends GetxController { try { await _asrService.stopContinuousRecognition(); - _asrService.setPause(); + _recognitionSubscription?.cancel(); _recognitionSubscription = null; isRecognizing.value = false; 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 7a9e15d16..132b8efa1 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 @@ -58,7 +58,7 @@ object AgentService : CoroutineScope { private val listeners = Collections.synchronizedSet(mutableSetOf()) // Azure服务 - private var azureAsrHelper: AzureAsrHelper? = null + var azureAsrHelper: AzureAsrHelper? = null // 使用BytedanceTTS作为唯一的TTS实现 private var ttsService: AzureTtsHelper? = null @@ -111,6 +111,7 @@ object AgentService : CoroutineScope { private var lastInterruptTime = 0L private val INTERRUPT_DEBOUNCE_MS = 300L + private var audioSourceType= AzureAsrHelper.AudioSourceType.MICROPHONE // 语气词过滤列表(中英文) private val FILLER_WORDS = setOf( // 中文语气词 @@ -351,15 +352,16 @@ object AgentService : CoroutineScope { */ private fun startIdleCheck() { stopIdleCheck() // 先停止现有的检查 - + Log.d(TAG, "启动空闲检测: ${isRecognitionActive}") if (!isRecognitionActive) return - + idleCheckJob = launch { try { delay(maxIdleSeconds * 1000L) if (isActive && isRecognitionActive && !hasSpeechDetected && !isTtsSpeaking && !isAiStreaming) { - stopRecognition() + Log.d(TAG, "启动空闲检测: stopRecognition") + //stopRecognition() sendEvent("auto_stop", mapOf("reason" to "idle_timeout", "seconds" to maxIdleSeconds)) } } catch (e: CancellationException) { @@ -393,10 +395,17 @@ object AgentService : CoroutineScope { */ fun startRecognition(isExternalActive: Boolean): Boolean { if (!isInitialized) { - Log.e(TAG, "服务未初始化") + Log.d(TAG, "服务未初始化") return false } - + Log.d(TAG, "麦克风音频未暂停,无法设置${azureAsrHelper!!.isPaused},$isExternalActive") + if(!(azureAsrHelper!!.isPaused)&&isExternalActive) + { + Log.d(TAG, "麦克风音频未暂停,无法设置") + BleService.closeCodec() + return false + } + Log.d(TAG, "开始语音识别") if (isRecognitionActive) return true // 检查录音权限 @@ -410,7 +419,7 @@ object AgentService : CoroutineScope { _hasSpeechDetected.set(false) try { - val audioSourceType = if (isExternalActive) { + audioSourceType = if (isExternalActive) { AzureAsrHelper.AudioSourceType.EXTERNAL } else { AzureAsrHelper.AudioSourceType.MICROPHONE @@ -480,6 +489,7 @@ object AgentService : CoroutineScope { override fun onSessionStarted() { sendEvent("recognition_started", mapOf("status" to "started")) startIdleCheck() + Log.d(TAG, "onSessionStarted") audioPlayer?.playAudio(R.raw.start) } @@ -489,12 +499,14 @@ object AgentService : CoroutineScope { _isRecognitionActive.set(false) stopIdleCheck() + Log.d(TAG, "onSessionStopped") audioPlayer?.playAudio(R.raw.stop) } override fun onCanceled(reason: String, errorDetails: String) { _isRecognitionActive.set(false) stopIdleCheck() + Log.d(TAG, "recognition_canceled") BleService.closeCodec() sendEvent("recognition_canceled", mapOf( "reason" to reason, @@ -505,6 +517,7 @@ object AgentService : CoroutineScope { override fun onError(error: String) { _isRecognitionActive.set(false) stopIdleCheck() + Log.d(TAG, "error") BleService.closeCodec() Log.e(TAG, "语音识别错误: $error") sendEvent("error", mapOf( @@ -536,6 +549,7 @@ object AgentService : CoroutineScope { try { azureAsrHelper?.stopContinuousRecognition() + Log.d(TAG, "停止语音识别") BleService.closeCodec() _isRecognitionActive.set(false) stopIdleCheck() @@ -545,7 +559,55 @@ object AgentService : CoroutineScope { stopIdleCheck() } } + /** + * 继续音频输入 + */ + fun audioContinue() { + + + + try { + if(audioSourceType== AzureAsrHelper.AudioSourceType.EXTERNAL) + { + Log.d(TAG, "当前是什么输入:$audioSourceType") + BleService.closeCodec() + stopRecognition() + startRecognition(false) + } + + // if (!isRecognitionActive) { + + // } + + azureAsrHelper?.audioContinue() + //BleService.closeCodec() + //_isRecognitionActive.set(false) + //stopIdleCheck() + } catch (e: Exception) { + Log.e(TAG, "暂停音频输入异常: ${e.message}") + // _isRecognitionActive.set(false) + //stopIdleCheck() + } + } + /** + * 暂停音频输入 + */ + fun audioPause() { + if (!isRecognitionActive) return + + try { + azureAsrHelper?.audioPause() + Log.d(TAG, "暂停音频输入") + BleService.closeCodec() + //_isRecognitionActive.set(false) + //stopIdleCheck() + } catch (e: Exception) { + Log.e(TAG, "暂停音频输入异常: ${e.message}") + // _isRecognitionActive.set(false) + //stopIdleCheck() + } + } /** * 打断当前响应 * 停止TTS播放和AI流输出 @@ -676,6 +738,7 @@ object AgentService : CoroutineScope { hasImage: Boolean = false, imagePath: String? = null ) { + Log.d(TAG, "内部方法:通用的ChatAPI处理逻辑") // 如果有正在进行的AI流式输出,先停止它 stopAiStream() stopTts() @@ -685,6 +748,7 @@ object AgentService : CoroutineScope { currsessionId = UUID.randomUUID().toString() // 设置状态为正在流式输出 _isAiStreaming.set(true) + Log.d(TAG, "processWithChatApiInternal") audioPlayer?.playAudio(R.raw.await, true,0.3f) // 使用历史记录作为上下文发送到OpenAI val responseBuilder = StringBuilder() @@ -1190,6 +1254,7 @@ object AgentService : CoroutineScope { fun playAudio(resId: Int, isLooping: Boolean = false, volume: Float = 1.0f) { synchronized(playbackLock) { try { + Log.d(TAG, "playAudio${isLooping}") // 强制停止并释放之前的资源 forceStop() @@ -1233,6 +1298,7 @@ object AgentService : CoroutineScope { fun stopAudio() { synchronized(playbackLock) { try { + Log.d(TAG, "stopAudio") mediaPlayer?.apply { if (isMediaPlayerPlaying()) { stop() 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 44f6013e8..579f20d23 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 @@ -103,6 +103,24 @@ class AgentServicePlugin : FlutterPlugin, MethodCallHandler, EventChannel.Stream Log.e(TAG, "停止对话失败", e) result.error("STOP_ERROR", "停止对话失败: ${e.message}", null) } + } + "audioContinue" -> { + try { + AgentService.audioContinue() + result.success(true) + } catch (e: Exception) { + Log.e(TAG, "audioContinue失败", e) + result.error("STOP_ERROR", "audioContinue失败: ${e.message}", null) + } + } + "audioPause" -> { + try { + AgentService.audioPause() + result.success(true) + } catch (e: Exception) { + Log.e(TAG, "audioContinue失败", e) + result.error("STOP_ERROR", "audioContinue失败: ${e.message}", null) + } } "processTextInput" -> { val text = call.argument("text") diff --git a/local_plugins/agent_service/android/src/main/kotlin/com/yunqiinnovation/agent_service/BleAgent.kt b/local_plugins/agent_service/android/src/main/kotlin/com/yunqiinnovation/agent_service/BleAgent.kt index 36e34df05..58d46a5f9 100644 --- a/local_plugins/agent_service/android/src/main/kotlin/com/yunqiinnovation/agent_service/BleAgent.kt +++ b/local_plugins/agent_service/android/src/main/kotlin/com/yunqiinnovation/agent_service/BleAgent.kt @@ -142,7 +142,7 @@ object BleAgent : BleService.Callback, AgentServiceListener { AgentService.interruptCurrentResponse() // AgentService.speakText("我在!") // 启动语音识别 - if (AgentService.isRecognitionActive) { + if (AgentService.isRecognitionActive&&AgentService.azureAsrHelper!!.isPaused) { // 如果已经在识别,则重新启动 stopListening() } diff --git a/local_plugins/agent_service/lib/agent_service.dart b/local_plugins/agent_service/lib/agent_service.dart index 61cf6b5b1..6ac0411df 100644 --- a/local_plugins/agent_service/lib/agent_service.dart +++ b/local_plugins/agent_service/lib/agent_service.dart @@ -261,6 +261,32 @@ class AgentService { } } + /// 停止对话 + /// + /// 停止语音识别 + /// 返回是否成功停止对话 + static Future audioContinue() async { + try { + final bool result = await _channel.invokeMethod('audioContinue'); + return result; + } on PlatformException catch (e) { + throw AgentServiceException(e.code, e.message ?? '停止对话失败', e.details); + } + } + + /// 停止对话 + /// + /// 停止语音识别 + /// 返回是否成功停止对话 + static Future audioPause() async { + try { + final bool result = await _channel.invokeMethod('audioPause'); + return result; + } on PlatformException catch (e) { + throw AgentServiceException(e.code, e.message ?? '停止对话失败', e.details); + } + } + /// 处理文本输入 /// /// [text] 文本内容 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 40e9c1861..fb1d36394 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 @@ -34,9 +34,6 @@ class AzureAsrHelper(private val context: Context) { private val tag = "AzureAsrHelper" // 核心组件 - private var echoCanceler: AcousticEchoCanceler? = null - private var noiseSuppressor: NoiseSuppressor? = null - private var automaticGainControl: AutomaticGainControl? = null private var speechConfig: SpeechConfig? = null private var recognizer: SpeechRecognizer? = null private var audioConfig: AudioConfig? = null @@ -55,7 +52,7 @@ class AzureAsrHelper(private val context: Context) { var audioSourceType = AudioSourceType.MICROPHONE // 音频处理 - // private var microphoneStream: MicrophoneStream? = null + private var audioStream: AudioStream? = null private var externalAudioStream: ExternalAudioPullStream? = null // 音频模式管理 @@ -64,11 +61,7 @@ class AzureAsrHelper(private val context: Context) { // 录音文件处理 var recordfile: RecordFile? = null - - private var isPaused = false - private var audioRecord: AudioRecord? = null - private var captureThread: Thread? = null - private var audioStream: PushAudioInputStream? = null + var isPaused = true /** * 音频来源类型 @@ -129,9 +122,7 @@ class AzureAsrHelper(private val context: Context) { // 释放之前的资源 dispose() - // 1. 创建可控制的音频流 - val format = getOptimalAudioFormat() - audioStream = AudioInputStream.createPushStream(format) + // 初始化音频管理器 audioManager = context.getSystemService(Context.AUDIO_SERVICE) as AudioManager originalAudioMode = audioManager?.mode ?: AudioManager.MODE_NORMAL @@ -197,6 +188,7 @@ class AzureAsrHelper(private val context: Context) { */ private fun setupRecognizer(): Boolean { try { + // 清理旧的识别器 recognizer?.close() recognizer = null @@ -211,7 +203,11 @@ class AzureAsrHelper(private val context: Context) { AudioSourceType.EXTERNAL -> { // 改用拉流方式处理外部音频 + Log.d(tag, "改用拉流方式处理外部音频") + + setupExternalAudioStream() + } } @@ -237,13 +233,25 @@ class AzureAsrHelper(private val context: Context) { */ private fun setupMicrophoneStream() { try { - + Log.d(tag, "设置麦克风流 - 使用拉流方式: }") + restoreOriginalAudioState() + if (audioStream == null) { + // 创建外部音频拉流对象 + audioStream = AudioStream() + audioStream!!.initAudioRecord() + } + // else + // { + // audioStream.stopCaptureThread() + // audioStream.startCaptureThread() + // } // 创建麦克风流 // microphoneStream = MicrophoneStream() // 创建音频配置 - 正确使用fromStreamInput方法,只传入回调 // audioConfig = AudioConfig.fromStreamInput(microphoneStream) - audioConfig = AudioConfig.fromStreamInput(audioStream) + audioConfig = AudioConfig.fromStreamInput(audioStream!!.pushAudioStream) + } catch (e: Exception) { Log.e(tag, "设置麦克风流失败: ${e.message}") @@ -278,6 +286,8 @@ class AzureAsrHelper(private val context: Context) { */ private fun setupExternalAudioStream() { try { + Log.d(tag, "设置外部音频流 - 使用拉流方式: }") + //disableBluetoothAudio() // 创建外部音频拉流对象 externalAudioStream = ExternalAudioPullStream() @@ -299,7 +309,6 @@ class AzureAsrHelper(private val context: Context) { if (audioSourceType != AudioSourceType.EXTERNAL) { return } - // 使用拉流模式,将数据推入队列 externalAudioStream?.pushAudio(data) @@ -379,8 +388,7 @@ class AzureAsrHelper(private val context: Context) { } try { - // 5. 初始化麦克风 - initAudioRecord() + // 设置各种事件监听 setupEventListeners(callback) @@ -389,9 +397,7 @@ class AzureAsrHelper(private val context: Context) { // 开始连续识别 recognizer?.startContinuousRecognitionAsync() - // 开始录音 - audioRecord?.startRecording() - startCaptureThread() // 再启动数据读取线程 + audioStream?.startCaptureThread() isContinuousRecognitionActive = true @@ -442,6 +448,7 @@ class AzureAsrHelper(private val context: Context) { recognizer?.sessionStarted?.addEventListener( EventHandler { _, _ -> // 直接在当前线程调用回调 + Log.d(tag, "会话开始事件") callback.onSessionStarted() } ) @@ -450,6 +457,7 @@ class AzureAsrHelper(private val context: Context) { recognizer?.sessionStopped?.addEventListener( EventHandler { _, _ -> // 直接在当前线程调用回调 + Log.d(tag, "会话结束事件") callback.onSessionStopped() isContinuousRecognitionActive = false stopAudioProcessing() @@ -497,8 +505,6 @@ class AzureAsrHelper(private val context: Context) { // 停止音频处理 stopAudioProcessing() - // 停止录音 - stopMicrophoneCapture() // 会话结束事件会设置isContinuousRecognitionActive = false return true } catch (e: Exception) { @@ -508,8 +514,6 @@ class AzureAsrHelper(private val context: Context) { // 停止音频处理 stopAudioProcessing() - // 停止录音 - stopMicrophoneCapture() // 尝试强制关闭识别器 try { recognizer?.close() @@ -538,7 +542,6 @@ class AzureAsrHelper(private val context: Context) { recognizer?.stopContinuousRecognitionAsync() isContinuousRecognitionActive = false } - releaseAudioResources() // 停止音频处理 stopAudioProcessing() @@ -552,9 +555,6 @@ class AzureAsrHelper(private val context: Context) { speechConfig?.close() speechConfig = null - // 关闭音频流(根据实际实现可能需要) - audioStream?.close() - audioStream = null // 释放音频配置 audioConfig?.close() @@ -601,16 +601,19 @@ class AzureAsrHelper(private val context: Context) { * 停止音频处理 */ private fun stopAudioProcessing() { - // microphoneStream?.let { - // try { - // it.close() - // microphoneStream = null - // } catch (e: Exception) { - // Log.e(tag, "关闭麦克风流失败: ${e.message}") - // e.printStackTrace() - // } - // } + audioStream?.let { + try { + it.stopMicrophoneCapture() + it.releaseAudioResources() + + it.pushAudioStream?.close() + audioStream = null + } catch (e: Exception) { + Log.e(tag, "关闭麦克风流失败: ${e.message}") + e.printStackTrace() + } + } // 关闭音频流(根据实际实现可能需要) externalAudioStream?.let { try { it.close() @@ -622,70 +625,22 @@ class AzureAsrHelper(private val context: Context) { } } - /** - * 开启录音 - */ - fun enableRecord(filePath: String) { - Log.i(tag, "开启录音:") - - recordfile!!.closeFile(true) - - - recordfile!!.creatingFiles(filePath) - - } - - /** - * 移动文件到新路径 - */ - fun moveFile(sourcePath: String, destPath: String): Boolean { - Log.i(tag, "移动文件到新路径:") - - recordfile!!.moveFile(sourcePath, destPath) - return true - } - - - /** - * 重命名指定路径的音频文件 - */ - fun renameFile(filePath: String, newName: String): Boolean { - Log.i(tag, "重命名指定路径的音频文件:") - - - recordfile!!.renameFile(filePath, newName) - return true - } - - /** - * 停止录音 - */ - fun pauseRecord() { - Log.i(tag, "停止连续录音:") - - recordfile!!.isPause = true - } - - /** - * 关闭录音 - */ - fun stopRecord(isSave: Boolean) { - Log.i(tag, "关闭录音:") - - recordfile!!.isPause = false - recordfile!!.closeFile(isSave) - } - - fun stopAudioPause() { + /* + 暂停音频输入 + */ + fun audioPause() { Log.d(tag, "关闭麦克风stopAudioPause: ") // 清理旧的识别器 - isPaused = true + isPaused = true } - fun setAudiocontinue() { + /* + 继续音频输入 + */ + fun audioContinue() { Log.d(tag, "继续麦克风stopAudioPause: ") // 开始连续识别 @@ -727,403 +682,251 @@ class AzureAsrHelper(private val context: Context) { } } + +//录音音频文件 /** - * 开始麦克风捕获 + * 开启录音 */ - private fun initAudioRecord() { - // 获取已确定的采样率 - val format = getOptimalAudioFormat() - val supportedSampleRates = intArrayOf(16000, 8000, 11025, 22050, 44100) - val channelConfig = AudioFormat.CHANNEL_IN_MONO // 单声道输入 - val audioFormat = AudioFormat.ENCODING_PCM_16BIT // 16位PCM格式 - // 查找设备支持的最佳采样率 - val sampleRate = supportedSampleRates.firstOrNull { rate -> - val bufferSize = AudioRecord.getMinBufferSize( - rate, - channelConfig, - audioFormat - ) - bufferSize > 0 // 返回正值表示支持 - } ?: 16000 // 默认回退值 - - - // 计算最小缓冲区大小(避免出现音频欠载) - val minBufferSize = AudioRecord.getMinBufferSize( - sampleRate, - channelConfig, - audioFormat - ) -// 创建录音对象 - if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) { - Log.d("AzureASR", "android.os.Build.VERSION.SDK_INT") - val format = AudioFormat.Builder() - .setSampleRate(sampleRate) - .setEncoding(audioFormat) - .setChannelMask(channelConfig) - .build() - - audioRecord = AudioRecord.Builder() - .setAudioSource(MediaRecorder.AudioSource.VOICE_COMMUNICATION) - .setAudioFormat(format) - .setBufferSizeInBytes(minBufferSize * 2) - .build() - } else { - // 创建 AudioRecord 对象 - audioRecord = AudioRecord( - MediaRecorder.AudioSource.VOICE_RECOGNITION, // 语音识别专用音源(自带降噪/回声消除) - sampleRate, - channelConfig, - audioFormat, - minBufferSize * 2 // 使用两倍缓冲区防止溢出 - ) - - } + fun enableRecord(filePath: String) { + Log.i(tag, "开启录音:") + recordfile!!.closeFile(true) - // 检查初始化状态 - if (audioRecord?.state != AudioRecord.STATE_INITIALIZED) { - throw IllegalStateException("AudioRecord初始化失败") - } + recordfile!!.creatingFiles(filePath) } - // 3. 单独封装线程启动逻辑 - private fun startCaptureThread() { - captureThread = Thread { - // 根据实际采样率计算缓冲区大小 - val supportedSampleRates = intArrayOf(16000, 8000, 11025, 22050, 44100) - var bufferSize = 0 - // 查找设备支持的最佳采样率 - val sampleRate = supportedSampleRates.firstOrNull { rate -> - bufferSize = AudioRecord.getMinBufferSize( - rate, - AudioFormat.CHANNEL_IN_MONO, - AudioFormat.ENCODING_PCM_16BIT - ) - bufferSize > 0 // 返回正值表示支持 - } ?: 16000 // 默认回退值 + /** + * 移动文件到新路径 + */ + fun moveFile(sourcePath: String, destPath: String): Boolean { + Log.i(tag, "移动文件到新路径:") - val buffer = ByteArray(bufferSize) + recordfile!!.moveFile(sourcePath, destPath) + return true + } - while (!Thread.interrupted() && audioRecord?.recordingState == AudioRecord.RECORDSTATE_RECORDING) { + /** + * 重命名指定路径的音频文件 + */ + fun renameFile(filePath: String, newName: String): Boolean { + Log.i(tag, "重命名指定路径的音频文件:") - if (!isPaused) { - // 读取音频 - val bytesRead = audioRecord?.read(buffer, 0, buffer.size) ?: 0 - if (bytesRead > 0) { - // 写入Azure流 - audioStream?.write(buffer) - // 保存录音 - recordfile?.saveAudioDataToWav(buffer) - } - } - } - }.apply { start() } + recordfile!!.renameFile(filePath, newName) + return true } /** - * 停止麦克风捕获并释放所有相关资源 + * 停止录音 */ - private fun stopMicrophoneCapture() { - try { - // 中断并等待捕获线程结束 - captureThread?.interrupt() - captureThread?.join(300) // 最多等待300ms + fun pauseRecord() { + Log.i(tag, "停止连续录音:") - // 停止录音并释放AudioRecord资源 - audioRecord?.stop() // 必须先停止再释放 + recordfile!!.isPause = true + } - } catch (e: Exception) { - Log.e("AudioConfig", "Error releasing resources: ${e.message}") - } finally { - // 确保恢复原始音频状态 - restoreOriginalAudioState() - } + /** + * 关闭录音 + */ + fun stopRecord(isSave: Boolean) { + Log.i(tag, "关闭录音:") + + recordfile!!.isPause = false + recordfile!!.closeFile(isSave) } /** - * 应用音频效果 - 总是启用所有音频增强功能 + * 麦克风流 - 拉流模式 + * 实现PullAudioInputStreamCallback,为Azure SDK提供音频数据 */ - private fun applyAudioEffects() { - val sessionId = audioRecord?.audioSessionId ?: return + inner class AudioStream { - try { - // 设置音频模式为通信模式 - audioManager?.mode = AudioManager.MODE_IN_COMMUNICATION + private var echoCanceler: AcousticEchoCanceler? = null + private var noiseSuppressor: NoiseSuppressor? = null + private var automaticGainControl: AutomaticGainControl? = null - // 启用声学回音消除 - if (AcousticEchoCanceler.isAvailable()) { - echoCanceler = AcousticEchoCanceler.create(sessionId) - echoCanceler?.enabled = true - Log.i(tag, "声学回音消除已启用") - } else { - Log.w(tag, "设备不支持声学回音消除") - } - // 启用噪声抑制 - if (NoiseSuppressor.isAvailable()) { - noiseSuppressor = NoiseSuppressor.create(sessionId) - noiseSuppressor?.enabled = true - Log.i(tag, "噪声抑制已启用") + var audioRecord: AudioRecord? = null + private var captureThread: Thread? = null + var pushAudioStream: PushAudioInputStream? = null + + + // 音频配置 + + private val channelConfig = AudioFormat.CHANNEL_IN_MONO + private val audioFormat = AudioFormat.ENCODING_PCM_16BIT + + /** + * 开始麦克风捕获 + */ + fun initAudioRecord() { + + val format = getOptimalAudioFormat() + pushAudioStream = AudioInputStream.createPushStream(format) + val supportedSampleRates = intArrayOf(16000, 8000, 11025, 22050, 44100) + // 查找设备支持的最佳采样率 + val sampleRate = supportedSampleRates.firstOrNull { rate -> + val bufferSize = AudioRecord.getMinBufferSize( + rate, + channelConfig, + audioFormat + ) + bufferSize > 0 // 返回正值表示支持 + } ?: 16000 // 默认回退值 + + + // 计算最小缓冲区大小(避免出现音频欠载) + val minBufferSize = AudioRecord.getMinBufferSize( + sampleRate, + channelConfig, + audioFormat + ) +// 创建录音对象 + if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) { + Log.d("AzureASR", "android.os.Build.VERSION.SDK_INT") + val format = AudioFormat.Builder() + .setSampleRate(sampleRate) + .setEncoding(audioFormat) + .setChannelMask(channelConfig) + .build() + + audioRecord = AudioRecord.Builder() + .setAudioSource(MediaRecorder.AudioSource.VOICE_COMMUNICATION) + .setAudioFormat(format) + .setBufferSizeInBytes(minBufferSize * 2) + .build() } else { - Log.w(tag, "设备不支持噪声抑制") + // 创建 AudioRecord 对象 + audioRecord = AudioRecord( + MediaRecorder.AudioSource.VOICE_RECOGNITION, // 语音识别专用音源(自带降噪/回声消除) + sampleRate, + channelConfig, + audioFormat, + minBufferSize * 2 // 使用两倍缓冲区防止溢出 + ) + } - // 启用自动增益控制 - if (AutomaticGainControl.isAvailable()) { - automaticGainControl = AutomaticGainControl.create(sessionId) - automaticGainControl?.enabled = true - Log.i(tag, "自动增益控制已启用") - } else { - Log.w(tag, "设备不支持自动增益控制") + + // 检查初始化状态 + if (audioRecord?.state != AudioRecord.STATE_INITIALIZED) { + throw IllegalStateException("AudioRecord初始化失败") } - Log.i(tag, "回音消除和音频增强功能已全部启用") - } catch (e: Exception) { - Log.e(tag, "设置音频效果失败: ${e.message}") + startCaptureThread() // 再启动数据读取线程 } - } - /** - * 释放音频资源 - */ - private fun releaseAudioResources() { - try { - // 停止录音 - if (audioRecord?.recordingState == AudioRecord.RECORDSTATE_RECORDING) { - audioRecord?.stop() - } + // 3. 单独封装线程启动逻辑 + fun startCaptureThread() { + // 开始录音 + audioRecord?.startRecording() + captureThread = Thread { + // 根据实际采样率计算缓冲区大小 + val supportedSampleRates = intArrayOf(16000, 8000, 11025, 22050, 44100) + var bufferSize = 0 + // 查找设备支持的最佳采样率 + val sampleRate = supportedSampleRates.firstOrNull { rate -> + bufferSize = AudioRecord.getMinBufferSize( + rate, + AudioFormat.CHANNEL_IN_MONO, + AudioFormat.ENCODING_PCM_16BIT + ) + bufferSize > 0 // 返回正值表示支持 + } ?: 16000 // 默认回退值 + + val buffer = ByteArray(bufferSize) + + while (!Thread.interrupted() && audioRecord?.recordingState == AudioRecord.RECORDSTATE_RECORDING) { + if (!isPaused) { + // 读取音频 + val bytesRead = audioRecord?.read(buffer, 0, buffer.size) ?: 0 + if (bytesRead > 0) { + + // 写入Azure流 + pushAudioStream?.write(buffer) + + // 保存录音 + recordfile?.saveAudioDataToWav(buffer) + } + } + } + }.apply { start() } + } - // 释放回音消除器 - echoCanceler?.let { - it.enabled = false - it.release() - echoCanceler = null - } + /** + * 停止麦克风捕获并释放所有相关资源 + */ + fun stopMicrophoneCapture() { + try { + if (captureThread != null) { + // 中断并等待捕获线程结束 + captureThread?.interrupt() + captureThread?.join(300) // 最多等待300ms + + // 停止录音并释放AudioRecord资源 + audioRecord?.stop() // 必须先停止再释放 + isPaused= true + } - // 释放噪声抑制器 - noiseSuppressor?.let { - it.enabled = false - it.release() - noiseSuppressor = null - } - // 释放自动增益控制 - automaticGainControl?.let { - it.enabled = false - it.release() - automaticGainControl = null + } catch (e: Exception) { + Log.e("AudioConfig", "Error releasing resources: ${e.message}") + } finally { + // 确保恢复原始音频状态 + // restoreOriginalAudioState() } + } - // 恢复音频模式 - this@AzureAsrHelper.audioManager?.mode = this@AzureAsrHelper.originalAudioMode + + /** + * 释放音频资源 + */ + fun releaseAudioResources() { + try { + isPaused= true + // 停止录音 + if (audioRecord?.recordingState == AudioRecord.RECORDSTATE_RECORDING) { + audioRecord?.stop() + } - // 释放录音实例 - audioRecord?.release() - audioRecord = null - } catch (e: Exception) { - Log.e(tag, "释放音频资源失败: ${e.message}") - e.printStackTrace() + // // 释放回音消除器 + // echoCanceler?.let { + // it.enabled = false + // it.release() + // echoCanceler = null + // } + + // // 释放噪声抑制器 + // noiseSuppressor?.let { + // it.enabled = false + // it.release() + // noiseSuppressor = null + // } + + // // 释放自动增益控制 + // automaticGainControl?.let { + // it.enabled = false + // it.release() + // automaticGainControl = null + // } + + // 恢复音频模式 + this@AzureAsrHelper.audioManager?.mode = this@AzureAsrHelper.originalAudioMode + + // 释放录音实例 + audioRecord?.release() + audioRecord = null + } catch (e: Exception) { + Log.e(tag, "释放音频资源失败: ${e.message}") + e.printStackTrace() + } } - } - // /** - // * 麦克风流 - 拉流模式 - // * 实现PullAudioInputStreamCallback,为Azure SDK提供音频数据 - // */ - // private inner class MicrophoneStream : PullAudioInputStreamCallback() { - // private var audioRecord: AudioRecord? = null - // private var echoCanceler: AcousticEchoCanceler? = null - // private var noiseSuppressor: NoiseSuppressor? = null - // private var automaticGainControl: AutomaticGainControl? = null - - // // 音频配置 - // private val sampleRate = 16000 - // private val channelConfig = AudioFormat.CHANNEL_IN_MONO - // private val audioFormat = AudioFormat.ENCODING_PCM_16BIT - - // // 优化:减少缓冲区大小以降低延迟 - // private val bufferSize = AudioRecord.getMinBufferSize( - // sampleRate, channelConfig, audioFormat - // ).let { if (it < 0) 2048 else it } - - // init { - // initMicrophone() - // } - - // /** - // * 初始化麦克风 - // */ - // private fun initMicrophone() { - // try { - // // 创建录音对象 - // if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { - // val format = AudioFormat.Builder() - // .setSampleRate(sampleRate) - // .setEncoding(audioFormat) - // .setChannelMask(channelConfig) - // .build() - - // audioRecord = AudioRecord.Builder() - // .setAudioSource(MediaRecorder.AudioSource.VOICE_COMMUNICATION) - // .setAudioFormat(format) - // .setBufferSizeInBytes(bufferSize) - // .build() - // } else { - // audioRecord = AudioRecord( - // MediaRecorder.AudioSource.VOICE_COMMUNICATION, - // sampleRate, - // channelConfig, - // audioFormat, - // bufferSize - // ) - // } - - // // 检查初始化状态 - // if (audioRecord?.state != AudioRecord.STATE_INITIALIZED) { - // throw IllegalStateException("AudioRecord初始化失败") - // } - - // // 应用音频效果 - // applyAudioEffects() - - // // 开始录音 - // audioRecord?.startRecording() - - // // 检查录音状态 - // if (audioRecord?.recordingState != AudioRecord.RECORDSTATE_RECORDING) { - // throw IllegalStateException("录音启动失败") - // } - // } catch (e: Exception) { - // e.printStackTrace() - // } - // } - - // /** - // * 应用音频效果 - 总是启用所有音频增强功能 - // */ - // private fun applyAudioEffects() { - // val sessionId = audioRecord?.audioSessionId ?: return - - // try { - // // 设置音频模式为通信模式 - // this@AzureAsrHelper.audioManager?.mode = AudioManager.MODE_IN_COMMUNICATION - - // // 启用声学回音消除 - // if (AcousticEchoCanceler.isAvailable()) { - // echoCanceler = AcousticEchoCanceler.create(sessionId) - // echoCanceler?.enabled = true - // Log.i(tag, "声学回音消除已启用") - // } else { - // Log.w(tag, "设备不支持声学回音消除") - // } - - // // 启用噪声抑制 - // if (NoiseSuppressor.isAvailable()) { - // noiseSuppressor = NoiseSuppressor.create(sessionId) - // noiseSuppressor?.enabled = true - // Log.i(tag, "噪声抑制已启用") - // } else { - // Log.w(tag, "设备不支持噪声抑制") - // } - - // // 启用自动增益控制 - // if (AutomaticGainControl.isAvailable()) { - // automaticGainControl = AutomaticGainControl.create(sessionId) - // automaticGainControl?.enabled = true - // Log.i(tag, "自动增益控制已启用") - // } else { - // Log.w(tag, "设备不支持自动增益控制") - // } - - // Log.i(tag, "回音消除和音频增强功能已全部启用") - // } catch (e: Exception) { - // Log.e(tag, "设置音频效果失败: ${e.message}") - // } - // } - - // /** - // * 获取音频格式 - // */ - // fun getFormat(): AudioStreamFormat = - // AudioStreamFormat.getWaveFormatPCM(16000.toLong(), 16.toShort(), 1.toShort()) - - // /** - // * Azure SDK 调用此方法获取音频数据 - // * 这是拉流模式的核心方法,由SDK调用以获取音频数据 - // */ - // /** - // * 优化:简化音频数据读取(移除文件保存) - // */ - // override fun read(buffer: ByteArray): Int { - // try { - // val result = audioRecord?.read(buffer, 0, buffer.size) ?: -1 - // if (result < 0) { - // Log.e(tag, "读取音频数据失败: $result") - // return 0 - // } - // recordfile?.saveAudioDataToWav(buffer) - // return result - // } catch (e: Exception) { - // Log.e(tag, "读取音频异常: ${e.message}") - // return 0 - // } - // } - - // /** - // * 优化:简化资源关闭 - // */ - // override fun close() { - // releaseAudioResources() - // } - - // /** - // * 释放音频资源 - // */ - // private fun releaseAudioResources() { - // try { - // // 停止录音 - // if (audioRecord?.recordingState == AudioRecord.RECORDSTATE_RECORDING) { - // audioRecord?.stop() - // } - - // // 释放回音消除器 - // echoCanceler?.let { - // it.enabled = false - // it.release() - // echoCanceler = null - // } - - // // 释放噪声抑制器 - // noiseSuppressor?.let { - // it.enabled = false - // it.release() - // noiseSuppressor = null - // } - - // // 释放自动增益控制 - // automaticGainControl?.let { - // it.enabled = false - // it.release() - // automaticGainControl = null - // } - - // // 恢复音频模式 - // this@AzureAsrHelper.audioManager?.mode = this@AzureAsrHelper.originalAudioMode - - // // 释放录音实例 - // audioRecord?.release() - // audioRecord = null - // } catch (e: Exception) { - // Log.e(tag, "释放音频资源失败: ${e.message}") - // e.printStackTrace() - // } - // } - // } + } /** * 外部音频拉流 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 8cd740589..d885c92cd 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 @@ -256,13 +256,12 @@ class AzureSpeechPlugin : BleService.Callback, FlutterPlugin { } "setPause" -> { - azureAsrHelper.stopAudioPause(); + azureAsrHelper.audioPause(); return } "setcontinue" -> { - // azureAsrHelper.stopAudioPause(); - azureAsrHelper.setAudiocontinue(); + azureAsrHelper.audioContinue(); return } @@ -272,7 +271,6 @@ class AzureSpeechPlugin : BleService.Callback, FlutterPlugin { } "restoreOriginalAudioState" -> { - // azureAsrHelper.stopAudioPause(); azureAsrHelper.restoreOriginalAudioState(); return } 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 f06a8c54e..22a674269 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 @@ -578,15 +578,14 @@ object BleService { // 根据特征UUID区分处理 when (c.uuid) { // 音频特征数据 - BleConst.RECEIVE_AUDIO_CHAR_UUID1 -> { + // BleConst.RECEIVE_AUDIO_CHAR_UUID1 -> { - Log.i(TAG, "RECEIVE_AUDIO_CHAR_UUID1") - processAudioData(data) - } + // Log.i(TAG, "RECEIVE_AUDIO_CHAR_UUID1") + // processAudioData(data) + // } // 音频特征数据 BleConst.RECEIVE_AUDIO_CHAR_UUID -> { - Log.i(TAG, "RECEIVE_AUDIO_CHAR_UUID") processAudioData(data) } // 通知特征数据(命令和控制)