java程序添加背景音乐

在写Java程序的时候常常需要播放背景音乐,其实实现只需两步即可。

1.首先需要下载一个jar包

最近有许多网友反应说原来的下载地址不能用了,这里提供一个最新下载地址:jlayer-1.0.1.jar,下载完成直接导入jar即可,亲测可用。

网址:http://www.javazoom.net/javalayer/javalayer.html

下载完成,解压后找到如图所示的包导入到项目中去。

2.然后, 只需将下面的几行代码粘入程序中即可,即粘即用,如果出现错误多半是jar包没有正确导入。

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.*; 

class Play0 extends Thread{
    Player player;
    String music;
    public Play0(String file) {
        this.music = file;
    }
     public void run() {
        try {
            play();     
        } catch (FileNotFoundException | JavaLayerException e) {
             e.printStackTrace();
        }
    }
    public void play() throws FileNotFoundException, JavaLayerException { 
        BufferedInputStream buffer = new BufferedInputStream(new FileInputStream(music)); 
        player = new Player(buffer); 
        player.play(); 
    } 
} 

上面的代码实则是将播放程序放入线程中去,然后再在需要播放音乐的地方写入如下代码,开启线程。

new Play0("C:\\Users\\ds_surk\\Desktop\\My soul.mp3").start();

如需结束播放则需要这样写。

Play0 play0 = new Play0("C:\\Users\\ds_surk\\Desktop\\My soul.mp3");
        play0.start();  //开启
        play0.stop();   //结束

如果看不懂,直接粘即可,只需将 "C:\\Users\\ds_surk\\Desktop\\My soul.mp3" 替换成自己想要播放的音乐即可,格式为MP3。

后记:

由于原有代码过期,现根据已有的问题,特作统一回复。

1.Java多线程的stop方法过期,如何停止播放?

直接放代码吧,简单粗暴。

public class Music {

