Package com.bramosystems.oss.player.core.client.ui

Source Code of com.bramosystems.oss.player.core.client.ui.NativePlayer

/*
* Copyright 2009 Sikirulai Braheem
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.bramosystems.oss.player.core.client.ui;

import com.bramosystems.oss.player.core.client.*;
import com.bramosystems.oss.player.core.client.playlist.MRL;
import com.bramosystems.oss.player.core.client.MediaInfo.MediaInfoKey;
import com.bramosystems.oss.player.core.client.playlist.PlaylistManager;
import com.bramosystems.oss.player.core.client.impl.LoopManager;
import com.bramosystems.oss.player.core.client.impl.NativePlayerImpl;
import com.bramosystems.oss.player.core.client.impl.NativePlayerUtil;
import com.bramosystems.oss.player.core.client.spi.PlayerWidget;
import com.bramosystems.oss.player.core.client.impl.CorePlayerProvider;
import com.bramosystems.oss.player.core.event.client.MediaInfoEvent;
import com.bramosystems.oss.player.core.event.client.MediaInfoHandler;
import com.bramosystems.oss.player.core.event.client.PlayStateEvent;
import com.bramosystems.oss.player.core.event.client.PlayerStateEvent;
import com.bramosystems.oss.player.core.client.spi.Player;
import com.google.gwt.i18n.client.NumberFormat;
import com.google.gwt.user.client.Command;
import com.google.gwt.user.client.DOM;
import java.util.ArrayList;
import java.util.List;

/**
* Widget to embed media files with HTML 5 video elements in compliant browsers.
*
* <h3>Usage Example</h3>
*
* <p>
* <code><pre>
* SimplePanel panel = new SimplePanel();   // create panel to hold the player
* Widget player = null;
* try {
*      // create the player
*      player = new NativePlayer("www.example.com/mediafile.ogg");
* } catch(PluginNotFoundException e) {
*      // PluginNotFoundException thrown if browser does not support HTML 5 specs.
*      player = PlayerUtil.getMissingPluginNotice(e.getPlugin());
* }
*
* panel.setWidget(player); // add player to panel.
* </pre></code>
*
* @author Sikirulai Braheem <sbraheem at bramosystems dot com>
*/
@Player(name = "Native", providerFactory = CorePlayerProvider.class, minPluginVersion = "5.0.0")
public class NativePlayer extends AbstractMediaPlayer implements PlaylistSupport {

    private NumberFormat volFmt = NumberFormat.getPercentFormat();
    private NativePlayerImpl impl;
    private String playerId, _height, _width;
    private PlayerWidget playerWidget;
    private boolean adjustToVideoSize, isEmbedded, isWasPlaying;
    private LoopManager loopManager;
    private PlaylistManager playlistManager;
    private NativePlayerUtil.NativeEventCallback _callback;

