From 6f30df7cb010290cebb36609243275fe2a7012b4 Mon Sep 17 00:00:00 2001 From: lxm <1274844347@qq.com> Date: Sat, 5 Jul 2025 15:11:40 +0800 Subject: [PATCH] =?UTF-8?q?fix(azure=5Fspeech):=20=E6=94=B9=E8=BF=9B?= =?UTF-8?q?=E9=9F=B3=E9=A2=91=E6=8D=95=E8=8E=B7=E7=BA=BF=E7=A8=8B=E7=9A=84?= =?UTF-8?q?=E5=BC=82=E5=B8=B8=E5=A4=84=E7=90=86=E5=92=8C=E8=B5=84=E6=BA=90?= =?UTF-8?q?=E9=87=8A=E6=94=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 添加线程优先级设置和更完善的异常处理逻辑 确保线程安全停止并释放资源 优化暂停状态下的CPU使用率 --- .../azure_speech/AzureAsrHelper.kt | 98 +++++++++++++------ 1 file changed, 68 insertions(+), 30 deletions(-) diff --git a/local_plugins/azure_speech/android/src/main/kotlin/com/yunqiinnovation/azure_speech/AzureAsrHelper.kt b/local_plugins/azure_speech/android/src/main/kotlin/com/yunqiinnovation/azure_speech/AzureAsrHelper.kt index fb1d36394..aaa4887c5 100644 --- a/local_plugins/azure_speech/android/src/main/kotlin/com/yunqiinnovation/azure_speech/AzureAsrHelper.kt +++ b/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. 单独封装线程启动逻辑 fun startCaptureThread() { - // 开始录音 - audioRecord?.startRecording() - captureThread = Thread { - // 根据实际采样率计算缓冲区大小 - val supportedSampleRates = intArrayOf(16000, 8000, 11025, 22050, 44100) - var bufferSize = 0 - // 查找设备支持的最佳采样率 - val sampleRate = supportedSampleRates.firstOrNull { rate -> - bufferSize = AudioRecord.getMinBufferSize( - rate, - AudioFormat.CHANNEL_IN_MONO, - AudioFormat.ENCODING_PCM_16BIT - ) - bufferSize > 0 // 返回正值表示支持 - } ?: 16000 // 默认回退值 - - val buffer = ByteArray(bufferSize) - - while (!Thread.interrupted() && audioRecord?.recordingState == AudioRecord.RECORDSTATE_RECORDING) { - if (!isPaused) { - // 读取音频 - val bytesRead = audioRecord?.read(buffer, 0, buffer.size) ?: 0 - if (bytesRead > 0) { + try { + // 确保之前的线程已停止 + stopCaptureThread() + + // 开始录音 + audioRecord?.startRecording() + + captureThread = Thread({ + android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_URGENT_AUDIO) + + val supportedSampleRates = intArrayOf(16000, 8000, 11025, 22050, 44100) + var bufferSize = 0 + val sampleRate = supportedSampleRates.firstOrNull { rate -> + bufferSize = AudioRecord.getMinBufferSize( + rate, + AudioFormat.CHANNEL_IN_MONO, + AudioFormat.ENCODING_PCM_16BIT + ) + bufferSize > 0 + } ?: 16000 + + val buffer = ByteArray(bufferSize) + + try { + while (!Thread.currentThread().isInterrupted && + audioRecord?.recordingState == AudioRecord.RECORDSTATE_RECORDING) { - // 写入Azure流 - pushAudioStream?.write(buffer) - - // 保存录音 - recordfile?.saveAudioDataToWav(buffer) + if (!isPaused) { + val bytesRead = audioRecord?.read(buffer, 0, buffer.size) ?: 0 + if (bytesRead > 0) { + // 安全地写入Azure流 + 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) { } -} \ No newline at end of file +} \ No newline at end of file