Browse Source

Merge branch 'new_dev' of https://github.com/deepcloud2048/deep_voice into new_dev

weicu
liwei1dao 1 year ago
parent
commit
2f91557635
  1. 178
      local_plugins/azure_speech/ios/azure_speech/Sources/azure_speech/AzureAsrHelper.swift

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

@ -27,6 +27,16 @@ public class AzureAsrHelper: NSObject {
private var networkMonitor: NetworkStateMonitor = NetworkStateMonitor() private var networkMonitor: NetworkStateMonitor = NetworkStateMonitor()
private var continuousCallback: ContinuousRecognizeCallback? private var continuousCallback: ContinuousRecognizeCallback?
private var isNetworkRecovering = false private var isNetworkRecovering = false
// 网络丢失计数器
private var networkLostCount = 0
// 最大网络丢失次数(3秒检测)
private let maxNetworkLostCount = 3
// 防抖机制相关变量
private var lastNetworkLostTime: Int64 = 0
private let networkLostDebounceInterval: Int64 = 3000 // 3秒防抖间隔
// 状态管理 // 状态管理
private var _isContinuousRecognitionActive = false private var _isContinuousRecognitionActive = false
@ -141,61 +151,52 @@ public class AzureAsrHelper: NSObject {
private func handleNetworkAvailable() { private func handleNetworkAvailable() {
os_log("网络已恢复", log: log, type: .info) os_log("网络已恢复", log: log, type: .info)
DispatchQueue.main.async { [weak self] in
guard let self = self else { return }
if !self.isNetworkRecovering { if !self.isNetworkRecovering {
self.isNetworkRecovering = true self.isNetworkRecovering = true
os_log("网络恢复,准备重新启动识别", log: self.log, type: .info) os_log("网络恢复,准备重新启动识别", log: self.log, type: .info)
// 如果之前在进行连续识别,重新启动
DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) {
self.restartContinuousRecognition()
}
} }
}
} }
/**
* 重新启动连续识别(网络恢复时使用) /**
* 处理网络连接丢失(带防抖机制)
*/ */
private func restartContinuousRecognition() { private func handleNetworkLost() {
os_log("重新启动连续识别", log: log, type: .info) let currentTime = Int64(Date().timeIntervalSince1970 * 1000) // 转换为毫秒
// 检查continuousCallback是否为空 // 防抖机制:如果距离上次触发时间小于防抖间隔,则忽略本次触发
guard let callback = continuousCallback else { if currentTime - lastNetworkLostTime < networkLostDebounceInterval {
os_log("连续识别回调为空,无法重新启动", log: log, type: .info) os_log("网络丢失事件被防抖过滤,距离上次触发仅%{public}dms", log: log, type: .debug, currentTime - lastNetworkLostTime)
return return
} }
do { // 更新最后触发时间
_ = setupEventListeners(callback: callback) lastNetworkLostTime = currentTime
isNetworkRecovering = false
os_log("连续识别重新启动成功", log: log, type: .info)
} catch {
os_log("重新启动连续识别失败: %@", log: log, type: .error, error.localizedDescription)
isNetworkRecovering = false
}
}
/**
* 立即停止音频处理
*/
private func stopAudioProcessingImmediately() {
audioStream?.stopMicrophoneCapture()
if _isContinuousRecognitionActive { // 这里启动一个3秒定时器,3秒后检查网络是否恢复
do { DispatchQueue.main.asyncAfter(deadline: .now() + 3.0) { [weak self] in
try recognizer?.stopContinuousRecognition() guard let self = self else { return }
_isContinuousRecognitionActive = false
os_log("因网络问题强制停止识别", log: log, type: .info) os_log("网络不可用", log: self.log, type: .error)
} catch { let isNetworkAvailable = self.checkNetworkStatus()
_isContinuousRecognitionActive = false
os_log("强制停止识别失败: %@", log: log, type: .error, error.localizedDescription) if isNetworkAvailable {
// 如果网络恢复,重置计数器和防抖时间
os_log("网络已恢复,重置计数器", log: self.log, type: .info)
self.lastNetworkLostTime = 0
self.isNetworkRecovering = true
} else {
self.continuousCallback?.onError(1000, "网络连接不可用,请检查网络设置")
os_log("网络仍未恢复,继续检测", log: self.log, type: .debug)
self.networkLostCount = 0
self.stopContinuousRecognition()
} }
} }
} }
/** /**
* 预初始化音频组件 * 预初始化音频组件
* 在初始化阶段就准备好音频流和相关组件,减少首次启动延迟 * 在初始化阶段就准备好音频流和相关组件,减少首次启动延迟
@ -245,13 +246,11 @@ public class AzureAsrHelper: NSObject {
do { do {
guard recognizer != nil else { if recognizer == nil {
if !setupRecognizer() { // 检查continuousCallback是否为空,只有在不为空时才设置事件监听器
print("重置识别器失败") if let callback = self.continuousCallback {
// callback.onError("重置识别器失败") setupEventListeners(callback: callback)
return false
} }
return false
} }
print("startContinuousRecognition:\(audioSourceType)") print("startContinuousRecognition:\(audioSourceType)")
@ -266,7 +265,7 @@ public class AzureAsrHelper: NSObject {
return true return true
} catch { } catch {
audioStream?.stopMicrophoneCapture() stopContinuousRecognition()
_isContinuousRecognitionActive = false _isContinuousRecognitionActive = false
//callback.onError("启动连续识别失败: \(error.localizedDescription)") //callback.onError("启动连续识别失败: \(error.localizedDescription)")
return false return false
@ -300,13 +299,10 @@ public class AzureAsrHelper: NSObject {
do { do {
_isContinuousRecognitionActive = false _isContinuousRecognitionActive = false
if audioSourceType == .external {
//pushAudioData(data: Data())
}
audioStream?.stopMicrophoneCapture() audioStream?.stopMicrophoneCapture()
// 停止连续识别 // 停止连续识别
try recognizer.stopContinuousRecognition() try recognizer.stopContinuousRecognition()
self.recognizer = nil
print("stopContinuousRecognition") print("stopContinuousRecognition")
return true return true
} catch { } catch {
@ -320,6 +316,7 @@ public class AzureAsrHelper: NSObject {
// 【修复】在 catch 块中安全地停止识别器,避免再次抛出异常 // 【修复】在 catch 块中安全地停止识别器,避免再次抛出异常
do { do {
try recognizer.stopContinuousRecognition() try recognizer.stopContinuousRecognition()
self.recognizer = nil
} catch { } catch {
// 如果强制停止也失败,记录错误但不再抛出异常 // 如果强制停止也失败,记录错误但不再抛出异常
os_log("强制停止识别器失败: %@", log: log, type: .error, error.localizedDescription) os_log("强制停止识别器失败: %@", log: log, type: .error, error.localizedDescription)
@ -623,18 +620,9 @@ public class AzureAsrHelper: NSObject {
os_log("识别取消: %{public}@", log: self.log, type: .error, errorDetails) os_log("识别取消: %{public}@", log: self.log, type: .error, errorDetails)
// 检查是否为网络相关错误
if self.isNetworkRelatedError(errorDetails) {
os_log("检测到网络相关错误,停止音频处理", log: self.log, type: .info)
self.stopAudioProcessingImmediately()
// 如果不是正在恢复网络,通知上层网络错误
if !self.isNetworkRecovering {
callback.onError(1000,"启动连续识别失败,网络连接已断开")
}
} else {
callback.onCanceled(reason, errorDetails) callback.onCanceled(reason, errorDetails)
}
} }
return true return true
} }
@ -845,75 +833,17 @@ extension AzureAsrHelper: NetworkStateMonitor.NetworkStateListener {
func onNetworkAvailable() { func onNetworkAvailable() {
os_log("网络已恢复", log: log, type: .info) os_log("网络已恢复", log: log, type: .info)
DispatchQueue.main.async { [weak self] in self.handleNetworkAvailable()
self?.handleNetworkAvailable()
}
} }
/**
* 处理网络丢失事件
*/
func onNetworkLost() { func onNetworkLost() {
os_log("网络连接丢失", log: log, type: .error) os_log("网络连接丢失", log: log, type: .error)
// 立即停止音频处理 self.handleNetworkLost()
stopAudioProcessingImmediately()
DispatchQueue.main.async { [weak self] in
self?.continuousCallback?.onError(1000,"网络连接已断开")
}
} }
} }
// //ios 语言检测
// /**
// * 检测输入文本的语言,从支持的语言列表中选择最匹配的
// *
// * @param text 需要检测的文本
// * @return 从supportedLanguages中选择的最匹配语言代码
// */
// public func detectTextLanguage(_ text: String) -> String? {
// // 如果只有一种支持的语言,直接返回
// if supportedLanguages.count == 1 {
// return supportedLanguages[0]
// }
// // 获取所有可能的语言及其置信度
// let languageResults = LanguageDetector.detectLanguageWithConfidence(from: text)
// // 遍历检测结果,找到第一个在supportedLanguages中的语言
// for result in languageResults {
// let azureLanguageCode = LanguageDetector.convertToAzureLanguageCode(result.language)
// if supportedLanguages.contains(azureLanguageCode) {
// return azureLanguageCode
// }
// }
// // 如果没有找到匹配的语言,返回第一个支持的语言作为默认值
// return supportedLanguages.first
// }
// /**
// * 检测文本语言并返回详细信息
// *
// * @param text 需要检测的文本
// * @return 包含语言代码、置信度和语言名称的字典
// */
// public func detectTextLanguageWithDetails(_ text: String) -> [String: Any]? {
// let results = LanguageDetector.detectLanguageWithConfidence(from: text)
// guard let topResult = results.first else {
// return nil
// }
// let azureLanguageCode = LanguageDetector.convertToAzureLanguageCode(topResult.language)
// let languageName = LanguageDetector.getLanguageName(from: topResult.language)
// return [
// "languageCode": azureLanguageCode,
// "confidence": topResult.confidence,
// "languageName": languageName,
// "originalCode": topResult.language
// ]
// }

Loading…
Cancel
Save