【android】Java实现PCM格式音频转MP3或WAV
最近做语音合成的项目,需要把PCM格式的音频文件转换成MP3或WAV,记录一下。
Java实现的PCM格式音频文件转换MP3格式
import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; /** * PCM 转 MP3 * * @author QC班长 * @since 2020-02-02 */ public class PcmToMp3 { public static void main(String[] agrs) throws Exception { //convertAudioFiles("resource/茯茶素是什么,有什么效果,生产工艺有哪些?.pcm", "resource/茯茶素是什么,有什么效果,生产工艺有哪些?.mp3"); convertAudioFiles("tnafcs.pcm", "tnafcs.mp3"); } /** * @param src 待转换文件路径 * @param target 目标文件路径 * @throws IOException 抛出异常 */ public static String convertAudioFiles(String src, String target) throws IOException { FileInputStream fis = new FileInputStream(src); FileOutputStream fos = new FileOutputStream(target); //计算长度 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(); //填入参数,比特率等等。这里用的是16位单声道 8000 hz WaveHeader header = new WaveHeader(); //长度字段 = 内容的大小(PCMSize) + 头部字段的大小(不包括前面4字节的标识符RIFF以及fileLength本身的4字节) header.fileLength = PCMSize + (44 - 8); header.FmtHdrLeth = 16; header.BitsPerSample = 16; header.Channels = 1; header.FormatTag = 0x0001; header.SamplesPerSec = 16000;//正常速度是8000,这里写成了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标准,头部应该是44字节 //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(); System.out.println("PCM Convert to MP3 OK!"); return "ok"; } }
Java实现的PCM格式音频文件转换WAV格式
import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; /** * PCM 转 WAV * * @author QC班长 * @since 2020-02-02 */ public class PcmToWav { public static void main(String[] agrs) throws Exception { //convertAudioFiles("resource/茯茶素是什么,有什么效果,生产工艺有哪些?.pcm", "resource/茯茶素是什么,有什么效果,生产工艺有哪些?.mp3"); convertAudioFiles("tnafcs.pcm", "tnafcs.mp3"); } /** * @param src 待转换文件路径 * @param target 目标文件路径 * @throws IOException 抛出异常 */ public static void convertAudioFiles(String src, String target) throws IOException { FileInputStream fis = new FileInputStream(src); FileOutputStream fos = new FileOutputStream(target); //计算长度 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(); //填入参数,比特率等等。这里用的是16位单声道 8000 hz WaveHeader header = new WaveHeader(); //长度字段 = 内容的大小(PCMSize) + 头部字段的大小(不包括前面4字节的标识符RIFF以及fileLength本身的4字节) header.fileLength = PCMSize + (44 - 8); header.FmtHdrLeth = 16; header.BitsPerSample = 16; header.Channels = 2; header.FormatTag = 0x0001; header.SamplesPerSec = 8000; 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标准,头部应该是44字节 // 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(); System.out.println("Convert OK!"); } }
WaveHeader类
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); } } }
【参考链接】
android支持pcm格式转换,Android中Pcm文件转Amr文件
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
2020-02-16 【git】coding迁移GitHub-Git仓库迁移保留commit历史记录