English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

Lerne, wie du einfach einen Java-Musikspieler erstellst

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

 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.

二、界面效果图

三、功能结构图

四、各种实现功能的代码

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={"Abgelegte Wiedergabe","Einzelwiedergabe","Zufällige Wiedergabe"};        //Array der Auswahlmöglichkeiten der Dropdown-Liste
 JComboBox select=new JComboBox(s);          //Erstellen Sie Auswahlmöglichkeiten
 JPanel p1=new JPanel();           //Bereich der Wiedergabeliste
 JPanel p=new JPanel(); 
 JPanel p2=new JPanel();           //Bereich der Schaltflächen
 JPanel p3=new JPanel(); 
 JLabel l=new JLabel(); 
 JPanel p5=new JPanel(); //Platzieren Sie die Wiedergabeliste
 JPanel p6=new JPanel(); //Platzieren Sie den Namen des gespielten Liedes
 static JPanel pp=new JPanel();
 static JLabel lb;
 public static JTextArea jt=new JTextArea();
 static int index;  //Index der Wiedergabeliste
 int count;
 int flag;   //Markieren Sie, ob zufällige Wiedergabe oder abgelegte Wiedergabe verwendet wird
 int countSecond; //Erhalten Sie den Gesamtwert der Musikdauer
 static int newtime = 0;
 int ischanging = 0; //Wenn die Maus auf den Cursor klickt, ändert sich auch der Fortschrittswert
 int ispressing = 0; //Prüfen Sie, ob die Maus auf den Cursor klickt
 File MusicName = null;
 static java.util.List<File> MusicNames = null;  //Verwenden Sie Generics, um ein File-Objekt zu erstellen.
 File currentDirectory = null;
 List list;// 文件列表
 FileDialog open; // Definieren Sie ein Objekt für das Dateidialogfenster.
 Random rand = new Random();
 String filename;
 //Fortschrittsleiste
 JButton timeInformation = new JButton();
 JSlider timeSlider = new JSlider(SwingConstants.HORIZONTAL, 0, 100, 0); //(SwingConstants.HORIZONTAL) Sammlung von Konstanten zur Ausrichtung der Fortschrittsleiste horizontal.
                     //( 0, 100, 0) einen horizontalen Schieberegler mit angegebenem Minimalwert, Maximalwert und Initialwert erstellen.
 // Wiedergabe
 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);//Rufe diese Methode auf, um den Abstand der Hauptmarkierungen zu setzen. Die übergebenen Zahl gibt den Abstand zwischen den Hauptmarkierungen in Wertmaß an.
   timeSlider.setPaintTicks(true); //Um die Hauptmarkierungen zu zeichnen, muss setPaintTicks auf true gesetzt werden
   timeSlider.addChangeListener(new ChangeListener() { //Erstelle einen neuen ChangeListener und füge ihn dem Schieberegler hinzu.
    public void stateChanged(ChangeEvent arg0) {
     if (player != null && ispressing == 1) {
      newtime = (int)((JSlider)arg0.getSource()).getValue();
      timeInformation.setText("Aktuelle Zeit:"+newtime/60+":"+newtime%60+"  ||  "+" Gesamtdauer: "+countSecond/60+":"+countSecond%60);
      ischanging = 1;
     }
    }
   });
   timeSlider.addMouseListener(new MouseAdapter(){
    public void mousePressed(MouseEvent arg0) {
     ispressing = 1;   //Wenn der Mauszeiger auf den Cursor geklickt wird
    }
    public void mouseReleased(MouseEvent arg0) {
     ispressing = 0;   //Wenn der Mauszeiger nicht auf den Cursor geklickt wird
    }
   });
   timeInformation.setText("Aktuelle Zeit:00:00  ||  Gesamtzeit: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);
 }
 /*
  * Hauptfunktion
  * */
 public static void main(String[] args) throws IOException, InterruptedException { //InterruptedException: Wird diese Ausnahme ausgelöst, wenn ein Thread in einem Wartezustand, in einem Schlafzustand oder in einem Zustand der Inanspruchnahme ist und gleichzeitig unterbrochen wird, bevor oder während seiner Aktivität.
  MyMusicPlayer play=new MyMusicPlayer();
  Thread timeRun = new Thread(play);
  timeRun.start(); 
 }
 @Override
 public void actionPerformed(ActionEvent e) {
  String cmd = e.getActionCommand();     //Durch das Erhalten von Zeichenfolgen wird bestimmt, ob abgespielt oder pausiert wird,
  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(); //Erhalten Sie den aktuellen Pfad
     if (cd != this.currentDirectory || this.currentDirectory == null) {
      FileFilter[] fileFilters = fileChooser.getChoosableFileFilters(); //FileFilter ist eine abstrakte Klasse, JFileChooser verwendet sie, um die Dateisammlung anzuzeigen, die dem Benutzer gezeigt wird
      File files[] = cd.listFiles(); //cd.listFiles() gibt ein Array von abstrakten Pfadnamen zurück, die Dateien im Verzeichnis darstellen, das durch diesen abstrakten Pfadnamen angegeben wird.
      this.MusicNames = new ArrayList<File>();
      for (File file : files) { //Jedes Mal, wenn der Loop die Dateiobjekte im Array an die Variable file zuweist, wird diese Variable im Loopkörper verwendet, z.B.:
             //for(int i=0;i<files.length;i++{ file = files[i];……}
       filename = file.getName().toLowerCase();   //Erhalten Sie alle Musiknamen
       for (FileFilter filter : fileFilters) {
        if (!file.isDirectory() && filter.accept(file)) {
         this.MusicNames.add(file);
          list.add(filename);
         filename=e.getActionCommand();
        }
       }
      }
     }
     index = MusicNames.indexOf(MusicName); //Definieren Sie den Index des Liedes
     count = MusicNames.size();
     PlayFile();
    }
   } else {
    player.start();
   }
  }
  if(cmd.equals("Pause")){
   BPlayer.setText("Wiedergabe");
   player.stop();  
   }
  if(cmd.equals("Wiedergabe")){
   BPlayer.setText("Pause");
   player.start();
  }
  if(e.getSource()==BStop){   //Stopp
    if (player != null) {
     player.stop();
     timeInformation.setText("Aktuelle Zeit:00:00  ||  Gesamtzeit:00:00");
     timeSlider.setValue(0);
     player.setMediaTime(new Time(0)); //Zeit auf Null setzen
  }
    }
  if(e.getSource()==BMoveNext){  //Nächstes Lied
    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();   //Wenn auf das vorherige Lied geklickt wird, wird das aktuelle Lied gestoppt und das vorherige Lied abgespielt
         try {
          player=Manager.createRealizedPlayer(MusicNames.get(index).toURI().toURL());
          player.prefetch();
          player.setMediaTime(new Time(0.0));// Ab einem bestimmten Zeitraum abspielen
          player.addControllerListener(this);
          l.setText("Wiedergabe: ",+this.MusicNames.get(index).toString());
          list.select(index);
          player.start(); 
          flag=1;
         } catch (NoPlayerException | CannotRealizeException | IOException e1) {
          e1.printStackTrace();
         }
       }
     }
    }
  }
  if(e.getSource()==BMovePrevious){  //Vorheriges Lied
    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();    //Wenn auf das vorherige Lied geklickt wird, wird das aktuelle Lied gestoppt und das vorherige Lied abgespielt
       try {
        player=Manager.createRealizedPlayer(MusicNames.get(index).toURI().toURL());
        player.prefetch();
        player.setMediaTime(new Time(0.0));// Ab einem bestimmten Zeitraum abspielen
        player.addControllerListener(this);
        l.setText("Wiedergabe: ",+this.MusicNames.get(index).toString());
        list.select(index);
        player.start(); 
        flag=1;
       } catch (NoPlayerException | CannotRealizeException | IOException e1) {
        e1.printStackTrace();
       }
      }
    }
    }
  }
  if(e.getSource()==BDelect){    //Lied löschen
   index = list.getSelectedIndex();
   list.remove(index);
   MusicNames.remove(this.index);
  }
  if(e.getSource()==BDelectTable){   //Liste leeren
   list.removeAll();
   MusicNames.removeAll(MusicNames);
   player.stop();
   player = null;
  }
  //Doppelklick auf die Liste abspielen
  list.addMouseListener(new MouseAdapter() {
   public void mouseClicked(MouseEvent e) {
    // Doppelklick bearbeiten
    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));// Ab einem bestimmten Zeitraum abspielen
        player.addControllerListener(this);
        l.setText("Wiedergabe: ",+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() {
 }
 /**
  * MP abspielen3Dateihauptfunktion
  */
 public void PlayFile() {
  try {
   player = Manager.createRealizedPlayer(MusicNames.get(index).toURI().toURL());
   player.prefetch();
   player.setMediaTime(new Time(0.0));// Ab einem bestimmten Zeitraum abspielen
   player.addControllerListener(this);
   l.setFont(new Font("宋体",0,20));
   l.setText("Wiedergabe: ",+this.MusicNames.get(index).toString()); //Wiedergabesong anzeigen
   list.select(index);
   player.start();
   Mythread11 tt=new Mythread11();
   tt.start();
  } catch (Exception e1) { //Wenn ein Lied nicht abgespielt werden kann, wird es behandelt
   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-generierter Methodenstummel
 MusicNames.remove(index);
 if( --count == index )
  index = 0;
 if( count == 0)
  player = null;
 else
  PlayFile();
 }
/**
 * MP3Dateifilter-Internklasse
 */
class MusicFileChooser extends JFileChooser {
 }
/**
 * MP3Dateifilter-Assistentenklasse
 * 
 */
class MyFileFilter extends FileFilter { //FileFilter ist eine abstrakte Klasse, JFileChooser verwendet sie, um die Dateisammlung anzuzeigen, die dem Benutzer gezeigt wird
 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;
 }
}
/**
 * Zeitfortschritt der Anzeige lesen
 */
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("Aktuelle Zeit: "+newtime/60+":"+newtime%60+"  ||  "+" Gesamtdauer: "+countSecond/60+":"+countSecond%60);
    }
   }
  }
 }
}
//Liedtext-Thread umzusetzen
class Mythread11 extends Thread { 
 public void run() {
  // TODO Auto-generierter Methodenstummel
  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播放器功能》进行学习。

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

Mag sein