net.sourceforge.atunes.kernel.modules.player.PlayerHandler.java Source code

Java tutorial

Introduction

Here is the source code for net.sourceforge.atunes.kernel.modules.player.PlayerHandler.java

Source

/*
 * aTunes 1.14.0
 * Copyright (C) 2006-2009 Alex Aranda, Sylvain Gaudard, Thomas Beckers and contributors
 *
 * See http://www.atunes.org/wiki/index.php?title=Contributing for information about contributors
 *
 * http://www.atunes.org
 * http://sourceforge.net/projects/atunes
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU 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 General Public License for more details.
 */

package net.sourceforge.atunes.kernel.modules.player;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;

import net.sourceforge.atunes.kernel.Handler;
import net.sourceforge.atunes.kernel.Kernel;
import net.sourceforge.atunes.kernel.modules.notify.NotifyHandler;
import net.sourceforge.atunes.kernel.modules.player.mplayer.MPlayerEngine;
import net.sourceforge.atunes.kernel.modules.player.xine.XineEngine;
import net.sourceforge.atunes.kernel.modules.state.ApplicationState;
import net.sourceforge.atunes.kernel.modules.visual.VisualHandler;
import net.sourceforge.atunes.misc.log.LogCategories;
import net.sourceforge.atunes.model.AudioObject;
import net.sourceforge.atunes.utils.LanguageTool;
import net.sourceforge.atunes.utils.StringUtils;

import org.apache.commons.lang.ArrayUtils;
import org.commonjukebox.plugins.Plugin;
import org.commonjukebox.plugins.PluginInfo;
import org.commonjukebox.plugins.PluginListener;
import org.commonjukebox.plugins.PluginSystemException;

/**
 * This class is resopnsible for handling the player engine.
 */
public final class PlayerHandler extends Handler implements PluginListener {

    /**
     * The player engine used
     */
    private static PlayerHandler instance;

    /**
     * Default player engine
     */
    public static final String DEFAULT_ENGINE = "MPlayer";

    /**
     * Names of all engines
     */
    private static String[] engineNames;

    /**
     * The player engine
     */
    private PlayerEngine playerEngine;

    /**
     * Instantiates a new player handler.
     */
    private PlayerHandler() {
    }

    @Override
    public void applicationStateChanged(ApplicationState newState) {
        // TODO Auto-generated method stub

    }

    @Override
    public void applicationStarted() {
        if (ApplicationState.getInstance().isPlayAtStartup()) {
            playCurrentAudioObject(true);
        }
    }

    /**
     * Checks if engine is currently playing (<code>true</code>) or not (
     * <code>false</code>)
     * 
     * @return <code>true</code> if engine is currently playing
     */
    public boolean isEnginePlaying() {
        return playerEngine.isEnginePlaying();
    }

    /**
     * This method must be implemented by player engines. Applies volume value
     * in player engine
     * 
     * @param perCent
     *            0-100
     */
    public void setVolume(int perCent) {
        playerEngine.setVolume(perCent);
    }

    /**
     * This method must be implemented by player engines. Apply mute state in
     * player engine
     * 
     * @param state
     *            : enabled (<code>true</code>) or disabled (<code>false</code>)
     * 
     */
    public void applyMuteState(boolean state) {
        playerEngine.applyMuteState(state);
    }

    /**
     * This method must be implemented by player engines. Method to apply
     * normalization in player engine
     * 
     * @param values
     */
    public void applyNormalization() {
        playerEngine.applyNormalization();
    }

    /**
     * This methods checks if the specified player capability is supported by
     * this player engine
     * 
     * @param capability
     *            The capability that should be checked
     * @return If the specified player capability is supported by this player
     *         engine
     */
    public boolean supportsCapability(PlayerEngineCapability capability) {
        return playerEngine.supportsCapability(capability);
    }