    private NativePlayer() throws PluginNotFoundException {
        if (!PlayerUtil.isHTML5CompliantClient()) {
            throw new PluginNotFoundException(Plugin.Native);
        }

        playerId = DOM.createUniqueId().replace("-", "");
        adjustToVideoSize = false;
        playlistManager = new PlaylistManager(this);
        loopManager = new LoopManager(new LoopManager.LoopCallback() {

            @Override
            public void playNextItem() throws PlayException {
                playlistManager.playNext();
            }

            @Override
            public void onLoopFinished() {
                isWasPlaying = false;
                fireDebug("Play finished - " + playlistManager.getPlaylistIndex());
                firePlayStateEvent(PlayStateEvent.State.Finished,
                        playlistManager.getPlaylistIndex());
            }

            @Override
            public void repeatPlay() {
                playlistManager.play(playlistManager.getPlaylistIndex());
            }

            @Override
            public void playNextLoop() {
                impl.play();
            }
        });
        _callback = new NativePlayerUtil.NativeEventCallback() {

            @Override
            public void onProgressChanged() {
                NativePlayerImpl.TimeRange time = impl.getBuffered();
                if (time != null) {
                    double i = time.getLength();
                    fireLoadingProgress((time.getEnd(i - 1) - time.getStart(0)) * 1000 / impl.getDuration());
                }
            }

            @Override
            public void onStateChanged(int code) {
                switch (code) {
                    case 1: // play started
                        isWasPlaying = true;
                        fireDebug("Play started");
                        firePlayStateEvent(PlayStateEvent.State.Started, playlistManager.getPlaylistIndex());
                        fireDebug("Playing media at '" + impl.getMediaURL() + "'");
                        break;
                    case 2: // pause
                        fireDebug("Play paused");
                        firePlayStateEvent(PlayStateEvent.State.Paused, playlistManager.getPlaylistIndex());
                        break;
                    case 3: // finished
                        // notify loop manager, it handles play finished event ...
                        loopManager.notifyPlayFinished();
                        break;
                    case 4: // buffering
                        fireDebug("Buffering started");
                        firePlayerStateEvent(PlayerStateEvent.State.BufferingStarted);
                        break;
                    case 5: // playing again, buffering stopped
                        fireDebug("Buffering stopped");
                        firePlayerStateEvent(PlayerStateEvent.State.BufferingFinished);
                        break;
                    case 6: // process metadata
                        fireDebug("Media Metadata available");
                        MediaInfo info = new MediaInfo();
                        impl.fillMediaInfo(info);
                        fireMediaInfoAvailable(info);
                        break;
                    case 7: // volume changed
                        if (impl.isMute()) {
                            fireDebug("Volume muted");
                        } else {
                            fireDebug("Volume changed : " + volFmt.format(impl.getVolume()));
                        }
                        break;
                    case 10: // loading started
                        fireDebug("Loading '" + impl.getMediaURL() + "'");
                        fireLoadingProgress(0);
                        break;
                    case 11: // loading finished
                        fireDebug("Loading completed");
                        fireLoadingProgress(1.0);
                        break;
                    case 12: // error
                        switch (MediaError.values()[impl.getErrorState()]) {
                            case Aborted:
                                fireError("ERROR: Loading aborted!");
                                break;
                            case DecodeError:
                                fireError("ERROR: Decoding error");
                                break;
                            case NetworkError:
                                fireError("ERROR: Network error");
                                break;
                            case UnsupportedMedia:
                                fireError("ERROR: Media could not be loaded or format not supported! '"
                                        + playlistManager.getCurrentItem() + "'");
                                fireDebug("Trying alternative playlist item ...");
                                try {
                                    playlistManager.loadAlternative();
                                } catch (LoadException ex) {
                                    fireError("ERROR: No alternative media available!");
                                    if (isWasPlaying) {
                                        loopManager.notifyPlayFinished();
                                    } else {
                                        playlistManager.loadNext();
                                    }
                                }
                                break;
                        }
                        break;
                    case 13: // loading aborted
                        fireDebug("Media loading aborted!");
                        break;
                }
            }
        };
    }

    private void _init(String width, String height) {
        initWidget(playerWidget);

        if ((width == null) || (height == null)) {
            _height = "0px";
            _width = "0px";
            isEmbedded = true;
        } else {
            _height = height;
            _width = width;
            addMediaInfoHandler(new MediaInfoHandler() {

                @Override
                public void onMediaInfoAvailable(MediaInfoEvent event) {
                    MediaInfo info = event.getMediaInfo();
                    if (info.getAvailableItems().contains(MediaInfoKey.VideoHeight)
                            || info.getAvailableItems().contains(MediaInfoKey.VideoWidth)) {
                        checkVideoSize(Integer.parseInt(info.getItem(MediaInfoKey.VideoHeight)),
                                Integer.parseInt(info.getItem(MediaInfoKey.VideoWidth)));
                    }
                }
            });
        }
    }

    /**
     * Constructs <code>NativePlayer</code> to playback media located at {@code mediaURL}.
     * Media playback begins automatically.
     *
     * <p>This is the same as calling {@code NativePlayer(mediaURL, true, "20px", "100%")}</p>
     *
     * @param mediaURL the URL of the media to playback
     *
     * @throws PluginNotFoundException if browser does not support the HTML 5 specification.
     */
    public NativePlayer(String mediaURL) throws PluginNotFoundException {
        this(mediaURL, true, NativePlayerUtil.get.getPlayerHeight(), "100%");
    }

    /**
     * Constructs <code>NativePlayer</code> to playback media located at {@code mediaURL}.
     * Media playback begins automatically if {@code autoplay} is {@code true}.
     *
     * <p>This is the same as calling {@code NativePlayer(mediaURL, autoplay, "20px", "100%")}</p>
     *
     * @param mediaURL the URL of the media to playback
     * @param autoplay {@code true} to start playing automatically, {@code false} otherwise
     *
     * @throws PluginNotFoundException if browser does not support the HTML 5 specification.
     */
    public NativePlayer(String mediaURL, boolean autoplay) throws PluginNotFoundException {
        this(mediaURL, autoplay, NativePlayerUtil.get.getPlayerHeight(), "100%");
    }

