|
|
|
@ -34,6 +34,7 @@ class AzureAsrHelper(private val context: Context) { |
|
|
|
|
|
|
|
// 添加前台服务管理标志 |
|
|
|
private var isForegroundServiceRunning = false |
|
|
|
|
|
|
|
// 配置参数 |
|
|
|
private var currentLanguage = "zh-CN" |
|
|
|
private var supportedLanguages = arrayOf("zh-CN") |
|
|
|
@ -41,6 +42,9 @@ class AzureAsrHelper(private val context: Context) { |
|
|
|
private var subscriptionKey = "" |
|
|
|
private var region = "" |
|
|
|
|
|
|
|
private var useXunfei = false |
|
|
|
private var xunFeiAsrHelper: XunFeiAsrHelper? = null |
|
|
|
|
|
|
|
// 音频源配置 |
|
|
|
var audioSourceType = AudioSourceType.MICROPHONE |
|
|
|
|
|
|
|
@ -53,6 +57,7 @@ class AzureAsrHelper(private val context: Context) { |
|
|
|
|
|
|
|
// 网络丢失计数器 |
|
|
|
private var networkLostCount = 0 |
|
|
|
|
|
|
|
// 最大网络丢失次数(3秒检测) |
|
|
|
private val maxNetworkLostCount = 3 |
|
|
|
|
|
|
|
@ -109,6 +114,8 @@ class AzureAsrHelper(private val context: Context) { |
|
|
|
this.supportedLanguages = supportedLanguages |
|
|
|
} |
|
|
|
|
|
|
|
this.useXunfei = supportedLanguages.any { it == "zh-CN" || it == "en-US" } |
|
|
|
|
|
|
|
// 根据支持的语言数量决定是否启用自动语言检测 |
|
|
|
this.isAutoDetectLanguage = supportedLanguages.size >= 2 |
|
|
|
|
|
|
|
@ -264,6 +271,47 @@ class AzureAsrHelper(private val context: Context) { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
if (useXunfei) { |
|
|
|
Log.d(tag, "Using Xunfei Recognition") |
|
|
|
val callback = continuousCallback |
|
|
|
if (callback == null) { |
|
|
|
Log.e(tag, "无法启动连续识别:回调为空") |
|
|
|
continuousCallback?.onError(currsessionid, 1001, "回调为空") |
|
|
|
return false |
|
|
|
} |
|
|
|
|
|
|
|
if (xunFeiAsrHelper == null) { |
|
|
|
xunFeiAsrHelper = XunFeiAsrHelper(context) |
|
|
|
} |
|
|
|
|
|
|
|
try { |
|
|
|
xunFeiAsrHelper?.start(callback) |
|
|
|
|
|
|
|
this.audioSourceType = audioSourceType |
|
|
|
if (!audioStream.isContinuousRecognitionActive) { |
|
|
|
audioStream.startAudioRecord( |
|
|
|
when (audioSourceType) { |
|
|
|
AudioSourceType.MICROPHONE -> SimpleAudioReceiver.AudioSourceType.MICROPHONE |
|
|
|
AudioSourceType.EXTERNAL -> SimpleAudioReceiver.AudioSourceType.EXTERNAL |
|
|
|
}, |
|
|
|
object : SimpleAudioReceiver.AudioDataCallback { |
|
|
|
override fun onAudio(data: ByteArray) { |
|
|
|
audioDataCallback?.onAudio(data) |
|
|
|
xunFeiAsrHelper?.sendAudio(data) |
|
|
|
} |
|
|
|
} |
|
|
|
) |
|
|
|
} |
|
|
|
audioStream.isContinuousRecognitionActive = true |
|
|
|
return true |
|
|
|
} catch (e: Exception) { |
|
|
|
Log.e(tag, "Start Xunfei failed: ${e.message}") |
|
|
|
xunFeiAsrHelper?.stop() |
|
|
|
audioStream.isContinuousRecognitionActive = false |
|
|
|
return false |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
if (!isRecognizerValid()) { |
|
|
|
Log.d(tag, "重新启动连续识别") |
|
|
|
val callback = continuousCallback |
|
|
|
@ -398,6 +446,27 @@ class AzureAsrHelper(private val context: Context) { |
|
|
|
* @return 是否成功停止 |
|
|
|
*/ |
|
|
|
fun stopContinuousRecognition(): Boolean { |
|
|
|
if (useXunfei) { |
|
|
|
try { |
|
|
|
xunFeiAsrHelper?.stop() |
|
|
|
stopAudioProcessing() |
|
|
|
audioStream.isContinuousRecognitionActive = false |
|
|
|
|
|
|
|
if (isForegroundServiceRunning) { |
|
|
|
try { |
|
|
|
AudioRecordingForegroundService.stopService(context) |
|
|
|
isForegroundServiceRunning = false |
|
|
|
} catch (e: Exception) { |
|
|
|
Log.e(tag, "停止前台服务失败: ${e.message}") |
|
|
|
} |
|
|
|
} |
|
|
|
return true |
|
|
|
} catch (e: Exception) { |
|
|
|
Log.e(tag, "Stop Xunfei failed: ${e.message}") |
|
|
|
return false |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
if (speechConfig == null) { |
|
|
|
Log.e(tag, "语音服务未初始化") |
|
|
|
return false |
|
|
|
@ -462,8 +531,12 @@ class AzureAsrHelper(private val context: Context) { |
|
|
|
try { |
|
|
|
// 如果正在进行连续识别,先停止 |
|
|
|
if (audioStream.isContinuousRecognitionActive) { |
|
|
|
if (useXunfei) { |
|
|
|
xunFeiAsrHelper?.stop() |
|
|
|
} else { |
|
|
|
// 直接停止,不等待结果 |
|
|
|
recognizer?.stopContinuousRecognitionAsync() |
|
|
|
} |
|
|
|
audioStream.isContinuousRecognitionActive = false |
|
|
|
} |
|
|
|
// 停止音频处理 |
|
|
|
@ -477,6 +550,9 @@ class AzureAsrHelper(private val context: Context) { |
|
|
|
recognizer?.close() |
|
|
|
recognizer = null |
|
|
|
|
|
|
|
xunFeiAsrHelper?.stop() |
|
|
|
xunFeiAsrHelper = null |
|
|
|
|
|
|
|
// 释放speechConfig |
|
|
|
speechConfig?.close() |
|
|
|
speechConfig = null |
|
|
|
@ -526,14 +602,15 @@ class AzureAsrHelper(private val context: Context) { |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//录音音频文件 |
|
|
|
/** |
|
|
|
* 开启录音 |
|
|
|
*/ |
|
|
|
fun enableRecord(audioSourceType: AudioSourceType = AudioSourceType.MICROPHONE,filePath: String, audioDataCallback: SimpleAudioReceiver.AudioDataCallback? = null) { |
|
|
|
fun enableRecord( |
|
|
|
audioSourceType: AudioSourceType = AudioSourceType.MICROPHONE, |
|
|
|
filePath: String, |
|
|
|
audioDataCallback: SimpleAudioReceiver.AudioDataCallback? = null |
|
|
|
) { |
|
|
|
Log.i(tag, "开启录音:") |
|
|
|
this.audioSourceType = audioSourceType |
|
|
|
if (audioSourceType == AudioSourceType.EXTERNAL) { |
|
|
|
@ -565,7 +642,8 @@ class AzureAsrHelper(private val context: Context) { |
|
|
|
audioStream.setupStream() |
|
|
|
|
|
|
|
|
|
|
|
audioStream.startAudioRecord( when (audioSourceType) { |
|
|
|
audioStream.startAudioRecord( |
|
|
|
when (audioSourceType) { |
|
|
|
AudioSourceType.MICROPHONE -> SimpleAudioReceiver.AudioSourceType.MICROPHONE |
|
|
|
AudioSourceType.EXTERNAL -> SimpleAudioReceiver.AudioSourceType.EXTERNAL |
|
|
|
}, |
|
|
|
@ -661,7 +739,6 @@ class AzureAsrHelper(private val context: Context) { |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
* 一次性识别回调接口 |
|
|
|
*/ |
|
|
|
@ -738,6 +815,7 @@ class AzureAsrHelper(private val context: Context) { |
|
|
|
private fun checkNetworkStatus(): Boolean { |
|
|
|
return networkMonitor.checkNetworkStatus() |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* 检查是否是网络相关错误 |
|
|
|
*/ |
|
|
|
@ -805,6 +883,7 @@ class AzureAsrHelper(private val context: Context) { |
|
|
|
Log.e(tag, "立即停止音频处理失败: ${e.message}") |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* 清理网络检测相关资源 |
|
|
|
*/ |
|
|
|
|