|
|
|
@ -82,8 +82,6 @@ class AzureAsrHelper(private val context: Context) { |
|
|
|
audioSourceType: AudioSourceType = AudioSourceType.MICROPHONE |
|
|
|
): Boolean { |
|
|
|
try { |
|
|
|
FileLogger.d(tag, "初始化 Azure 语音服务, 音频源类型: $audioSourceType") |
|
|
|
|
|
|
|
// 检查配置是否为空 |
|
|
|
if (subscriptionKey.isEmpty() || region.isEmpty()) { |
|
|
|
FileLogger.e(tag, "Azure 配置信息不完整") |
|
|
|
@ -155,7 +153,6 @@ class AzureAsrHelper(private val context: Context) { |
|
|
|
val method = AudioManager::class.java.getMethod("isBluetoothA2dpOn") |
|
|
|
method.invoke(audioManager) as Boolean |
|
|
|
} catch (e: Exception) { |
|
|
|
FileLogger.d(tag, "无法检测蓝牙连接状态,假设未连接") |
|
|
|
false |
|
|
|
} |
|
|
|
|
|
|
|
@ -165,18 +162,15 @@ class AzureAsrHelper(private val context: Context) { |
|
|
|
val needEchoCancellation = !isHeadsetConnected |
|
|
|
|
|
|
|
if (needEchoCancellation) { |
|
|
|
FileLogger.d(tag, "检测到扬声器模式(扬声器: $isSpeakerphoneOn, 耳机: $isHeadsetConnected), 启用回音消除") |
|
|
|
// 使用拉流方式进行回音消除 |
|
|
|
setupMicrophoneStream() |
|
|
|
} else { |
|
|
|
FileLogger.d(tag, "使用默认麦克风输入(扬声器: $isSpeakerphoneOn, 耳机: $isHeadsetConnected)") |
|
|
|
audioConfig = AudioConfig.fromDefaultMicrophoneInput() |
|
|
|
} |
|
|
|
} |
|
|
|
AudioSourceType.EXTERNAL -> { |
|
|
|
// 改用拉流方式处理外部音频 |
|
|
|
setupExternalAudioStream() |
|
|
|
FileLogger.d(tag, "使用外部音频源(拉流模式)") |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
@ -188,7 +182,6 @@ class AzureAsrHelper(private val context: Context) { |
|
|
|
SpeechRecognizer(speechConfig, audioConfig) |
|
|
|
} |
|
|
|
|
|
|
|
FileLogger.d(tag, "Azure 语音服务初始化成功") |
|
|
|
return true |
|
|
|
} catch (e: Exception) { |
|
|
|
FileLogger.e(tag, "创建识别器失败: ${e.message}") |
|
|
|
@ -207,8 +200,6 @@ class AzureAsrHelper(private val context: Context) { |
|
|
|
|
|
|
|
// 创建音频配置 - 正确使用fromStreamInput方法,只传入回调 |
|
|
|
audioConfig = AudioConfig.fromStreamInput(microphoneStream) |
|
|
|
|
|
|
|
FileLogger.d(tag, "已设置麦克风流(拉流模式)") |
|
|
|
} catch (e: Exception) { |
|
|
|
FileLogger.e(tag, "设置麦克风流失败: ${e.message}") |
|
|
|
e.printStackTrace() |
|
|
|
@ -225,8 +216,6 @@ class AzureAsrHelper(private val context: Context) { |
|
|
|
|
|
|
|
// 创建音频配置 |
|
|
|
audioConfig = AudioConfig.fromStreamInput(externalAudioStream) |
|
|
|
|
|
|
|
FileLogger.d(tag, "已设置外部音频流(拉流模式)") |
|
|
|
} catch (e: Exception) { |
|
|
|
FileLogger.e(tag, "设置外部音频流失败: ${e.message}") |
|
|
|
e.printStackTrace() |
|
|
|
@ -241,7 +230,6 @@ class AzureAsrHelper(private val context: Context) { |
|
|
|
*/ |
|
|
|
fun pushAudioData(data: ByteArray) { |
|
|
|
if (audioSourceType != AudioSourceType.EXTERNAL) { |
|
|
|
FileLogger.w(tag, "当前未使用外部音频源,忽略推送的音频数据") |
|
|
|
return |
|
|
|
} |
|
|
|
|
|
|
|
@ -343,8 +331,6 @@ class AzureAsrHelper(private val context: Context) { |
|
|
|
recognizer?.recognizing?.addEventListener( |
|
|
|
EventHandler<SpeechRecognitionEventArgs> { _, event -> |
|
|
|
val detectedLanguage = AutoDetectSourceLanguageResult.fromResult(event.result)?.language ?: "" |
|
|
|
FileLogger.d(tag, "识别中: ${event.result.text}, 语言: $detectedLanguage") |
|
|
|
|
|
|
|
// 直接在当前线程调用回调 |
|
|
|
callback.onRecognizing(event.result.text, detectedLanguage) |
|
|
|
} |
|
|
|
@ -355,8 +341,6 @@ class AzureAsrHelper(private val context: Context) { |
|
|
|
EventHandler<SpeechRecognitionEventArgs> { _, event -> |
|
|
|
if (event.result.reason == ResultReason.RecognizedSpeech) { |
|
|
|
val detectedLanguage = AutoDetectSourceLanguageResult.fromResult(event.result)?.language ?: "" |
|
|
|
FileLogger.d(tag, "识别完成: ${event.result.text}, 语言: $detectedLanguage") |
|
|
|
|
|
|
|
// 直接在当前线程调用回调 |
|
|
|
callback.onResult(event.result.text, detectedLanguage) |
|
|
|
} |
|
|
|
@ -366,8 +350,6 @@ class AzureAsrHelper(private val context: Context) { |
|
|
|
// 会话开始事件 |
|
|
|
recognizer?.sessionStarted?.addEventListener( |
|
|
|
EventHandler<SessionEventArgs> { _, _ -> |
|
|
|
FileLogger.d(tag, "识别会话已开始") |
|
|
|
|
|
|
|
// 直接在当前线程调用回调 |
|
|
|
callback.onSessionStarted() |
|
|
|
} |
|
|
|
@ -376,13 +358,10 @@ class AzureAsrHelper(private val context: Context) { |
|
|
|
// 会话结束事件 |
|
|
|
recognizer?.sessionStopped?.addEventListener( |
|
|
|
EventHandler<SessionEventArgs> { _, _ -> |
|
|
|
FileLogger.d(tag, "识别会话已结束") |
|
|
|
// 直接在当前线程调用回调 |
|
|
|
callback.onSessionStopped() |
|
|
|
isContinuousRecognitionActive = false |
|
|
|
stopAudioProcessing() |
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
) |
|
|
|
|
|
|
|
@ -419,13 +398,10 @@ class AzureAsrHelper(private val context: Context) { |
|
|
|
} |
|
|
|
|
|
|
|
if (!isContinuousRecognitionActive) { |
|
|
|
FileLogger.d(tag, "未进行连续识别,忽略停止请求") |
|
|
|
return true |
|
|
|
} |
|
|
|
|
|
|
|
try { |
|
|
|
FileLogger.d(tag, "停止连续语音识别") |
|
|
|
|
|
|
|
if (recognizer == null) { |
|
|
|
FileLogger.w(tag, "识别器为空,重置状态") |
|
|
|
isContinuousRecognitionActive = false |
|
|
|
@ -442,7 +418,6 @@ class AzureAsrHelper(private val context: Context) { |
|
|
|
stopAudioProcessing() |
|
|
|
|
|
|
|
// 会话结束事件会设置isContinuousRecognitionActive = false |
|
|
|
FileLogger.d(tag, "连续识别停止指令已发送") |
|
|
|
return true |
|
|
|
} catch (e: Exception) { |
|
|
|
// 强制重置状态 |
|
|
|
@ -503,11 +478,7 @@ class AzureAsrHelper(private val context: Context) { |
|
|
|
audioConfig = null |
|
|
|
recognizer = null |
|
|
|
speechConfig = null |
|
|
|
|
|
|
|
FileLogger.d(tag, "资源已释放") |
|
|
|
} catch (e: Exception) { |
|
|
|
FileLogger.e(tag, "释放资源失败: ${e.message}") |
|
|
|
|
|
|
|
// 确保状态被重置 |
|
|
|
isContinuousRecognitionActive = false |
|
|
|
microphoneStream = null |
|
|
|
@ -585,8 +556,6 @@ class AzureAsrHelper(private val context: Context) { |
|
|
|
*/ |
|
|
|
private fun initMicrophone() { |
|
|
|
try { |
|
|
|
FileLogger.d(tag, "初始化麦克风 (拉流模式)") |
|
|
|
|
|
|
|
// 创建录音对象 |
|
|
|
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) { |
|
|
|
val format = AudioFormat.Builder() |
|
|
|
@ -625,12 +594,8 @@ class AzureAsrHelper(private val context: Context) { |
|
|
|
if (audioRecord?.recordingState != AudioRecord.RECORDSTATE_RECORDING) { |
|
|
|
throw IllegalStateException("录音启动失败") |
|
|
|
} |
|
|
|
|
|
|
|
FileLogger.d(tag, "麦克风初始化完成 (拉流模式)") |
|
|
|
} catch (e: Exception) { |
|
|
|
FileLogger.e(tag, "初始化麦克风失败: ${e.message}") |
|
|
|
e.printStackTrace() |
|
|
|
releaseAudioResources() |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
@ -641,14 +606,9 @@ class AzureAsrHelper(private val context: Context) { |
|
|
|
val sessionId = audioRecord?.audioSessionId ?: return |
|
|
|
|
|
|
|
// 回音消除 |
|
|
|
if (AcousticEchoCanceler.isAvailable()) { |
|
|
|
echoCanceler = AcousticEchoCanceler.create(sessionId).apply { |
|
|
|
enabled = true |
|
|
|
} |
|
|
|
FileLogger.d(tag, "回音消除已启用") |
|
|
|
echoCanceler = AcousticEchoCanceler.create(sessionId).apply { |
|
|
|
enabled = true |
|
|
|
} |
|
|
|
|
|
|
|
// 其他音频效果可以按需添加 |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
@ -697,10 +657,8 @@ class AzureAsrHelper(private val context: Context) { |
|
|
|
// 释放录音实例 |
|
|
|
audioRecord?.release() |
|
|
|
audioRecord = null |
|
|
|
|
|
|
|
FileLogger.d(tag, "音频资源已释放 (拉流模式)") |
|
|
|
} catch (e: Exception) { |
|
|
|
FileLogger.e(tag, "释放音频资源失败: ${e.message}") |
|
|
|
e.printStackTrace() |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
@ -750,7 +708,6 @@ class AzureAsrHelper(private val context: Context) { |
|
|
|
override fun close() { |
|
|
|
closed = true |
|
|
|
queue.clear() |
|
|
|
FileLogger.d(tag, "外部音频流已关闭") |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|