赞
踩
在写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。
后记:
由于原有代码过期,现根据已有的问题,特作统一回复。
直接放代码吧,简单粗暴。
- 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;
- }
-
- }
首先现有的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;)就可以了。
同样的,无论是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()。就可以循环播放啦!
这个问题嘛,结合已有代码,自己实现吧!
提示一下。
1.你需要注意暂停帧(pauseFrame)的重置。
2.AdvancedPlayer类有两个停止方法,close()和stop(),其中stop会触发停止事件,close则不会触发停止事件。这样就可以通过close方法来实现暂停,通过stop方法来实现停止播放。
总体来说,jLayer这个jar包,年代过于久远,功能很有限,只能说凑合能用,它的源码读起来不是很困难,读读源码大概就知道怎么回事了,所以想要实现更多的功能,一是自己写:),二是寻找其他jar包。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。