欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

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

程序员文章站 2024-03-31 20:35:22
一、音乐播放器的实现原理  javase的多媒体功能很弱,所以有一个专门处理多媒体的插件叫jmf,jmf提供的模型可大致分为七类 * 数据源(data s...

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

 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播放器功能》进行学习。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。