教你輕松制作java音樂播放器
一、音樂播放器的實現(xiàn)原理
Javase的多媒體功能很弱,所以有一個專門處理多媒體的插件叫JMF,JMF提供的模型可大致分為七類
* 數(shù)據(jù)源(Data source)
* 截取設備(Capture Device,包括視頻和音頻截取設備)
* 播放器(Player)
* 處理器(Processor)
* 數(shù)據(jù)池(DataSink)
* 數(shù)據(jù)格式(Format)
* 管理器(Manager)
而我所做的這個音樂播放器MyMusicPlayer(這是我創(chuàng)建的類名)正是調用了JMF中的Player類來實現(xiàn)其播放等各種功能.
我們首先要做的就是要安裝JMF。JMF的安裝,相信對于許多的新手來說是很傷腦筋的,JMF只支持32位的JDK版本,然而像eclipse這樣的IDE環(huán)境要與JDK對應,也就是IDE環(huán)境要支持32位JDK版本。當安裝完JMF之后,有時候對于MP3的播放并不成功,還需要裝JMF的mp3plugin。
二、界面效果圖
三、功能結構圖
四、各種實現(xiàn)功能的代碼
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={"順序播放","單曲循環(huán)","隨機播放"}; //下拉列表選項數(shù)組 JComboBox select=new JComboBox(s); //創(chuàng)建下拉選項 JPanel p1=new JPanel(); //播放列表區(qū)域 JPanel p=new JPanel(); JPanel p2=new JPanel(); //按鈕區(qū)域 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; //運用泛型,創(chuàng)建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)用指定的最小值、最大值和初始值創(chuàng)建一個水平滑塊。 // 播放 Player player = null; MusicFileChooser fileChooser = new MusicFileChooser(); static JTextPane tp=new JTextPane(); //顯示歌詞區(qū)域 static JTextArea are=new JTextArea(); //顯示圖片區(qū)域 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); /*實現(xiàn)圖片插入 * */ 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); //列表區(qū)域 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); /* * 實現(xiàn)進度條 * */ timeSlider.setMajorTickSpacing(1);//調用此方法設置主刻度標記的間隔。傳入的數(shù)字表示在每個主刻度標記之間以值衡量的距離。 timeSlider.setPaintTicks(true); //要繪制主刻度,setPaintTicks 必須設置為 true timeSlider.addChangeListener(new ChangeListener() { //創(chuàng)建一個新的 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); } /* * 主函數(shù) * */ public static void main(String[] args) throws IOException, InterruptedException { //InterruptedException:當線程在活動之前或活動期間處于正在等待、休眠或占用狀態(tài)且該線程被中斷時,拋出該異常 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()表示返回一個抽象路徑名數(shù)組,這些路徑名表示此抽象路徑名表示的目錄中的文件。 this.MusicNames = new ArrayList<File>(); for (File file : files) { //每次循環(huán)都將數(shù)組中的文件對象賦給file這個變量,然后再在循環(huán)體中對這個變量進行操作如: //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; } //雙擊列表時實現(xiàn)播放 list.addMouseListener(new MouseAdapter() { public void mouseClicked(MouseEvent e) { // 雙擊時處理 if (e.getClickCount() == 2) { if(player!=null){ player.stop(); } // 播放選中的文件 index=list.getSelectedIndex(); PlayFile(); } } }); } // 因為實現(xiàn)了"ControllerListener"接口,本方法用于處理媒體播放器傳來的事件; public void controllerUpdate(ControllerEvent e) { String box=(String)select.getSelectedItem(); //判斷播放的順序 if (e instanceof EndOfMediaEvent) { player.setMediaTime(new Time(0)); if ("單曲循環(huán)".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; } /** * 下一首 實現(xiàn)函數(shù) */ public void nextMusic() { } /** * 上一首實現(xiàn)函數(shù) */ public void PreviousMusic() { } /** * 播放MP3文件主函數(shù) */ 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); } } } } } //實現(xiàn)歌詞的線程 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); //將歌詞區(qū)中顯示 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播放器功能》進行學習。
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
相關文章
基于ScheduledExecutorService的兩種方法(詳解)
下面小編就為大家?guī)硪黄赟cheduledExecutorService的兩種方法(詳解)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-10-10java、js中實現(xiàn)無限層級的樹形結構方法(類似遞歸)
下面小編就為大家?guī)硪黄猨ava、js中實現(xiàn)無限層級的樹形結構方法(類似遞歸)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2016-11-11SpringBoot使用Spring Security實現(xiàn)登錄注銷功能
這篇文章主要介紹了SpringBoot使用Spring Security實現(xiàn)登錄注銷功能,本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友參考下吧2020-09-09對java for 循環(huán)執(zhí)行順序的詳解
今天小編就為大家分享一篇對java for 循環(huán)執(zhí)行順序的詳解,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-06-06springsecurity輕松實現(xiàn)角色權限的示例代碼
這篇文章主要介紹了springsecurity輕松實現(xiàn)角色權限的示例代碼,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2020-03-03