当前位置:   article > 正文

java程序添加背景音乐_java添加背景音乐

java添加背景音乐

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

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

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

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

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

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

  1. import java.io.BufferedInputStream;
  2. import java.io.File;
  3. import java.io.FileInputStream;
  4. import java.io.FileNotFoundException;
  5. import javazoom.jl.decoder.JavaLayerException;
  6. import javazoom.jl.player.*;
  7. class Play0 extends Thread{
  8. Player player;
  9. String music;
  10. public Play0(String file) {
  11. this.music = file;
  12. }
  13. public void run() {
  14. try {
  15. play();
  16. } catch (FileNotFoundException | JavaLayerException e) {
  17. e.printStackTrace();
  18. }
  19. }
  20. public void play() throws FileNotFoundException, JavaLayerException {
  21. BufferedInputStream buffer = new BufferedInputStream(new FileInputStream(music));
  22. player = new Player(buffer);
  23. player.play();
  24. }
  25. }

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

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

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

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

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

后记:

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

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

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

  1. public class Music {
  2. public static void main(String[] args) {
  3. String file = "C:\\Users\\surk\\Desktop\\1.mp3";
  4. Play play = new Play(file);
  5. Player player = play.getPlayer();
  6. // 开启
  7. play.start();
  8. try {
  9. Thread.sleep(2000);
  10. // 输出当前播放的位置(时间)
  11. System.out.println(player.getPosition());
  12. Thread.sleep(4000);
  13. } catch (InterruptedException e) {
  14. e.printStackTrace();
  15. }
  16. // 输出是否播放完毕
  17. System.out.println(player.isComplete());
  18. //结束
  19. play.stop();
  20. }
  21. }
  22. class Play implements Runnable {
  23. private Player player = null;
  24. private Thread thread = null;
  25. public Play(String file) {
  26. try {
  27. player = new Player(new FileInputStream(file));
  28. } catch (JavaLayerException | FileNotFoundException e) {
  29. e.printStackTrace();
  30. }
  31. }
  32. public void run() {
  33. try {
  34. player.play();
  35. } catch (JavaLayerException ex) {
  36. System.err.println("Problem playing audio: " + ex);
  37. }
  38. }
  39. public void start() {
  40. thread = new Thread(this, "Player thread");
  41. thread.start();
  42. }
  43. public void stop() {
  44. player.close();
  45. thread = null;
  46. }
  47. public Player getPlayer() {
  48. return player;
  49. }
  50. }

2.如何暂停?

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

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

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

  1. public class Music {
  2. public static void main(String[] args) {
  3. String file = "C:\\Users\\surk\\Desktop\\1.mp3";
  4. Play play = new Play(file);
  5. // 开启
  6. play.start();
  7. try {
  8. Thread.sleep(5000);
  9. // 暂停
  10. play.stop();
  11. Thread.sleep(2000);
  12. // 重新播放
  13. play.start();
  14. } catch (InterruptedException e) {
  15. e.printStackTrace();
  16. }
  17. //结束
  18. play.stop();
  19. System.out.println("stop!");
  20. }
  21. }
  22. class Play implements Runnable {
  23. private final String file;
  24. private AdvancedPlayer player = null;
  25. private Thread thread = null;
  26. public int pauseFrame = 0;
  27. public Play(String file) {
  28. this.file = file;
  29. }
  30. public void run() {
  31. // 每次开始需要重新创建AdvancedPlayer,否则会报错
  32. createPlayer();
  33. play();
  34. }
  35. public void start() {
  36. thread = new Thread(this, "Player thread");
  37. thread.start();
  38. }
  39. public void stop() {
  40. player.stop();
  41. thread = null;
  42. }
  43. protected void play() {
  44. try {
  45. player.play(pauseFrame, Integer.MAX_VALUE);
  46. } catch (JavaLayerException ex) {
  47. System.err.println("Problem playing audio: " + ex);
  48. }
  49. }
  50. protected void createPlayer() {
  51. try {
  52. player = new AdvancedPlayer(new FileInputStream(file));
  53. // 这里设置一个监听器,来监听停止事件,记录停止帧
  54. player.setPlayBackListener(new PlaybackListener() {
  55. @Override
  56. public void playbackFinished(PlaybackEvent event) {
  57. pauseFrame = event.getFrame();
  58. }
  59. });
  60. } catch (JavaLayerException | IOException e) {
  61. e.printStackTrace();
  62. }
  63. }
  64. }

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

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

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

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

