|
|
|
@ -272,7 +272,15 @@ public class AzureAsrHelper: NSObject { |
|
|
|
|
|
|
|
// 创建识别器 |
|
|
|
if isAutoDetectLanguage { |
|
|
|
let autoDetectConfig = try SPXAutoDetectSourceLanguageConfiguration(supportedLanguages) |
|
|
|
// 使用更精确的语言配置方式 |
|
|
|
var sourceLanguageConfigs: [SPXSourceLanguageConfiguration] = [] |
|
|
|
for language in supportedLanguages { |
|
|
|
if let config = try? SPXSourceLanguageConfiguration(language) { |
|
|
|
sourceLanguageConfigs.append(config) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
let autoDetectConfig = try SPXAutoDetectSourceLanguageConfiguration(sourceLanguageConfigurations: sourceLanguageConfigs) |
|
|
|
recognizer = try SPXSpeechRecognizer( |
|
|
|
speechConfiguration: speechConfig!, |
|
|
|
autoDetectSourceLanguageConfiguration: autoDetectConfig, |
|
|
|
@ -336,19 +344,59 @@ public class AzureAsrHelper: NSObject { |
|
|
|
recognizer.addRecognizingEventHandler { [weak self] (_, event) in |
|
|
|
guard let self = self else { return } |
|
|
|
let result = event.result |
|
|
|
let detectedLanguage = self.detectLanguage(from: result) |
|
|
|
print("识别中文本: \(result.text)") |
|
|
|
// 优化:只处理非空结果 |
|
|
|
if !(result.text?.isEmpty ?? true) { |
|
|
|
let detectedLanguage: String |
|
|
|
if self.isAutoDetectLanguage { |
|
|
|
do { |
|
|
|
let langResult = try SPXAutoDetectSourceLanguageResult(result) |
|
|
|
let rawLanguage = langResult.language |
|
|
|
print("[DEBUG] 原始检测语言: \(rawLanguage ?? "nil"), 文本: \(result.text ?? "nil"), 支持的语言: \(self.supportedLanguages)") |
|
|
|
|
|
|
|
// 应用启发式语言检测纠正 |
|
|
|
detectedLanguage = self.correctLanguageDetection(rawLanguage: rawLanguage ?? "", text: result.text ?? "") |
|
|
|
print("[DEBUG] 纠正后语言: \(detectedLanguage)") |
|
|
|
} catch { |
|
|
|
print("[DEBUG] 语言检测异常: \(error.localizedDescription)") |
|
|
|
detectedLanguage = "" |
|
|
|
} |
|
|
|
} else { |
|
|
|
detectedLanguage = self.currentLanguage |
|
|
|
print("[DEBUG] 使用当前语言: \(detectedLanguage)") |
|
|
|
} |
|
|
|
print("识别中事件: \(detectedLanguage)") |
|
|
|
DispatchQueue.main.async { |
|
|
|
callback.onRecognizing(result.text ?? "", detectedLanguage) |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
// 识别完成事件 |
|
|
|
recognizer.addRecognizedEventHandler { [weak self] (_, event) in |
|
|
|
guard let self = self else { return } |
|
|
|
let result = event.result |
|
|
|
if result.reason == .recognizedSpeech { |
|
|
|
let detectedLanguage = self.detectLanguage(from: result) |
|
|
|
print("识别完成文本: \(result.text)") |
|
|
|
if result.reason == .recognizedSpeech && !(result.text?.isEmpty ?? true) { |
|
|
|
let detectedLanguage: String |
|
|
|
if self.isAutoDetectLanguage { |
|
|
|
do { |
|
|
|
let langResult = try SPXAutoDetectSourceLanguageResult(result) |
|
|
|
let rawLanguage = langResult.language |
|
|
|
print("[DEBUG] 识别完成 - 原始检测语言: \(rawLanguage ?? "nil"), 文本: \(result.text ?? "nil"), 支持的语言: \(self.supportedLanguages)") |
|
|
|
|
|
|
|
// 应用启发式语言检测纠正 |
|
|
|
let correctedLanguage = self.correctLanguageDetection(rawLanguage: rawLanguage ?? "", text: result.text ?? "") |
|
|
|
detectedLanguage = correctedLanguage.isEmpty ? (self.supportedLanguages.first ?? self.currentLanguage) : correctedLanguage |
|
|
|
print("[DEBUG] 识别完成 - 纠正后语言: \(detectedLanguage)") |
|
|
|
} catch { |
|
|
|
print("[DEBUG] 识别完成 - 语言检测异常: \(error.localizedDescription)") |
|
|
|
detectedLanguage = self.supportedLanguages.first ?? self.currentLanguage |
|
|
|
} |
|
|
|
} else { |
|
|
|
detectedLanguage = self.currentLanguage |
|
|
|
print("[DEBUG] 识别完成 - 使用当前语言: \(detectedLanguage)") |
|
|
|
} |
|
|
|
print("识别完成事件: \(detectedLanguage)") |
|
|
|
DispatchQueue.main.async { |
|
|
|
callback.onResult(result.text ?? "", detectedLanguage) |
|
|
|
@ -387,38 +435,6 @@ public class AzureAsrHelper: NSObject { |
|
|
|
return true |
|
|
|
} |
|
|
|
|
|
|
|
// 提取的辅助方法 |
|
|
|
private func detectLanguage(from result: SPXSpeechRecognitionResult) -> String { |
|
|
|
if isAutoDetectLanguage { |
|
|
|
let langResult = try SPXAutoDetectSourceLanguageResult(result) |
|
|
|
return langResult.language ?? "" |
|
|
|
} else { |
|
|
|
return currentLanguage |
|
|
|
} |
|
|
|
} |
|
|
|
/** |
|
|
|
* 获取检测到的语言 |
|
|
|
*/ |
|
|
|
private func getDetectedLanguage(from result: SPXSpeechRecognitionResult) -> String { |
|
|
|
if !isAutoDetectLanguage { |
|
|
|
return "" |
|
|
|
} |
|
|
|
|
|
|
|
// 尝试从属性中获取语言 |
|
|
|
if let properties = result.properties, |
|
|
|
let language = properties.getPropertyByName("SpeechServiceResponse_RecognitionLanguage") { |
|
|
|
return language |
|
|
|
} |
|
|
|
|
|
|
|
// 尝试另一种方式获取语言 |
|
|
|
do { |
|
|
|
let langResult = try SPXAutoDetectSourceLanguageResult(result) |
|
|
|
print("获取检测到的语言") |
|
|
|
return langResult.language ?? "" |
|
|
|
} catch { |
|
|
|
return "" |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* 禁用蓝牙音频功能,切换回正常音频模式 |
|
|
|
@ -853,6 +869,57 @@ private func detectLanguage(from result: SPXSpeechRecognitionResult) -> String { |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* 启发式语言检测纠正方法 |
|
|
|
* 基于文本内容特征来纠正Azure语音服务的语言检测结果 |
|
|
|
*/ |
|
|
|
private func correctLanguageDetection(rawLanguage: String, text: String) -> String { |
|
|
|
// 如果原始检测为空,返回空 |
|
|
|
if rawLanguage.isEmpty || text.isEmpty { |
|
|
|
return rawLanguage |
|
|
|
} |
|
|
|
|
|
|
|
let trimmedText = text.trimmingCharacters(in: .whitespacesAndNewlines).lowercased() |
|
|
|
|
|
|
|
// 英文特征检测 |
|
|
|
let englishPattern = "^[a-z\\s\\.,!?;:'-]+$" |
|
|
|
let englishRegex = try? NSRegularExpression(pattern: englishPattern, options: .caseInsensitive) |
|
|
|
let englishMatches = englishRegex?.numberOfMatches(in: trimmedText, options: [], range: NSRange(location: 0, length: trimmedText.count)) ?? 0 |
|
|
|
|
|
|
|
// 中文特征检测 |
|
|
|
let chinesePattern = "[\\u4e00-\\u9fff]" |
|
|
|
let chineseRegex = try? NSRegularExpression(pattern: chinesePattern, options: []) |
|
|
|
let chineseMatches = chineseRegex?.numberOfMatches(in: trimmedText, options: [], range: NSRange(location: 0, length: trimmedText.count)) ?? 0 |
|
|
|
|
|
|
|
// 常见英文单词列表 |
|
|
|
let commonEnglishWords = ["hello", "hi", "please", "thank", "you", "yes", "no", "good", "morning", "afternoon", "evening", "night", "how", "are", "what", "where", "when", "why", "who", "can", "could", "would", "should", "will", "the", "and", "or", "but", "if", "then", "this", "that", "these", "those"] |
|
|
|
|
|
|
|
let hasCommonEnglishWords = commonEnglishWords.contains { word in |
|
|
|
trimmedText.contains(word) |
|
|
|
} |
|
|
|
|
|
|
|
print("[DEBUG] 语言纠正分析 - 文本: '\(trimmedText)', 英文匹配: \(englishMatches > 0), 中文字符: \(chineseMatches), 常见英文词: \(hasCommonEnglishWords), 原始语言: \(rawLanguage)") |
|
|
|
|
|
|
|
// 纠正逻辑 |
|
|
|
if rawLanguage == "zh-CN" { |
|
|
|
// 如果Azure检测为中文,但文本明显是英文特征 |
|
|
|
if (englishMatches > 0 && chineseMatches == 0) || hasCommonEnglishWords { |
|
|
|
print("[DEBUG] 纠正: \(rawLanguage) -> en-US (检测到英文特征)") |
|
|
|
return "en-US" |
|
|
|
} |
|
|
|
} else if rawLanguage == "en-US" { |
|
|
|
// 如果Azure检测为英文,但包含中文字符 |
|
|
|
if chineseMatches > 0 { |
|
|
|
print("[DEBUG] 纠正: \(rawLanguage) -> zh-CN (检测到中文字符)") |
|
|
|
return "zh-CN" |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
// 如果没有明确的纠正理由,保持原始检测结果 |
|
|
|
return rawLanguage |
|
|
|
} |
|
|
|
|
|
|
|
// MARK: - 回调函数 |
|
|
|
/** |
|
|
|
* 连续识别回调接口 |
|
|
|
|