    /**
     * Constructs <code>NativePlayer</code> with the specified {@code height} and
     * {@code width} to playback media located at {@code mediaURL}. Media playback
     * begins automatically if {@code autoplay} is {@code true}.
     *
     * <p> {@code height} and {@code width} are specified as CSS units.</p>
     *
     * @param mediaURL the URL of the media to playback
     * @param autoplay {@code true} to start playing automatically, {@code false} otherwise
     * @param height the height of the player
     * @param width the width of the player.
     *
     * @throws PluginNotFoundException if browser does not support the HTML 5 specification.
     */
    public NativePlayer(String mediaURL, boolean autoplay, String height, String width)
            throws PluginNotFoundException {
        this();
        playerWidget = new PlayerWidget("core", Plugin.Native.name(), playerId, "", autoplay);
        _init(width, height);
        playlistManager.addToPlaylist(mediaURL);
    }

    /**
     * Constructs <code>NativePlayer</code> with the specified {@code height} and
     * {@code width} to playback media located at any of the {@code mediaSources}.
     * Playback begins automatically if {@code autoplay} is {@code true}.
     *
     * <p>As per the HTML 5 specification, the browser chooses any of the {@code mediaSources}
     * it supports</p>
     *
     * <p> {@code height} and {@code width} are specified as CSS units.</p>
     *
     * @param mediaSources a list of media URLs
     * @param autoplay {@code true} to start playing automatically, {@code false} otherwise
     * @param height the height of the player
     * @param width the width of the player.
     *
     * @throws PluginNotFoundException if browser does not support the HTML 5 specification.
     */
    public NativePlayer(ArrayList<String> mediaSources, boolean autoplay, String height, String width)
            throws PluginNotFoundException {
        this();
        playerWidget = new PlayerWidget("core", Plugin.Native.name(), playerId, "", autoplay);
        _init(width, height);
        playlistManager.addToPlaylist(new MRL(mediaSources));
    }

    /**
     * Overriden to register player for DOM events.
     */
    @Override
    protected void onLoad() {
        fireDebug("HTML5 Native Player");
        playerWidget.setSize("100%", _height);
        setWidth(_width);

        impl = NativePlayerImpl.getPlayer(playerId);
        impl.registerMediaStateHandler(_callback);
        firePlayerStateEvent(PlayerStateEvent.State.Ready);
        playlistManager.load(0);
    }

    @Override
    public void loadMedia(String mediaURL) throws LoadException {
        checkAvailable();
        impl.setMediaURL(mediaURL);
        impl.load();
    }

    @Override
    public void playMedia() throws PlayException {
        checkAvailable();
        impl.play();
    }

    @Override
    public void stopMedia() {
        checkAvailable();
        impl.pause();
        impl.setTime(0);
        firePlayStateEvent(PlayStateEvent.State.Stopped, playlistManager.getPlaylistIndex());
    }

    @Override
    public void pauseMedia() {
        checkAvailable();
        impl.pause();
    }

    @Override
    public long getMediaDuration() {
        checkAvailable();
        return (long) impl.getDuration();
    }

    @Override
    public double getPlayPosition() {
        checkAvailable();
        return impl.getTime();
    }

    @Override
    public void setPlayPosition(double position) {
        checkAvailable();
        impl.setTime(position);
    }

    @Override
    public double getVolume() {
        checkAvailable();
        return impl.getVolume();
    }

    @Override
    public void setVolume(double volume) {
        checkAvailable();
        impl.setVolume(volume);
    }

    @Override
    public int getLoopCount() {
        checkAvailable();
        return loopManager.getLoopCount();
    }

    @Override
    public int getVideoHeight() {
        checkAvailable();
        return impl.getVideoHeight();
    }

    @Override
    public int getVideoWidth() {
        checkAvailable();
        return impl.getVideoWidth();
    }

    @Override
    public boolean isControllerVisible() {
        checkAvailable();
        return impl.isControlsVisible();
    }

    @Override
    public boolean isResizeToVideoSize() {
        return adjustToVideoSize;
    }

    /**
     * Displays or hides the player controls.
     *
     * <p>If this player is not available on the panel, this method
     * call is added to the command-queue for later execution.
     */
    @Override
    public void setControllerVisible(final boolean show) {
        if (isPlayerOnPage(playerId)) {
            impl.setControlsVisible(show);
        } else {
            addToPlayerReadyCommandQueue("controller", new Command() {

                @Override
                public void execute() {
                    impl.setControlsVisible(show);
                }
            });
        }
    }

    /**
     * Sets the number of times the current media file should repeat playback before stopping.
     *
     * <p>If this player is not available on the panel, this method call is added
     * to the command-queue for later execution.
     */
    @Override
    public void setLoopCount(final int loop) {
        if (isPlayerOnPage(playerId)) {
            loopManager.setLoopCount(loop);
        } else {
            addToPlayerReadyCommandQueue("loop", new Command() {

                @Override
                public void execute() {
                    loopManager.setLoopCount(loop);
                }
            });
        }
    }

