我们使用AudioRecord录制的声音文件为PCM格式的,如何使用JAVA将PCM格式转化为MP3或者WAVE格式呢?非常简单,来看看下面的示例吧!
package com.test; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.util.HashMap; import java.util.Map; public class TestDemo { static Map<String,String> map = new HashMap<String,String>(); public static void main(String[] args) throws IOException { //如果想要把pcm转wave,直接将后缀改成wave即可 convertAudioFiles("D:\\excelFile\\1606288228441.pcm", "D:\\excelFile\\tnafcs.mp3"); } //PCM转MP3工具类 public static String convertAudioFiles(String src, String target) throws IOException { try { FileInputStream fis = new FileInputStream(src); FileOutputStream fos = new FileOutputStream(target); //Calculate the length byte[] buf = new byte[1024 * 4]; int size = fis.read(buf); int PCMSize = 0; while (size != -1) { PCMSize += size; size = fis.read(buf); } fis.close(); //Fill in the parameters, bit rate, etc. Here is 16-bit mono 8000 Hz //一般只需要修改channels和samplesPerSec的值即可,取决于你录制的是8000HZ还是16000HZ WaveHeader header = new WaveHeader(); //Length field = content size (PCMSize) + header field size (not including the first 4-byte identifier RIFF and the 4-byte fileLength itself) header.fileLength = PCMSize + (44 - 8); header.FmtHdrLeth = 16; header.BitsPerSample = 16; header.Channels = 1; header.FormatTag = 0x0001; header.SamplesPerSec = 16000; header.BlockAlign = (short) (header.Channels * header.BitsPerSample / 8); header.AvgBytesPerSec = header.BlockAlign * header.SamplesPerSec; header.DataHdrLeth = PCMSize; byte[] h = header.getHeader(); assert h.length == 44; //WAV standard, the header should be 44 bytes //write header fos.write(h, 0, h.length); //write data stream fis = new FileInputStream(src); size = fis.read(buf); while (size != -1) { fos.write(buf, 0, size); size = fis.read(buf); } fis.close(); fos.close(); }catch(Exception ex) { ex.printStackTrace(); } System.out.println("PCM Convert to MP3 OK!"); return "ok"; } }
WaveHeader类的代码如下:
package com.test; import java.io.ByteArrayOutputStream; import java.io.IOException; /** * WaveHeader * * @author QC * @since 2020-04-03 */ public class WaveHeader { public final char fileID[] = {'R', 'I', 'F', 'F'}; public int fileLength; public char wavTag[] = {'W', 'A', 'V', 'E'}; public char FmtHdrID[] = {'f', 'm', 't', ' '}; public int FmtHdrLeth; public short FormatTag; public short Channels; public int SamplesPerSec; public int AvgBytesPerSec; public short BlockAlign; public short BitsPerSample; public char DataHdrID[] = {'d', 'a', 't', 'a'}; public int DataHdrLeth; public byte[] getHeader() throws IOException { ByteArrayOutputStream bos = new ByteArrayOutputStream(); WriteChar(bos, fileID); WriteInt(bos, fileLength); WriteChar(bos, wavTag); WriteChar(bos, FmtHdrID); WriteInt(bos, FmtHdrLeth); WriteShort(bos, FormatTag); WriteShort(bos, Channels); WriteInt(bos, SamplesPerSec); WriteInt(bos, AvgBytesPerSec); WriteShort(bos, BlockAlign); WriteShort(bos, BitsPerSample); WriteChar(bos, DataHdrID); WriteInt(bos, DataHdrLeth); bos.flush(); byte[] r = bos.toByteArray(); bos.close(); return r; } private void WriteShort(ByteArrayOutputStream bos, int s) throws IOException { byte[] mybyte = new byte[2]; mybyte[1] = (byte) ((s << 16) >> 24); mybyte[0] = (byte) ((s << 24) >> 24); bos.write(mybyte); } private void WriteInt(ByteArrayOutputStream bos, int n) throws IOException { byte[] buf = new byte[4]; buf[3] = (byte) (n >> 24); buf[2] = (byte) ((n << 8) >> 24); buf[1] = (byte) ((n << 16) >> 24); buf[0] = (byte) ((n << 24) >> 24); bos.write(buf); } private void WriteChar(ByteArrayOutputStream bos, char[] id) { for (char c : id) { bos.write(c); } } }
Java将PCM转为MP3或WAVE格式很简单,复制上方代码即可使用,不需要使用所谓的lame之类的库来操作。