    /**
     * This method must be implemented by player engines. Method to apply
     * equalizer values in player engine
     * 
     * @param values
     */
    void applyEqualization(float[] values) {
        playerEngine.applyEqualization(values);
    }

    /**
     * This method must be implemented by player engines. Transform values
     * retrieved from equalizer dialog to values for player engine
     * 
     * @param values
     * @return
     */
    float[] transformEqualizerValues(float[] values) {
        return playerEngine.transformEqualizerValues(values);
    }

    /**
     * Adds a new playback state listener
     */
    public void addPlaybackStateListener(PlaybackStateListener listener) {
        playerEngine.addPlaybackStateListener(listener);
    }

    /**
     * Removes a playback state listener
     * 
     * @param listener
     */
    public void removePlaybackStateListener(PlaybackStateListener listener) {
        playerEngine.removePlaybackStateListener(listener);
    }

    /**
     * Starts playing current audio object from play list
     * 
     * @param buttonPressed
     *            TODO: Add more javadoc
     */
    public final void playCurrentAudioObject(boolean buttonPressed) {
        playerEngine.playCurrentAudioObject(buttonPressed);
    }

    /**
     * Stops playing current audio object
     * 
     * @param userStopped
     *            <code>true</code> if user has stopped playback
     * 
     */
    public final void stopCurrentAudioObject(boolean userStopped) {
        playerEngine.stopCurrentAudioObject(userStopped);
    }

    /**
     * Starts playing previous audio object from play list
     */
    public final void playPreviousAudioObject() {
        playerEngine.playPreviousAudioObject();
    }

    /**
     * Starts playing next audio object from play list
     */
    public final void playNextAudioObject() {
        playerEngine.playNextAudioObject(false);
    }

    /**
     * Seek function: play current audio object from position defined by
     * parameter (0-100%)
     * 
     * @param position
     *            From start of audio object (0) to end of audio object (100)
     * 
     */
    public final void seekCurrentAudioObject(double position) {
        playerEngine.seekCurrentAudioObject(position);
    }

    /**
     * Lower volume
     */
    public final void volumeDown() {
        playerEngine.volumeDown();
    }

    /**
     * Raise volume
     */
    public final void volumeUp() {
        playerEngine.volumeUp();
    }

    @Override
    public void applicationFinish() {
        // Stop must be called explicitely to avoid playback after user closed app
        PlayerHandler.getInstance().stopCurrentAudioObject(true);
        playerEngine.finishPlayer();
    }

    /**
     * Returns the equalizer of this player engine
     * 
     * @return the equalizer of this player engine
     */
    public Equalizer getEqualizer() {
        return playerEngine.getEqualizer();
    }

    /**
     * Returns the list of player engines
     * 
     * @return list with player engines
     */
    private static List<PlayerEngine> getEngines() {
        List<PlayerEngine> result = new ArrayList<PlayerEngine>();
        result.add(new MPlayerEngine());
        result.add(new XineEngine());
        //result.add(new VlcPlayerEngine());
        //result.add(new GStreamerEngine());
        return result;
    }

    public AudioObject getAudioObject() {
        return playerEngine.getAudioObject();
    }

