教你轻松制作java音乐播放器

作者:lijiao 时间:2023-09-27 11:17:11 

一、音乐播放器的实现原理

 Javase的多媒体功能很弱,所以有一个专门处理多媒体的插件叫JMF,JMF提供的模型可大致分为七类

* 数据源(Data source)
* 截取设备(Capture Device,包括视频和音频截取设备)
* 播放器(Player)
* 处理器(Processor)
* 数据池(DataSink)
* 数据格式(Format)
* 管理器(Manager)

而我所做的这个音乐播放器MyMusicPlayer(这是我创建的类名)正是调用了JMF中的Player类来实现其播放等各种功能.

我们首先要做的就是要安装JMF。JMF的安装,相信对于许多的新手来说是很伤脑筋的,JMF只支持32位的JDK版本,然而像eclipse这样的IDE环境要与JDK对应,也就是IDE环境要支持32位JDK版本。当安装完JMF之后,有时候对于MP3的播放并不成功,还需要装JMF的mp3plugin。

二、界面效果图

教你轻松制作java音乐播放器

三、功能结构图

教你轻松制作java音乐播放器

四、各种实现功能的代码


public class MyMusicPlayer implements ActionListener, ControllerListener,Runnable{

JFrame j=new JFrame("音乐播放器");
JLabel TablePlaer=new JLabel("播放列表");
JButton BAdd=new JButton("添加歌曲");
JButton BDelect=new JButton("删除歌曲");
JButton BDelectTable=new JButton("清空列表");

JButton BMoveNext=new JButton("下一曲");
JButton BMovePrevious=new JButton("上一曲");
JButton BPlayer=new JButton("暂停");
JButton BStop=new JButton("停止");
JButton BSet=new JButton("显示歌词");
JButton BEnd=new JButton("停止");
String[] s={"顺序播放","单曲循环","随机播放"};        //下拉列表选项数组
JComboBox select=new JComboBox(s);          //创建下拉选项
JPanel p1=new JPanel();           //播放列表区域
JPanel p=new JPanel();
JPanel p2=new JPanel();           //按钮区域
JPanel p3=new JPanel();
JLabel l=new JLabel();
JPanel p5=new JPanel(); //放置播放列表
JPanel p6=new JPanel(); //放置播放歌曲的名称

static JPanel pp=new JPanel();
static JLabel lb;
public static JTextArea jt=new JTextArea();

static int index;  //播放列表的下标
int count;
int flag;   //标记是随机播放还是顺序播放
int countSecond; //获取音乐的总时间值
static int newtime = 0;
int ischanging = 0; //当鼠标是对游标进行点击,进度值也会改变
int ispressing = 0; //判断鼠标是否对游标进行点击
File MusicName = null;
static java.util.List<File> MusicNames = null;  //运用泛型,创建File对象
File currentDirectory = null;
List list;// 文件列表
FileDialog open; // 定义文件对话框对象

Random rand = new Random();

String filename;

//进度条
JButton timeInformation = new JButton();
JSlider timeSlider = new JSlider(SwingConstants.HORIZONTAL, 0, 100, 0); //(SwingConstants.HORIZONTAL)用于定向进度条为水平方向的常量的集合
                    //( 0, 100, 0)用指定的最小值、最大值和初始值创建一个水平滑块。

// 播放
Player player = null;
MusicFileChooser fileChooser = new MusicFileChooser();

static JTextPane tp=new JTextPane();  //显示歌词区域
static JTextArea are=new JTextArea(); //显示图片区域

public MyMusicPlayer(){
 j.setSize(1200, 700);
 j.setLayout(null);
 j.getContentPane().setBackground(Color.BLACK);
 j.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
 p.setBounds(2, 563, 1180, 95);
 p.setLayout(new BorderLayout());

p1.setBounds(2, 3, 298, 30);  
 p1.setBackground(new Color(255,255,255));

p2.setLayout(new GridLayout(2,3,20,20));
 p2.setBackground(Color.LIGHT_GRAY);

p3.setLayout(new GridLayout(2,0,200,10));
 p3.setBackground(new Color(255,255,255));

p5.setBounds(2, 35, 298, 526);
 p5.setLayout(null);
 p5.setBackground(new Color(255,255,255));

p6.setBounds(301, 3,880, 30);
 p6.setLayout(null);
 p6.setBackground(new Color(255,255,255));

l.setBounds(250, 4, 600, 30);  //设置显示播放的歌曲
 p6.add(l);

/*实现图片插入
  * */
 ImageIcon ic=new ImageIcon("image\\2.3.jpg");
 ic=new ImageIcon(ic.getImage().getScaledInstance(880, 477, 2)); //获取图片以及设置图片大小

lb=new JLabel(ic);
 lb.setOpaque(false);  
 pp.setOpaque(false);  //设置为透明

pp.setBounds(241, 80,990, 500);

are.setBounds(241, 56,990, 520);
 are.setOpaque(false);

tp.setBackground(new Color(255,255,255));
 tp.setBounds(301, 35,880, 49);

pp.add(are);
 pp.add(lb);

// 文件列表
 list = new List(10);
 list.setBounds(100, 55, 187, 495); //列表区域
 list.addActionListener(this);
 j.add(list);
 j.add(jt);
 j.add(tp);

BAdd.setBounds(5,20, 90,30);
 BAdd.setBackground(new Color(255,255,255));
 BDelect.setBounds(5, 80, 90, 30);
 BDelect.setBackground(new Color(255,255,255));
 BDelectTable.setBounds(5, 140, 90, 30);
 BDelectTable.setBackground(new Color(255,255,255));
 TablePlaer.setBounds(30, 100, 200, 50);
 TablePlaer.setFont(new Font("宋体",1, 20));

p1.add(TablePlaer);
 BMovePrevious.setBackground(new Color(255,255,255));
 BPlayer.setBackground(new Color(255,255,255));
 BMoveNext.setBackground(new Color(255,255,255));
 BStop.setBackground(new Color(255,255,255));
 select.setBackground(new Color(255,255,255));
 BSet.setBackground(new Color(255,255,255));
 p2.add(BMovePrevious);
 p2.add(BPlayer);
 p2.add(BMoveNext);
 p2.add(BStop);
 p2.add(select);
 p2.add(BSet);
 p2.setBackground(new Color(255,255,255));

p.add(p2,BorderLayout.WEST);
 p.add(p3,BorderLayout.CENTER);

p5.add(p);
 p5.add(BAdd);
 p5.add(BDelect);
 p5.add(BDelectTable);

BAdd.addActionListener(this);
 BDelect.addActionListener(this);
 BDelectTable.addActionListener(this);

BMoveNext.addActionListener(this);
 BPlayer.addActionListener(this);
 BMovePrevious.addActionListener(this);
 BStop.addActionListener(this);
 select.addActionListener(this);
 BSet.addActionListener(this);
 timeInformation.setEnabled(false);
  /*
  * 实现进度条
  * */

timeSlider.setMajorTickSpacing(1);//调用此方法设置主刻度标记的间隔。传入的数字表示在每个主刻度标记之间以值衡量的距离。
  timeSlider.setPaintTicks(true); //要绘制主刻度,setPaintTicks 必须设置为 true
  timeSlider.addChangeListener(new ChangeListener() { //创建一个新的 ChangeListener 添加到滑块。
   public void stateChanged(ChangeEvent arg0) {
    if (player != null && ispressing == 1) {
     newtime = (int)((JSlider)arg0.getSource()).getValue();
     timeInformation.setText("当前时间:"+newtime/60+":"+newtime%60+"  ||  "+" 总时间: "+countSecond/60+":"+countSecond%60);
     ischanging = 1;
    }
   }
  });
  timeSlider.addMouseListener(new MouseAdapter(){
   public void mousePressed(MouseEvent arg0) {
    ispressing = 1;   //当鼠标对游标进行点击时
   }
   public void mouseReleased(MouseEvent arg0) {
    ispressing = 0;   //当鼠标不对游标进行点击时
   }
  });
  timeInformation.setText("当前时间:00:00  ||  总时间:00:00");
  timeInformation.setBackground(new Color(255,255,255));
  p3.add(timeInformation,BorderLayout.NORTH);
  p3.add(timeSlider,BorderLayout.SOUTH);

j.add(pp);
  j.add(p5);
  j.add(p);
  j.add(p1);
  j.add(p6);
  j.setVisible(true);
//  j.setResizable(false);
}

/*
 * 主函数
 * */

public static void main(String[] args) throws IOException, InterruptedException { //InterruptedException:当线程在活动之前或活动期间处于正在等待、休眠或占用状态且该线程被中断时,抛出该异常
 MyMusicPlayer play=new MyMusicPlayer();
 Thread timeRun = new Thread(play);
 timeRun.start();
}
@Override
public void actionPerformed(ActionEvent e) {
 String cmd = e.getActionCommand();     //通过获取字符串来判断是播放还是暂停,
 String box=(String)select.getSelectedItem();   //判断播放的顺序
 if(e.getSource()==BAdd)
 {
  if (player == null) {
   if (fileChooser.showOpenDialog(j) == MusicFileChooser.APPROVE_OPTION) {
    this.MusicName = fileChooser.getSelectedFile();
    File cd = fileChooser.getCurrentDirectory(); //获取当前路径
    if (cd != this.currentDirectory|| this.currentDirectory == null) {
     FileFilter[] fileFilters = fileChooser.getChoosableFileFilters(); //FileFilter 是一个抽象类,JFileChooser 使用它过滤显示给用户的文件集合
     File files[] = cd.listFiles(); //cd.listFiles()表示返回一个抽象路径名数组,这些路径名表示此抽象路径名表示的目录中的文件。
     this.MusicNames = new ArrayList<File>();
     for (File file : files) { //每次循环都将数组中的文件对象赋给file这个变量,然后再在循环体中对这个变量进行操作如:
            //for(int i=0;i<files.length;i++){ file = files[i];……}
      filename = file.getName().toLowerCase();   //获取所有的音乐名称
      for (FileFilter filter : fileFilters) {
       if (!file.isDirectory() && filter.accept(file)) {
        this.MusicNames.add(file);
         list.add(filename);
        filename=e.getActionCommand();
       }
      }
     }
    }
    index = MusicNames.indexOf(MusicName); //定义歌曲的下标
    count = MusicNames.size();
    PlayFile();
   }
  } else {
   player.start();
  }

}

if(cmd.equals("暂停")){
  BPlayer.setText("播放");
  player.stop();  
  }
 if(cmd.equals("播放")){
  BPlayer.setText("暂停");
  player.start();
 }

if(e.getSource()==BStop){   //停止
   if (player != null) {

player.stop();
    timeInformation.setText("当前时间:00:00  ||  总时间:00:00");
    timeSlider.setValue(0);
    player.setMediaTime(new Time(0)); //设置时间为零
 }
   }
 if(e.getSource()==BMoveNext){  //下一曲
   if (player != null) {
    if("顺序播放".equals(box)){
     nextMusic();
    }
    if("随机播放".equals(box)){
     int index = (int) rand.nextInt(this.MusicNames.size())+1;
      if (this.MusicNames != null && !this.MusicNames.isEmpty()) {
        if ( ++index == this.MusicNames.size()) {
         index=(int) rand.nextInt(this.MusicNames.size())+1;
        }
        player.stop();   //若点击上一曲,则将当前的歌曲停止播放,播放上一曲
        try {
         player=Manager.createRealizedPlayer(MusicNames.get(index).toURI().toURL());
         player.prefetch();
         player.setMediaTime(new Time(0.0));// 从某个时间段开始播放
         player.addControllerListener(this);
         l.setText("正在播放:"+this.MusicNames.get(index).toString());
         list.select(index);
         player.start();
         flag=1;
        } catch (NoPlayerException | CannotRealizeException | IOException e1) {
         e1.printStackTrace();
        }
      }
    }
   }
 }
 if(e.getSource()==BMovePrevious){  //上一曲
   if (player != null) {
    if("顺序播放".equals(box)){
     PreviousMusic();
    }
    if("随机播放".equals(box)){
     int index = (int) rand.nextInt(this.MusicNames.size())+1;
     if (this.MusicNames != null && !this.MusicNames.isEmpty()) {
      if ( index--==(int) rand.nextInt(this.MusicNames.size())+1) {
       index = this.MusicNames.size() - 1;
      }
      player.stop();    //若点击上一曲,则将当前的歌曲停止播放,播放上一曲
      try {
       player=Manager.createRealizedPlayer(MusicNames.get(index).toURI().toURL());
       player.prefetch();
       player.setMediaTime(new Time(0.0));// 从某个时间段开始播放
       player.addControllerListener(this);
       l.setText("正在播放:"+this.MusicNames.get(index).toString());
       list.select(index);
       player.start();
       flag=1;
      } catch (NoPlayerException | CannotRealizeException | IOException e1) {
       e1.printStackTrace();
      }
     }
   }
   }
 }
 if(e.getSource()==BDelect){    //删除歌曲
  index =list.getSelectedIndex();
  list.remove(index);
  MusicNames.remove(this.index);
 }
 if(e.getSource()==BDelectTable){   //清空列表

list.removeAll();
  MusicNames.removeAll(MusicNames);
  player.stop();
  player = null;
 }

//双击列表时实现播放
 list.addMouseListener(new MouseAdapter() {
  public void mouseClicked(MouseEvent e) {
   // 双击时处理
   if (e.getClickCount() == 2) {
    if(player!=null){
     player.stop();
    }
    // 播放选中的文件
    index=list.getSelectedIndex();
    PlayFile();
   }
  }
 });

}

// 因为实现了"ControllerListener"接口,本方法用于处理媒体播放器传来的事件;
public void controllerUpdate(ControllerEvent e) {
 String box=(String)select.getSelectedItem();   //判断播放的顺序
 if (e instanceof EndOfMediaEvent) {
  player.setMediaTime(new Time(0));
  if ("单曲循环".equals(box)) {
   player.start();
  }
  if("顺序播放".equals(box)){
   nextMusic();
  }
  if("随机播放".equals(box)){
    if (this.MusicNames != null && !this.MusicNames.isEmpty()) {
      int index = (int) rand.nextInt(this.MusicNames.size())+1;
      try {
       player=Manager.createRealizedPlayer(MusicNames.get(index).toURI().toURL());
       player.prefetch();
       player.setMediaTime(new Time(0.0));// 从某个时间段开始播放
       player.addControllerListener(this);
       l.setText("正在播放:"+this.MusicNames.get(index).toString());
       list.select(index);
       player.start();
       flag=1;
      } catch (NoPlayerException | CannotRealizeException | IOException e1) {
       e1.printStackTrace();
      }
    }
  }
 }
}

/**
 * 获取MP3歌曲名
 *
 * @MP3文件路径
 * @歌曲名
 */
public String getMusicName(String str) {
 int i;
 for (i = str.length() - 1; i > 0; i--) {
  if (str.charAt(i) == '\\')
   break;
 }
 str = str.substring(i + 1, str.length() - 4);
 return str;
}

/**
 * 下一首 实现函数
 */
public void nextMusic() {
}

/**
 * 上一首实现函数
 */
public void PreviousMusic() {
}

/**
 * 播放MP3文件主函数
 */
public void PlayFile() {
 try {
  player = Manager.createRealizedPlayer(MusicNames.get(index).toURI().toURL());
  player.prefetch();
  player.setMediaTime(new Time(0.0));// 从某个时间段开始播放
  player.addControllerListener(this);
  l.setFont(new Font("宋体",0,20));
  l.setText("正在播放:"+this.MusicNames.get(index).toString()); //显示正在播放的歌曲
  list.select(index);
  player.start();

Mythread11 tt=new Mythread11();
  tt.start();

} catch (Exception e1) { //当选到一首音乐不能播放时,对其进行处理
  dealError();
  return;
 }
 this.setFrame();
 }

public void setFrame()
{
 countSecond = (int)player.getDuration().getSeconds();
 timeSlider.setMaximum(countSecond);
 timeSlider.setValue(0);
 newtime = 0;
}

private void dealError() {  
 // TODO Auto-generated method stub
MusicNames.remove(index);
if( --count == index )
 index = 0;
if( count == 0)
 player = null;
else
 PlayFile();
}

/**
* MP3文件筛选内部类
*/
class MusicFileChooser extends JFileChooser {
}

/**
* MP3文件筛选辅助内部类
*
*/
class MyFileFilter extends FileFilter { //FileFilter 是一个抽象类,JFileChooser 使用它过滤显示给用户的文件集合
String[] suffarr;
String decription;

public MyFileFilter() {
 super();
}

public MyFileFilter(String[] suffarr, String decription) {
 super();
 this.suffarr = suffarr;
 this.decription = decription;
}

public boolean accept(File f) {
 for (String s : suffarr) {
  if (f.getName().toUpperCase().endsWith(s)) {
   return true;
  }
 }
 return f.isDirectory();
}

public String getDescription() {
 return this.decription;
}
}

/**
* 读取显示时间进度条
*/
public void run() {
while(true) {
 sleep();
 if(player != null) {
  if(ispressing == 0) {
   if(ischanging == 1) {
    newtime = timeSlider.getValue();
    player.setMediaTime(new Time(((long)newtime)*1000000000));
    ischanging = 0;
   } else {
    newtime = (int)player.getMediaTime().getSeconds();
    timeSlider.setValue(newtime);
    timeInformation.setText("当前时间:"+newtime/60+":"+newtime%60+"  ||  "+" 总时间: "+countSecond/60+":"+countSecond%60);

}

}
 }
}
}

//实现歌词的线程
class Mythread11 extends Thread {
public void run() {
 // TODO Auto-generated method stub
 try{
  LRC lrc = ReadLRC.readLRC("Traveling Light.lrc");
  Lyrics ls = ParseLRC.parseLRC(lrc);
  playTest(ls);
 }catch(Exception e){

}
}

}
static void playTest(Lyrics ls) throws InterruptedException {
tp.setFont(new Font("宋体",1,20));
tp.setForeground(Color.BLUE);
StyledDocument doc = tp.getStyledDocument();
SimpleAttributeSet center = new SimpleAttributeSet();
StyleConstants.setAlignment(center, StyleConstants.ALIGN_CENTER);  //将歌词区中显示
doc.setParagraphAttributes(0, doc.getLength(), center, false);
tp.setText("艺术家:" + ls.getAr());
tp.setText("专辑:" + ls.getAl());
tp.setText("歌曲:" + ls.getTi());
tp.setText("歌词制作:" + ls.getBy());
for (Lyric l : ls.getLyrics()) {
 tp.setText( l.getTxt());
 Thread.sleep(l.getTimeSize());
}
}

}

