Source: decorators/player/interfaces/playerinterface.js

define('application/decorators/player/interfaces/playerinterface', [
    'rofl/lib/utils',
    'rofl/class',
    'antie/runtimecontext',
    'rofl/media/source',
    'rofl/devices/mediaplayer/mediaplayer',
    'rofl/media/drm/item/playready'
], function (
    Utils,
    Class,
    RuntimeContext,
    MediaSource,
    MediaPlayer,
    PlayReadyItem
) {
    'use strict';

    var device = RuntimeContext.getCurrentApplication().getDevice(),
        mediaplayer = device.getMediaPlayer(),
        deviceBrand = device.getBrand(),
        AppcorePlaybackInterface;

    AppcorePlaybackInterface = Class.extend({

        /**
         * Initialises the widget.
         *
         * @param {*|PlayerProperties} playerProperties - The player properties.
         */
        initPlayer: function (playerProperties) {

            if (playerProperties) {
                this.setPlayerProperties(playerProperties);
            }
        },

        /**
         * Sets the media source.
         *
         * @param {Object} source - The media source being loaded.
         */
        setSrc: function (source) {
            this.source = source;
        },

        /**
         * Sets the media DRM if any.
         *
         * @param {Object} [drmConfig] - The media's DRM.
         */
        setDrm: function (drmConfig) {
            this.drmConfig = drmConfig;
        },

        /**
         * Sets the starting bitrate.
         *
         * @param {Object} startBitrate - The starting bitrate.
         */
        setStartBitrate: function (startBitrate) {
            this.startBitrate = startBitrate;
        },

        /**
         * Sets the player properties such as DRM and MediaSource.
         *
         * @param {Object} playerProperties - Object that contains different properties for the loading source.
         */
        setPlayerProperties: function (playerProperties) {
            var source = playerProperties.source,
                autoplay = playerProperties.autoplay,
                drmConfig = playerProperties.drmConfig;

            if (source === this._source) {
                return;
            }
            this.isLiveItem = playerProperties.isLiveItem;
            this.isRestartItem = playerProperties.isRestartItem;
            this.setSrc(source);
            this.setDrm(drmConfig);
            this.setStartBitrate(playerProperties.startBitrate);

            if (autoplay) {

                this.load()
                    .then(Utils.bind(this.play, this, playerProperties))
                    ['catch'](Utils.bind(this.onError, this));
            } else {
                this.load()
                    ['catch'](Utils.bind(this.onError, this));
            }
        },

        /**
         * Loads the new media source.
         *
         * @returns {*|Promise<any>} - The prepared media source.
         */
        load: function () {
            var mediaSource = new MediaSource(
                this.source.src,
                this.isLiveItem ? MediaPlayer.TYPE.LIVE_VIDEO : MediaPlayer.TYPE.VIDEO,
                this.source.mimeType
                ),
                drmConfig = this.drmConfig,
                drmItem;

            if (this.drmConfig) {
                drmItem = new PlayReadyItem();

                if (drmConfig.licenseServer) {
                    drmItem.setLicenseOverrideUri(drmConfig.licenseServer);
                }

                if (drmConfig.customData) {
                    drmItem.setCustomData(drmConfig.customData);
                }

                if (deviceBrand === 'hbbtv' || deviceBrand === 'lg') {
                    drmItem.setEmbeddedLicense(false);
                }

                drmItem.setProtectionHeaderUTF16(true);

                mediaSource.setDrmItem(drmItem);
            }

            if (this.startBitrate) {
                mediaSource.setStartBitRate(this.startBitrate);
            }

            this.mediaSource = mediaSource;

            if (deviceBrand !== 'lg' && this.mediaSource === mediaSource) {
                this._resetMediaPlayer();
                mediaplayer.setMediaSource(mediaSource);
            }

            return mediaSource.prepare()
                .then(Utils.bind(function () {

                    if (deviceBrand === 'lg' && this.mediaSource === mediaSource) {
                        this._resetMediaPlayer();
                        mediaplayer.setMediaSource(mediaSource);
                    }
                }, this))
                ['catch'](Utils.bind(this.onError, this));
        },

        /**
         * Resets/unloads the media player.
         */
        unload: function () {
            this._resetMediaPlayer();

            this.isLiveItem = null;
            this.isRestartItem = null;
            this.drmConfig = null;
            this.source = null;
            this.mediaSource = null;
            this.startTime = null;
            this.startBitrate = null;
        },

        /**
         * Unloads and removes any event callbacks.
         */
        destroy: function () {
            this.unload();

            mediaplayer.removeEventCallback(this, this._onEventCallback);
        },

        /**
         * Attepmts to play the given player properties from media source.
         *
         * @param {Object} playerProperties - Contains player properties such as source..
         */
        play: function (playerProperties) {
            var mediaSource = this.mediaSource,
                startTime = playerProperties && playerProperties.startTime,
                async = playerProperties && playerProperties.async;

            startTime = startTime || 0;

            if (playerProperties.source !== this.source) {

                // Source has changed since las time, there's another source coming up so discard playback.
                return;
            }

            if (!mediaSource) {
                throw 'MediaSource missing from player';
            }

            if (!this.isPlaying()) {
                if (!isNaN(startTime)) {
                    mediaplayer.beginPlaybackFrom(startTime, {
                        async: async
                    });
                } else {
                    mediaplayer.beginPlayback({
                        async: async
                    });
                }
            }
        },

        /**
         * Handles errors.
         *
         * @param {Object} error - An error event.
         */
        onError: function (error) {

            if (this._onError) {
                this._onError(error);
            }
        },

        /**
         * Pauses current playback.
         */
        pause: function () {
            mediaplayer.pause();
        },

        /**
         * Stops the current playback.
         */
        stop: function () {
            if (mediaplayer.getState() !== MediaPlayer.STATE.EMPTY) {
                mediaplayer.stop();
            }
        },

        /**
         * Resumes the current playback.
         */
        resume: function () {
            mediaplayer.resume();
        },

        /**
         * Seeks to the given value.
         *
         * @param {number} value - The time that the media player should attempt to play from.
         */
        seek: function (value) {
            mediaplayer.playFrom(value);
        },

        /**
         * Forward playback from value.
         *
         * @param {number} value - Value to go forward.
         */
        forward: function (value) {
            var playTime = mediaplayer.getCurrentTime() + value;

            if (playTime >= mediaplayer.getDuration() - 5) {
                playTime = mediaplayer.getDuration() - 5;
            }

            mediaplayer.playerFrom(playTime);
        },

        /**
         * Backward playback from value.
         *
         * @param {number} value - Value to go backwards.
         */
        backward: function (value) {
            var playTime = mediaplayer.getCurrentTime() - value;

            if (playTime < 0) {
                playTime = 0;
            }

            mediaplayer.playerFrom(playTime);
        },

        /**
         * Gets the currents time from media player.
         *
         * @returns {number} - The media player's current playback time.
         */
        getCurrentTime: function () {
            return mediaplayer.getCurrentTime();
        },

        /**
         * Gets the duration of the playback content.
         *
         * @returns {number} - The content's duration.
         */
        getDuration: function () {
            return mediaplayer.getDuration();
        },

        /**
         * Checks if the video is live type.
         *
         * @returns {boolean} - True if the video type is live item.
         */
        isLive: function () {
            return this.isLiveItem;
        },

        /**
         * Checks if the video is restart type.
         *
         * @returns {boolean} - True if the video type is restart item.
         */
        isRestart: function () {
            return this.isRestartItem;
        },

        /**
         * Checks if the media player state is playing.
         *
         * @returns {boolean} - True if the media player state is playing.
         */
        isPlaying: function () {
            return mediaplayer.getState() === MediaPlayer.STATE.PLAYING;
        },

        /**
         * Checks if the media player state is playing.
         *
         * @returns {boolean} - True if the media player state is playing.
         */
        isPaused: function () {
            return mediaplayer.getState() === MediaPlayer.STATE.PAUSED;
        },

        /**
         * Sets a listener for mediaplayer events.
         *
         * @param {Function} listener - Event listener for media player events.
         */
        listen: function (listener) {
            this._listener = listener;

            mediaplayer.addEventCallback(this, this._onEventCallback);
        },

        /**
         * Handles event callback through listener.
         *
         * @param {Object} e - Media player event.
         * @private
         */
        _onEventCallback: function (e) {

            if (this._listener) {
                this._listener(e);
            }

            // TODO Error logging.
        },

        /**
         * Shorthand for resetting the device mediaplayer.
         *
         * @private
         */
        _resetMediaPlayer: function () {
            var mediaPlayerState = mediaplayer.getState();

            if (mediaPlayerState !== MediaPlayer.STATE.STOPPED
                && mediaPlayerState !== MediaPlayer.STATE.EMPTY
                && mediaPlayerState !== MediaPlayer.STATE.ERROR) {
                mediaplayer.stop();
            }

            mediaPlayerState = mediaplayer.getState();

            if (mediaPlayerState !== MediaPlayer.STATE.EMPTY) {
                mediaplayer.reset();
            }
        }
    });

    AppcorePlaybackInterface.EVENTS = MediaPlayer.EVENT;

    return AppcorePlaybackInterface;
});