Browse Source

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

newdev_shunjiawei
liwei1dao 8 months ago
parent
commit
1b1e6ddda5
  1. 2
      lib/modules/translation/controllers/translation_controller.dart
  2. 30
      local_plugins/azure_speech/android/src/main/kotlin/com/yunqiinnovation/azure_speech/AzureAsrHelper.kt
  3. 7
      local_plugins/azure_speech/android/src/main/kotlin/com/yunqiinnovation/azure_speech/AzureSpeechPlugin.kt
  4. 76
      local_plugins/azure_speech/android/src/main/kotlin/com/yunqiinnovation/azure_speech/XunFeiAsrHelper.kt
  5. 1019
      local_plugins/azure_speech/ios/azure_speech/Sources/azure_speech/AzureAsrHelper.swift
  6. 10
      local_plugins/azure_speech/ios/azure_speech/Sources/azure_speech/AzureSpeechPlugin.swift
  7. 49
      local_plugins/azure_speech/ios/azure_speech/Sources/azure_speech/XunFeiAsrHelper.swift

2
lib/modules/translation/controllers/translation_controller.dart

@ -964,8 +964,10 @@ class TranslationController extends GetxController with WidgetsBindingObserver {
}
/// 开始语音识别
/// 同声翻译、通话翻译、多媒体翻译的语音识别调用入口
Future<void> startRecognition() async {
Logger.info('开始语音识别');
//检查用户是否登录且积分是否足够,不足则提示充值
if (User.isLoggedIn() && User.instance.tradeintegral <= 0) {
showRechargeDialog('translation');
return;

30
local_plugins/azure_speech/android/src/main/kotlin/com/yunqiinnovation/azure_speech/AzureAsrHelper.kt

@ -127,10 +127,24 @@ class AzureAsrHelper(private val context: Context) {
this.supportedLanguages = supportedLanguages
}
Log.i(
tag,
"lxm---ASR initialize: supportedLanguages=${supportedLanguages.joinToString(",")}, audioSourceType=$audioSourceType"
)
val xunfeiConfigReady = this.xunfeiAppId.isNotBlank() &&
this.xunfeiAccessKeyId.isNotBlank() &&
this.xunfeiAccessKeySecret.isNotBlank()
this.useXunfei = supportedLanguages.all { it == "zh-CN" || it == "en-US" || it == "zh-HK"|| it == "en-TW" } && xunfeiConfigReady
val onlySupportedByXunfei = supportedLanguages.all {
it == "zh-CN" || it == "en-US" || it == "zh-HK" || it == "zh-TW"
}
val chineseVariantsCount = supportedLanguages
.map { it.trim().lowercase() }
.filter { it == "zh" || it.startsWith("zh-") }
.distinct()
.size
val hasMultipleChineseVariants = chineseVariantsCount >= 2
this.useXunfei = onlySupportedByXunfei && xunfeiConfigReady && !hasMultipleChineseVariants
// 根据支持的语言数量决定是否启用自动语言检测
this.isAutoDetectLanguage = supportedLanguages.size >= 2
@ -140,6 +154,11 @@ class AzureAsrHelper(private val context: Context) {
this.currentLanguage = supportedLanguages[0]
}
Log.i(
tag,
"lxm---ASR initialize derived: isAutoDetectLanguage=$isAutoDetectLanguage, currentLanguage=$currentLanguage, provider=${getAsrProvider()}, xunfeiConfigured=$xunfeiConfigReady"
)
// 创建语音配置
speechConfig = SpeechConfig.fromSubscription(subscriptionKey, region).apply {
if (isAutoDetectLanguage) {
@ -314,7 +333,14 @@ class AzureAsrHelper(private val context: Context) {
}
try {
xunFeiAsrHelper?.start(callback, currentLanguage, isAutoDetectLanguage, isRemoveFirstPunctuation)
Log.d(tag, "startContinuousRecognition: ${audioStream.isContinuousRecognitionActive}")
xunFeiAsrHelper?.start(
callback,
currentLanguage,
supportedLanguages.toList(),
isAutoDetectLanguage,
isRemoveFirstPunctuation
)
this.audioSourceType = audioSourceType
if (!audioStream.isContinuousRecognitionActive) {

7
local_plugins/azure_speech/android/src/main/kotlin/com/yunqiinnovation/azure_speech/AzureSpeechPlugin.kt

@ -423,6 +423,13 @@ class AzureSpeechPlugin : BleService.Callback, FlutterPlugin {
val xunfeiAccessKeySecret = call.argument<String>("xunfeiAccessKeySecret") ?: ""
try {
val isXunfeiConfigured = xunfeiAppId.isNotBlank() &&
xunfeiAccessKeyId.isNotBlank() &&
xunfeiAccessKeySecret.isNotBlank()
FileLogger.i(
tag,
"lxm---ASR initialize args: supportedLanguages=${supportedLanguages.joinToString(",")}, useExternalAudio=$useExternalAudio, region=$region, xunfeiConfigured=$isXunfeiConfigured"
)
FileLogger.d(tag, "选择音频源类型: ${useExternalAudio}") //
// 选择音频源类型
val audioSourceType = if (useExternalAudio) {

76
local_plugins/azure_speech/android/src/main/kotlin/com/yunqiinnovation/azure_speech/XunFeiAsrHelper.kt

@ -34,6 +34,7 @@ class XunFeiAsrHelper(private val context: Context) {
private var lastIntermediateResult = ""
private var currentLanguage = "zh-CN"
private var supportedLanguages: List<String> = emptyList()
private var isAutoDetectLanguage = false
// 是否第去除一个文字的标点符号
@ -58,7 +59,13 @@ class XunFeiAsrHelper(private val context: Context) {
return appId.isNotBlank() && accessKeyId.isNotBlank() && accessKeySecret.isNotBlank()
}
fun start(callback: AzureAsrHelper.ContinuousRecognizeCallback, language: String, isAutoDetect: Boolean, isRemoveFirstPunctuation: Boolean) {
fun start(
callback: AzureAsrHelper.ContinuousRecognizeCallback,
language: String,
supportedLanguages: List<String>,
isAutoDetect: Boolean,
isRemoveFirstPunctuation: Boolean
) {
try {
webSocket?.cancel()
webSocket = null
@ -70,6 +77,7 @@ class XunFeiAsrHelper(private val context: Context) {
lastIntermediateResult = ""
currentLanguage = language
this.supportedLanguages = supportedLanguages
isAutoDetectLanguage = isAutoDetect
removeFirstPunctuation = isRemoveFirstPunctuation
@ -99,15 +107,7 @@ class XunFeiAsrHelper(private val context: Context) {
override fun onClosed(webSocket: WebSocket, code: Int, reason: String) {
Log.d(tag, "WebSocket Closed: $code / $reason")
if (currentSessionId.isNotEmpty() && lastIntermediateResult.isNotEmpty()) {
val detectedLanguage = if (isAutoDetectLanguage) {
if (lastIntermediateResult.contains(Regex("[\\u4e00-\\u9fa5]"))) {
"zh-CN"
} else {
"en-US"
}
} else {
currentLanguage
}
val detectedLanguage = selectDetectedLanguage(lastIntermediateResult)
callback.onResult(currentSessionId, lastIntermediateResult, detectedLanguage)
}
callback.onSessionStopped(currentSessionId)
@ -219,15 +219,7 @@ class XunFeiAsrHelper(private val context: Context) {
return
}
val detectedLanguage = if (isAutoDetectLanguage) {
if (resultTextTemp.contains(Regex("[\\u4e00-\\u9fa5]"))) {
"zh-CN"
} else {
"en-US"
}
} else {
currentLanguage
}
val detectedLanguage = selectDetectedLanguage(resultTextTemp)
if (st.optInt("type") == 0) {
callback.onResult(currentSessionId, resultTextTemp, detectedLanguage)
@ -254,6 +246,52 @@ class XunFeiAsrHelper(private val context: Context) {
}
}
private fun normalizeLanguageCode(code: String): String {
val trimmed = code.trim()
if (trimmed.isEmpty()) return trimmed
val parts = trimmed.split("-")
val lang = parts.getOrNull(0)?.lowercase() ?: trimmed.lowercase()
val region = parts.getOrNull(1)?.uppercase()
return if (region.isNullOrEmpty()) lang else "$lang-$region"
}
private fun findSupportedExact(target: String): String? {
val targetNorm = normalizeLanguageCode(target)
return supportedLanguages.firstOrNull { normalizeLanguageCode(it) == targetNorm }
}
private fun findSupportedPrefix(prefix: String): String? {
val p = prefix.lowercase()
return supportedLanguages.firstOrNull { normalizeLanguageCode(it).startsWith(p) }
}
private fun pickPreferredChineseLanguage(): String {
return findSupportedExact("zh-CN")
?: findSupportedExact("zh-HK")
?: findSupportedExact("zh-TW")
?: findSupportedPrefix("zh")
?: currentLanguage
}
private fun pickPreferredEnglishLanguage(): String {
return findSupportedExact("en-US")
?: findSupportedPrefix("en")
?: currentLanguage
}
// 选择检测到的语言
// 如果开启了自动检测语言,根据文本内容判断是否为中文
// 如果是中文,选择中文语言;否则选择英文语言
// 如果未开启自动检测语言,返回当前语言
private fun selectDetectedLanguage(text: String): String {
if (!isAutoDetectLanguage) return currentLanguage
val hasChinese = text.contains(Regex("[\\u4e00-\\u9fa5]"))
return if (hasChinese) pickPreferredChineseLanguage() else pickPreferredEnglishLanguage()
}
private fun getWebSocketUrl(): String {
val baseWsUrl = "wss://office-api-ast-dx.iflyaisol.com/ast/communicate/v1"

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

File diff suppressed because it is too large

10
local_plugins/azure_speech/ios/azure_speech/Sources/azure_speech/AzureSpeechPlugin.swift

@ -343,6 +343,16 @@ private func sendAstEvent(_ event: [String: Any]) {
let xunfeiAppId = args["xunfeiAppId"] as? String ?? ""
let xunfeiAccessKeyId = args["xunfeiAccessKeyId"] as? String ?? ""
let xunfeiAccessKeySecret = args["xunfeiAccessKeySecret"] as? String ?? ""
let isXunfeiConfigured = !xunfeiAppId.isEmpty && !xunfeiAccessKeyId.isEmpty && !xunfeiAccessKeySecret.isEmpty
os_log(
"ASR initialize args: supportedLanguages=%{public}@, region=%{public}@, xunfeiConfigured=%{public}@",
log: log,
type: .info,
supportedLanguages.joined(separator: ","),
region,
String(isXunfeiConfigured)
)
// 初始化ASR引擎
let success = azureAsrHelper.initialize(

49
local_plugins/azure_speech/ios/azure_speech/Sources/azure_speech/XunFeiAsrHelper.swift

@ -23,6 +23,7 @@ class XunFeiAsrHelper: NSObject, URLSessionWebSocketDelegate {
private var lastIntermediateResult = ""
private var currentLanguage = "zh-CN"
private var supportedLanguages: [String] = []
private var isAutoDetectLanguage = false
// 是否第去除一个文字的标点符号
@ -47,11 +48,12 @@ class XunFeiAsrHelper: NSObject, URLSessionWebSocketDelegate {
return !appId.isEmpty && !accessKeyId.isEmpty && !accessKeySecret.isEmpty
}
func start(callback: AzureAsrHelper.ContinuousRecognizeCallback, language: String, isAutoDetect: Bool, isRemoveFirstPunctuation: Bool) {
func start(callback: AzureAsrHelper.ContinuousRecognizeCallback, language: String, supportedLanguages: [String], isAutoDetect: Bool, isRemoveFirstPunctuation: Bool) {
stop()
self.callback = callback
self.currentLanguage = language
self.supportedLanguages = supportedLanguages
self.isAutoDetectLanguage = isAutoDetect
self.removeFirstPunctuation = isRemoveFirstPunctuation
self.currentSessionId = UUID().uuidString
@ -268,16 +270,43 @@ class XunFeiAsrHelper: NSObject, URLSessionWebSocketDelegate {
}
}
private func normalizeLanguageCode(_ code: String) -> String {
let trimmed = code.trimmingCharacters(in: .whitespacesAndNewlines)
if trimmed.isEmpty { return trimmed }
let parts = trimmed.split(separator: "-")
let lang = parts.first?.lowercased() ?? trimmed.lowercased()
let region = parts.count > 1 ? parts[1].uppercased() : ""
return region.isEmpty ? lang : "\(lang)-\(region)"
}
private func findSupportedExact(_ target: String) -> String? {
let targetNorm = normalizeLanguageCode(target)
return supportedLanguages.first { normalizeLanguageCode($0) == targetNorm }
}
private func findSupportedPrefix(_ prefix: String) -> String? {
let p = prefix.lowercased()
return supportedLanguages.first { normalizeLanguageCode($0).hasPrefix(p) }
}
private func pickPreferredChineseLanguage() -> String {
return findSupportedExact("zh-CN")
?? findSupportedExact("zh-HK")
?? findSupportedExact("zh-TW")
?? findSupportedPrefix("zh")
?? currentLanguage
}
private func pickPreferredEnglishLanguage() -> String {
return findSupportedExact("en-US")
?? findSupportedPrefix("en")
?? currentLanguage
}
private func detectLanguage(from text: String) -> String {
if isAutoDetectLanguage {
if text.range(of: "[\\u4e00-\\u9fa5]", options: .regularExpression) != nil {
return "zh-CN"
} else {
return "en-US"
}
} else {
return currentLanguage
}
guard isAutoDetectLanguage else { return currentLanguage }
let hasChinese = text.range(of: "[\\u4e00-\\u9fa5]", options: .regularExpression) != nil
return hasChinese ? pickPreferredChineseLanguage() : pickPreferredEnglishLanguage()
}
private func getWebSocketUrl() -> String {

Loading…
Cancel
Save