Java 播放MP3 的六种方法
Java Sound Api(JDK)原生支 .wav .au .aiff 这些格式的音频文件,当然 PCM文件也是可以直接播放的,如果是 mp3,ogg,ape,flac 则需要第三方 jar 。
package com.xu.music; import javax.sound.sampled.AudioSystem; import java.util.stream.Stream; public class Test {
public static void main(String[] args) {
// 查看系统支持音频文件 Stream.of(AudioSystem.getAudioFileTypes()).forEach(System.out::println); } }
WAVE AU AIFF Process finished with exit code 0
音频格式 | 添加依赖 |
---|---|
*.wav *.au *.aiff | java sound api(JDK原生支持) |
*.mp3 *.mp4 *.ogg *.flac *.wav *.aif *.dsf *.wma (获取音频标签) | jaudiotagger.jar |
*.mp3 | mp3spi.jar |
*.mp3 | jl1.0.jar |
*.mp3 | jmp123.jar |
*.flac | jflac.jar |
1 使用官方的解决方案
使用官方开发的 JMF (Java Media Framework),现在JMF已经不再更新了。如果使用方法1,你必须安装好 JMF 软件并导入JMF安装目录下对应的jar包。
音频格式 | 添加依赖 |
---|---|
*.mp3 | jmf 安装目录的 jar 包 |
package com.xu.musicplayer.player; import java.io.File; import java.io.IOException; import java.net.MalformedURLException; import javax.media.Manager; import javax.media.NoPlayerException; import javax.media.Player; / * Java 播放音频 * @ClassName: MusicPlayer * @Description: TODO * @author: hyacinth * @date: 2019年8月9日 上午12:10:53 * @Copyright: hyacinth */ public class MusicPlayer {
public static void main(String[] args) throws NoPlayerException, MalformedURLException, IOException {
File file = new File("F:\\KuGou\\张婉清、童英然、薛之谦、黄云龙 - 丑八怪.mp3"); Player player = Manager.createPlayer(file.toURL()); player.start();//开始播放 } }
2 使用第三方解决方案 (jl1.0.jar)
使用第三方jar包 jl1.0.jar。
音频格式 | 添加依赖 |
---|---|
*.mp3 | jl1.0.jar |
package com.xu.musicplayer.player; import java.io.BufferedInputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import javazoom.jl.decoder.JavaLayerException; import javazoom.jl.player.Player; / * Java 播放音频 * @ClassName: MusicPlayer * @Description: TODO * @author: hyacinth * @date: 2020年3月5日 上午12:10:53 * @Copyright: hyacinth */ public class MusicPlayer {
static Player player = null; public static void main(String[] args) throws FileNotFoundException, JavaLayerException {
File file = new File("C:\\Users\\hyacinth\\Desktop\\Work\\花涵 - 假行僧.mp3"); FileInputStream fis = new FileInputStream(file); BufferedInputStream stream = new BufferedInputStream(fis); Player player = new Player(stream); player.play(); } / * 播放 20 秒并结束播放 */ public void play() {
new Thread(new Runnable() {
@Override public void run() {
try {
File file = new File("C:\\Users\\hyacinth\\Desktop\\Work\\花涵 - 假行僧.mp3"); FileInputStream fis = new FileInputStream(file); BufferedInputStream stream = new BufferedInputStream(fis); player = new Player(stream); player.play(); } catch (Exception e) {
// TODO: handle exception } } }).start(); try {
Thread.sleep(20000); } catch (InterruptedException e) {
e.printStackTrace(); } player.close(); } }
3 使用第三方解决方案 (jmp123.jar)
3 使用第三方jar包 jmp123.jar。CSDN jmp
音频格式 | 添加依赖 |
---|---|
*.mp3 | jmp123.jar |
package com.xu.musicplayer.player; import java.io.File; import java.io.IOException; import jmp123.output.Audio; / * Java 播放音频 * @ClassName: MusicPlayer * @Description: TODO * @author: hyacinth * @date: 2019年8月9日 上午12:10:53 * @Copyright: hyacinth */ public class MusicPlayer {
public static void main(String[] args) {
String path="G:\\KuGou\\梦涵 - 爱的故事上集.mp3"; MiniPlayer player = new MiniPlayer(new Audio()); try {
long t0 = System.nanoTime(); String msg = player.open(path); long t1 = System.nanoTime() - t0; File file = new File(path); long length = file.length(); int frames = player.getFrameCount(); System.out.println(msg); System.out.printf(" length: %d bytes, %d frames\n", length, frames); System.out.printf("elapsed time: %,dns (%.9fs, %.2f fps)\n", t1, t1/1e9, frames/(t1/1e9)); player.run(); } catch (IOException e) {
e.printStackTrace(); } } }
4 使用第三方解决方案 (mp3spi.jar)
5 使用 Google 的 mp3spi 播放MP3。添加 mp3spi 的 maven 依赖。
音频格式 | 添加依赖 |
---|---|
*.mp3 | mp3spi.jar |
4.1 依赖引用
<dependency> <groupId>com.googlecode.soundlibs</groupId> <artifactId>mp3spi</artifactId> <version>1.9.5.4</version> </dependency>
4.2 测试代码
/ * * @Author: hyacinth * @Title: MusicPlayer.java * @Package com.xu.test * @Description: TODO: * @Date: 2019年8月25日 下午10:40:47 * @Version V-1.0 * @Copyright: 2019 hyacinth * */ package com.xu.test; import java.io.File; import java.io.FileInputStream; import javazoom.jl.player.Player; / * @Author: hyacinth * @ClassName: MusicPlayer * @Description: TODO * @Date: 2019年8月25日 下午10:40:47 * @Copyright: hyacinth */ public class MusicPlayer {
public static void main(String[] args) throws Exception {
File file=new File("I:\\KuGou\\许丽静 - 昨天今天下雨天.mp3"); FileInputStream stream=new FileInputStream(file); Player player=new Player(stream); player.play(); } }
5 使用第三方解决方案 (jaudiotagger.jar)
jaudiotagger.jar 本身不能播放 音频文件,但是能解码 音频文件 中的标签信息。
音频格式 | 添加依赖 |
---|---|
*.mp3 *.mp4 *.ogg *.flac *.wav *.aif *.dsf *.wma (获取音频标签) | jaudiotagger.jar |
5.1 添加依赖
<dependency> <groupId>org</groupId> <artifactId>jaudiotagger</artifactId> <version>2.0.3</version> </dependency>
5.2 测试代码
package com.xu.music.player; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import org.jaudiotagger.audio.AudioFile; import org.jaudiotagger.audio.AudioFileIO; import org.jaudiotagger.audio.exceptions.CannotReadException; import org.jaudiotagger.audio.exceptions.InvalidAudioFrameException; import org.jaudiotagger.audio.exceptions.ReadOnlyFileException; import org.jaudiotagger.tag.TagException; import javazoom.jl.decoder.JavaLayerException; import javazoom.jl.player.Player; public class MusicPlayer {
public static void main(String[] args) throws Exception {
get_music_play_length("I:\\KuGou\\许丽静 - 昨天今天下雨天.mp3"); } / * Java Music 获取歌曲播放时长 * @Title: get_music_play_length * @Description: 获取歌曲播放时长 * @param path mp3路径 * @throws InvalidAudioFrameException * @throws ReadOnlyFileException * @throws TagException * @throws IOException * @throws CannotReadException * @date 2019年10月25日 下午12:28:41 */ public int get_music_play_length(String path) throws CannotReadException, IOException, TagException, ReadOnlyFileException, InvalidAudioFrameException {
File file=new File("C:\\Users\\Administrator\\Desktop\\梦涵 - 加减乘除.mp3"); AudioFile mp3=AudioFileIO.read(file); return mp3.getAudioHeader().getTrackLength(); } }
6 使用自定义解决方案(推荐)
6.1 SourceDataLine和Clip
方式 | 优点 | 缺点 |
---|---|---|
SourceDataLine | 1、适合需要实时处理音频数据的应用,如音频流媒体、音频处理和效果应用等。 2、可以逐块地写入音频数据,因此可以动态生成或修改音频流。 3、提供更高的控制力,可以控制播放速度、音量、音调等参数。 4、可以处理各种格式的音频数据,只要通过适当的编码解码器进行转换。 5、适合处理大文件,因为音频数据是逐块处理的,不需要一次性加载到内存中。 |
1、代码实现相对复杂,需要处理缓冲区管理、同步和错误处理等。 2、需要更详细的了解音频数据格式和音频系统。 3、由于需要初始化音频流,可能会有一定的启动延迟。 |
Clip | 1、适合播放简单的音频片段,如短音乐、音效等。 2、API 简单,使用方便,只需加载音频文件后调用 start() 方法即可播放。 3、启动延迟小,适合快速播放音频的场景,如游戏音效、用户界面提示音等。 4、将音频文件一次性加载到内存中,减少了对磁盘 I/O 的依赖,播放时性能较高。 |
1、对于较大的音频文件,需要一次性加载到内存中,内存消耗较大,不适合播放大文件或长时间音频。 2、不适合需要动态生成或实时处理音频数据的场景。 3、控制能力有限,难以实现复杂的音频处理和效果。 |
如果你的应用需要实时处理音频数据、播放长时间音频或大文件、或者需要高度自定义的音频控制,SourceDataLine 是更好的选择。 | ||
如果你的应用主要是播放短音频片段,要求启动延迟小,且对音频处理和控制要求不高,Clip 是更为简便和高效的选择。 |
1、推荐使用 SourceDataLine 播放音频
2、Clip 播放音频
自定义通过获取MP3的PCM播放MP3,需要导入Google的一个jar包,可以获取音频的播放时长。
音频格式 | 添加依赖 |
---|---|
*.wav | 无 (JDK 原生支持) |
*.pcm | 无 (JDK 原生支持) |
*.au | 无 (JDK 原生支持) |
*.aiff | 无 (JDK 原生支持) |
*.mp3 | mp3spi.jar |
*.flac | jflac-codec.jar |
6.2 依赖引用
<!-- 如果需要解码播放mp3文件则引入这个jar包 --> <dependency> <groupId>com.googlecode.soundlibs</groupId> <artifactId>mp3spi</artifactId> <version>1.9.5.4</version> </dependency> <!-- 如果需要解码播放flac文件则引入这个jar包 --> <dependency> <groupId>org.jflac</groupId> <artifactId>jflac-codec</artifactId> <version>1.5.2</version> </dependency>
7.3 播放时长
// float 类型 秒 AudioSystem.getAudioInputStream(new File("")).getFrameLength()/AudioSystem.getAudioInputStream(new File("")).getFormat().getSampleRate()
/ * Java Music 获取音频文件信息 * @Title: get_info * @Description: 获取音频文件信息 * @param path 音频文件路径 * @return 音频文件信息 * @date 2019年10月25日 下午12:28:41 */ public String get_info(String path) {
File file=new File(path); AudioInputStream ais; String result=""; try {
ais = AudioSystem.getAudioInputStream(file); AudioFormat af = ais.getFormat(); result = af.toString(); System.out.println(result); System.out.println("音频总帧数:"+ais.getFrameLength()); System.out.println("每秒播放帧数:"+af.getSampleRate()); float len = ais.getFrameLength()/af.getSampleRate(); System.out.println("音频时长(秒):"+len); System.out.println("音频时长:"+(int)len/60+"分"+(int)len%60+"秒"); } catch(UnsupportedAudioFileException e) {
throw new RuntimeException(e.getMessage()); } catch(IOException e) {
throw new RuntimeException(e.getMessage()); } return result; }
6.4 全部代码
package com.xu.player; import org.apache.commons.lang3.StringUtils; / * @author Administrator */ public enum Audio {
/ * Specifies a WAVE file. */ WAVE(1, "WAVE", "wav"), / * Specifies an AU file. */ AU(2, "AU", "au"), / * Specifies an AIFF file. */ AIFF(3, "AIFF", "aif"), / * Specifies an AIFF-C file. */ AIFF_C(4, "AIFF-C", "aifc"), / * Specifies an SND file. */ SND(5, "SND", "snd"), / * Specifies an MP3 file. */ MP3(6, "MP3", "mp3"), / * Specifies an FLAC file. */ FLAC(7, "FLAC", "flac"); private int index; private String type; private String suffix; Audio(int index, String type, String suffix) {
this.index = index; this.type = type; this.suffix = suffix; } public int index() {
return index; } public static int getIndex(String name) {
if (StringUtils.isBlank(name)) {
throw new RuntimeException("文件名称为空!"); } name = StringUtils.substring(name, StringUtils.lastIndexOf(name, ".") + 1); for (Audio audio : values()) {
if (StringUtils.equalsIgnoreCase(audio.suffix, name)) {
return audio.index; } } return -1; } public static boolean isSupport(String name) {
if (StringUtils.isBlank(name)) {
throw new RuntimeException("文件名称为空!"); } name = StringUtils.substring(name, StringUtils.lastIndexOf(name, ".") + 1); for (Audio audio : values()) {
if (StringUtils.equalsIgnoreCase(audio.suffix, name)) {
return true; } } return false; } }
package com.xu.player; import java.awt.Image; import java.awt.Toolkit; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.net.URL; import javax.sound.sampled.AudioFileFormat; import javax.sound.sampled.AudioFormat; import javax.sound.sampled.AudioInputStream; import javax.sound.sampled.AudioSystem; import javax.sound.sampled.DataLine; import javax.sound.sampled.SourceDataLine; import javax.sound.sampled.UnsupportedAudioFileException; import javax.swing.ImageIcon; import org.jaudiotagger.audio.mp3.MP3File; import org.jaudiotagger.tag.id3.AbstractID3v2Frame; import org.jaudiotagger.tag.id3.AbstractID3v2Tag; import org.jaudiotagger.tag.id3.framebody.FrameBodyAPIC; import javazoom.spi.mpeg.sampled.file.MpegAudioFileReader; / * Java 播放音频 * * @ClassName: MusicPlayer * @Description: TODO * @author: hyacinth * @date: 2019年10月25日 下午12:28:41 * @Copyright: hyacinth */ public class MusicPlayer {
private static DataLine.Info info = null; private static AudioFormat format = null; private static SourceDataLine line = null; private static AudioInputStream audio = null; public static void main(String[] args) throws Exception {
MusicPlayer player = new MusicPlayer(); //player.audio_to_pcm("E:\\KuGou\\左宏 - 功德圆满 (情与法笛子版).mp3", "E:\\KuGou\\左宏 - 功德圆满 (情与法笛子版).pcm"); //player.get_info("C:\\Users\\Administrator\\Desktop\\梦涵 - 加减乘除.wav"); //player.play("C:\\Users\\Administrator\\Desktop\\梦涵 - 加减乘除.pcm"); //player.play("C:\\Users\\Administrator\\Desktop\\梦涵 - 加减乘除.wav"); player.play("E:\\KuGou\\左宏 - 功德圆满 (情与法笛子版).mp3"); //player.play("C:\\Users\\Administrator\\Desktop\\梦涵 - 加减乘除.flac"); } / * Java Music 播放 * * @param path 文件路径 * @throws Exception * @Title: play_pcm * @Description: 播放 pcm * @date 2019年10月25日 下午12:28:41 */ public void play(String path) throws Exception {
load(path); try {
line = (SourceDataLine) AudioSystem.getLine(info); line.open(format); line.start(); byte[] buffer = new byte[1024]; int len = -1; while ((len = audio.read(buffer)) > 0) {
line.write(buffer, 0, len); } line.drain(); line.stop(); line.close(); audio.close(); } catch (Exception e) {
throw new RuntimeException(e.getMessage()); } } / * 加载音频 * * @param url * @throws Exception * @date 2022年1月7日14点15分 */ public void load(URL url) throws Exception {
load(AudioSystem.getAudioInputStream(url)); } / * 加载音频 * * @param file * @throws Exception * @date 2022年1月7日14点15分 */ public void load(File file) throws Exception {
String name = file.getName(); if (Audio.isSupport(name)) {
if (Audio.getIndex(name) == Audio.MP3.index()) {
MpegAudioFileReader reader = new MpegAudioFileReader(); load(reader.getAudioInputStream(file)); } else {
load(AudioSystem.getAudioInputStream(file)); } } } / * 加载音频 * * @param path * @throws Exception * @date 2022年1月7日14点15分 */ public void load(String path) throws Exception {
load(new File(path)); } / * 加载音频 * * @param stream * @throws Exception * @date 2022年1月7日14点15分 */ public void load(InputStream stream) throws Exception {
load_audio(AudioSystem.getAudioInputStream(stream)); } / * 加载音频 * * @param encoding * @param stream * @date 2022年1月7日14点15分 */ public void load(AudioFormat.Encoding encoding, AudioInputStream stream) {
load_audio(AudioSystem.getAudioInputStream(encoding, stream)); } / * 加载音频 * * @param format * @param stream * @date 2022年1月7日14点15分 */ public void load(AudioFormat format, AudioInputStream stream) {
load_audio(AudioSystem.getAudioInputStream(format, stream)); } / * 加载音频 * * @param stream 音频流 * @date 2022年1月7日14点15分 */ public void load_audio(AudioInputStream stream) {
try {
format = stream.getFormat(); format = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED, format.getSampleRate(), 16, format.getChannels(), format.getChannels() * 2, format.getSampleRate(), false); audio = AudioSystem.getAudioInputStream(format, stream); info = new DataLine.Info(SourceDataLine.class, format, AudioSystem.NOT_SPECIFIED); line = (SourceDataLine) AudioSystem.getLine(info); } catch (Exception e) {
throw new RuntimeException(e.getMessage()); } } / * 导出文件为PCM * * @param src 音频文件路径 * @param dst PCM文件导出路径 * @throws Exception * @date 2022年1月7日14点15分 */ private void audio_to_pcm(String src, String dst) throws Exception {
load(src); AudioSystem.write(audio, AudioFileFormat.Type.WAVE, new File(dst)); line.close(); audio.close(); } / * Java Music 获取wav或者pcm文件的编码信息 * * @param path wav或者pcm文件路径 * @return wav或者pcm文件的编码信息 * @Title: get_info * @Description: 获取wav或者pcm文件的编码信息 * @date 2019年10月25日 下午12:28:41 */ public String get_info(String path) {
File file = new File(path); AudioInputStream ais; String result = ""; try {
ais = AudioSystem.getAudioInputStream(file); AudioFormat af = ais.getFormat(); result = af.toString(); System.out.println(result); System.out.println("音频总帧数:" + ais.getFrameLength()); System.out.println("每秒播放帧数:" + af.getSampleRate()); float len = ais.getFrameLength() / af.getSampleRate(); System.out.println("音频时长(秒):" + len); System.out.println("音频时长:" + (int) len / 60 + "分" + len % 60 + "秒"); } catch (UnsupportedAudioFileException e) {
throw new RuntimeException(e.getMessage()); } catch (IOException e) {
throw new RuntimeException(e.getMessage()); } return result; } / * Java Music 获取mp3文件的图片 * * @param mpath mp3flac文件路径 * @Title: get_image_from_mp3 * @Description: 获取mp3文件的图片 * @date 2019年10月25日 下午12:28:41 */ public void get_image_from_mp3(String mpath) throws Exception {
File sourceFile = new File(mpath); MP3File mp3file = new MP3File(sourceFile); AbstractID3v2Tag tag = mp3file.getID3v2Tag(); AbstractID3v2Frame frame = (AbstractID3v2Frame) tag.getFrame("APIC"); FrameBodyAPIC body = (FrameBodyAPIC) frame.getBody(); byte[] image = body.getImageData(); Image img = Toolkit.getDefaultToolkit().createImage(image, 0, image.length); ImageIcon icon = new ImageIcon(img); FileOutputStream fos = new FileOutputStream("C:\\Users\\Administrator\\Desktop\\梦涵 - 加减乘除.jpg"); fos.write(image); fos.close(); System.out.println("width:" + icon.getIconWidth()); System.out.println("height:" + icon.getIconHeight()); } }
7 使用JavaFX解决方案
7.1 添加依赖
<dependency> <groupId>org.openjfx</groupId> <artifactId>javafx-controls</artifactId> <version>17.0.10</version> </dependency> <dependency> <groupId>org.openjfx</groupId> <artifactId>javafx-media</artifactId> <version>17.0.10</version> </dependency>
7.2 下载JavaFX SDK
JavaFX
7.3 测试代码
--module-path D:\Environment\JavaFX\lib --add-modules=javafx.controls,javafx.media java --module-path D:\Environment\JavaFX\lib --add-modules=javafx.controls,javafx.media -cp target/test.jar com.xu.test.Test
package com.xu.test; import java.nio.file.Paths; import javafx.application.Application; import javafx.scene.media.Media; import javafx.scene.media.MediaPlayer; import javafx.stage.Stage; public class Test extends Application {
@Override public void start(Stage primaryStage) {
Media media = new Media(Paths.get("D:\\Kugou\\梦涵 - 加减乘除.mp3").toUri().toString()); MediaPlayer player = new MediaPlayer(media); player.play(); } public static void main(String[] args) {
launch(args); } }
8 制作一个 Java 音乐播放器
博主用 Java SWT 编写的 Java MusicPlayer
支持FFT频谱显示,默认不开启FFT频谱,喜欢的帮助点颗心。
Java MusicPlayer GitHub 地址 (旧版本)
Java MusicPlayer GitHub 地址 (新版本)
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/bian-cheng-ji-chu/80239.html