我有从base64字符串生成的原始PCM文件。 Here is the link to the API response that returns in.。
然后我从此字符串创建PCM文件,然后使用LAME库将其转换为MP3。
以下是处理转换的代码:
companion object {
init {
System.loadLibrary("mp3lame")
}
}
private external fun initEncoder(numChannels: Int, sampleRate: Int, bitRate: Int, mode: Int, quality: Int)
private external fun destroyEncoder()
private external fun encodeFile(sourcePath: String, targetPath: String): Int
val NUM_CHANNELS = 1
val SAMPLE_RATE = 16000
val BITRATE = 128
val MODE = 3
val QUALITY = 0
fun createAudioFromBase64AndGetPath(inputBase64: String, outputFileName: String) {
initEncoder(NUM_CHANNELS, SAMPLE_RATE, BITRATE, MODE, QUALITY)
val path: String = "newFile.wav"
try {
val decoded = Base64.decode(inputBase64, Base64.NO_WRAP)
try {
val fileRaw = File(Environment.getExternalStorageDirectory().toString() + "/$outputFileName.pcm")
val fileEncoded = File(Environment.getExternalStorageDirectory().toString() + "/$outputFileName.mp3")
val os = FileOutputStream(fileRaw, true)
os.write(decoded)
os.close()
val result = encodeFile(fileRaw!!.absolutePath, fileEncoded!!.absolutePath)
if (result == 0) {
Log.d ("encoded to ", fileEncoded!!.name)
}
destroyEncoder()
} catch (e: Exception) {
Log.e ("decode ", "first catch", e)
e.printStackTrace()
}
} catch (e: Exception) {
e.printStackTrace()
Log.d ("decode ", "2nd catch", e)
}
}
音频听起来像this.
我尝试浏览C库文件,这些文件解释了 initEncoder 的不同变量选项的含义,我一直在摆弄,但没有任何变化。
为了尝试解决此问题而没有每次都编译应用程序的延迟,我采用了base64字符串,并使用在线转换器(Motobit)将其转换为PCM文件。然后,我在Mac上使用了一个非常漂亮(免费)的转换器XLD来测试这些转换,而不必每次都编译应用程序以查看是否可以确定发生了什么,并且也许我只是使用了错误的组合initEncoder的变量。
我注意到的第一件事是我必须选择“打开原始PCM(bin + cue)...”选项,以便打开从motobit下载的pcm文件。
难题的下一部分似乎是至关重要的部分,那就是在Endian框中选择“小”时,我只能正确转换音频(没有噪音)。问题是,回到我的应用程序后,我无法找到如何甚至是否可以访问和更改LAME库中的此属性。
为清楚起见,我在这里使用包装器:https://developer.samsung.com/technical-doc/view.do?v=T000000090
答案 0 :(得分:1)
如果您感到绝望,可以随时切换自己的字节序:
for (i in decoded.indices step 2)
{
val swap = decoded[i]
decoded[i] = decoded[i + 1]
decoded[i + 1] = swap
}
...由于Base64.decode()
返回一个字节数组,因此我假设您使用的是16位音频。
我自己找不到initEncoder()
文档。