Browse Source

修复没有记录时不翻译问题

weicu
fdp 1 year ago
parent
commit
5403b95189
  1. 3
      lib/modules/translation/controllers/translation_controller.dart
  2. 108
      local_plugins/azure_speech/android/src/main/kotlin/com/yunqiinnovation/azure_speech/AzureAsrHelper.kt

3
lib/modules/translation/controllers/translation_controller.dart

@ -161,7 +161,7 @@ class TranslationController extends GetxController {
}
// 加载历史记录
loadTranslationHistory();
//loadTranslationHistory();
// 初始化服务
_initServices();
@ -469,6 +469,7 @@ class TranslationController extends GetxController {
isIntermediate: true,
);
// 添加新项后滚动到底部
translationHistory.add(newItem);
_scrollToBottom();
} else {
// 更新当前项

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

@ -80,7 +80,29 @@ class AzureAsrHelper(private val context: Context) {
/** 使用外部提供的音频数据 */
EXTERNAL
}
/**
* 获取设备支持的最佳音频格式
* 优先选择16000Hz,若不支持则降级到8000Hz
*/
private fun getOptimalAudioFormat(): AudioStreamFormat {
// 支持的采样率列表(按优先级排序)
val supportedSampleRates = intArrayOf(16000, 8000, 11025, 22050, 44100)
// 查找设备支持的最佳采样率
val sampleRate = supportedSampleRates.firstOrNull { rate ->
val bufferSize = AudioRecord.getMinBufferSize(
rate,
AudioFormat.CHANNEL_IN_MONO,
AudioFormat.ENCODING_PCM_16BIT
)
bufferSize > 0 // 返回正值表示支持
} ?: 16000 // 默认回退值
Log.i(tag, "使用采样率: ${sampleRate}Hz")
// 创建对应的音频格式
return AudioStreamFormat.getWaveFormatPCM(sampleRate.toLong(), 16, 1)
}
/**
* 初始化Azure语音服务
*
@ -106,7 +128,7 @@ class AzureAsrHelper(private val context: Context) {
// 释放之前的资源
dispose()
// 1. 创建可控制的音频流
val format = AudioStreamFormat.getWaveFormatPCM(16000, 16, 1)
val format = getOptimalAudioFormat()
audioStream = AudioInputStream.createPushStream(format)
// 初始化音频管理器
audioManager = context.getSystemService(Context.AUDIO_SERVICE) as AudioManager
@ -157,7 +179,7 @@ class AzureAsrHelper(private val context: Context) {
// 录音文件类
recordfile = RecordFile;
//进入界面手机麦克风就被占用,导致其他app无法使用麦克风,在开始录音再去申请
// 创建识别器
// // 创建识别器
// val setupSuccess = setupRecognizer()
// if (setupSuccess) {
// // 优化:初始化完成后进行预热
@ -369,6 +391,8 @@ class AzureAsrHelper(private val context: Context) {
audioRecord?.startRecording()
startCaptureThread() // 再启动数据读取线程
isContinuousRecognitionActive = true
Log.d(tag, "识别器创建成功: ${recognizer != null}")
Log.d(tag, "开始识别任务: recognizeOnce 或 startContinuousRecognition 被调用")
return true
} catch (e: Exception) {
@ -705,8 +729,19 @@ class AzureAsrHelper(private val context: Context) {
* 开始麦克风捕获
*/
private fun initAudioRecord() {
// 设置音频参数
val sampleRate = 16000 // 16kHz采样率(语音识别常用)
// 获取已确定的采样率
val format = getOptimalAudioFormat()
val supportedSampleRates = intArrayOf(16000, 8000, 11025, 22050, 44100)
// 查找设备支持的最佳采样率
val sampleRate = supportedSampleRates.firstOrNull { rate ->
val bufferSize = AudioRecord.getMinBufferSize(
rate,
AudioFormat.CHANNEL_IN_MONO,
AudioFormat.ENCODING_PCM_16BIT
)
bufferSize > 0 // 返回正值表示支持
} ?: 16000 // 默认回退值
val channelConfig = AudioFormat.CHANNEL_IN_MONO // 单声道输入
val audioFormat = AudioFormat.ENCODING_PCM_16BIT // 16位PCM格式
@ -732,35 +767,42 @@ class AzureAsrHelper(private val context: Context) {
}
// 3. 单独封装线程启动逻辑
private fun startCaptureThread() {
captureThread = Thread {
// 循环条件确保录音已开始
val buffer = ByteArray(1024) // 4KB数据缓冲区
while (!Thread.interrupted() && audioRecord?.recordingState == AudioRecord.RECORDSTATE_RECORDING) {
// 从麦克风读取数据
val bytesRead = audioRecord?.read(buffer, 0, buffer.size) ?: 0
// 仅在未暂停时处理数据
if (!isPaused && bytesRead > 0) {
// 写入音频流(可能是网络传输或本地处理)
audioStream?.write(buffer)
// 保存到WAV文件(如果启用了录制功能)
recordfile?.saveAudioDataToWav(buffer)
}
// 暂停时短暂休眠以减少CPU占用
if (isPaused) {
try {
Thread.sleep(50)
} catch (e: InterruptedException) {
break // 线程被中断时退出循环
}
}
private fun startCaptureThread() {
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 // 默认回退值
// (sampleRate * 0.032).toInt() * 2 // 32ms数据量
val buffer = ByteArray(bufferSize)
while (!Thread.interrupted() && audioRecord?.recordingState == AudioRecord.RECORDSTATE_RECORDING) {
// 读取音频
val bytesRead = audioRecord?.read(buffer, 0, buffer.size) ?: 0
Log.i("AzureASR", "AudioRecord state: ${audioRecord?.state}, recordingState: ${audioRecord?.recordingState}")
Log.i("AzureASR", "BytesRead = $bytesRead, buffer.isSilent = ${buffer.all { it == 0.toByte() }}")
if (!isPaused && bytesRead > 0) {
// 写入Azure流
audioStream?.write(buffer)
// 保存录音
recordfile?.saveAudioDataToWav(buffer)
}
}.apply { start() }
}
}
}.apply { start() }
}
/**
* 停止麦克风捕获并释放所有相关资源

Loading…
Cancel
Save