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