    /**
     * Gets the single instance of PlayerHandler. This method returns player
     * engine configured by user or default if it's available on the system
     * 
     * @return single instance of PlayerHandler
     */
    public static final synchronized PlayerHandler getInstance() {
        if (instance == null) {
            instance = new PlayerHandler();
            // Get engines list
            List<PlayerEngine> engines = getEngines();

            // Remove unsupported engines
            Iterator<PlayerEngine> it = engines.iterator();
            while (it.hasNext()) {
                if (!it.next().isEngineAvailable()) {
                    it.remove();
                }
            }

            // Update engine names
            engineNames = new String[engines.size()];
            for (int i = 0; i < engines.size(); i++) {
                engineNames[i] = engines.get(i).getEngineName();
            }

            Arrays.sort(engineNames);

            getLogger().info(LogCategories.PLAYER,
                    "List of availables engines : " + ArrayUtils.toString(engineNames));

            if (engines.isEmpty()) {
                handlePlayerError(new IllegalStateException(LanguageTool.getString("NO_PLAYER_ENGINE")));
            } else {
                // Get engine of application state (default or selected by user)
                String selectedEngine = ApplicationState.getInstance().getPlayerEngine();

                // If selected engine is not available then try default engine or another one
                if (!ArrayUtils.contains(engineNames, selectedEngine)) {

                    getLogger().info(LogCategories.PLAYER, selectedEngine + " is not availaible");
                    if (ArrayUtils.contains(engineNames, DEFAULT_ENGINE)) {
                        selectedEngine = DEFAULT_ENGINE;
                    } else {
                        // If default engine is not available, then get the first engine of map returned
                        selectedEngine = engines.iterator().next().getEngineName();
                    }
                    // Update application state with this engine
                    ApplicationState.getInstance().setPlayerEngine(selectedEngine);
                }

                for (PlayerEngine engine : engines) {
                    if (engine.getEngineName().equals(selectedEngine)) {
                        instance.playerEngine = engine;
                        getLogger().info(LogCategories.PLAYER, "Engine initialized : " + selectedEngine);
                    }
                }

                if (instance.playerEngine == null) {
                    handlePlayerError(new IllegalStateException(LanguageTool.getString("NO_PLAYER_ENGINE")));
                }

                // Init engine
                instance.playerEngine.initializePlayerEngine();
                Kernel.getInstance().addFinishListener(instance);

                // Add core playback listeners
                instance.playerEngine.addPlaybackStateListener(instance.playerEngine);
                instance.playerEngine.addPlaybackStateListener(VisualHandler.getInstance());
                instance.playerEngine.addPlaybackStateListener(NotifyHandler.getInstance());
            }

            // Add a shutdown hook to perform some actions before killing the JVM
            Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {

                @Override
                public void run() {
                    getLogger().debug(LogCategories.SHUTDOWN_HOOK, "Final check for Zombie player engines");
                    instance.playerEngine.killPlayer();
                    getLogger().debug(LogCategories.SHUTDOWN_HOOK, "Closing player ...");
                }

            }));
        }
        return instance;
    }

    /**
     * Initializes handler
     */
    public void initHandler() {
        // Initial playback state is stopped
        getInstance().playerEngine.callPlaybackStateListeners(PlaybackState.STOPPED);
    }

    private static void handlePlayerError(Throwable t) {
        getLogger().error(LogCategories.PLAYER, StringUtils.getString("Player Error: ", t));
        getLogger().error(LogCategories.PLAYER, t);
        VisualHandler.getInstance().showErrorDialog(t.getMessage());
    }

    /**
     * Return list of engine names as configured in settings file This method is
     * mainly designed to be used in preferences window to select a player
     * engine by its name
     * 
     * @return list of engine names
     */
    public final String[] getEngineNames() {
        return engineNames != null ? Arrays.copyOf(engineNames, engineNames.length) : null;
    }

    @Override
    public void pluginActivated(PluginInfo plugin) {
        try {
            PlaybackStateListener listener = (PlaybackStateListener) plugin.getInstance();
            addPlaybackStateListener(listener);
        } catch (PluginSystemException e) {
            getLogger().error(LogCategories.PLUGINS, e);
        }
    }

    @Override
    public void pluginDeactivated(PluginInfo plugin, Collection<Plugin> createdInstances) {
        getLogger().info(LogCategories.PLUGINS,
                StringUtils.getString("Plugin deactivated: ", plugin.getName(), " (", plugin.getClassName(), ")"));
        for (Plugin createdInstance : createdInstances) {
            PlayerHandler.getInstance().removePlaybackStateListener((PlaybackStateListener) createdInstance);
        }
    }

}