首页 > 解决方案 > Speech-To-Text api 错误通过 AudioRecorder 解析 pcm 文件的编码

问题描述

我在我的应用程序中使用 AudioRecord 来录制语音,然后我用 Firebase 调用语音到文本的 api,但它总是返回“编码”不正确。

 val DEFAULT_AUDIO_SOURCE: Int = MediaRecorder.AudioSource.UNPROCESSED
 val DEFAULT_SAMPLE_RATE_HZ: Int = 16_000
 val DEFAULT_CHANNEL_CONFIG: Int = AudioFormat.CHANNEL_IN_MONO
 val DEFAULT_AUDIO_FORMAT = AudioFormat.ENCODING_PCM_16BIT
 val BUFFER_SIZE: Int = 2*AudioRecord.getMinBufferSize(DEFAULT_SAMPLE_RATE_HZ, DEFAULT_CHANNEL_CONFIG, DEFAULT_AUDIO_FORMAT)

 mAudioRecord = AudioRecord(
                    DEFAULT_AUDIO_SOURCE,
                    DEFAULT_SAMPLE_RATE_HZ,
                    DEFAULT_CHANNEL_CONFIG,
                    DEFAULT_AUDIO_FORMAT,
                    DEFAULT_BUFFER_SIZE)
 val data = ByteArray(file.length().toInt())
 val input = DataInputStream(FileInputStream(file));
 input.read(data);
 input.close();
 val audioContent: String = Base64.encodeToString(data, Base64.NO_WRAP);
 val resp = 
 mApi.transcribe(FirebaseCloudFunctionsModel.Transcribe("LINEAR16", CloudTranslate.DEFAULT_SAMPLE_RATE_HZ, Locale.getDefault().toString(), audioContent)).execute()

标签: androidgoogle-cloud-functionsaudio-recording

解决方案


由于您使用的是 PCM 16 位,因此将音频记录在 ShortArray 缓冲区中(它的大小应该是缓冲区大小的一半,因为 short 是 16 位或 2 个字节)并使用此函数将缓冲区转换为 ByteArray:

private fun short2byte(sData:ShortArray):ByteArray {
  val shortArrsize = sData.size
  val bytes = ByteArray(shortArrsize * 2)
  for (i in 0 until shortArrsize)
  {
    bytes[i * 2] = (sData[i] and 0x00FF).toByte()
    bytes[(i * 2) + 1] = (sData[i] shr 8).toByte()
    sData[i] = 0
  }
  return bytes
}

Google Cloud API 使用 URL 安全 Base64 编码,因此将其作为标志之一添加到 encodeString 函数。

 val audioContent: String = Base64.encodeToString(data,  Base64.URL_SAFE | Base64.NO_WRAP);

如果音频很小,您可以直接将其写入内存中的 ByteArrayOutputStream,而不是将音频写入文件。


推荐阅读