Java tutorial
/* * PlayerUI. * * JavaZOOM : jlgui@javazoom.net * http://www.javazoom.net * *----------------------------------------------------------------------- * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as published * by the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *---------------------------------------------------------------------- */ package javazoom.jlgui.player.amp; import java.awt.dnd.DnDConstants; import java.awt.dnd.DropTarget; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.KeyEvent; import java.awt.event.MouseEvent; import java.io.File; import java.io.InputStream; import java.net.MalformedURLException; import java.net.URL; import java.text.MessageFormat; import java.util.ArrayList; import java.util.List; import java.util.ListIterator; import java.util.Map; import java.util.StringTokenizer; import javax.sound.sampled.SourceDataLine; import javax.swing.JCheckBoxMenuItem; import javax.swing.JMenu; import javax.swing.JMenuItem; import javax.swing.JPanel; import javax.swing.JPopupMenu; import javax.swing.KeyStroke; import javax.swing.SwingUtilities; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; import javazoom.jlgui.basicplayer.BasicController; import javazoom.jlgui.basicplayer.BasicPlayer; import javazoom.jlgui.basicplayer.BasicPlayerEvent; import javazoom.jlgui.basicplayer.BasicPlayerException; import javazoom.jlgui.basicplayer.BasicPlayerListener; import javazoom.jlgui.player.amp.equalizer.ui.EqualizerUI; import javazoom.jlgui.player.amp.playlist.Playlist; import javazoom.jlgui.player.amp.playlist.PlaylistFactory; import javazoom.jlgui.player.amp.playlist.PlaylistItem; import javazoom.jlgui.player.amp.playlist.ui.PlaylistUI; import javazoom.jlgui.player.amp.skin.AbsoluteLayout; import javazoom.jlgui.player.amp.skin.DropTargetAdapter; import javazoom.jlgui.player.amp.skin.ImageBorder; import javazoom.jlgui.player.amp.skin.PopupAdapter; import javazoom.jlgui.player.amp.skin.Skin; import javazoom.jlgui.player.amp.skin.UrlDialog; import javazoom.jlgui.player.amp.tag.ui.TagSearch; import javazoom.jlgui.player.amp.util.Config; import javazoom.jlgui.player.amp.util.FileSelector; import javazoom.jlgui.player.amp.util.ui.Preferences; import javazoom.jlgui.player.amp.visual.ui.SpectrumTimeAnalyzer; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; public class PlayerUI extends JPanel implements ActionListener, ChangeListener, BasicPlayerListener { private static Log log = LogFactory.getLog(PlayerUI.class); public static final int INIT = 0; public static final int OPEN = 1; public static final int PLAY = 2; public static final int PAUSE = 3; public static final int STOP = 4; public static final int TEXT_LENGTH_MAX = 30; public static final long SCROLL_PERIOD = 250; private Skin ui = null; private Loader loader = null; private Config config = null; /*-- Pop up menus --*/ private JPopupMenu mainpopup = null; private JPopupMenu ejectpopup = null; private JCheckBoxMenuItem miPlaylist = null; private JCheckBoxMenuItem miEqualizer = null; private JMenuItem miPlayFile = null; private JMenuItem miPlayLocation = null; private PopupAdapter popupAdapter = null; private PopupAdapter ejectpopupAdapter = null; /*-- Sound player --*/ private BasicController theSoundPlayer = null; private Map audioInfo = null; private int playerState = INIT; /*-- Title text --*/ private String titleText = Skin.TITLETEXT.toUpperCase(); private String currentTitle = Skin.TITLETEXT.toUpperCase(); private String[] titleScrollLabel = null; private int scrollIndex = 0; private long lastScrollTime = 0L; private boolean scrollRight = true; private long secondsAmount = 0; /*-- Playlist --*/ private Playlist playlist = null; private PlaylistUI playlistUI = null; private String currentFileOrURL = null; private String currentSongName = null; private PlaylistItem currentPlaylistItem = null; private boolean currentIsFile; /*-- PosBar members --*/ private boolean posValueJump = false; private boolean posDragging = false; private double posValue = 0.0; /*-- EqualizerUI --*/ private EqualizerUI equalizerUI = null; public PlayerUI() { super(); setDoubleBuffered(true); ui = new Skin(); } public void setEqualizerUI(EqualizerUI eq) { equalizerUI = eq; } public EqualizerUI getEqualizerUI() { return equalizerUI; } public PlaylistUI getPlaylistUI() { return playlistUI; } public void setPlaylistUI(PlaylistUI playlistUI) { this.playlistUI = playlistUI; } public Playlist getPlaylist() { return playlist; } /** * Return config. * @return */ public Config getConfig() { return config; } /** * Return skin. * @return */ public Skin getSkin() { return ui; } /** * Return parent loader. * @return */ public Loader getLoader() { return loader; } /** * A handle to the BasicPlayer, plugins may control the player through * the controller (play, stop, ...) * @param controller */ public void setController(BasicController controller) { theSoundPlayer = controller; } /** * Return player controller. * @return */ public BasicController getController() { return theSoundPlayer; } /** * Load main player. * @param loader */ public void loadUI(Loader loader) { this.loader = loader; setLayout(new AbsoluteLayout()); config = Config.getInstance(); ui.setConfig(config); playlistUI = new PlaylistUI(); playlistUI.setSkin(ui); playlistUI.setPlayer(this); equalizerUI = new EqualizerUI(); equalizerUI.setSkin(ui); loadSkin(); // DnD support. DropTargetAdapter dnd = new DropTargetAdapter() { public void processDrop(Object data) { processDnD(data); } }; DropTarget dt = new DropTarget(this, DnDConstants.ACTION_COPY, dnd, true); } public void loadSkin() { log.info("Load PlayerUI (EDT=" + SwingUtilities.isEventDispatchThread() + ")"); removeAll(); // Load skin specified in args if (ui.getPath() != null) { log.info("Load default skin from " + ui.getPath()); ui.loadSkin(ui.getPath()); config.setDefaultSkin(ui.getPath()); } // Load skin specified in jlgui.ini else if ((config.getDefaultSkin() != null) && (!config.getDefaultSkin().trim().equals(""))) { log.info("Load default skin from " + config.getDefaultSkin()); ui.loadSkin(config.getDefaultSkin()); } // Default included skin else { ClassLoader cl = getClass().getClassLoader(); InputStream sis = cl.getResourceAsStream("javazoom/jlgui/player/amp/metrix.wsz"); log.info("Load default skin for JAR"); ui.loadSkin(sis); } // Background ImageBorder border = new ImageBorder(); border.setImage(ui.getMainImage()); setBorder(border); // Buttons add(ui.getAcPrevious(), ui.getAcPrevious().getConstraints()); ui.getAcPrevious().removeActionListener(this); ui.getAcPrevious().addActionListener(this); add(ui.getAcPlay(), ui.getAcPlay().getConstraints()); ui.getAcPlay().removeActionListener(this); ui.getAcPlay().addActionListener(this); add(ui.getAcPause(), ui.getAcPause().getConstraints()); ui.getAcPause().removeActionListener(this); ui.getAcPause().addActionListener(this); add(ui.getAcStop(), ui.getAcStop().getConstraints()); ui.getAcStop().removeActionListener(this); ui.getAcStop().addActionListener(this); add(ui.getAcNext(), ui.getAcNext().getConstraints()); ui.getAcNext().removeActionListener(this); ui.getAcNext().addActionListener(this); add(ui.getAcEject(), ui.getAcEject().getConstraints()); ui.getAcEject().removeActionListener(this); ui.getAcEject().addActionListener(this); // EqualizerUI toggle add(ui.getAcEqualizer(), ui.getAcEqualizer().getConstraints()); ui.getAcEqualizer().removeActionListener(this); ui.getAcEqualizer().addActionListener(this); // Playlist toggle add(ui.getAcPlaylist(), ui.getAcPlaylist().getConstraints()); ui.getAcPlaylist().removeActionListener(this); ui.getAcPlaylist().addActionListener(this); // Shuffle toggle add(ui.getAcShuffle(), ui.getAcShuffle().getConstraints()); ui.getAcShuffle().removeActionListener(this); ui.getAcShuffle().addActionListener(this); // Repeat toggle add(ui.getAcRepeat(), ui.getAcRepeat().getConstraints()); ui.getAcRepeat().removeActionListener(this); ui.getAcRepeat().addActionListener(this); // Volume add(ui.getAcVolume(), ui.getAcVolume().getConstraints()); ui.getAcVolume().removeChangeListener(this); ui.getAcVolume().addChangeListener(this); // Balance add(ui.getAcBalance(), ui.getAcBalance().getConstraints()); ui.getAcBalance().removeChangeListener(this); ui.getAcBalance().addChangeListener(this); // Seek bar add(ui.getAcPosBar(), ui.getAcPosBar().getConstraints()); ui.getAcPosBar().removeChangeListener(this); ui.getAcPosBar().addChangeListener(this); // Mono add(ui.getAcMonoIcon(), ui.getAcMonoIcon().getConstraints()); // Stereo add(ui.getAcStereoIcon(), ui.getAcStereoIcon().getConstraints()); // Title label add(ui.getAcTitleLabel(), ui.getAcTitleLabel().getConstraints()); // Sample rate label add(ui.getAcSampleRateLabel(), ui.getAcSampleRateLabel().getConstraints()); // Bit rate label add(ui.getAcBitRateLabel(), ui.getAcBitRateLabel().getConstraints()); // Play icon add(ui.getAcPlayIcon(), ui.getAcPlayIcon().getConstraints()); // Time icon add(ui.getAcTimeIcon(), ui.getAcTimeIcon().getConstraints()); // MinuteH number add(ui.getAcMinuteH(), ui.getAcMinuteH().getConstraints()); // MinuteL number add(ui.getAcMinuteL(), ui.getAcMinuteL().getConstraints()); // SecondH number add(ui.getAcSecondH(), ui.getAcSecondH().getConstraints()); // SecondL number add(ui.getAcSecondL(), ui.getAcSecondL().getConstraints()); // TitleBar add(ui.getAcTitleBar(), ui.getAcTitleBar().getConstraints()); add(ui.getAcMinimize(), ui.getAcMinimize().getConstraints()); ui.getAcMinimize().removeActionListener(this); ui.getAcMinimize().addActionListener(this); add(ui.getAcExit(), ui.getAcExit().getConstraints()); ui.getAcExit().removeActionListener(this); ui.getAcExit().addActionListener(this); // DSP if (ui.getAcAnalyzer() != null) { add(ui.getAcAnalyzer(), ui.getAcAnalyzer().getConstraints()); } // Popup menu mainpopup = new JPopupMenu(ui.getResource("popup.title")); JMenuItem mi = new JMenuItem(Skin.TITLETEXT + "- JavaZOOM"); //mi.removeActionListener(this); //mi.addActionListener(this); mainpopup.add(mi); mainpopup.addSeparator(); JMenu playSubMenu = new JMenu(ui.getResource("popup.play")); miPlayFile = new JMenuItem(ui.getResource("popup.play.file")); miPlayFile.setActionCommand(PlayerActionEvent.MIPLAYFILE); miPlayFile.removeActionListener(this); miPlayFile.addActionListener(this); miPlayLocation = new JMenuItem(ui.getResource("popup.play.location")); miPlayLocation.setActionCommand(PlayerActionEvent.MIPLAYLOCATION); miPlayLocation.removeActionListener(this); miPlayLocation.addActionListener(this); playSubMenu.add(miPlayFile); playSubMenu.add(miPlayLocation); mainpopup.add(playSubMenu); mainpopup.addSeparator(); miPlaylist = new JCheckBoxMenuItem(ui.getResource("popup.playlist")); miPlaylist.setActionCommand(PlayerActionEvent.MIPLAYLIST); if (config.isPlaylistEnabled()) miPlaylist.setState(true); miPlaylist.removeActionListener(this); miPlaylist.addActionListener(this); mainpopup.add(miPlaylist); miEqualizer = new JCheckBoxMenuItem(ui.getResource("popup.equalizer")); miEqualizer.setActionCommand(PlayerActionEvent.MIEQUALIZER); if (config.isEqualizerEnabled()) miEqualizer.setState(true); miEqualizer.removeActionListener(this); miEqualizer.addActionListener(this); mainpopup.add(miEqualizer); mainpopup.addSeparator(); mi = new JMenuItem(ui.getResource("popup.preferences")); mi.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_P, ActionEvent.CTRL_MASK, false)); mi.setActionCommand(PlayerActionEvent.MIPREFERENCES); mi.removeActionListener(this); mi.addActionListener(this); mainpopup.add(mi); JMenu skinsSubMenu = new JMenu(ui.getResource("popup.skins")); mi = new JMenuItem(ui.getResource("popup.skins.browser")); mi.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_S, ActionEvent.ALT_MASK, false)); mi.setActionCommand(PlayerActionEvent.MISKINBROWSER); mi.removeActionListener(this); mi.addActionListener(this); skinsSubMenu.add(mi); mi = new JMenuItem(ui.getResource("popup.skins.load")); mi.setActionCommand(PlayerActionEvent.MILOADSKIN); mi.removeActionListener(this); mi.addActionListener(this); skinsSubMenu.add(mi); mainpopup.add(skinsSubMenu); JMenu playbackSubMenu = new JMenu(ui.getResource("popup.playback")); mi = new JMenuItem(ui.getResource("popup.playback.jump")); mi.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_J, 0, false)); mi.setActionCommand(PlayerActionEvent.MIJUMPFILE); mi.removeActionListener(this); mi.addActionListener(this); playbackSubMenu.add(mi); mi = new JMenuItem(ui.getResource("popup.playback.stop")); mi.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_V, 0, false)); mi.setActionCommand(PlayerActionEvent.MISTOP); mi.removeActionListener(this); mi.addActionListener(this); playbackSubMenu.add(mi); mainpopup.add(playbackSubMenu); mainpopup.addSeparator(); mi = new JMenuItem(ui.getResource("popup.exit")); mi.setActionCommand(PlayerActionEvent.ACEXIT); mi.removeActionListener(this); mi.addActionListener(this); mainpopup.add(mi); // Popup menu on TitleBar ui.getAcTitleBar().removeMouseListener(popupAdapter); popupAdapter = new PopupAdapter(mainpopup); ui.getAcTitleBar().addMouseListener(popupAdapter); // Popup menu on Eject button ejectpopup = new JPopupMenu(); mi = new JMenuItem(ui.getResource("popup.eject.openfile")); mi.setActionCommand(PlayerActionEvent.MIPLAYFILE); mi.removeActionListener(this); mi.addActionListener(this); ejectpopup.add(mi); mi = new JMenuItem(ui.getResource("popup.eject.openlocation")); mi.setActionCommand(PlayerActionEvent.MIPLAYLOCATION); mi.removeActionListener(this); mi.addActionListener(this); ejectpopup.add(mi); ui.getAcEject().removeMouseListener(ejectpopupAdapter); ejectpopupAdapter = new PopupAdapter(ejectpopup); ui.getAcEject().addMouseListener(ejectpopupAdapter); // EqualizerUI if (equalizerUI != null) equalizerUI.loadUI(); if (playlistUI != null) playlistUI.loadUI(); validate(); loader.loaded(); } /** * Load playlist. * @param playlistName * @return */ public boolean loadPlaylist(String playlistName) { boolean loaded = false; PlaylistFactory plf = PlaylistFactory.getInstance(); playlist = plf.getPlaylist(); if (playlist == null) { config.setPlaylistClassName("javazoom.jlgui.player.amp.playlist.BasePlaylist"); playlist = plf.getPlaylist(); } playlistUI.setPlaylist(playlist); if ((playlistName != null) && (!playlistName.equals(""))) { // M3U file or URL. if ((playlistName.toLowerCase().endsWith(ui.getResource("playlist.extension.m3u"))) || (playlistName.toLowerCase().endsWith(ui.getResource("playlist.extension.pls")))) loaded = playlist.load(playlistName); // Simple song. else { String name = playlistName; if (!Config.startWithProtocol(playlistName)) { int indn = playlistName.lastIndexOf(java.io.File.separatorChar); if (indn != -1) name = playlistName.substring(indn + 1); PlaylistItem pli = new PlaylistItem(name, playlistName, -1, true); playlist.appendItem(pli); loaded = true; } else { PlaylistItem pli = new PlaylistItem(name, playlistName, -1, false); playlist.appendItem(pli); loaded = true; } } } return loaded; } /* (non-Javadoc) * @see javax.swing.event.ChangeListener#stateChanged(javax.swing.event.ChangeEvent) */ public void stateChanged(ChangeEvent e) { Object src = e.getSource(); //log.debug("State (EDT=" + SwingUtilities.isEventDispatchThread() + ")"); // Volume if (src == ui.getAcVolume()) { Object[] args = { String.valueOf(ui.getAcVolume().getValue()) }; String volumeText = MessageFormat.format(ui.getResource("slider.volume.text"), args); ui.getAcTitleLabel().setAcText(volumeText); try { int gainValue = ui.getAcVolume().getValue(); int maxGain = ui.getAcVolume().getMaximum(); if (gainValue == 0) theSoundPlayer.setGain(0); else theSoundPlayer.setGain(((double) gainValue / (double) maxGain)); config.setVolume(gainValue); } catch (BasicPlayerException ex) { log.debug("Cannot set gain", ex); } } // Balance else if (src == ui.getAcBalance()) { Object[] args = { String.valueOf(Math.abs(ui.getAcBalance().getValue() * 100 / Skin.BALANCEMAX)) }; String balanceText = null; if (ui.getAcBalance().getValue() > 0) { balanceText = MessageFormat.format(ui.getResource("slider.balance.text.right"), args); } else if (ui.getAcBalance().getValue() < 0) { balanceText = MessageFormat.format(ui.getResource("slider.balance.text.left"), args); } else { balanceText = MessageFormat.format(ui.getResource("slider.balance.text.center"), args); } ui.getAcTitleLabel().setAcText(balanceText); try { float balanceValue = ui.getAcBalance().getValue() * 1.0f / Skin.BALANCEMAX; theSoundPlayer.setPan(balanceValue); } catch (BasicPlayerException ex) { log.debug("Cannot set pan", ex); } } else if (src == ui.getAcPosBar()) { if (ui.getAcPosBar().getValueIsAdjusting() == false) { if (posDragging == true) { posDragging = false; posValue = ui.getAcPosBar().getValue() * 1.0 / Skin.POSBARMAX; processSeek(posValue); } } else { posDragging = true; posValueJump = true; } } } /* (non-Javadoc) * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent) */ public void actionPerformed(ActionEvent e) { final ActionEvent evt = e; if (e.getActionCommand().equals(PlayerActionEvent.ACPAUSE)) { processActionEvent(e); } else if ((e.getActionCommand().equals(PlayerActionEvent.ACPLAY)) && (playerState == PAUSE)) { processActionEvent(e); } else { new Thread("PlayerUIActionEvent") { public void run() { processActionEvent(evt); } }.start(); } } /** * Process action event. * @param e */ public void processActionEvent(ActionEvent e) { String cmd = e.getActionCommand(); log.debug("Action=" + cmd + " (EDT=" + SwingUtilities.isEventDispatchThread() + ")"); // Preferences. if (cmd.equalsIgnoreCase(PlayerActionEvent.MIPREFERENCES)) { processPreferences(e.getModifiers()); } // Skin browser else if (cmd.equals(PlayerActionEvent.MISKINBROWSER)) { processSkinBrowser(e.getModifiers()); } // Jump to file else if (cmd.equals(PlayerActionEvent.MIJUMPFILE)) { processJumpToFile(e.getModifiers()); } // Stop else if (cmd.equals(PlayerActionEvent.MISTOP)) { processStop(MouseEvent.BUTTON1_MASK); } // Load skin else if (e.getActionCommand().equals(PlayerActionEvent.MILOADSKIN)) { File[] file = FileSelector.selectFile(loader, FileSelector.OPEN, false, ui.getResource("skin.extension"), ui.getResource("loadskin.dialog.filtername"), new File(config.getLastDir())); if (FileSelector.getInstance().getDirectory() != null) config.setLastDir(FileSelector.getInstance().getDirectory().getPath()); if (file != null) { String fsFile = file[0].getName(); ui.setPath(config.getLastDir() + fsFile); loadSkin(); config.setDefaultSkin(ui.getPath()); } } // Shuffle else if (cmd.equals(PlayerActionEvent.ACSHUFFLE)) { if (ui.getAcShuffle().isSelected()) { config.setShuffleEnabled(true); if (playlist != null) { playlist.shuffle(); playlistUI.initPlayList(); // Play from the top PlaylistItem pli = playlist.getCursor(); setCurrentSong(pli); } } else { config.setShuffleEnabled(false); } } // Repeat else if (cmd.equals(PlayerActionEvent.ACREPEAT)) { if (ui.getAcRepeat().isSelected()) { config.setRepeatEnabled(true); } else { config.setRepeatEnabled(false); } } // Play file else if (cmd.equals(PlayerActionEvent.MIPLAYFILE)) { processEject(MouseEvent.BUTTON1_MASK); } // Play URL else if (cmd.equals(PlayerActionEvent.MIPLAYLOCATION)) { processEject(MouseEvent.BUTTON3_MASK); } // Playlist menu item else if (cmd.equals(PlayerActionEvent.MIPLAYLIST)) { ui.getAcPlaylist().setSelected(miPlaylist.getState()); togglePlaylist(); } // Playlist toggle button else if (cmd.equals(PlayerActionEvent.ACPLAYLIST)) { togglePlaylist(); } // EqualizerUI menu item else if (cmd.equals(PlayerActionEvent.MIEQUALIZER)) { ui.getAcEqualizer().setSelected(miEqualizer.getState()); toggleEqualizer(); } // EqualizerUI else if (cmd.equals(PlayerActionEvent.ACEQUALIZER)) { toggleEqualizer(); } // Exit player else if (cmd.equals(PlayerActionEvent.ACEXIT)) { closePlayer(); } // Minimize else if (cmd.equals(PlayerActionEvent.ACMINIMIZE)) { loader.minimize(); } // Eject else if (cmd.equals(PlayerActionEvent.ACEJECT)) { processEject(e.getModifiers()); } // Play else if (cmd.equals(PlayerActionEvent.ACPLAY)) { processPlay(e.getModifiers()); } // Pause else if (cmd.equals(PlayerActionEvent.ACPAUSE)) { processPause(e.getModifiers()); } // Stop else if (cmd.equals(PlayerActionEvent.ACSTOP)) { processStop(e.getModifiers()); } // Next else if (cmd.equals(PlayerActionEvent.ACNEXT)) { processNext(e.getModifiers()); } // Previous else if (cmd.equals(PlayerActionEvent.ACPREVIOUS)) { processPrevious(e.getModifiers()); } } /* (non-Javadoc) * @see javazoom.jlgui.basicplayer.BasicPlayerListener#opened(java.lang.Object, java.util.Map) */ public void opened(Object stream, Map properties) { // Not in EDT. audioInfo = properties; log.debug(properties.toString()); } /* (non-Javadoc) * @see javazoom.jlgui.basicplayer.BasicPlayerListener#stateUpdated(javazoom.jlgui.basicplayer.BasicPlayerEvent) */ public void stateUpdated(final BasicPlayerEvent event) { // Not in EDT. processStateUpdated(event); } /* (non-Javadoc) * @see javazoom.jlgui.basicplayer.BasicPlayerListener#progress(int, long, byte[], java.util.Map) */ public void progress(int bytesread, long microseconds, byte[] pcmdata, Map properties) { // Not in EDT. processProgress(bytesread, microseconds, pcmdata, properties); } /** * Process PREFERENCES event. * @param modifiers */ protected void processPreferences(int modifiers) { Preferences preferences = Preferences.getInstance(this); preferences.setLocation(loader.getLocation().x, loader.getLocation().y); preferences.setSize(512, 350); preferences.setVisible(true); } /** * Process SKINS BROWSER event. * @param modifiers */ protected void processSkinBrowser(int modifiers) { Preferences preferences = Preferences.getInstance(this); preferences.selectSkinBrowserPane(); preferences.setLocation(loader.getLocation().x, loader.getLocation().y); preferences.setSize(512, 350); preferences.setVisible(true); } /** * Process JUMP FILE event. * @param modifiers */ protected void processJumpToFile(int modifiers) { TagSearch ts = new TagSearch(this); ts.setIconImage(config.getIconParent().getImage()); ts.setSize(400, 300); ts.setLocation(loader.getLocation()); ts.display(); } /** * Process EJECT event. * @param modifiers */ protected void processEject(int modifiers) { if ((playerState == PLAY) || (playerState == PAUSE)) { try { if (theSoundPlayer != null) { theSoundPlayer.stop(); } } catch (BasicPlayerException e) { log.info("Cannot stop", e); } playerState = STOP; } if ((playerState == INIT) || (playerState == STOP) || (playerState == OPEN)) { PlaylistItem pli = null; // Local File. if (modifiers == MouseEvent.BUTTON1_MASK) { File[] file = FileSelector.selectFile(loader, FileSelector.OPEN, false, config.getExtensions(), ui.getResource("button.eject.filedialog.filtername"), new File(config.getLastDir())); if (FileSelector.getInstance().getDirectory() != null) config.setLastDir(FileSelector.getInstance().getDirectory().getPath()); if (file != null) { String fsFile = file[0].getName(); if (fsFile != null) { // Loads a new playlist. if ((fsFile.toLowerCase().endsWith(ui.getResource("playlist.extension.m3u"))) || (fsFile.toLowerCase().endsWith(ui.getResource("playlist.extension.pls")))) { if (loadPlaylist(config.getLastDir() + fsFile)) { config.setPlaylistFilename(config.getLastDir() + fsFile); playlist.begin(); playlistUI.initPlayList(); setCurrentSong(playlist.getCursor()); playlistUI.repaint(); } } else if (fsFile.toLowerCase().endsWith(ui.getResource("skin.extension"))) { ui.setPath(config.getLastDir() + fsFile); loadSkin(); config.setDefaultSkin(ui.getPath()); } else pli = new PlaylistItem(fsFile, config.getLastDir() + fsFile, -1, true); } } } // Remote File. else if (modifiers == MouseEvent.BUTTON3_MASK) { UrlDialog UD = new UrlDialog(config.getTopParent(), ui.getResource("button.eject.urldialog.title"), loader.getLocation().x, loader.getLocation().y + 10, config.getLastURL()); UD.show(); if (UD.getFile() != null) { showTitle(ui.getResource("title.loading")); // Remote playlist ? if ((UD.getURL().toLowerCase().endsWith(ui.getResource("playlist.extension.m3u"))) || (UD.getURL().toLowerCase().endsWith(ui.getResource("playlist.extension.pls")))) { if (loadPlaylist(UD.getURL())) { config.setPlaylistFilename(UD.getURL()); playlist.begin(); playlistUI.initPlayList(); setCurrentSong(playlist.getCursor()); playlistUI.repaint(); } } // Remote file or stream. else { pli = new PlaylistItem(UD.getFile(), UD.getURL(), -1, false); } config.setLastURL(UD.getURL()); } } if ((pli != null) && (playlist != null)) { playlist.removeAllItems(); playlist.appendItem(pli); playlist.nextCursor(); playlistUI.initPlayList(); setCurrentSong(pli); playlistUI.repaint(); } } // Display play/time icons. ui.getAcPlayIcon().setIcon(2); ui.getAcTimeIcon().setIcon(1); } /** * Process PLAY event. * @param modifiers */ protected void processPlay(int modifiers) { if (playlist.isModified()) // playlist has been modified since we were last there, must update our cursor pos etc. { PlaylistItem pli = playlist.getCursor(); if (pli == null) { playlist.begin(); pli = playlist.getCursor(); } setCurrentSong(pli); playlist.setModified(false); playlistUI.repaint(); } // Resume is paused. if (playerState == PAUSE) { try { theSoundPlayer.resume(); } catch (BasicPlayerException e) { log.error("Cannot resume", e); } playerState = PLAY; ui.getAcPlayIcon().setIcon(0); ui.getAcTimeIcon().setIcon(0); } // Stop if playing. else if (playerState == PLAY) { try { theSoundPlayer.stop(); } catch (BasicPlayerException e) { log.error("Cannot stop", e); } playerState = PLAY; secondsAmount = 0; ui.getAcMinuteH().setAcText("0"); ui.getAcMinuteL().setAcText("0"); ui.getAcSecondH().setAcText("0"); ui.getAcSecondL().setAcText("0"); if (currentFileOrURL != null) { try { if (currentIsFile == true) theSoundPlayer.open(openFile(currentFileOrURL)); else { theSoundPlayer.open(new URL(currentFileOrURL)); } theSoundPlayer.play(); } catch (Exception ex) { log.error("Cannot read file : " + currentFileOrURL, ex); showMessage(ui.getResource("title.invalidfile")); } } } else if ((playerState == STOP) || (playerState == OPEN)) { try { theSoundPlayer.stop(); } catch (BasicPlayerException e) { log.error("Stop failed", e); } if (currentFileOrURL != null) { try { if (currentIsFile == true) theSoundPlayer.open(openFile(currentFileOrURL)); else theSoundPlayer.open(new URL(currentFileOrURL)); theSoundPlayer.play(); titleText = currentSongName.toUpperCase(); // Get bitrate, samplingrate, channels, time in the following order : // PlaylistItem, BasicPlayer (JavaSound SPI), Manual computation. int bitRate = -1; if (currentPlaylistItem != null) bitRate = currentPlaylistItem.getBitrate(); if ((bitRate <= 0) && (audioInfo.containsKey("bitrate"))) bitRate = ((Integer) audioInfo.get("bitrate")).intValue(); if ((bitRate <= 0) && (audioInfo.containsKey("audio.framerate.fps")) && (audioInfo.containsKey("audio.framesize.bytes"))) { float FR = ((Float) audioInfo.get("audio.framerate.fps")).floatValue(); int FS = ((Integer) audioInfo.get("audio.framesize.bytes")).intValue(); bitRate = Math.round(FS * FR * 8); } int channels = -1; if (currentPlaylistItem != null) channels = currentPlaylistItem.getChannels(); if ((channels <= 0) && (audioInfo.containsKey("audio.channels"))) channels = ((Integer) audioInfo.get("audio.channels")).intValue(); float sampleRate = -1.0f; if (currentPlaylistItem != null) sampleRate = currentPlaylistItem.getSamplerate(); if ((sampleRate <= 0) && (audioInfo.containsKey("audio.samplerate.hz"))) sampleRate = ((Float) audioInfo.get("audio.samplerate.hz")).floatValue(); long lenghtInSecond = -1L; if (currentPlaylistItem != null) lenghtInSecond = currentPlaylistItem.getLength(); if ((lenghtInSecond <= 0) && (audioInfo.containsKey("duration"))) lenghtInSecond = ((Long) audioInfo.get("duration")).longValue() / 1000000; if ((lenghtInSecond <= 0) && (audioInfo.containsKey("audio.length.bytes"))) { // Try to compute time length. lenghtInSecond = (long) Math.round(getTimeLengthEstimation(audioInfo) / 1000); if (lenghtInSecond > 0) { int minutes = (int) Math.floor(lenghtInSecond / 60); int hours = (int) Math.floor(minutes / 60); minutes = minutes - hours * 60; int seconds = (int) (lenghtInSecond - minutes * 60 - hours * 3600); if (seconds >= 10) titleText = "(" + minutes + ":" + seconds + ") " + titleText; else titleText = "(" + minutes + ":0" + seconds + ") " + titleText; } } bitRate = Math.round((bitRate / 1000)); ui.getAcSampleRateLabel().setAcText(String.valueOf(Math.round((sampleRate / 1000)))); if (bitRate > 999) { bitRate = (int) (bitRate / 100); ui.getAcBitRateLabel().setAcText(bitRate + "H"); } else { ui.getAcBitRateLabel().setAcText(String.valueOf(bitRate)); } if (channels == 2) { ui.getAcStereoIcon().setIcon(1); ui.getAcMonoIcon().setIcon(0); } else if (channels == 1) { ui.getAcStereoIcon().setIcon(0); ui.getAcMonoIcon().setIcon(1); } showTitle(titleText); ui.getAcMinuteH().setAcText("0"); ui.getAcMinuteL().setAcText("0"); ui.getAcSecondH().setAcText("0"); ui.getAcSecondL().setAcText("0"); ui.getAcPlayIcon().setIcon(0); ui.getAcTimeIcon().setIcon(0); } catch (BasicPlayerException bpe) { log.info("Stream error :" + currentFileOrURL, bpe); showMessage(ui.getResource("title.invalidfile")); } catch (MalformedURLException mue) { log.info("Stream error :" + currentFileOrURL, mue); showMessage(ui.getResource("title.invalidfile")); } // Set pan/gain. try { theSoundPlayer.setGain( ((double) ui.getAcVolume().getValue() / (double) ui.getAcVolume().getMaximum())); theSoundPlayer.setPan((float) ui.getAcBalance().getValue() / 10.0f); } catch (BasicPlayerException e) { log.info("Cannot set control", e); } playerState = PLAY; log.info(titleText); } } } /** * Process PAUSE event. * @param modifiers */ public void processPause(int modifiers) { if (playerState == PLAY) { try { theSoundPlayer.pause(); } catch (BasicPlayerException e) { log.error("Cannot pause", e); } playerState = PAUSE; ui.getAcPlayIcon().setIcon(1); ui.getAcTimeIcon().setIcon(1); } else if (playerState == PAUSE) { try { theSoundPlayer.resume(); } catch (BasicPlayerException e) { log.info("Cannot resume", e); } playerState = PLAY; ui.getAcPlayIcon().setIcon(0); ui.getAcTimeIcon().setIcon(0); } } /** * Process STOP event. * @param modifiers */ public void processStop(int modifiers) { if ((playerState == PAUSE) || (playerState == PLAY)) { try { theSoundPlayer.stop(); } catch (BasicPlayerException e) { log.info("Cannot stop", e); } playerState = STOP; secondsAmount = 0; ui.getAcPosBar().setValue(0); ui.getAcPlayIcon().setIcon(2); ui.getAcTimeIcon().setIcon(1); } } /** * Process NEXT event. * @param modifiers */ public void processNext(int modifiers) { // Try to get next song from the playlist playlist.nextCursor(); playlistUI.nextCursor(); PlaylistItem pli = playlist.getCursor(); setCurrentSong(pli); } /** * Process PREVIOUS event. * @param modifiers */ public void processPrevious(int modifiers) { // Try to get previous song from the playlist playlist.previousCursor(); playlistUI.nextCursor(); PlaylistItem pli = playlist.getCursor(); setCurrentSong(pli); } /** * Process STATEUPDATED event. * @param event */ public void processStateUpdated(BasicPlayerEvent event) { log.debug("Player:" + event + " (EDT=" + SwingUtilities.isEventDispatchThread() + ")"); /*-- End Of Media reached --*/ int state = event.getCode(); Object obj = event.getDescription(); if (state == BasicPlayerEvent.EOM) { if ((playerState == PAUSE) || (playerState == PLAY)) { playlist.nextCursor(); playlistUI.nextCursor(); PlaylistItem pli = playlist.getCursor(); setCurrentSong(pli); } } else if (state == BasicPlayerEvent.PLAYING) { lastScrollTime = System.currentTimeMillis(); posValueJump = false; if (audioInfo.containsKey("basicplayer.sourcedataline")) { if (ui.getAcAnalyzer() != null) { ui.getAcAnalyzer().setupDSP((SourceDataLine) audioInfo.get("basicplayer.sourcedataline")); ui.getAcAnalyzer().startDSP((SourceDataLine) audioInfo.get("basicplayer.sourcedataline")); } } } else if (state == BasicPlayerEvent.SEEKING) { posValueJump = true; } else if (state == BasicPlayerEvent.SEEKED) { try { theSoundPlayer .setGain(((double) ui.getAcVolume().getValue() / (double) ui.getAcVolume().getMaximum())); theSoundPlayer.setPan((float) ui.getAcBalance().getValue() / 10.0f); } catch (BasicPlayerException e) { log.debug(e); } } else if (state == BasicPlayerEvent.OPENING) { if ((obj instanceof URL) || (obj instanceof InputStream)) { showTitle(ui.getResource("title.buffering")); } } else if (state == BasicPlayerEvent.STOPPED) { if (ui.getAcAnalyzer() != null) { ui.getAcAnalyzer().stopDSP(); ui.getAcAnalyzer().repaint(); } } } /** * Process PROGRESS event. * @param bytesread * @param microseconds * @param pcmdata * @param properties */ public void processProgress(int bytesread, long microseconds, byte[] pcmdata, Map properties) { //log.debug("Player: Progress (EDT="+SwingUtilities.isEventDispatchThread()+")"); int byteslength = -1; long total = -1; // Try to get time from playlist item. if (currentPlaylistItem != null) total = currentPlaylistItem.getLength(); // If it fails then try again with JavaSound SPI. if (total <= 0) total = (long) Math.round(getTimeLengthEstimation(audioInfo) / 1000); // If it fails again then it might be stream => Total = -1 if (total <= 0) total = -1; if (audioInfo.containsKey("basicplayer.sourcedataline")) { // Spectrum/time analyzer if (ui.getAcAnalyzer() != null) ui.getAcAnalyzer().writeDSP(pcmdata); } if (audioInfo.containsKey("audio.length.bytes")) { byteslength = ((Integer) audioInfo.get("audio.length.bytes")).intValue(); } float progress = -1.0f; if ((bytesread > 0) && ((byteslength > 0))) progress = bytesread * 1.0f / byteslength * 1.0f; if (audioInfo.containsKey("audio.type")) { String audioformat = (String) audioInfo.get("audio.type"); if (audioformat.equalsIgnoreCase("mp3")) { //if (properties.containsKey("mp3.position.microseconds")) secondsAmount = (long) Math.round(((Long) properties.get("mp3.position.microseconds")).longValue()/1000000); // Shoutcast stream title. if (properties.containsKey("mp3.shoutcast.metadata.StreamTitle")) { String shoutTitle = ((String) properties.get("mp3.shoutcast.metadata.StreamTitle")).trim(); if (shoutTitle.length() > 0) { if (currentPlaylistItem != null) { String sTitle = " (" + currentPlaylistItem.getFormattedDisplayName() + ")"; if (!currentPlaylistItem.getFormattedName().equals(shoutTitle + sTitle)) { currentPlaylistItem.setFormattedDisplayName(shoutTitle + sTitle); showTitle((shoutTitle + sTitle).toUpperCase()); playlistUI.paintList(); } } } } // EqualizerUI if (properties.containsKey("mp3.equalizer")) equalizerUI.setBands((float[]) properties.get("mp3.equalizer")); if (total > 0) secondsAmount = (long) (total * progress); else secondsAmount = -1; } else if (audioformat.equalsIgnoreCase("wave")) { secondsAmount = (long) (total * progress); } else { secondsAmount = (long) Math.round(microseconds / 1000000); equalizerUI.setBands(null); } } else { secondsAmount = (long) Math.round(microseconds / 1000000); equalizerUI.setBands(null); } if (secondsAmount < 0) secondsAmount = (long) Math.round(microseconds / 1000000); /*-- Display elapsed time --*/ int secondD = 0, second = 0, minuteD = 0, minute = 0; int seconds = (int) secondsAmount; int minutes = (int) Math.floor(seconds / 60); int hours = (int) Math.floor(minutes / 60); minutes = minutes - hours * 60; seconds = seconds - minutes * 60 - hours * 3600; if (seconds < 10) { secondD = 0; second = seconds; } else { secondD = ((int) seconds / 10); second = ((int) (seconds - (((int) seconds / 10)) * 10)); } if (minutes < 10) { minuteD = 0; minute = minutes; } else { minuteD = ((int) minutes / 10); minute = ((int) (minutes - (((int) minutes / 10)) * 10)); } ui.getAcMinuteH().setAcText(String.valueOf(minuteD)); ui.getAcMinuteL().setAcText(String.valueOf(minute)); ui.getAcSecondH().setAcText(String.valueOf(secondD)); ui.getAcSecondL().setAcText(String.valueOf(second)); // Update PosBar location. if (total != 0) { if (posValueJump == false) { int posValue = ((int) Math.round(secondsAmount * Skin.POSBARMAX / total)); ui.getAcPosBar().setValue(posValue); } } else ui.getAcPosBar().setValue(0); long ctime = System.currentTimeMillis(); long lctime = lastScrollTime; // Scroll title ? if ((titleScrollLabel != null) && (titleScrollLabel.length > 0)) { if (ctime - lctime > SCROLL_PERIOD) { lastScrollTime = ctime; if (scrollRight == true) { scrollIndex++; if (scrollIndex >= titleScrollLabel.length) { scrollIndex--; scrollRight = false; } } else { scrollIndex--; if (scrollIndex <= 0) { scrollRight = true; } } // TODO : Improve ui.getAcTitleLabel().setAcText(titleScrollLabel[scrollIndex]); } } } /** * Process seek feature. * @param rate */ protected void processSeek(double rate) { try { if ((audioInfo != null) && (audioInfo.containsKey("audio.type"))) { String type = (String) audioInfo.get("audio.type"); // Seek support for MP3. if ((type.equalsIgnoreCase("mp3")) && (audioInfo.containsKey("audio.length.bytes"))) { long skipBytes = (long) Math .round(((Integer) audioInfo.get("audio.length.bytes")).intValue() * rate); log.debug("Seek value (MP3) : " + skipBytes); theSoundPlayer.seek(skipBytes); } // Seek support for WAV. else if ((type.equalsIgnoreCase("wave")) && (audioInfo.containsKey("audio.length.bytes"))) { long skipBytes = (long) Math .round(((Integer) audioInfo.get("audio.length.bytes")).intValue() * rate); log.debug("Seek value (WAVE) : " + skipBytes); theSoundPlayer.seek(skipBytes); } else posValueJump = false; } else posValueJump = false; } catch (BasicPlayerException ioe) { log.error("Cannot skip", ioe); posValueJump = false; } } /** * Process Drag&Drop * @param data */ public void processDnD(Object data) { log.debug("Player DnD"); // Looking for files to drop. if (data instanceof List) { List al = (List) data; if ((al != null) && (al.size() > 0)) { ArrayList fileList = new ArrayList(); ArrayList folderList = new ArrayList(); ListIterator li = al.listIterator(); while (li.hasNext()) { File f = (File) li.next(); if ((f.exists()) && (f.canRead())) { if (f.isFile()) fileList.add(f); else if (f.isDirectory()) folderList.add(f); } } playFiles(fileList); // TODO : Add dir support } } else if (data instanceof String) { String files = (String) data; if ((files.length() > 0)) { ArrayList fileList = new ArrayList(); ArrayList folderList = new ArrayList(); StringTokenizer st = new StringTokenizer(files, System.getProperty("line.separator")); // Transfer files dropped. while (st.hasMoreTokens()) { String path = st.nextToken(); if (path.startsWith("file://")) { path = path.substring(7, path.length()); if (path.endsWith("\r")) path = path.substring(0, (path.length() - 1)); } File f = new File(path); if ((f.exists()) && (f.canRead())) { if (f.isFile()) fileList.add(f); else if (f.isDirectory()) folderList.add(f); } } playFiles(fileList); // TODO : Add dir support } } else { log.info("Unknown dropped objects"); } } /** * Play files from a list. * @param files */ protected void playFiles(List files) { if (files.size() > 0) { // Clean the playlist. playlist.removeAllItems(); // Add all dropped files to playlist. ListIterator li = files.listIterator(); while (li.hasNext()) { File file = (File) li.next(); PlaylistItem pli = null; if (file != null) { pli = new PlaylistItem(file.getName(), file.getAbsolutePath(), -1, true); if (pli != null) playlist.appendItem(pli); } } // Start the playlist from the top. playlist.nextCursor(); playlistUI.initPlayList(); setCurrentSong(playlist.getCursor()); } } /** * Sets the current song to play and start playing if needed. * @param pli */ public void setCurrentSong(PlaylistItem pli) { int playerStateMem = playerState; if ((playerState == PAUSE) || (playerState == PLAY)) { try { theSoundPlayer.stop(); } catch (BasicPlayerException e) { log.error("Cannot stop", e); } playerState = STOP; secondsAmount = 0; // Display play/time icons. ui.getAcPlayIcon().setIcon(2); ui.getAcTimeIcon().setIcon(0); } playerState = OPEN; if (pli != null) { // Read tag info. pli.getTagInfo(); currentSongName = pli.getFormattedName(); currentFileOrURL = pli.getLocation(); currentIsFile = pli.isFile(); currentPlaylistItem = pli; } // Playlist ended. else { // Try to repeat ? if (config.isRepeatEnabled()) { if (playlist != null) { // PlaylistItems available ? if (playlist.getPlaylistSize() > 0) { playlist.begin(); PlaylistItem rpli = playlist.getCursor(); if (rpli != null) { // OK, Repeat the playlist. rpli.getTagInfo(); currentSongName = rpli.getFormattedName(); currentFileOrURL = rpli.getLocation(); currentIsFile = rpli.isFile(); currentPlaylistItem = rpli; } } // No, so display Title. else { currentSongName = Skin.TITLETEXT; currentFileOrURL = null; currentIsFile = false; currentPlaylistItem = null; } } } // No, so display Title. else { currentSongName = Skin.TITLETEXT; currentFileOrURL = null; currentIsFile = false; currentPlaylistItem = null; } } if (currentIsFile == true) { ui.getAcPosBar().setEnabled(true); ui.getAcPosBar().setHideThumb(false); } else { config.setLastURL(currentFileOrURL); ui.getAcPosBar().setEnabled(false); ui.getAcPosBar().setHideThumb(true); } titleText = currentSongName.toUpperCase(); showMessage(titleText); // Start playing if needed. if ((playerStateMem == PLAY) || (playerStateMem == PAUSE)) { processPlay(MouseEvent.BUTTON1_MASK); } } /** * Display text in title area. * @param str */ public void showTitle(String str) { if (str != null) { currentTitle = str; titleScrollLabel = null; scrollIndex = 0; scrollRight = true; if (str.length() > TEXT_LENGTH_MAX) { int a = ((str.length()) - (TEXT_LENGTH_MAX)) + 1; titleScrollLabel = new String[a]; for (int k = 0; k < a; k++) { String sText = str.substring(k, TEXT_LENGTH_MAX + k); titleScrollLabel[k] = sText; } str = str.substring(0, TEXT_LENGTH_MAX); } ui.getAcTitleLabel().setAcText(str); } } /** * Shows message in title an updates bitRate,sampleRate, Mono/Stereo,time features. * @param txt */ public void showMessage(String txt) { showTitle(txt); ui.getAcSampleRateLabel().setAcText(" "); ui.getAcBitRateLabel().setAcText(" "); ui.getAcStereoIcon().setIcon(0); ui.getAcMonoIcon().setIcon(0); ui.getAcMinuteH().setAcText("0"); ui.getAcMinuteL().setAcText("0"); ui.getAcSecondH().setAcText("0"); ui.getAcSecondL().setAcText("0"); } /** * Toggle playlistUI. */ protected void togglePlaylist() { if (ui.getAcPlaylist().isSelected()) { miPlaylist.setState(true); config.setPlaylistEnabled(true); loader.togglePlaylist(true); } else { miPlaylist.setState(false); config.setPlaylistEnabled(false); loader.togglePlaylist(false); } } /** * Toggle equalizerUI. */ protected void toggleEqualizer() { if (ui.getAcEqualizer().isSelected()) { miEqualizer.setState(true); config.setEqualizerEnabled(true); loader.toggleEqualizer(true); } else { miEqualizer.setState(false); config.setEqualizerEnabled(false); loader.toggleEqualizer(false); } } /** * Returns a File from a filename. * @param file * @return */ protected File openFile(String file) { return new File(file); } /** * Free resources and close the player. */ protected void closePlayer() { if ((playerState == PAUSE) || (playerState == PLAY)) { try { if (theSoundPlayer != null) { theSoundPlayer.stop(); } } catch (BasicPlayerException e) { log.error("Cannot stop", e); } } if (theSoundPlayer != null) { config.setAudioDevice(((BasicPlayer) theSoundPlayer).getMixerName()); } if (ui.getAcAnalyzer() != null) { if (ui.getAcAnalyzer().getDisplayMode() == SpectrumTimeAnalyzer.DISPLAY_MODE_OFF) config.setVisualMode("off"); else if (ui.getAcAnalyzer().getDisplayMode() == SpectrumTimeAnalyzer.DISPLAY_MODE_SCOPE) config.setVisualMode("oscillo"); else config.setVisualMode("spectrum"); } if (playlist != null) { playlist.save("default.m3u"); config.setPlaylistFilename("default.m3u"); } loader.close(); } /** * Return current title in player. * @return */ public String getCurrentTitle() { return currentTitle; } /** * Try to compute time length in milliseconds. * @param properties * @return */ public long getTimeLengthEstimation(Map properties) { long milliseconds = -1; int byteslength = -1; if (properties != null) { if (properties.containsKey("audio.length.bytes")) { byteslength = ((Integer) properties.get("audio.length.bytes")).intValue(); } if (properties.containsKey("duration")) { milliseconds = (int) (((Long) properties.get("duration")).longValue()) / 1000; } else { // Try to compute duration int bitspersample = -1; int channels = -1; float samplerate = -1.0f; int framesize = -1; if (properties.containsKey("audio.samplesize.bits")) { bitspersample = ((Integer) properties.get("audio.samplesize.bits")).intValue(); } if (properties.containsKey("audio.channels")) { channels = ((Integer) properties.get("audio.channels")).intValue(); } if (properties.containsKey("audio.samplerate.hz")) { samplerate = ((Float) properties.get("audio.samplerate.hz")).floatValue(); } if (properties.containsKey("audio.framesize.bytes")) { framesize = ((Integer) properties.get("audio.framesize.bytes")).intValue(); } if (bitspersample > 0) { milliseconds = (int) (1000.0f * byteslength / (samplerate * channels * (bitspersample / 8))); } else { milliseconds = (int) (1000.0f * byteslength / (samplerate * framesize)); } } } return milliseconds; } /** * Simulates "Play" selection. */ public void pressStart() { ui.getAcPlay().doClick(); } /** * Simulates "Pause" selection. */ public void pressPause() { ui.getAcPause().doClick(); } /** * Simulates "Stop" selection. */ public void pressStop() { ui.getAcStop().doClick(); } /** * Simulates "Next" selection. */ public void pressNext() { ui.getAcNext().doClick(); } /** * Simulates "Previous" selection. */ public void pressPrevious() { ui.getAcPrevious().doClick(); } /** * Simulates "Eject" selection. */ public void pressEject() { ui.getAcEject().doClick(); } }