Browse Source

fix(azure_speech): 改进音频捕获线程的异常处理和资源释放

添加线程优先级设置和更完善的异常处理逻辑
确保线程安全停止并释放资源
优化暂停状态下的CPU使用率
weicu
lxm 1 year ago
parent
commit
6f30df7cb0
  1. 98
      local_plugins/azure_speech/android/src/main/kotlin/com/yunqiinnovation/azure_speech/AzureAsrHelper.kt

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

@ -822,39 +822,77 @@ class AzureAsrHelper(private val context: Context) {
// 3. 单独封装线程启动逻辑 // 3. 单独封装线程启动逻辑
fun startCaptureThread() { fun startCaptureThread() {
// 开始录音 try {
audioRecord?.startRecording() // 确保之前的线程已停止
captureThread = Thread { stopCaptureThread()
// 根据实际采样率计算缓冲区大小
val supportedSampleRates = intArrayOf(16000, 8000, 11025, 22050, 44100) // 开始录音
var bufferSize = 0 audioRecord?.startRecording()
// 查找设备支持的最佳采样率
val sampleRate = supportedSampleRates.firstOrNull { rate -> captureThread = Thread({
bufferSize = AudioRecord.getMinBufferSize( android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_URGENT_AUDIO)
rate,
AudioFormat.CHANNEL_IN_MONO, val supportedSampleRates = intArrayOf(16000, 8000, 11025, 22050, 44100)
AudioFormat.ENCODING_PCM_16BIT var bufferSize = 0
) val sampleRate = supportedSampleRates.firstOrNull { rate ->
bufferSize > 0 // 返回正值表示支持 bufferSize = AudioRecord.getMinBufferSize(
} ?: 16000 // 默认回退值 rate,
AudioFormat.CHANNEL_IN_MONO,
val buffer = ByteArray(bufferSize) AudioFormat.ENCODING_PCM_16BIT
)
while (!Thread.interrupted() && audioRecord?.recordingState == AudioRecord.RECORDSTATE_RECORDING) { bufferSize > 0
if (!isPaused) { } ?: 16000
// 读取音频
val bytesRead = audioRecord?.read(buffer, 0, buffer.size) ?: 0 val buffer = ByteArray(bufferSize)
if (bytesRead > 0) {
try {
while (!Thread.currentThread().isInterrupted &&
audioRecord?.recordingState == AudioRecord.RECORDSTATE_RECORDING) {
// 写入Azure流 if (!isPaused) {
pushAudioStream?.write(buffer) val bytesRead = audioRecord?.read(buffer, 0, buffer.size) ?: 0
if (bytesRead > 0) {
// 保存录音 // 安全地写入Azure流
recordfile?.saveAudioDataToWav(buffer) try {
pushAudioStream?.write(buffer)
recordfile?.saveAudioDataToWav(buffer)
} catch (e: Exception) {
Log.w(tag, "写入音频流失败: ${e.message}")
}
} else if (bytesRead < 0) {
Log.w(tag, "AudioRecord读取错误: $bytesRead")
break
}
} else {
Thread.sleep(10) // 暂停时短暂休眠
}
} }
} catch (e: InterruptedException) {
Log.d(tag, "音频捕获线程被中断")
} catch (e: Exception) {
Log.e(tag, "音频捕获异常: ${e.message}", e)
}
}, "AudioCaptureThread")
captureThread?.start()
} catch (e: Exception) {
Log.e(tag, "启动音频捕获线程失败: ${e.message}", e)
throw e
}
}
private fun stopCaptureThread() {
captureThread?.let { thread ->
if (thread.isAlive) {
thread.interrupt()
try {
thread.join(500) // 等待最多500ms
} catch (e: InterruptedException) {
Log.w(tag, "等待音频线程结束被中断")
} }
} }
}.apply { start() } }
captureThread = null
} }
/** /**
@ -1050,4 +1088,4 @@ class AzureAsrHelper(private val context: Context) {
} }
} }
Loading…
Cancel
Save