English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
本文
一、音楽プレーヤーの実現原理
* Javaseのマルチメディア機能は弱いため、マルチメディアを専門に処理するプラグインJMFがあります。JMFが提供するモデルは主に七種類に分類できます
* データソース(Data source)
* キャプチャーデバイス(キャプチャーデバイス、ビデオおよびオーディオキャプチャーデバイスを含む)
* プレイヤー(Player)
* プロセッサー(Processor)
* データプール(DataSink)
* データフォーマット(Format)
マネージャー(Manager)
私が作成したこの音楽プレーヤーMyMusicPlayer(これは私が作成したクラス名です)は、JMFのPlayerクラスを呼び出して再生などの機能を実現しています。32のJDKバージョンが必要ですが、EclipseなどのIDE環境はJDKに対応する必要があり、つまりIDE環境は32のJDKバージョンが必要です。JMFをインストールした後、時にはMP3の再生は成功しませんでした。JMFのmp3プラグイン。
二、インターフェース效果图
三、機能構造図
四、各種機能の実現コード
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(); } } } } } /** * MPを取得3曲名 * * @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 自动-生成方法存根 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 自动-生成方法存根 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()); } } }
5. 全体的なテスト結果
以下
プレイヤーの詳細について学ぶには、『java プレイヤー機能』をクリックしてください。
これでこの記事のすべての内容が終わります。皆さんの学習に役立つことを願っています。また、ナイアラートゥートゥーンモノのサポートを多くお願いします。