Browse Source

上传代码

weicu
liwei1dao 1 year ago
parent
commit
a4c7c6c173
  1. 88
      local_plugins/agent_service/ios/agent_service/Sources/agent_service/AgentServiceImpl.swift
  2. 1
      local_plugins/azure_speech/ios/azure_speech/Sources/azure_speech/AzureAsrHelper.swift
  3. 2
      local_plugins/ble_service/ios/ble_service/Sources/ble_service/SwiftBleServicePlugin.swift

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

@ -84,6 +84,7 @@ class AgentServiceImpl: NSObject {
private var serverurl = "" private var serverurl = ""
private var usertoken = "" private var usertoken = ""
private let timerQueue = DispatchQueue(label: "com.example.idleTimer.queue")
private var idleTimer: DispatchSourceTimer? private var idleTimer: DispatchSourceTimer?
private let maxIdleSeconds: TimeInterval = 10 private let maxIdleSeconds: TimeInterval = 10
var micCapture: MicrophoneCapture! var micCapture: MicrophoneCapture!
@ -360,41 +361,62 @@ class AgentServiceImpl: NSObject {
} }
private func startIdleCheck(idleSeconds: TimeInterval = 10) { private func startIdleCheck(idleSeconds: TimeInterval = 10) {
stopIdleCheck() // 2. 所有对idleTimer的操作都通过串行队列执行,避免竞态条件
timerQueue.async {
guard isRecognizing else { return } // 先停止旧的定时器(在串行队列中执行,确保线程安全)
self.stopIdleCheck()
os_log("启动空闲检测,超时时间: %.0f秒,模式: %{public}@", log: logger, type: .info, idleSeconds, currentRecognitionMode)
guard self.isRecognizing else { return }
// 使用全局队列而不是主队列,避免后台挂起问题
let timer = DispatchSource.makeTimerSource(queue: DispatchQueue.global(qos: .utility)) os_log("启动空闲检测,超时时间: %.0f秒,模式: %{public}@",
idleTimer = timer log: self.logger,
type: .info,
timer.schedule(deadline: .now() + idleSeconds) idleSeconds,
timer.setEventHandler { [weak self] in self.currentRecognitionMode)
// 使用更安全的方式检查self是否存在
DispatchQueue.main.async { [weak self] in // 使用全局队列作为定时器回调队列(避免后台挂起)
let timer = DispatchSource.makeTimerSource(queue: DispatchQueue.global(qos: .utility))
timer.schedule(deadline: .now() + idleSeconds)
timer.setEventHandler { [weak self] in
guard let self = self else { return } guard let self = self else { return }
if self.isRecognizing && !self.isSpeaking && !self.isAiStreaming { // 回调在全局队列,涉及UI或实例变量操作时切换到主线程
os_log("空闲检测触发自动停止,模式: %{public}@", log: self.logger, type: .info, self.currentRecognitionMode) DispatchQueue.main.async { [weak self] in
// 关闭编码器 (设备侧) guard let self = self else { return }
BleService.shared.closeCodec()
self.stopRecognition() // 检查状态(确保在主线程访问这些属性,避免UI相关竞态)
self.sendEvent(name: "auto_stop", data: [ if self.isRecognizing && !self.isSpeaking && !self.isAiStreaming {
"reason": "idle_timeout", os_log("空闲检测触发自动停止,模式: %{public}@",
"seconds": idleSeconds, log: self.logger,
"mode": self.currentRecognitionMode type: .info,
]) self.currentRecognitionMode)
// 关闭编码器(设备侧操作,若BleService线程安全可直接调用,否则需加锁)
BleService.shared.closeCodec()
self.stopRecognition()
self.sendEvent(name: "auto_stop", data: [
"reason": "idle_timeout",
"seconds": idleSeconds,
"mode": self.currentRecognitionMode
])
}
} }
} }
timer.resume()
// 3. 在串行队列中安全赋值
self.idleTimer = timer
} }
timer.resume()
} }
private func stopIdleCheck() { private func stopIdleCheck() {
idleTimer?.cancel() timerQueue.async {
idleTimer = nil self.idleTimer?.cancel()
self.idleTimer = nil // 清空引用
}
} }
private func restartIdleCheck() { private func restartIdleCheck() {
@ -523,11 +545,11 @@ class AgentServiceImpl: NSObject {
if !isRecognizing || !isInitialized { if !isRecognizing || !isInitialized {
return false return false
} }
guard let audioStream = azureAsrHelper?.audioStream else { guard let audioStream = azureAsrHelper?.audioStream else {
os_log("AI音频流未初始化", log: logger,type: .error) os_log("AI音频流未初始化", log: logger,type: .error)
return false return false
} }
audioStream.saveAudioDataTo(data: audioData) audioStream.saveAudioDataTo(data: audioData)
return true return true
} }

1
local_plugins/azure_speech/ios/azure_speech/Sources/azure_speech/AzureAsrHelper.swift

@ -801,6 +801,7 @@ public class AzureAsrHelper: NSObject {
// 在主线程回调结果 // 在主线程回调结果
DispatchQueue.main.async { DispatchQueue.main.async {
callback.onResult(sessionid: self.currsessionId,result.text ?? "", detectedLanguage) callback.onResult(sessionid: self.currsessionId,result.text ?? "", detectedLanguage)
self.currsessionId = UUID().uuidString
} }
} }

2
local_plugins/ble_service/ios/ble_service/Sources/ble_service/SwiftBleServicePlugin.swift

@ -141,7 +141,7 @@ public class SwiftBleServicePlugin: NSObject, FlutterPlugin {
case "getPairedMacAddress": case "getPairedMacAddress":
let pairedUUID = BleService.shared.getPairedMacAddress() let pairedUUID = BleService.shared.getPairedMacAddress()
result(pairedUUID) result(true)
case "clearAssociations": case "clearAssociations":
BleService.shared.clearAssociations() BleService.shared.clearAssociations()
result(true) result(true)

Loading…
Cancel
Save