    public static void main(String[] args) {
        String file = "C:\\Users\\surk\\Desktop\\1.mp3";

        Play play = new Play(file);
        Player player = play.getPlayer();
        // 开启
        play.start();
        try {
            Thread.sleep(2000);
            // 输出当前播放的位置(时间)
            System.out.println(player.getPosition());
            Thread.sleep(4000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        // 输出是否播放完毕
        System.out.println(player.isComplete());
        //结束
        play.stop();
    }

}

class Play implements Runnable {

    private Player player = null;
    private Thread thread = null;

    public Play(String file) {
        try {
            player = new Player(new FileInputStream(file));
        } catch (JavaLayerException | FileNotFoundException e) {
            e.printStackTrace();
        }
    }

    public void run() {
        try {
            player.play();
        } catch (JavaLayerException ex) {
            System.err.println("Problem playing audio: " + ex);
        }
    }

    public void start() {
        thread = new Thread(this, "Player thread");
        thread.start();
    }

    public void stop() {
        player.close();
        thread = null;
    }

    public Player getPlayer() {
        return player;
    }

}

2.如何暂停?

首先现有的Player类是没有提供暂停方法的,所以想要暂停播放,需要一些技巧。

Player只提供了播放和停止方法,然后还有一个AdvancedPlayer,它提供的方法会多些,

于是根据AdvancedPlayer类有如下代码,来实现暂停播放。

public class Music {

    public static void main(String[] args) {
        String file = "C:\\Users\\surk\\Desktop\\1.mp3";

        Play play = new Play(file);
        // 开启
        play.start();
        try {
            Thread.sleep(5000);
            // 暂停
            play.stop();
            Thread.sleep(2000);
            // 重新播放
            play.start();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        //结束
        play.stop();
        System.out.println("stop!");
    }

}

class Play implements Runnable {

    private final String file;
    private AdvancedPlayer player = null;
    private Thread thread = null;
    public int pauseFrame = 0;

    public Play(String file) {
        this.file = file;
    }

    public void run() {
        // 每次开始需要重新创建AdvancedPlayer,否则会报错
        createPlayer();
        play();
    }

    public void start() {
        thread = new Thread(this, "Player thread");
        thread.start();
    }

    public void stop() {
        player.stop();
        thread = null;
    }

    protected void play() {
        try {
            player.play(pauseFrame, Integer.MAX_VALUE);
        } catch (JavaLayerException ex) {
            System.err.println("Problem playing audio: " + ex);
        }
    }

    protected void createPlayer() {
        try {
            player = new AdvancedPlayer(new FileInputStream(file));
            // 这里设置一个监听器,来监听停止事件,记录停止帧
            player.setPlayBackListener(new PlaybackListener() {
                @Override
                public void playbackFinished(PlaybackEvent event) {
                    pauseFrame = event.getFrame();
                }
            });
        } catch (JavaLayerException | IOException e) {
            e.printStackTrace();
        }
    }
}

大致思路是通过监听停止事件来记录停止时的帧,然后从停止帧继续播放。这样重新播放时就可以从上次暂停的地方继续。但是,这里有坑!!!我发现,无论是event.getFrame()还是Player类的player.getPosition()方法均不能正确的获取帧!

所以你会发现,当重新播放时,它播放的点并不是上次暂停的地方!!

不过,总归思路是行的通的!只要正确的找到帧,就可以成功实现暂停,在播放的需求。

来看AdvancedPlayer类源码,其中有一个decodeFrame()方法用来解析帧,不难发现,它每次只解析一帧,所以,可以继承AdvancedPlayer类,重写该方法,就可以达到记录帧的目的了!

直接放代码。

public class Music {

    public static void main(String[] args) {
        String file = "C:\\Users\\surk\\Desktop\\1.mp3";

        Play play = new Play(file);
        // 开启
        play.start();
        try {
            Thread.sleep(14000);
            // 暂停
            play.stop();
            Thread.sleep(1000);
            // 重新播放
            play.start();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        //结束
        play.stop();
        System.out.println("stop!");
    }

}

class Play implements Runnable {

    private final String file;
    private MyPlayer player = null;
    private Thread thread = null;
    public int pauseFrame = 0;

    public Play(String file) {
        this.file = file;
    }

    public void run() {
        // 每次开始需要重新创建AdvancedPlayer,否则会报错
        createPlayer();
        play();
    }

    public void start() {
        thread = new Thread(this, "Player thread");
        thread.start();
    }

    public void stop() {
        // 在停止的时候,记录停止帧
        pauseFrame = player.getFrame();
        player.close();
        thread = null;
    }

    protected void play() {
        try {
            player.play(pauseFrame, Integer.MAX_VALUE);
        } catch (JavaLayerException ex) {
            System.err.println("Problem playing audio: " + ex);
        }
    }

    protected void createPlayer() {
        try {
            player = new MyPlayer(new FileInputStream(file));
        } catch (FileNotFoundException | JavaLayerException e) {
            e.printStackTrace();
        }
    }
}

class MyPlayer extends AdvancedPlayer {

    /**
     * 当前帧
     */
    @Getter
    private int frame = 0;

    public MyPlayer(InputStream stream) throws JavaLayerException {
        super(stream);
    }

    /**
     * 重写decodeFrame方法,每次解析,记录帧+1
     */
    protected boolean decodeFrame() throws JavaLayerException {
        frame++;
        return super.decodeFrame();
    }

}

这里选择在停止时获取帧,没有使用监听器来获取帧,因为它记录的帧是不对的!

在测试时,发现重新播放时可能会丢失一两帧,不过影响不大,可以在停止时少记录两帧(pauseFrame = player.getFrame()-2;)就可以了。

3.如何循环播放?

同样的,无论是AdvancedPlayer类还是Player类,都没有提供循环播放的方法,所以,这个也需要自己去实现。

这个实现比较简单,直接放代码。

public class Music {

    public static void main(String[] args) {
        String file = "C:\\Users\\surk\\Desktop\\2.mp3";

        Play play = new Play(file);
        // 开启
        play.start();
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("stop!");
    }

}

class Play implements Runnable {

    private final String file;
    private AdvancedPlayer player = null;
    private Thread thread = null;

    public Play(String file) {
        this.file = file;
    }

    public void run() {
        // 每次开始需要重新创建AdvancedPlayer,否则会报错
        createPlayer();
        play();
    }

    public void start() {
        thread = new Thread(this, "Player thread");
        thread.start();
    }

    public void stop() {
        player.stop();
        thread = null;
    }

    protected void play() {
        try {
            player.play();
        } catch (JavaLayerException ex) {
            System.err.println("Problem playing audio: " + ex);
        }
    }

    protected void createPlayer() {
        try {
            player = new AdvancedPlayer(new FileInputStream(file));
            // 这里设置一个监听器,来监听停止事件
            player.setPlayBackListener(new PlaybackListener() {
                @Override
                public void playbackFinished(PlaybackEvent event) {
                    // 当播放完毕后,会触发该事件,再次调用start()即可!
                    start();
                }
            });
        } catch (JavaLayerException | IOException e) {
            e.printStackTrace();
        }
    }
}

可以通过监听停止事件,重新调用start()。就可以循环播放啦!

4.如何暂停播放+循环播放?

这个问题嘛,结合已有代码,自己实现吧!

提示一下。

1.你需要注意暂停帧(pauseFrame)的重置。

2.AdvancedPlayer类有两个停止方法,close()和stop(),其中stop会触发停止事件,close则不会触发停止事件。这样就可以通过close方法来实现暂停,通过stop方法来实现停止播放。

总体来说,jLayer这个jar包,年代过于久远,功能很有限,只能说凑合能用,它的源码读起来不是很困难,读读源码大概就知道怎么回事了,所以想要实现更多的功能,一是自己写:),二是寻找其他jar包。

  • 89
    点赞
  • 459
    收藏
    觉得还不错? 一键收藏
  • 105
    评论
评论 105
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值