五、总的测试效果

如下

教你轻松制作java音乐播放器

标签:java,播放器
0
投稿

猜你喜欢

  • Java程序部署到服务器上,接口请求下载文件失败/文件为空/文件名不对的问题

    2023-05-12 15:30:00
  • Java使用wait和notify实现线程之间的通信

    2022-07-20 16:05:02
  • Spring Boot用户注册验证的实现全过程记录

    2023-01-03 01:58:34
  • Java创建线程池为什么一定要用ThreadPoolExecutor

    2023-04-22 06:03:31
  • C# datagridview、datagrid、GridControl增加行号代码解析

    2023-02-03 10:42:56
  • C#操作注册表的方法

    2023-06-24 14:34:46
  • 算法练习之从String.indexOf的模拟实现开始

    2023-02-23 09:20:40
  • 关于cron表达式每天整点执行一次的问题

    2023-06-24 13:51:27
  • JAVA ArrayList详细介绍(示例)

    2023-02-18 22:30:56
  • java 创建线程的几种方式

    2023-10-29 19:40:16
  • Android 创建依赖库的方法(保姆级教程)

    2023-03-12 03:55:51
  • 设置Android系统永不锁屏永不休眠的方法

    2021-06-28 12:01:21
  • c# 获取照片的经纬度和时间的示例代码

    2022-03-22 18:21:54
  • unity将图片转换成字体的方法

    2023-02-16 22:51:09
  • Java中lock和tryLock及lockInterruptibly的区别

    2023-05-27 11:33:56
  • java实现简单猜数字

    2022-12-31 16:20:02
  • unity制作瞄准镜效果

    2022-04-15 23:45:10
  • 举例说明自定义C++异常处理的实例

    2022-10-25 13:45:27
  • 详谈java 堆区、方法区和栈区

    2023-11-23 18:35:22
  • Android仿英语流利说取词放大控件的实现方法(附demo源码下载)

    2022-07-10 23:14:18
  • asp之家 软件编程 m.aspxhome.com