    @Override
    public void setResizeToVideoSize(boolean resize) {
        adjustToVideoSize = resize;
        if (isPlayerOnPage(playerId)) {
            // if player is on panel now update its size, otherwise
            // allow it to be handled by the MediaInfoHandler...
            checkVideoSize(getVideoHeight(), getVideoWidth());
        }
    }

    private void checkVideoSize(int vidHeight, int vidWidth) {
        String _h = _height, _w = _width;
        if (adjustToVideoSize) {
            if ((vidHeight > 0) && (vidWidth > 0)) {
                // adjust to video size ...
                fireDebug("Resizing Player : " + vidWidth + " x " + vidHeight);
                _w = vidWidth + "px";
                _h = vidHeight + "px";
            }
        }

        playerWidget.setSize("100%", _h);
        setWidth(_w);

        if (!_height.equals(_h) && !_width.equals(_w)) {
            firePlayerStateEvent(PlayerStateEvent.State.DimensionChangedOnVideo);
        }
    }

    @Override
    public void setRate(final double rate) {
        if (isPlayerOnPage(playerId)) {
            impl.setRate(rate);
        } else {
            addToPlayerReadyCommandQueue("rate", new Command() {

                @Override
                public void execute() {
                    impl.setRate(rate);
                }
            });
        }
    }

    @Override
    public double getRate() {
        checkAvailable();
        return impl.getRate();
    }

    private void checkAvailable() {
        if (!isPlayerOnPage(playerId)) {
            String message = "Player not available, create an instance";
            fireDebug(message);
            throw new IllegalStateException(message);
        }
    }

    @Override
    public void setShuffleEnabled(final boolean enable) {
        if (isPlayerOnPage(playerId)) {
            playlistManager.setShuffleEnabled(enable);
        } else {
            addToPlayerReadyCommandQueue("shuffle", new Command() {

                @Override
                public void execute() {
                    playlistManager.setShuffleEnabled(enable);
                }
            });
        }
    }

    @Override
    public boolean isShuffleEnabled() {
        checkAvailable();
        return playlistManager.isShuffleEnabled();
    }

    @Override
    public void addToPlaylist(String mediaURL) {
        playlistManager.addToPlaylist(mediaURL);
    }

    /**
     * Adds the media at the specified URLs to the players' playlist.  However, as
     * per the HTML 5 specification, the browser chooses ONLY ONE of the {@code mediaURLs}
     * it supports.
     *
     * <p>In respect of the same domain policy of some browsers, the URLs should point to
     * a destination on the same domain where the application is hosted.
     *
     * @param mediaURLs the alternative URLs of the same media (probably in different formats).
     * @since 1.2
     */
    @Override
    public void addToPlaylist(String... mediaURLs) {
        playlistManager.addToPlaylist(mediaURLs);
    }

    @Override
    public void addToPlaylist(MRL mediaLocator) {
        playlistManager.addToPlaylist(mediaLocator);
    }

    @Override
    public void addToPlaylist(List<MRL> mediaLocators) {
        playlistManager.addToPlaylist(mediaLocators);
    }

    @Override
    public void removeFromPlaylist(int index) {
        checkAvailable();
        playlistManager.removeFromPlaylist(index);
    }

    @Override
    public void clearPlaylist() {
        checkAvailable();
        playlistManager.clearPlaylist();
    }

    @Override
    public void playNext() throws PlayException {
        checkAvailable();
        playlistManager.playNext();
    }

    @Override
    public void playPrevious() throws PlayException {
        checkAvailable();
        playlistManager.playPrevious();
    }

    @Override
    public void play(int index) throws IndexOutOfBoundsException {
        checkAvailable();
        playlistManager.play(index);
    }

    @Override
    public int getPlaylistSize() {
        checkAvailable();
        return playlistManager.getPlaylistSize();
    }

    @Override
    public RepeatMode getRepeatMode() {
        return loopManager.getRepeatMode();
    }

    @Override
    public void setRepeatMode(RepeatMode mode) {
        loopManager.setRepeatMode(mode);
    }

    @Override
    public <C extends ConfigParameter> void setConfigParameter(C param, Object value) {
        super.setConfigParameter(param, value);
        if(param.getName().equals(DefaultConfigParameter.BackgroundColor.getName())) {
           
        }
    }
   
   

    private enum NetworkState {

        Empty, Idle, Loading, Loaded, NoSource
    }

    private enum MediaError {

        NoError, Aborted, NetworkError, DecodeError, UnsupportedMedia
    }

    private enum ReadyState {

        HaveNothing, HaveMetadata, CurrentData, FutureData, EnoughData
    }
}
TOP

Related Classes of com.bramosystems.oss.player.core.client.ui.NativePlayer

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.