diff --git a/lib/data/services/novice_guide_service.dart b/lib/data/services/novice_guide_service.dart index 17d9f0a35..f7617114f 100644 --- a/lib/data/services/novice_guide_service.dart +++ b/lib/data/services/novice_guide_service.dart @@ -14,7 +14,7 @@ class NoviceGuideService extends GetxService { final BleService _bleService = BleService(); StreamSubscription? _statusSubscription; - bool isHomeGuide = false; + bool isHomeGuide = false; //false代表未完成新手引导,true代表已经完成 bool isAIGuide = false; RxBool isWakeup = false.obs; diff --git a/lib/modules/agent/views/agent_view.dart b/lib/modules/agent/views/agent_view.dart index b3a5846b1..76edfeca9 100644 --- a/lib/modules/agent/views/agent_view.dart +++ b/lib/modules/agent/views/agent_view.dart @@ -521,6 +521,14 @@ class _AgentViewState extends State with WidgetsBindingObserver { controller.noviceGuideService .aiStep]['input']; }, + onTap: () { + controller.textController.text = + controller.noviceGuideService + .aiStepsList[ + controller.noviceGuideService + .aiStep]['input']; + params.onNext!(); + }, ); }, onWidgetLoad: () { diff --git a/lib/modules/home/controllers/home_controller.dart b/lib/modules/home/controllers/home_controller.dart index 35c45ef1c..8b47ae480 100644 --- a/lib/modules/home/controllers/home_controller.dart +++ b/lib/modules/home/controllers/home_controller.dart @@ -177,7 +177,7 @@ class HomeController extends GetxController { bool wasConnected = _isFullyConnected.value; bool isNowConnected = hasClassicBluetooth && hasBleConnection; - bool isGuideCompleted = _storage.read('home_guide') ?? false; + //bool isGuideCompleted = _storage.read('home_guide') ?? false; if (isNowConnected && currentDevice == null) { isNowConnected = false; @@ -197,7 +197,7 @@ class HomeController extends GetxController { // 移除了连接成功后的电池信息刷新 // 连接成功后检查OTA升级 - if (isGuideCompleted) { + if (noviceGuideService.isHomeGuide) { Future.delayed(const Duration(seconds: 2), () { _checkOtaUpgrade(); }); diff --git a/lib/modules/home/views/home_view.dart b/lib/modules/home/views/home_view.dart index 440db691a..34156f114 100644 --- a/lib/modules/home/views/home_view.dart +++ b/lib/modules/home/views/home_view.dart @@ -105,6 +105,10 @@ class HomeView extends GetView { onNext: () { controller.noviceGuideService.startWakeupListen(); }, + onTap: () { + params.onNext!(); + controller.noviceGuideService.startWakeupListen(); + }, ); }, builder: (BuildContext context, GlobalKey key) => SizedBox( diff --git a/local_plugins/azure_speech/ios/azure_speech/Sources/azure_speech/AzureTtsHelper.swift b/local_plugins/azure_speech/ios/azure_speech/Sources/azure_speech/AzureTtsHelper.swift index 30dfd7464..6689f5138 100644 --- a/local_plugins/azure_speech/ios/azure_speech/Sources/azure_speech/AzureTtsHelper.swift +++ b/local_plugins/azure_speech/ios/azure_speech/Sources/azure_speech/AzureTtsHelper.swift @@ -264,44 +264,77 @@ public class AzureTtsHelper: NSObject, ITtsService { pendingTasks.removeAll() taskLock.unlock() - do { - print("liwei-------------停止语音合成播放") - try self.synthesizer?.stopSpeaking() - self.notifyEvent(eventType: .synthesisCanceled) - - if !micCapture.isCapturing{ - // 停止时设置音频会话为非活跃状态 - // try AVAudioSession.sharedInstance().setActive(false) - } - - print("音频会话已设置为非活跃状态") - } catch { - os_log("停止语音合成失败: %{public}@", log: self.log, type: .error, error.localizedDescription) - self.notifyEvent(eventType: .error, params: [ - "errorCode": "STOP_FAILED", - "errorMessage": error.localizedDescription - ]) - } + // 使用异步停止方法并等待完成 + let stopGroup = DispatchGroup() + stopGroup.enter() - synthesisQueue.async { + synthesisQueue.async { [weak self] in + guard let self = self else { + stopGroup.leave() + return + } + do { + print("liwei-------------停止语音合成播放") + // 使用异步停止方法 + if let synthesizer = self.synthesizer { + let stopFuture = synthesizer.stopSpeakingAsync() + // 等待停止操作完成 + _ = stopFuture.get() + } + + self.notifyEvent(eventType: .synthesisCanceled) + + if !self.micCapture.isCapturing { + // 停止时设置音频会话为非活跃状态 + // try AVAudioSession.sharedInstance().setActive(false) + } + + print("音频会话已设置为非活跃状态") + + // 等待所有合成操作完成后再重新创建 + self.synthesisGroup.wait() + + // 安全地销毁和重新创建合成器 self.synthesizer = nil try self.recreateSynthesizer() - }catch { - os_log("重置语音合成失败: %{public}@", log: self.log, type: .error, error.localizedDescription) + + } catch { + os_log("停止语音合成失败: %{public}@", log: self.log, type: .error, error.localizedDescription) + self.notifyEvent(eventType: .error, params: [ + "errorCode": "STOP_FAILED", + "errorMessage": error.localizedDescription + ]) } + + stopGroup.leave() } + // 等待停止操作完成 + stopGroup.wait() return true } /** * 释放资源 */ public func dispose() { + // 先停止所有操作 _ = stop() + + // 等待所有异步操作完成 synthesisGroup.wait() synthesisQueue.sync { + // 确保合成器完全停止后再销毁 + if let synthesizer = self.synthesizer { + do { + let stopFuture = synthesizer.stopSpeakingAsync() + _ = try stopFuture.get() + } catch { + os_log("停止合成器失败: %{public}@", log: self.log, type: .error, error.localizedDescription) + } + } + synthesizer = nil speechConfig = nil customAudioOutputStream = nil @@ -441,29 +474,55 @@ public class AzureTtsHelper: NSObject, ITtsService { /** * 执行语音合成 */ - private func performSynthesis(sessionid:String,text: String) { + private func performSynthesis(sessionid: String, text: String) { if (self.sessionid != sessionid) { return } + + // 进入合成组 + synthesisGroup.enter() + speaking = true -// lastSpokenText = text // 生成SSML let ssml = generateOptimizedSsml(text) do { if (self.sessionid != sessionid) { + synthesisGroup.leave() return } os_log("开始合成: %{public}@", log: log, type: .debug, ssml) - let result = try synthesizer?.startSpeakingSsml(ssml) - if let result = result { - os_log("合成完成,结果: %{public}@", log: log, type: .debug, String(describing: result.reason)) + // 使用异步合成方法 + if let synthesizer = self.synthesizer { + let future = synthesizer.speakSsmlAsync(ssml) + + // 在后台等待合成完成 + DispatchQueue.global(qos: .userInitiated).async { [weak self] in + defer { + self?.synthesisGroup.leave() + } + + do { + let result = try future.get() + os_log("合成完成,结果: %{public}@", log: self?.log ?? OSLog.default, type: .debug, String(describing: result.reason)) + } catch { + self?.speaking = false + self?.pendingTextCount = max(0, (self?.pendingTextCount ?? 0) - text.count) + os_log("异步语音合成失败: %{public}@", log: self?.log ?? OSLog.default, type: .error, error.localizedDescription) + self?.notifyEvent(eventType: .error, params: [ + "errorCode": "ASYNC_SYNTHESIS_FAILED", + "errorMessage": error.localizedDescription + ]) + } + } } + } catch { speaking = false - // 减少待处理文本计数 pendingTextCount = max(0, pendingTextCount - text.count) + synthesisGroup.leave() + os_log("语音合成失败: %{public}@", log: log, type: .error, error.localizedDescription) notifyEvent(eventType: .error, params: [ "errorCode": "SYNTHESIS_FAILED",