直接放代码。

  1. public class Music {
  2. public static void main(String[] args) {
  3. String file = "C:\\Users\\surk\\Desktop\\1.mp3";
  4. Play play = new Play(file);
  5. // 开启
  6. play.start();
  7. try {
  8. Thread.sleep(14000);
  9. // 暂停
  10. play.stop();
  11. Thread.sleep(1000);
  12. // 重新播放
  13. play.start();
  14. } catch (InterruptedException e) {
  15. e.printStackTrace();
  16. }
  17. //结束
  18. play.stop();
  19. System.out.println("stop!");
  20. }
  21. }
  22. class Play implements Runnable {
  23. private final String file;
  24. private MyPlayer player = null;
  25. private Thread thread = null;
  26. public int pauseFrame = 0;
  27. public Play(String file) {
  28. this.file = file;
  29. }
  30. public void run() {
  31. // 每次开始需要重新创建AdvancedPlayer,否则会报错
  32. createPlayer();
  33. play();
  34. }
  35. public void start() {
  36. thread = new Thread(this, "Player thread");
  37. thread.start();
  38. }
  39. public void stop() {
  40. // 在停止的时候,记录停止帧
  41. pauseFrame = player.getFrame();
  42. player.close();
  43. thread = null;
  44. }
  45. protected void play() {
  46. try {
  47. player.play(pauseFrame, Integer.MAX_VALUE);
  48. } catch (JavaLayerException ex) {
  49. System.err.println("Problem playing audio: " + ex);
  50. }
  51. }
  52. protected void createPlayer() {
  53. try {
  54. player = new MyPlayer(new FileInputStream(file));
  55. } catch (FileNotFoundException | JavaLayerException e) {
  56. e.printStackTrace();
  57. }
  58. }
  59. }
  60. class MyPlayer extends AdvancedPlayer {
  61. /**
  62. * 当前帧
  63. */
  64. @Getter
  65. private int frame = 0;
  66. public MyPlayer(InputStream stream) throws JavaLayerException {
  67. super(stream);
  68. }
  69. /**
  70. * 重写decodeFrame方法,每次解析,记录帧+1
  71. */
  72. protected boolean decodeFrame() throws JavaLayerException {
  73. frame++;
  74. return super.decodeFrame();
  75. }
  76. }

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

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

3.如何循环播放?

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

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

  1. public class Music {
  2. public static void main(String[] args) {
  3. String file = "C:\\Users\\surk\\Desktop\\2.mp3";
  4. Play play = new Play(file);
  5. // 开启
  6. play.start();
  7. try {
  8. Thread.sleep(5000);
  9. } catch (InterruptedException e) {
  10. e.printStackTrace();
  11. }
  12. System.out.println("stop!");
  13. }
  14. }
  15. class Play implements Runnable {
  16. private final String file;
  17. private AdvancedPlayer player = null;
  18. private Thread thread = null;
  19. public Play(String file) {
  20. this.file = file;
  21. }
  22. public void run() {
  23. // 每次开始需要重新创建AdvancedPlayer,否则会报错
  24. createPlayer();
  25. play();
  26. }
  27. public void start() {
  28. thread = new Thread(this, "Player thread");
  29. thread.start();
  30. }
  31. public void stop() {
  32. player.stop();
  33. thread = null;
  34. }
  35. protected void play() {
  36. try {
  37. player.play();
  38. } catch (JavaLayerException ex) {
  39. System.err.println("Problem playing audio: " + ex);
  40. }
  41. }
  42. protected void createPlayer() {
  43. try {
  44. player = new AdvancedPlayer(new FileInputStream(file));
  45. // 这里设置一个监听器,来监听停止事件
  46. player.setPlayBackListener(new PlaybackListener() {
  47. @Override
  48. public void playbackFinished(PlaybackEvent event) {
  49. // 当播放完毕后,会触发该事件,再次调用start()即可!
  50. start();
  51. }
  52. });
  53. } catch (JavaLayerException | IOException e) {
  54. e.printStackTrace();
  55. }
  56. }
  57. }

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

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

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

提示一下。

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

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

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

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Guff_9hys/article/detail/759654
推荐阅读
相关标签
  

闽ICP备14008679号