Java中MPEG1L3 44.1kHz转48kHz PCM遇格式转换不支持问题求助
MPEG1L3转指定PCM格式失败的解决方法
核心原因
JDK默认的AudioSystem没有内置MPEG1L3(MP3)解码器,无法直接完成从MP3流到目标PCM格式的跨采样率转换,因此抛出Unsupported conversion异常。
可行解决方案
方案一:借助JLayer手动解码后转换
JLayer是轻量MP3解码库,先将MP3流解码为原始PCM,再通过AudioSystem完成格式转换。
1. 添加依赖
Maven坐标:
<dependency> <groupId>javazoom</groupId> <artifactId>jlayer</artifactId> <version>1.0.1</version> </dependency>
或下载对应jar包加入项目依赖。
2. 转换代码
import javazoom.jl.decoder.*; import javax.sound.sampled.*; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; public class Mp3Converter { public static AudioInputStream convertToTargetPcm(AudioInputStream mp3Stream) throws IOException { Bitstream bitstream = new Bitstream(mp3Stream); Decoder decoder = new Decoder(); ByteArrayOutputStream pcmBuffer = new ByteArrayOutputStream(); try { Header header; while ((header = bitstream.readFrame()) != null) { SampleBuffer sampleBuf = (SampleBuffer) decoder.decodeFrame(header, bitstream); short[] samples = sampleBuf.getBuffer(); // 将short采样转为字节数组(小端格式) for (short s : samples) { pcmBuffer.write(s & 0xFF); pcmBuffer.write((s >> 8) & 0xFF); } bitstream.closeFrame(); } } catch (Exception e) { throw new IOException("MP3解码失败", e); } finally { bitstream.close(); } // 构建解码后的PCM流(44.1kHz、16位、立体声、小端) AudioFormat decodedPcm = new AudioFormat(Encoding.PCM_SIGNED, 44100, 16, 2, 4, 44100, false); AudioInputStream pcmStream = new AudioInputStream( new ByteArrayInputStream(pcmBuffer.toByteArray()), decodedPcm, pcmBuffer.size() / decodedPcm.getFrameSize() ); // 转换为目标格式(48kHz、16位、立体声、大端) AudioFormat targetFormat = new AudioFormat(Encoding.PCM_SIGNED, 48000, 16, 2, 4, 48000, true); return AudioSystem.getAudioInputStream(targetFormat, pcmStream); } }
方案二:使用Tritonus MP3SPI插件(更简洁)
该插件为AudioSystem添加MP3解码支持,无需手动解码,直接复用你原来的代码。
1. 添加依赖
需同时引入三个jar包:
mp3spi-1.9.5.jartritonus_share-0.3.7.jarjl-1.0.1.jar
2. 复用原有代码
引入依赖后,直接执行你原来的转换代码即可:
AudioFormat targetFormat = new AudioFormat(Encoding.PCM_SIGNED, 48000, 16, 2, 4, 48000, true); AudioInputStream targetStream = AudioSystem.getAudioInputStream(targetFormat, in);
注意事项
- 若处理大音频流,方案一的内存缓冲方式可能占用过高内存,可改为流式分段处理;
- 确保引入的库版本与JDK版本兼容;
- 所有流操作完成后需及时关闭,避免资源泄漏。
内容的提问来源于stack exchange,提问作者Joa
相关产品推荐
相关产品推荐

