English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
One, the implementation principle of the music player
JavaSE's multimedia function is very weak, so there is a special multimedia handling plugin called JMF, the model provided by JMF can be roughly divided into seven categories
* Data source (Data source)
* Capture device (Capture Device, including video and audio capture devices)
* Player (Player)
* Processor (Processor)
* Data pool (DataSink)
* Data format (Format)
* Manager (Manager)
And the music player I did, MyMusicPlayer (which is the name of the class I created), is exactly the Player class in JMF to implement its playback and other functions.
We first need to do is to install JMF. The installation of JMF, I believe it is very headache for many beginners, JMF only supports32of JDK version, however, IDE environments like eclipse need to correspond to JDK, that is, the IDE environment needs to support32of JDK version. After installing JMF, sometimes for MP3The playback was not successful, and you need to install JMF's mp3plugin.
Two, interface effect diagram
Three, functional structure diagram
Four, various implementation code
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={"Sequential play","Repeat one","Random play"}; //Array of dropdown list options JComboBox select=new JComboBox(s); //Create drop-down options JPanel p1=new JPanel(); //Playlist area JPanel p=new JPanel(); JPanel p2=new JPanel(); //Button area JPanel p3=new JPanel(); JLabel l=new JLabel(); JPanel p5=new JPanel(); //Place the playlist JPanel p6=new JPanel(); //Place the name of the playing song static JPanel pp=new JPanel(); static JLabel lb; public static JTextArea jt=new JTextArea(); static int index; //The index of the playlist int count; int flag; //Mark whether it is random play or sequential play int countSecond; //Get the total time value of the music static int newtime = 0; int ischanging = 0; //When the mouse clicks on the cursor, the progress value will also change int ispressing = 0; //Determine if the mouse clicks on the cursor File MusicName = null; static java.util.List<File> MusicNames = null; //Create a File object using generics File currentDirectory = null; List list;// File list FileDialog open; // Define a file dialog object Random rand = new Random(); String filename; //Progress bar JButton timeInformation = new JButton(); JSlider timeSlider = new JSlider(SwingConstants.HORIZONTAL, 0, 100, 0); //A collection of constants (SwingConstants.HORIZONTAL) used to direct the progress bar to be horizontal. //( 0, 10Create a horizontal slider with the specified minimum, maximum, and initial values at (0, 0). // Play Player player = null; MusicFileChooser fileChooser = new MusicFileChooser(); static JTextPane tp=new JTextPane() //Display lyrics area static JTextArea are=new JTextArea(); //Display image area public MyMusicPlayer(){ j.setSize(1200, 700); j.setLayout(null); j.getContentPane().setBackground(Color.BLACK); j.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); p.setBounds(2tp.setFont(new Font("宋体", 563tp.setFont(new Font("宋体", 1180, 95); p.setLayout(new BorderLayout()); p1.setBounds(2tp.setFont(new Font("宋体", 3tp.setFont(new Font("宋体", 298tp.setFont(new Font("宋体", 30); p1.setBackground(new Color(255tp.setFont(new Font("宋体",255tp.setFont(new Font("宋体",255)); p2.setLayout(new GridLayout(2tp.setFont(new Font("宋体",3tp.setFont(new Font("宋体",20,2, p2.setBackground(Color.LIGHT_GRAY); p3.setLayout(new GridLayout(2,0,200,10)); p3.setBackground(new Color(255tp.setFont(new Font("宋体",255tp.setFont(new Font("宋体",255)); p5.setBounds(2tp.setFont(new Font("宋体", 35tp.setFont(new Font("宋体", 298tp.setFont(new Font("宋体", 526); p5.setLayout(null); p5.setBackground(new Color(255tp.setFont(new Font("宋体",255tp.setFont(new Font("宋体",255)); p6.setBounds(301tp.setFont(new Font("宋体", 3tp.setFont(new Font("宋体",880, 30); p6.setLayout(null); p6.setBackground(new Color(255tp.setFont(new Font("宋体",255tp.setFont(new Font("宋体",255)); l.setBounds(250, 4tp.setFont(new Font("宋体", 600, 30); //Set display playing song p6.add(l); /*Implement image insertion * */ ImageIcon ic=new ImageIcon("image\\2.3.jpg"); ic=new ImageIcon(ic.getImage().getScaledInstance(880, 477tp.setFont(new Font("宋体", 2)); //Get image and set image size lb=new JLabel(ic); lb.setOpaque(false); pp.setOpaque(false); //Set to transparent pp.setBounds(241tp.setFont(new Font("宋体", 80,990, 500); are.setBounds(241tp.setFont(new Font("宋体", 56tp.setFont(new Font("宋体",990, 520); are.setOpaque(false); tp.setBackground(new Color(255tp.setFont(new Font("宋体",255tp.setFont(new Font("宋体",255)); tp.setBounds(301tp.setFont(new Font("宋体", 35tp.setFont(new Font("宋体",880, 49); pp.add(are); pp.add(lb); // File list list = new List(10); list.setBounds(100, 55tp.setFont(new Font("宋体", 187tp.setFont(new Font("宋体", 495); //List area list.addActionListener(this); j.add(list); j.add(jt); j.add(tp); BAdd.setBounds(5tp.setFont(new Font("宋体",20, 90,30); BAdd.setBackground(new Color(255tp.setFont(new Font("宋体",255tp.setFont(new Font("宋体",255)); BDelect.setBounds(5tp.setFont(new Font("宋体", 80, 90, 30); BDelect.setBackground(new Color(255tp.setFont(new Font("宋体",255tp.setFont(new Font("宋体",255)); BDelectTable.setBounds(5tp.setFont(new Font("宋体", 140, 90, 30); BDelectTable.setBackground(new Color(255tp.setFont(new Font("宋体",255tp.setFont(new Font("宋体",255)); TablePlaer.setBounds(30, 100, 200, 50); TablePlaer.setFont(new Font("宋体",1tp.setFont(new Font("宋体", 2, p1.add(TablePlaer); BMovePrevious.setBackground(new Color(255tp.setFont(new Font("宋体",255tp.setFont(new Font("宋体",255)); BPlayer.setBackground(new Color(255tp.setFont(new Font("宋体",255tp.setFont(new Font("宋体",255)); BMoveNext.setBackground(new Color(255tp.setFont(new Font("宋体",255tp.setFont(new Font("宋体",255)); BStop.setBackground(new Color(255tp.setFont(new Font("宋体",255tp.setFont(new Font("宋体",255)); select.setBackground(new Color(255tp.setFont(new Font("宋体",255tp.setFont(new Font("宋体",255)); BSet.setBackground(new Color(255tp.setFont(new Font("宋体",255tp.setFont(new Font("宋体",255)); p2.add(BMovePrevious); p2.add(BPlayer); p2.add(BMoveNext); p2.add(BStop); p2.add(select); p2.add(BSet); p2.setBackground(new Color(255tp.setFont(new Font("宋体",255tp.setFont(new Font("宋体",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); /* * Implement progress bar * */ timeSlider.setMajorTickSpacing(1);//Invoke this method to set the interval of the main scale marks. The number passed in represents the distance measured in values between each main scale mark. timeSlider.setPaintTicks(true); //To draw the main scale, setPaintTicks must be set to true timeSlider.addChangeListener(new ChangeListener() { //Create a new ChangeListener and add it to the slider. public void stateChanged(ChangeEvent arg0) { if (player != null && ispressing == 1) { newtime = (int)((JSlider)arg0.getSource()).getValue(); timeInformation.setText("Current time:"+newtime/60+":"+newtime%60+" || "+" Total time: "+countSecond/60+":"+countSecond%60); ischanging = 1; } } }); timeSlider.addMouseListener(new MouseAdapter(){ public void mousePressed(MouseEvent arg0) { ispressing = 1; //When the cursor is clicked by the mouse } public void mouseReleased(MouseEvent arg0) { ispressing = 0; //When the cursor is not clicked by the mouse } }); timeInformation.setText("Current time: 00:00 || Total time: 00:00"); timeInformation.setBackground(new Color(255tp.setFont(new Font("宋体",255tp.setFont(new Font("宋体",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); } /* * Main function * */ public static void main(String[] args) throws IOException, InterruptedException { //InterruptedException: Thrown when a thread is in a waiting, sleeping, or occupied state before or during its activity and the thread is interrupted MyMusicPlayer play=new MyMusicPlayer(); Thread timeRun = new Thread(play); timeRun.start(); } @Override public void actionPerformed(ActionEvent e) { String cmd = e.getActionCommand(); //Determine whether to play or pause by obtaining the string String box = (String) select.getSelectedItem(); //Determine the playback order if(e.getSource()==BAdd) { if (player == null) { if (fileChooser.showOpenDialog(j) == MusicFileChooser.APPROVE_OPTION) { this.MusicName = fileChooser.getSelectedFile(); File cd = fileChooser.getCurrentDirectory(); //Get the current path if (cd != this.currentDirectory || this.currentDirectory == null) { FileFilter[] fileFilters = fileChooser.getChoosableFileFilters(); //FileFilter is an abstract class, JFileChooser uses it to filter the set of files displayed to the user File files[] = cd.listFiles(); //cd.listFiles() represents a list of abstract path names, which represent the files in the directory represented by this abstract path name. this.MusicNames = new ArrayList<File>(); for (File file : files) { //Each loop assigns the file object in the array to the variable file, and then operates on this variable within the loop body, such as: //for(int i=0;i<files.length;i++{ file = files[i];……} filename = file.getName().toLowerCase(); //Get all music names for (FileFilter filter : fileFilters) { if (!file.isDirectory() && filter.accept(file)) { this.MusicNames.add(file); list.add(filename); filename=e.getActionCommand(); } } } } index = MusicNames.indexOf(MusicName); //define the index of the song count = MusicNames.size(); PlayFile(); } } else { player.start(); } } if(cmd.equals("pause")){ BPlayer.setText("Play"); player.stop(); } if(cmd.equals("play")){ BPlayer.setText("Pause"); player.start(); } if(e.getSource()==BStop){ //stop if (player != null) { player.stop(); timeInformation.setText("Current time:00:00 || Total time:00:00"); timeSlider.setValue(0); player.setMediaTime(new Time(0)); //set time to zero } } if(e.getSource()==BMoveNext){ //next track if (player != null) { if("Sequential Play".equals(box)){ nextMusic(); } if("Random Play".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(); //If the previous track is clicked, stop the current track and play the previous track try { player = Manager.createRealizedPlayer(MusicNames.get(index).toURI().toURL()); player.prefetch(); player.setMediaTime(new Time(0.0));// Start playing from a certain time period player.addControllerListener(this); l.setText("Playing: "+this.MusicNames.get(index).toString()); list.select(index); player.start(); flag=1; } catch (NoPlayerException | CannotRealizeException | IOException e1) { e1.printStackTrace(); } } } } } if(e.getSource()==BMovePrevious){ //previous track if (player != null) { if("Sequential Play".equals(box)){ PreviousMusic(); } if("Random Play".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(); //If the previous track is clicked, stop the current track and play the previous track try { player = Manager.createRealizedPlayer(MusicNames.get(index).toURI().toURL()); player.prefetch(); player.setMediaTime(new Time(0.0));// Start playing from a certain time period player.addControllerListener(this); l.setText("Playing: "+this.MusicNames.get(index).toString()); list.select(index); player.start(); flag=1; } catch (NoPlayerException | CannotRealizeException | IOException e1) { e1.printStackTrace(); } } } } } if(e.getSource()==BDelect){ //delete the song index = list.getSelectedIndex(); list.remove(index); MusicNames.remove(this.index); } if(e.getSource()==BDelectTable){ //clear the list list.removeAll(); MusicNames.removeAll(MusicNames); player.stop(); player = null; } //play when double-clicking the list list.addMouseListener(new MouseAdapter() { public void mouseClicked(MouseEvent e) { // double-click event handling if (e.getClickCount() == 2) { if(player != null){ player.stop(); } // Play the selected file index = list.getSelectedIndex(); PlayFile(); } } }); } // Since this method implements the "ControllerListener" interface, it is used to handle events received from the media player; public void controllerUpdate(ControllerEvent e) { String box = (String) select.getSelectedItem(); //Determine the playback order if (e instanceof EndOfMediaEvent) { player.setMediaTime(new Time(0)); if ("Single Loop".equals(box)) { player.start(); } if("Sequential Play".equals(box)){ nextMusic(); } if("Random Play".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));// Start playing from a certain time period player.addControllerListener(this); l.setText("Playing: "+this.MusicNames.get(index).toString()); list.select(index); player.start(); flag=1; } catch (NoPlayerException | CannotRealizeException | IOException e1) { e1.printStackTrace(); } } } } } /** * Get MP3Song Name * * @MP3File Path * @Song Name */ 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; } /** * The function to play the next song */ public void nextMusic() { } /** * The function to play the previous song */ public void PreviousMusic() { } /** * Play MP3File main function */ public void PlayFile() { try { player = Manager.createRealizedPlayer(MusicNames.get(index).toURI().toURL()); player.prefetch(); player.setMediaTime(new Time(0.0));// Start playing from a certain time period player.addControllerListener(this); l.setFont(new Font("Song",0,2, l.setText("Playing: "+this.MusicNames.get(index).toString()); //Display the currently playing song list.select(index); player.start(); Mythread11 tt=new Mythread11(); tt.start(); } catch (Exception e1) { //When a song cannot be played, deal with it 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(); } /** * MP3File filter inner class */ class MusicFileChooser extends JFileChooser { } /** * MP3File filter auxiliary inner class * */ class MyFileFilter extends FileFilter { //FileFilter is an abstract class, JFileChooser uses it to filter the set of files displayed to the user String[] suffarr; String description; public MyFileFilter() { super(); } public MyFileFilter(String[] suffarr, String description) { super(); this.suffarr = suffarr; this.description = description; } 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.description; } } /** * read and display the time progress bar */ 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("Current time: "+newtime/60+":"+newtime%60+" || "+" Total time: "+countSecond/60+":"+countSecond%60); } } } } } //thread for implementing lyrics 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 {1tp.setFont(new Font("宋体",2, 0)); tp.setForeground(Color.BLUE); StyledDocument doc = tp.getStyledDocument(); SimpleAttributeSet center = new SimpleAttributeSet(); //StyleConstants.setAlignment(center, StyleConstants.ALIGN_CENTER); Display the lyrics area doc.setParagraphAttributes(0, doc.getLength(), center, false); + tp.setText("Artist:") tp.setText("Artist:") + tp.setText("Album:") tp.setText("Song:") + tp.setText(ls.getTi()); tp.setText("Lyric Creation:") + ls.getBy()); for (Lyric l : ls.getLyrics()) { tp.setText(l.getTxt()); Thread.sleep(l.getTimeSize()); } } }
V. Overall Test Results
As follows
For more content about players, please click on 'Java Player Features' to learn.
That is all for this article, I hope it is helpful for your learning, and I also hope everyone will support the Yell Tutorial.