java - 使用 ACRCloud 将音频记录保存在文件中
问题描述
我对调用 ACRCloud 的 Android 应用程序有疑问。对于我需要做的工作,我想将录音保存在 MP3 文件中,但我不知道为什么它不起作用。
那是我的代码:
File f = null;
try {
f = createAudioFile();
} catch (IOException e) {
e.printStackTrace();
}
byte[] data = acrCloudResult.getRecordDataPCM();
if(f.exists()){
String path = f.getPath();
FileOutputStream stream = null;
try {
stream = new FileOutputStream(path);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
try {
stream.write(data);
} catch (IOException e) {
e.printStackTrace();
}
}
解决方案
来自“acrCloudResult.getRecordDataPCM()”的 PCM 音频数据的格式是“PCM 16 bit, mono 8000 Hz”,这个音频数据缓冲区不包括“Audio Header”。
您可以在PCM音频数据中添加一个wav头,可以参考下面的代码“writeWaveFileHeader”,这一步可以将PCM转换为WAV,您可以用音频播放器播放这个wav文件。
writeWaveFileHeader(stream, data.length, data.length+36, 8000, 1, 2000);
您可以使用第三方库将 PCM/WAV 转换为 MP3。例如:Lame,你可以参考这段代码,https://github.com/Jay-Goo/Mp3Converter。
void writeWaveFileHeader(FileOutputStream out, long totalAudioLen, long totalDataLen, int sampleRate, int channels, long byteRate) throws IOException { byte[] header = new byte[44]; header[0] = 'R'; // RIFF header[1] = 'I'; header[2] = 'F'; header[3] = 'F'; header[4] = (byte)(totalDataLen & 0xff); header[5] = (byte)((totalDataLen >> 8) & 0xff); header[6] = (byte)((totalDataLen >> 16) & 0xff); header[7] = (byte)((totalDataLen >> 24) & 0xff); header[8] = 'W'; //WAVE header[9] = 'A'; header[10] = 'V'; header[11] = 'E'; //FMT Chunk header[12] = 'f'; // 'fmt ' header[13] = 'm'; header[14] = 't'; header[15] = ' '; header[16] = 16; // 4 bytes: size of 'fmt ' chunk header[17] = 0; header[18] = 0; header[19] = 0; header[20] = 1; // format = 1 header[21] = 0; header[22] = (byte) channels; header[23] = 0; header[24] = (byte)(sampleRate & 0xff); header[25] = (byte)((sampleRate >> 8) & 0xff); header[26] = (byte)((sampleRate >> 16) & 0xff); header[27] = (byte)((sampleRate >> 24) & 0xff); header[28] = (byte)(byteRate & 0xff); header[29] = (byte)((byteRate >> 8) & 0xff); header[30] = (byte)((byteRate >> 16) & 0xff); header[31] = (byte)((byteRate >> 24) & 0xff); header[32] = (byte)(channels * 16 / 8); header[33] = 0; header[34] = 16; header[35] = 0; //Data chunk header[36] = 'd'; //data header[37] = 'a'; header[38] = 't'; header[39] = 'a'; header[40] = (byte)(totalAudioLen & 0xff); header[41] = (byte)((totalAudioLen >> 8) & 0xff); header[42] = (byte)((totalAudioLen >> 16) & 0xff); header[43] = (byte)((totalAudioLen >> 24) & 0xff); out.write(header, 0, 44); }
推荐阅读
- stata - 计算员工先前经验的差异
- javascript - 输出图像始终为 PNG ,croppie 不保持原始格式
- shell - 如何通过另一个 cmd 的输出将容器 id 传递给 docker exec
- python-3.x - 如何使用 sklearn.base.SimpleImputer 实现 sklearn 转换器但返回 pandas DataFrame
- ios - 将数据从一个标签栏视图控制器的孩子(我认为?)传递到另一个 TabBarVC 的集合视图?(以编程方式)
- google-cloud-platform - gcloud ai-platform 本地火车未在 jupyter 笔记本中运行
- javascript - 不知道如何返回一个对象数组,其中每个对象都有一个数组
- php - 无论如何将json数组发送到服务器端php并将其值插入表中?
- python-3.x - Python中的字典无法正确打印
- python - Python替换所有字符都相同的地方