ich programmiere zur Zeit einen mp3 player mit dem JLayer. Play,stop, previous und next gehen soweit.
Nur die pause geht nicht, JLayer bietet an sich keine Funktion dafür. Ich habe momentan keine Idee wie ich das umsetzen soll .
Hier mal meine Klassen:
package Projekt; import java.io.InputStream; import javazoom.jl.decoder.Bitstream; import javazoom.jl.decoder.BitstreamException; import javazoom.jl.decoder.Decoder; import javazoom.jl.decoder.Header; import javazoom.jl.decoder.JavaLayerException; import javazoom.jl.decoder.SampleBuffer; import javazoom.jl.player.AudioDevice; import javazoom.jl.player.FactoryRegistry; /** * a hybrid of javazoom.jl.player.Player tweeked to include <code>play(startFrame, endFrame)</code> * hopefully this will be included in the api */ public class AdvancedPlayer { /** The MPEG audio bitstream.*/ private Bitstream bitstream; /** The MPEG audio decoder. */ private Decoder decoder; /** The AudioDevice the audio samples are written to. */ private AudioDevice audio; /** Has the player been closed? */ private boolean closed = false; /** Has the player played back all frames from the stream? */ private boolean complete = false; private int lastPosition = 0; /** Listener for the playback process */ private PlaybackListener listener; /** * Creates a new <code>Player</code> instance. */ public AdvancedPlayer(InputStream stream) throws JavaLayerException { this(stream, null); } public AdvancedPlayer(InputStream stream, AudioDevice device) throws JavaLayerException { bitstream = new Bitstream(stream); if (device!=null) audio = device; else audio = FactoryRegistry.systemRegistry().createAudioDevice(); audio.open(decoder = new Decoder()); } public void play() throws JavaLayerException { play(Integer.MAX_VALUE); } /** * Plays a number of MPEG audio frames. * * @param frames The number of frames to play. * @return true if the last frame was played, or false if there are * more frames. */ public boolean playing=true; public boolean play(int frames) throws JavaLayerException { boolean ret = true; // report to listener if(listener != null) listener.playbackStarted(createEvent(PlaybackEvent.STARTED)); while (frames-- > 0 && ret) { if( playing ) { ret = decodeFrame(); } else { try { Thread.sleep( 10 ); } catch( Exception e ) { } } } if (!ret) { //last frame, ensure all data flushed to the audio device. AudioDevice out = audio; if (out != null) { System.out.println(audio.getPosition()); out.flush(); System.out.println(audio.getPosition()); synchronized (this) { complete = (!closed); close(); } // report to listener if(listener != null) listener.playbackFinished(createEvent(out, PlaybackEvent.STOPPED)); } } return ret; } /** * Cloases this player. Any audio currently playing is stopped * immediately. */ public synchronized void close() { AudioDevice out = audio; if (out != null) { closed = true; audio = null; // this may fail, so ensure object state is set up before // calling this method. out.close(); lastPosition = out.getPosition(); try { bitstream.close(); } catch (BitstreamException ex) {} } } /** * Decodes a single frame. * * @return true if there are no more frames to decode, false otherwise. */ protected boolean decodeFrame() throws JavaLayerException { try { AudioDevice out = audio; if (out == null) return false; Header h = bitstream.readFrame(); if (h == null) return false; // sample buffer set when decoder constructed SampleBuffer output = (SampleBuffer) decoder.decodeFrame(h, bitstream); synchronized (this) { out = audio; if(out != null) { out.write(output.getBuffer(), 0, output.getBufferLength()); } } bitstream.closeFrame(); } catch (RuntimeException ex) { throw new JavaLayerException("Exception decoding audio frame", ex); } return true; } /** * skips over a single frame * @return false if there are no more frames to decode, true otherwise. */ protected boolean skipFrame() throws JavaLayerException { Header h = bitstream.readFrame(); if (h == null) return false; bitstream.closeFrame(); return true; } /** * Plays a range of MPEG audio frames * @param start The first frame to play * @param end The last frame to play * @return true if the last frame was played, or false if there are more frames. */ public boolean play(final int start, final int end) throws JavaLayerException { boolean ret = true; int offset = start; while (offset-- > 0 && ret) ret = skipFrame(); return play(end - start); } /** * Constructs a <code>PlaybackEvent</code> */ private PlaybackEvent createEvent(int id) { return createEvent(audio, id); } /** * Constructs a <code>PlaybackEvent</code> */ private PlaybackEvent createEvent(AudioDevice dev, int id) { return new PlaybackEvent(this, id, dev.getPosition()); } /** * sets the <code>PlaybackListener</code> */ public void setPlayBackListener(PlaybackListener listener) { this.listener = listener; } /** * gets the <code>PlaybackListener</code> */ public PlaybackListener getPlayBackListener() { return listener; } /** * closes the player and notifies <code>PlaybackListener</code> */ public void stop() { listener.playbackFinished(createEvent(PlaybackEvent.STOPPED)); close(); } public synchronized boolean isComplete() { return complete; } public int getPosition() { int position = lastPosition; AudioDevice out = audio; if (out!=null) { position = out.getPosition(); } return position; } public void pause() { playing=false; } public void weiter() { playing=true; } }
package Projekt; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Container; import java.awt.Dimension; import java.awt.Event; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.File; import java.util.ArrayList; import javax.swing.Icon; import javax.swing.ImageIcon; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JMenu; import javax.swing.JMenuBar; import javax.swing.JMenuItem; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTable; import javax.swing.KeyStroke; import javax.swing.table.AbstractTableModel; public class GUI extends JFrame implements ActionListener{ private static final long serialVersionUID = -5816282027776591160L; private final static String PLAY = "play"; private final static String STOP = "stop"; private final static String PAUSE = "pause"; private final static String PRE = "pre"; private final static String NEXT = "next"; private final static String OPEN = "open"; private final static String ABOUT = "about"; private final static String EXIT = "exit"; private final static String CLEAR = "clear playlist"; //Panel private JPanel norden; private JPanel center; private JPanel süden; private static JTable table; private PlayList playList = new PlayList(); private Mp3Filechooser filechooser; public GUI () { //Fenster super("Mp3 Player by Johannes Riemer & Daniel Schlegel"); filechooser = new Mp3Filechooser(this); //Veränderung der Groeße und das Ziehen des Fensters verhindern super.setResizable(false); pack(); //Fenstergroeße this.setSize(500, 580); Container contentPane = this.getContentPane(); contentPane.setLayout(new BorderLayout()); //Panel erzeugen norden = new JPanel(); center = new JPanel(); süden = new JPanel(); //Scrollbar erstellen final JScrollPane JScrollPane = null; this.machTableModel(); JScrollPane scrollbar = new JScrollPane(table); scrollbar.getViewport().setBackground(Color.WHITE); center.add(scrollbar); //Gridlines vom JTable ausblenden table.setShowGrid(false); //Back Button mit icon und listener zum abhören Icon backicon = new ImageIcon("src/Projekt/skip-backward-icon.png"); JButton back = new JButton(backicon); back.setActionCommand(PRE); back.addActionListener(this); //Forward Button mit icon und listener zum abhören Icon forwardeicon = new ImageIcon("src/Projekt/skip-forward-icon.png"); JButton forward = new JButton(forwardeicon); forward.setActionCommand(NEXT); forward.addActionListener(this); //Stop Button mit icon und listener zum abhören Icon stopicon = new ImageIcon("src/Projekt/stop-icon.png"); JButton stop = new JButton(stopicon); stop.setActionCommand(STOP); stop.addActionListener(this); //Pause Button mit icon und listener zum abhören Icon pauseicon = new ImageIcon("src/Projekt/pause-icon.png"); JButton pause = new JButton(pauseicon); pause.setActionCommand(PAUSE); pause.addActionListener(this); //Play Button mit icon und listener zum abhören Icon playicon = new ImageIcon("src/Projekt/play-icon.png"); JButton play = new JButton(playicon); play.setActionCommand(PLAY); play.addActionListener(this); //Groeße der Buttons festlegen play.setPreferredSize(new Dimension(70,70)); pause.setPreferredSize(new Dimension(70,70)); stop.setPreferredSize(new Dimension(70,70)); forward.setPreferredSize(new Dimension(70,70)); back.setPreferredSize(new Dimension(70,70)); //Buttons faerben play.setBackground(new Color(255, 255, 255)); pause.setBackground(new Color(255, 255, 255)); stop.setBackground(new Color(255, 255, 255)); forward.setBackground(new Color(255, 255, 255)); back.setBackground(new Color(255, 255, 255)); //Buttons auf Panel packen süden.add(back); süden.add(pause); süden.add(play); süden.add(stop); süden.add(forward); //Panel hinzufuegen contentPane.add(norden, BorderLayout.NORTH); contentPane.add(center, BorderLayout.CENTER); contentPane.add(süden, BorderLayout.SOUTH); //Menueitems erstellen JMenuItem Data_open = new JMenuItem( "Open" ); JMenuItem Data_close = new JMenuItem( "Close" ); JMenuItem Info_about = new JMenuItem( "About" ); JMenuItem Data_Clear_Playlist = new JMenuItem( "Clear Playlist" ); //Menue erstellen, aktion wenn Mauszeiger drueber gehalten wird JMenu m_Data = new JMenu( "Data" ); m_Data.setToolTipText( "Open files or close programm " ); JMenu m_Info = new JMenu( "Info" ); m_Info.setToolTipText( "about this programm" ); //Tool tipps bei Buttons play.setToolTipText("play this track"); stop.setToolTipText("stop this track"); pause.setToolTipText("pause this track"); back.setToolTipText("skip backward"); forward.setToolTipText("skip forward"); //Menueitems hinzufuegen m_Data.add( Data_open ); m_Data.add( Data_close ); m_Data.add( Data_Clear_Playlist); m_Info.add( Info_about ); //Aktionen beim druecken von items, Actionlistener und Tastenkombinationen Data_close.setActionCommand(EXIT); Data_close.addActionListener( this ); Data_close.setAccelerator(KeyStroke.getKeyStroke('C', Event.ALT_MASK)); Data_open.setActionCommand(OPEN); Data_open.addActionListener( this ); Data_open.setAccelerator(KeyStroke.getKeyStroke('O', Event.CTRL_MASK)); Info_about.setActionCommand(ABOUT); Info_about.addActionListener( this ); Info_about.setAccelerator(KeyStroke.getKeyStroke('A', Event.ALT_MASK)); Data_Clear_Playlist.setActionCommand(CLEAR); Data_Clear_Playlist.addActionListener(this); Data_Clear_Playlist.setAccelerator(KeyStroke.getKeyStroke('D', Event.ALT_MASK)); //Menue hinzufuegen JMenuBar Menueleiste = new JMenuBar(); //Menueleisten erstellen Menueleiste.add( m_Data ); Menueleiste.add( m_Info ); //Menueleiste dem Frame hinzufuegen setJMenuBar( Menueleiste ); //Farben Color[] colors = { Color.WHITE, }; //Menueleisten und Untermenues faerben süden.setBackground(colors[0]); center.setBackground(colors[0]); norden.setBackground(colors[0]); Menueleiste.setBackground(colors[0]); Data_close.setBackground(colors[0]); Info_about.setBackground(colors[0]); Data_open.setBackground(colors[0]); Data_Clear_Playlist.setBackground(colors[0]); //Standardaktion bei schließen des Programms setDefaultCloseOperation(EXIT_ON_CLOSE); } // Action Perfomed Mehtode public void actionPerformed(ActionEvent event) { //Umwandlung eines String in ein event String kommando = event.getActionCommand(); if ( kommando.equals(EXIT)) { //Schließt das Programm und gibt den Speicher frei System.exit( 0 ); } else if (kommando.equals(CLEAR)) { }else if ( kommando.equals(OPEN)) { /**Zugriff auf FileChooser und Erstellen eines Arrays * Die selektierten Files werden auf die Playlist * übertragen */ ArrayList<File> openFiels = filechooser.getFiles(); for (int i = 0; i < openFiels.size(); i++) { playList.addToList(openFiels.get(i)); System.out.println("add:" + openFiels.get(i)); } // int current = playList.getCurrent(); table.setRowSelectionInterval(current, current); this.table.updateUI(); } else if ( kommando.equals(ABOUT)) { //About als Info Fenster mit Textinhalt JOptionPane.showMessageDialog(this, " This programm is a semesterproject \n" + " designed by Johannes R. & Daniel S. \n \n "+ " ---Only MP3 files are supported--- ", "About", JOptionPane.INFORMATION_MESSAGE); // Hier finden die Events beim druecken der Buttons statt } else if (kommando.equals(PLAY)) { System.out.println("PLAY!!"); playList.play(); } else if (kommando.equals(PAUSE)) { playList.pause(); } else if (kommando.equals(STOP)) { playList.stop(); } else if (kommando.equals(PRE)) { int newCurrent = playList.pre(); if (newCurrent != PlayList.NOTRACK) { table.setRowSelectionInterval(newCurrent, newCurrent); } } else if (kommando.equals(NEXT)) { int newCurrent = playList.next(); if (newCurrent != PlayList.NOTRACK) { table.setRowSelectionInterval(newCurrent, newCurrent); } } } public void removeColumnAndData(JTable table, int vColIndex) { } /** * Display wird als JTable angezeigt * Hier finden keine Verarbeitungen sowie aktualisierungen der Playliste statt * Die Verarbeitung übernimmt die Klasse Playlist selbst * Das JTable dient nur als Optische Darstellung */ private void machTableModel() { table = new JTable(new AbstractTableModel() { private static final long serialVersionUID = 4079392991855412983L; @Override public Object getValueAt(int rowIndex, int columnIndex) { return playList.getList().get(rowIndex).getName(); } @Override public int getRowCount() { return playList.getList().size(); } @Override public int getColumnCount() { return 1; } @Override public String getColumnName(int columnIndex) { return "Playlist"; } }); } public static void main(String[] args) { GUI mainFrame = new GUI(); mainFrame.setVisible(true); } }
package Projekt; import java.io.File; import java.security.InvalidParameterException; import java.util.ArrayList; import javax.swing.JFileChooser; import javax.swing.JFrame; import javax.swing.filechooser.FileFilter; import javax.swing.filechooser.FileNameExtensionFilter; public class Mp3Filechooser extends JFileChooser { private JFrame callingFrame = null; private static final long serialVersionUID = -5816282027776591160L; private File currentDirectory; public Mp3Filechooser(JFrame frame) { //Fenster erzeugen super(); callingFrame = frame; //Filter einbauen für Dateiendung mp3 FileFilter filter = new FileNameExtensionFilter("mp3", "mp3"); //Filter hinzufügen this.addChoosableFileFilter(filter); //Auswahl von Dateien und directorys this.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES); this.setMultiSelectionEnabled(true); } /** * Gibt die ausgewaehlten Daten zurueck * * @return ausgewaehlte Dateien, wenn auf Abbruch gedrueckt wird, gehe zurueck zur leeren Liste. */ public ArrayList<File> getFiles() { if (currentDirectory != null && currentDirectory.isDirectory()) { this.setCurrentDirectory(currentDirectory); } int result = this.showOpenDialog(callingFrame); File[] selectedFiles = null; ArrayList<File> list = new ArrayList<File>(); /** * Hier werden nur die Dateien beruecksichtigt, nicht die Pfade * Wenn ausgewaehlte Dateien geoeffnet werden * füge sie einer Liste hinzu * Bei Abbruch, tue nichts * * @return ausgabe der Liste */ if (result == JFileChooser.OPEN_DIALOG) { selectedFiles = this.getSelectedFiles(); for (int i = 0; i < selectedFiles.length; i++) { if (selectedFiles[i].isDirectory()) { addToList(list, selectedFiles[i]); } else { if (isValidFile(selectedFiles[i])) { list.add(selectedFiles[i]); } } } } else if (result == JFileChooser.CANCEL_OPTION) { //tue nichts } currentDirectory = this.getCurrentDirectory(); return list; } /** * Hier wird der Pfad beruecksichtigt, nicht Dateien * @param liste * @param Pfad */ private void addToList(ArrayList<File> list, File directory) { if (!directory.isDirectory()) { throw new InvalidParameterException("File is not a directory."); } File[] files = directory.listFiles(); for (int i = 0; i < files.length; i++) { if (files[i].isDirectory()) { addToList(list, files[i]); } else { if (isValidFile(files[i])) { list.add(files[i]); } } } } /** * Ueberprüfe ob Dateiendung .mp3 ist * @param zu ueberprüfende Datei * @return Ausgabe bei true und false */ private boolean isValidFile(File file) { if (file.getName().endsWith(".mp3")) { return true; } return false; } }
package Projekt; import java.io.File; import java.io.FileInputStream; import java.util.ArrayList; import javazoom.jl.decoder.JavaLayerException; public class PlayList implements Runnable{ public static final int NOTRACK = -1; private ArrayList<File> liste = new ArrayList<File>(); private AdvancedPlayer player; private int current = NOTRACK; private int next = NOTRACK; private int pre = NOTRACK; public boolean playing=true; private State state = State.STOP; Thread thread = null; public int getCurrent() { return current; } public void addToList(File track) { if (liste.isEmpty()) { current = 0; } liste.add(track); setNext(); setPre(); System.out.println("addToList:"); System.out.println("pre: " + pre); System.out.println("current: " + current); System.out.println("next: " + next); } private void setNext() { if (current == NOTRACK) { next = NOTRACK; } else { if (current + 1 >= liste.size()) { next = 0; } else { next = current + 1; } } System.out.println("setNext:" + next); } private void setPre() { if (current == NOTRACK) { pre = NOTRACK; } else { if (current - 1 < 0) { pre = liste.size() - 1; } else { pre = current - 1; } } System.out.println("setPre:" + pre); } public void deleteFromList(File toDelete) { // @ToDo this.stop(); liste.remove(toDelete); if (liste.isEmpty()) { current = NOTRACK; pre = NOTRACK; next = NOTRACK; } else { if (current > liste.size() - 1) { current = liste.size() - 1; } setNext(); setPre(); } System.out.println("delete:"); System.out.println("pre: " + pre); System.out.println("current: " + current); System.out.println("next: " + next); } public ArrayList<File> getList() { return liste; } //Spielt den ausgewählten track ab public int play() { if (current == NOTRACK) { return NOTRACK; } try { player = new AdvancedPlayer(new FileInputStream(liste.get(current))); } catch (Exception e) { e.printStackTrace(); } // run in new thread to play in background new Thread() { public void run() { try {player.play(); } catch (Exception e) { System.out.println(e); } } }.start(); state = state.PLAY; return current; } public void stop() { player.close(); state = state.STOP; } public void pause() { //player.close(); state = state.PAUSED; player.pause(); } public int next() { boolean play = state.equals(state.PLAY); stop(); current = next; setNext(); setPre(); if (play) { play(); } return current; } public int pre() { boolean play = state.equals(state.PLAY); stop(); current = pre; setNext(); setPre(); if (play) { play(); } return current; } @Override public void run() { try { player.play(); } catch (JavaLayerException e) { e.printStackTrace(); } } }
Dieser Beitrag wurde von Witi bearbeitet: 12. November 2011 - 18:01
Änderungsgrund: codebox-Tag eingesetzt