1. The implementation principle of music player
Javase's multimedia function is very weak, so there is a plug-in that specializes in multimedia called JMF. The models provided by JMF can be roughly divided into seven categories.
* Data source
* Capture Device (including video and audio interceptor)
* Player
* Processor
* DataSink
* Data format (Format)
* Manager
The music player MyMusicPlayer (this is the class name I created) I made calls to the Player class in JMF to implement various functions such as its playback.
The first thing we have to do is install JMF. I believe that the installation of JMF is very troublesome for many novices. JMF only supports 32-bit JDK version, but IDE environments like eclipse must correspond to JDK, that is, the IDE environment must support 32-bit JDK version. After installing JMF, sometimes the playback of MP3 is not successful, and you also need to install JMF's mp3plugin.
2. Interface effect diagram
3. Functional structure diagram
4. Various codes for implementing functions
public class MyMusicPlayer implements ActionListener, ControllerListener,Runnable{ JFrame j=new JFrame("Music Player"); JLabel TablePlaer=new JLabel("Playlist"); JButton BAdd=new JButton("Add song"); JButton BDelect=new JButton("Delete song"); JButton BDelectTable=new JButton("Clear list"); JButton BMoveNext=new JButton("Next song"); JButton BMovePrevious=new JButton("Previous song"); JButton BPlayer=new JButton("Pause"); JButton BStop=new JButton("Stop"); JButton BSet=new JButton("Show lyrics"); JButton BEnd=new JButton("Stop"); String[] s={"Sequential play","Single loop","Shutter play"}; //Drop down list option array 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 playlist JPanel p6=new JPanel(); //Place the name of the play song static JPanel pp=new JPanel(); static JLabel lb; public static JTextArea jt=new JTextArea(); static int index; //Subscript of the playlist int count; int flag; //Is the marker of the playlist playing randomly or sequentially playing 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; //Defend whether the mouse clicks on the cursor File MusicName = null; static java.util.List<File> MusicNames = null; //Use generics to create File object File currentDirectory = null; List list;//File list FileDialog open; //Define file dialog object Random rand = new Random(); String filename; //Progress bar JButton timeInformation = new JButton(); JSlider timeSlider = new JSlider(SwingConstants.HORIZONTAL, 0, 100, 0); //(SwingConstants.HORIZONTAL) is used to direct the set of constants with the progress bar as horizontal direction //(0, 100, 0) Create a horizontal slider with the specified minimum, maximum and initial values. // Play Player player = null; MusicFileChooser fileChooser = new MusicFileChooser(); static JTextPane tp=new JTextPane(); //Show lyric area static JTextArea are=new JTextArea(); //Show image area 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); //Set the displayed and played song p6.add(l); /*Implement image insertion* */ ImageIcon ic=new ImageIcon("image//2.3.jpg"); ic=new ImageIcon(ic.getImage().getScaledInstance(880, 477, 2)); //Get the picture and set the image size lb=new JLabel(ic); lb.setOpaque(false); pp.setOpaque(false); //Set to transparent 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); // File list = new List(10); list.setBounds(100, 55, 187, 495); // List area 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)); BDelect.setBounds(5, 140, 90, 30); BDelect.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); /* * Implementation progress bar* */ timeSlider.setMajorTickSpacing(1);//Call this method to set the interval of the main scale mark. The incoming number represents the distance measured by value between each main scale marker. 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 mouse clicks the cursor} public void mouseReleased(MouseEvent arg0) { ispressing = 0; //When the mouse does not click the cursor} }); timeInformation.setText("Current time: 00:00 || Total time: 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); } /* * Main function* */ public static void main(String[] args) throws IOException, InterruptedException { //InterruptedException: When the thread is in a waiting, sleeping or occupied state before or during the activity and the thread is interrupted, the exception is thrown. MyMusicPlayer play=new MyMusicPlayer(); Thread timeRun = new Thread(play); timeRun.start(); } @Override public void actionPerformed(ActionEvent e) { String cmd = e.getActionCommand(); //Judge whether to play or pause by getting the string, String box=(String)select.getSelectedItem(); //Judge the order of playback 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, which JFileChooser uses to filter the set of files displayed to the user File files[] = cd.listFiles(); //cd.listFiles() means returning an array of abstract pathnames, which represent files in the directory represented by this abstract pathname. this.MusicNames = new ArrayList<File>(); for (File file : files) { //Every time the file object in the array is assigned to the file variable, and then this variable is operated in 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 subscript 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 song if (player != null) { if("Sequal playback".equals(box)){ nextMusic(); } if("Shutter playback".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 you click on the previous song, the current song will be stopped and the previous song will be played try { player=Manager.createRealizedPlayer(MusicNames.get(index).toURI().toURL()); player.prefetch(); player.setMediaTime(new Time(0.0));// Play 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 song if (player != null) { if("Sequential Play".equals(box)){ PreviousMusic(); } if("Shutter 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 you click on the previous song, the current song will be stopped and the previous song will be played try { player=Manager.createRealizedPlayer(MusicNames.get(index).toURI().toURL()); player.prefetch(); player.setMediaTime(new Time(0.0));// Start playing 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 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; } //Double-click the list to be played list.addMouseListener(new MouseAdapter() { public void mouseClicked(MouseEvent e) { //Double-click if (e.getClickCount() == 2) { if(player!=null){ player.stop(); } // Play the selected file index=list.getSelectedIndex(); PlayFile(); } } });} // Because the "ControllerListener" interface is implemented, this method is used to handle events transmitted from the media player; public void controllerUpdate(ControllerEvent e) { String box=(String)select.getSelectedItem(); //Judge the order of playback if (e instanceof EndOfMediaEvent) { player.setMediaTime(new Time(0)); if ("Single Loop".equals(box)) { player.start(); } if("Sequential Play".equals(box)){ nextMusic(); } if("Shutter 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));// Play 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 the MP3 song name* * @MP3 file 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; } /** * Next implementation function*/ public void nextMusic() { } /** * Previous Implementation function*/ public void PreviousMusic() { } /** * Play MP3 file main function*/ public void PlayFile() { try { player = Manager.createRealizedPlayer(MusicNames.get(index).toURI().toURL()); player.prefetch(); player.setMediaTime(new Time(0.0));// Play player.addControllerListener(this); l.setFont(new Font("宋体",0,20)); l.setText("Playing: "+this.MusicNames.get(index).toString()); //Show the song being played list.select(index); player.start(); Mythread11 tt=new Mythread11(); tt.start(); } catch (Exception e1) { //When a music cannot be played, handle 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(); }/** * MP3 file filtering internal class*/class MusicFileChooser extends JFileChooser { }/** * MP3 file filtering auxiliary internal class* */class MyFileFilter extends FileFilter { //FileFilter is an abstract class, which JFileChooser uses to filter the file collection displayed to the user String[] suffarr; String description; public MyFileFilter() { super(); } public MyFileFilter(String[] suffarr, String description) { super(); this.suffarr = suffarr; this.descript = 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.dection; }}/** * Read display 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 that implements lyrics 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); //Show doc.setParagraphAttributes(0, doc.getLength(), center, false); tp.setText("Artist: " + ls.getAr()); tp.setText("Album: " + ls.getAl()); tp.setText("Song: " + ls.getTi()); tp.setText("Lyrics production:" + ls.getBy()); for (Lyric l : ls.getLyrics()) { tp.setText( l.getTxt()); Thread.sleep(l.getTimeSize()); }}}V. Overall test results
as follows
For more information about the player, please click "java player function" to learn.
The above is all the content of this article. I hope it will be helpful to everyone's learning and I hope everyone will support Wulin.com more.