0

0

Java怎么解码MP3为PCM数据 Java使用Tritonus插件解码MP3【配置】

煙雲

煙雲

发布时间:2026-01-30 15:50:17

|

972人浏览过

|

来源于php中文网

原创

根本原因是Tritonus的MP3服务提供者(SPI)未被JVM正确加载,需确保tritonus-share与tritonus-mp3版本一致、含正确META-INF/services配置,Java 9+还需额外模块参数或手动注册。

java怎么解码mp3为pcm数据 java使用tritonus插件解码mp3【配置】

Java用Tritonus解码MP3时为什么AudioSystem.getAudioInputStream()抛出UnsupportedAudioFileException

根本原因是Tritonus的MP3服务提供者(SPI)未被JVM正确加载,不是代码写错了。Tritonus本身不自带MP3解码器,它依赖tritonus-sharetritonus-mp3两个jar,并且必须通过META-INF/services/javax.sound.sampled.spi.AudioFileReader声明实现类才能被AudioSystem发现。

实操建议:

  • 确认项目中同时存在tritonus-share-x.x.jartritonus-mp3-x.x.jar(版本需严格一致,如都用0.3.7
  • 检查这两个jar内是否包含META-INF/services/javax.sound.sampled.spi.AudioFileReader文件,内容应为org.tritonus.share.sampled.file.AudioFileReader
  • 若用Maven,避免只引入tritonus-share——它不含MP3解析逻辑,必须显式添加tritonus-mp3依赖
  • Java 9+用户注意:模块系统默认不读取classpath下的SPI配置,需在启动参数加--add-opens java.desktop/sun.audio=ALL-UNNAMED(仅调试用),或改用ServiceLoader.load()手动注册

如何用Tritonus把MP3转成16-bit PCM(LINEAR)格式

Tritonus默认输出的PCM格式可能不是你预期的AudioFormat.Encoding.PCM_SIGNED,尤其当原始MP3含VBR或非标准采样率时,AudioInputStream返回的AudioFormat常是Encoding.PCM_UNSIGNEDEncoding.ULAW,需显式重采样。

关键步骤:

立即学习Java免费学习笔记(深入)”;

AIPAI
AIPAI

AI视频创作智能体

下载
  • 先用AudioSystem.getAudioInputStream(File)获取原始流
  • 调用getFormat()检查encoding字段,若不是AudioFormat.Encoding.PCM_SIGNED,必须用AudioSystem.getAudioInputStream(targetFormat, originalStream)转换
  • 目标AudioFormat推荐设为:new AudioFormat(AudioFormat.Encoding.PCM_SIGNED, 44100, 16, 2, 4, 44100, false)(44.1kHz/16bit/stereo)
  • 注意frameRatesampleRate要一致,否则AudioSystem可能静默降级为其他编码
File mp3File = new File("input.mp3");
AudioInputStream ais = AudioSystem.getAudioInputStream(mp3File);
AudioFormat baseFormat = ais.getFormat();
AudioFormat targetFormat = new AudioFormat(
    AudioFormat.Encoding.PCM_SIGNED,
    44100.0f, 16, 2, 4, 44100.0f, false);
AudioInputStream pcmStream = AudioSystem.getAudioInputStream(targetFormat, ais);

Tritonus解码MP3后读取PCM数据时read()返回-1或数据截断

这不是解码失败,而是AudioInputStreamavailable()方法在Tritonus中不可靠——它常返回0或错误值,导致提前退出循环。必须依赖getFrameLength()getFrameSize()计算总字节数,或用阻塞式读取直到返回-1。

安全读取方式:

  • 不要用while (stream.available() > 0)判断循环条件
  • int totalFrames = (int) stream.getFrameLength()预估大小(若为AudioSystem.NOT_SPECIFIED,说明是流式源,只能边读边处理)
  • 分配byte[] buffer = new byte[8192],循环int len = stream.read(buffer),直到len == -1
  • 注意:Tritonus的read()可能一次只返回几百字节,尤其对低码率MP3,别假设能填满buffer

为什么同样代码在Windows能解码、Linux报No line matches或静音

这通常与底层ALSA/PulseAudio配置无关,而是Tritonus在不同JVM上对浮点型采样率(如44100.0000001)的处理差异导致格式匹配失败。Linux OpenJDK常将MP3元数据里的采样率解析为double近似值,而Tritonus的格式匹配器要求严格相等。

绕过办法:

  • 强制指定目标采样率为整数:Math.round(originalFormat.getSampleRate())再构造AudioFormat
  • 改用AudioFormat.Encoding.PCM_SIGNED + originalFormat.getSampleSizeInBits() + originalFormat.getChannels(),只修正sampleRateframeRate
  • 若仍失败,临时方案:先用ffmpeg -i input.mp3 -f s16le -ar 44100 -ac 2 output.pcm转成裸PCM,再用Java读二进制——比硬啃Tritonus兼容性更省时间
Tritonus的MP3支持本质是胶水层,它把libmad等C库封装成Java SPI,所以任何环节(jar缺失、JVM版本、采样率精度、SPI加载顺序)出问题都会表现为“不支持文件格式”。真要稳定解码,优先考虑ffmpeg-cli-wrapperjave2这类进程调用方案,它们绕过了JVM音频的所有不确定性。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
Java Maven专题
Java Maven专题

本专题聚焦 Java 主流构建工具 Maven 的学习与应用,系统讲解项目结构、依赖管理、插件使用、生命周期与多模块项目配置。通过企业管理系统、Web 应用与微服务项目实战,帮助学员全面掌握 Maven 在 Java 项目构建与团队协作中的核心技能。

0

2025.09.15

while的用法
while的用法

while的用法是“while 条件: 代码块”,条件是一个表达式,当条件为真时,执行代码块,然后再次判断条件是否为真,如果为真则继续执行代码块,直到条件为假为止。本专题为大家提供while相关的文章、下载、课程内容,供大家免费下载体验。

97

2023.09.25

string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

463

2023.08.02

int占多少字节
int占多少字节

int占4个字节,意味着一个int变量可以存储范围在-2,147,483,648到2,147,483,647之间的整数值,在某些情况下也可能是2个字节或8个字节,int是一种常用的数据类型,用于表示整数,需要根据具体情况选择合适的数据类型,以确保程序的正确性和性能。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

544

2024.08.29

c++怎么把double转成int
c++怎么把double转成int

本专题整合了 c++ double相关教程,阅读专题下面的文章了解更多详细内容。

113

2025.08.29

C++中int的含义
C++中int的含义

本专题整合了C++中int相关内容,阅读专题下面的文章了解更多详细内容。

200

2025.08.29

c++怎么把double转成int
c++怎么把double转成int

本专题整合了 c++ double相关教程,阅读专题下面的文章了解更多详细内容。

113

2025.08.29

C++中int、float和double的区别
C++中int、float和double的区别

本专题整合了c++中int和double的区别,阅读专题下面的文章了解更多详细内容。

102

2025.10.23

C++ 设计模式与软件架构
C++ 设计模式与软件架构

本专题深入讲解 C++ 中的常见设计模式与架构优化,包括单例模式、工厂模式、观察者模式、策略模式、命令模式等,结合实际案例展示如何在 C++ 项目中应用这些模式提升代码可维护性与扩展性。通过案例分析,帮助开发者掌握 如何运用设计模式构建高质量的软件架构,提升系统的灵活性与可扩展性。

14

2026.01.30

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
PostgreSQL 教程
PostgreSQL 教程

共48课时 | 8.1万人学习

Git 教程
Git 教程

共21课时 | 3.1万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号