define('application/components/players/live', [
'application/components/player',
'application/helpers/playerproperties',
'application/helpers/drmconfig',
'application/views/player/live',
'rofl/lib/utils',
'rofl/events/keyevent',
'rofl/lib/promise',
'antie/runtimecontext',
'application/managers/api',
'application/managers/channel',
'application/managers/progress',
'application/widgets/player/liveseeker',
'application/constants',
'application/utils',
'application/managers/player',
'application/models/epg/item',
'application/decorators/player/livemanipulation',
'application/decorators/player/interface',
'application/managers/session',
'rofl/analytics/web/google'
], function (
Component,
PlayerProperties,
DRMConfig,
LiveView,
Utils,
KeyEvent,
Promise,
RuntimeContext,
ApiManager,
ChannelManager,
ProgressManager,
Seeker,
Constants,
AppUtils,
PlayerManager,
EPGItem,
PlayerManipulation,
PlaybackInterface,
SessionManager,
GoogleAnalytics
) {
'use strict';
var api = ApiManager.getKPNAPI(),
channelManager = ChannelManager.getInstance(),
application = RuntimeContext.getCurrentApplication(),
configuration = application.getConfiguration(),
LIVE_PROGRESS_TIMEOUT = configuration.player.liveProgressTimeout,
CHANNEL_SWITCHER_TIMEOUT = configuration.channelSwitcherTimeout,
GA = GoogleAnalytics.getInstance(),
sessionManager = SessionManager.getInstance();
return Component.extend({
/**
* Sets the view for the player.
*
* @private
*/
_setView: function () {
this._view = new LiveView({
mouseOverHandler: Utils.bind(function () {
if (this._view.supportsPointer()) {
this._showUI();
}
}, this)
});
this.appendChildWidget(this._view);
},
/**
* Sets the given program.
*
* @param {Object} program - The program to set.
* @returns {Promise} - Solved promise with program.
* @private
*/
_setProgram: function (program) {
this._view.setProgram(program);
this._program = program;
this._startTime = new Date(program.getStartTime() * 1000);
this._endTime = new Date(program.getEndTime() * 1000);
// Attach seeker once the program is set.
this._buildSeeker();
// We can start progress at this point.
this._setProgress();
if (AppUtils.isBroadcastLocked(program)) {
application.hideLoader();
this._checkingParental = true;
this.playerInterface.unload();
this._playbackStatus.active = false;
this._showParental({
successCallback: Utils.bind(this._onParentalSuccess, this, program),
errorCallback: Utils.bind(this._onBack, this),
escapeCallback: Utils.bind(this._tunePreviousChannel, this),
keyEventCallback: Utils.bind(this._zapChannel, this)
});
// Close detail info if program is locked.
if (this._view.getProgramDetails().isExpanded()) {
this._view.closeExpandedContents();
}
this._view.hideUI();
return Promise.resolve(program);
}
// Sets the new program's detail info if it's expanded.
if (this._view.getProgramDetails().isExpanded()) {
this._requestDetailInfo()
.then(Utils.bind(this._onInfo, this, true));
}
// Set current program if channel stream is already playing.
if (this.playerInterface.isPlaying()) {
this._currentProgram = program;
}
return Promise.resolve(program);
},
/**
* Prepares player to reset state and prepares playback.
* Gets executed at:
* 1.- initial playback.
* 2.- zapping channel.
* 3.- Toggle from live to restart.
* 4.- Toggle from restart to live.
*
* @param {Object} playbackData - Playback content data.
* @param {Object} playbackData.type - The video playback data.
* @private
*/
_preparePlayer: function (playbackData) {
var programData = playbackData.data,
channelId = programData && programData.getChannelId() || playbackData.getId(),
type = playbackData.type || Constants.LIVE_VIDEO_TYPE;
this._view.focus();
this._view.hideWarningBox(true);
this._type = type;
this._restartStartTime = playbackData.startTime;
if (type === Constants.LIVE_VIDEO_TYPE) {
this._delayedStreamTime = null;
this._pauseTime = null;
this._delayedStartTime = null;
} else if (!this._restartStartTime) {
this._pauseTime = programData.getStartTime() * 1000;
}
this._preparePlayback(channelId, true);
},
/**
* Prepares channel and broadcast event, requests streams and will start playback.
*
* @param {number} channelId - The channelId to be tuned.
* @param {boolean} toggleStartoverLive - True if new stream should be requested.
* @private
*/
_preparePlayback: function (channelId, toggleStartoverLive) {
// Don't prepare playback if there's a parental modal.
if (this._checkingParental) {
return;
}
if (this._channelId !== channelId || toggleStartoverLive) {
channelManager.setLastWatchedChannel(this._channelId || channelId);
this._channelId = channelId;
this.playerInterface.unload();
this._playbackStatus.active = false;
// Resets to play button.
this._view.onPlay();
this._getCurrentBroadcastForChannel(channelId)
.then(Utils.bind(this._setProgram, this))
.then(Utils.bind(this._requestStream, this));
} else {
// If broadcast is already set, just update the program.
this._playbackStatus.active = true;
this._updateProgram(channelId);
}
},
/**
* Updates the program data for the given channelId.
*
* @param {number} channelId - The channel id to get its current broadcast.
* @private
*/
_updateProgram: function (channelId) {
this._getCurrentBroadcastForChannel(channelId)
.then(Utils.bind(this._setProgram, this))
.then(Utils.bind(application.hideLoader, application))
['catch'](Utils.bind(this._onPlayerError, this));
},
/**
* Requests the content's stream data.
*
* @param {Object} program - The requested program.
* @returns {Object} - Stream data.
*/
_requestStream: function (program) {
var headers = {},
channel = program && program.getChannel && program.getChannel() || program,
channelId = channel && channel.getId(),
promises = [],
isLive = this._type === Constants.LIVE_VIDEO_TYPE;
if (this._streamWithParental || program &&
(program.isLocked() || program.streamRequiresPin())) {
headers.pcPin = this.get;
this._streamWithParental = false;
}
// Get the streams if we're not checking parental.
if (!this._checkingParental) {
if (isLive) {
this._pauseTime = null;
}
promises.push(Promise.resolve(program));
promises.push(api.read('streams/live', {
params: {
type: this._type,
assetId: channel.getAssetId(),
contentId: channelId,
startTime: program.getStartTime() * 1000
},
withCredentials: true,
headers: this.getStreamHeaders(program)
}));
return Promise.all(promises)
.then(Utils.bind(this._startPlayback, this))
['catch'](Utils.bind(this._onPlayerError, this));
}
this._view.hideUI();
},
/**
* Prepares the player properties, sets the miniEPG channel, attempts to start playback.
*
* @param {Array} dataParams - Parameters needed to create properties and miniEPG update.
* @param {Object} dataParams.0 - Contains the current broadcasting program.
* @param {Object} dataParams.1 - Contains the stream data.
* @private
*/
_startPlayback: function _startPlayback (dataParams) {
var program = dataParams[0],
data = dataParams[1],
channelId = program.getChannelId(),
restartTime,
properties,
programStartTime;
if (this._type === Constants.RESTART_VIDEO_TYPE) {
programStartTime = program.getStartTime() * 1000;
restartTime = this._restartStartTime || programStartTime;
}
properties = new PlayerProperties({
source: {
src: data.url,
mimeType: data.mimeType || PlayerProperties.MIME_TYPES.ssm
},
startTime: restartTime,
programStartTime: programStartTime,
delayedStartTime: this._delayedStartTime,
pauseTime: this._pauseTime,
async: true,
autoplay: true,
isLiveItem: this._type === Constants.LIVE_VIDEO_TYPE,
isRestartItem: this._type === Constants.RESTART_VIDEO_TYPE,
drmConfig: new DRMConfig({
type: DRMConfig.TYPES.PLAYREADY,
options: {
licenseServer: data.licenseUrl
}
})
});
if (this._channelId === channelId) {
// Sets data for miniEPG.
this._view.getMiniEPG().setChannel(channelId);
_startPlayback.base.call(this, properties);
}
},
/**
* Parental pin success callback.
*
* @param {Object} program - THe program that was unlocked.
* @private
*/
_onParentalSuccess: function (program) {
// Update Program info.
this._setProgram(program)
.then(Utils.bind(this._requestStream, this));
},
/**
* On before show event.
*
* @param {Object} e - The on before show event data.
*/
onBeforeShow: function onBeforeShow (e) {
this._keys = '';
onBeforeShow.base.call(this, e);
},
/**
* PlayerEvent.
*
* @param {Object} e - The player event data.
* @private
*/
onPlayerEvent: function onPlayerEvent (e) {
switch (e.type) {
case this.MEDIA_PLAYER_EVENTS.ERROR:
case this.MEDIA_PLAYER_EVENTS.BITRATE_CHANGED:
onPlayerEvent.base.call(this, e);
break;
case this.MEDIA_PLAYER_EVENTS.PLAYING:
/**
* Set delayed stream time to be used on player properties
* when toggling from live to restart.
*/
if (this._type === Constants.LIVE_VIDEO_TYPE && !this._delayedStreamTime) {
this._delayedStartTime = this.playerInterface.getCurrentTime();
} else {
this._delayedStartTime = null;
}
this._sendZapAnalytics();
onPlayerEvent.base.call(this, e);
break;
case this.MEDIA_PLAYER_EVENTS.PAUSED:
if (this._progress !== null && (this._progress.behind >= 0 || isNaN(this._progress.behind))) {
this._pauseTime = application.getDate().getTime();
}
onPlayerEvent.base.call(this, e);
break;
case this.MEDIA_PLAYER_EVENTS.STATUS:
if (!this._program.isLive() && !this._pauseTime) {
// Restart playback.
if (this._currentProgram === this._program) {
application.hideLoader();
if (!this._playbackStatus.active) {
this._showUI();
this._playbackStatus.active = true;
}
}
} else if (this._currentProgram === this._program && !this._playbackStatus.active) {
application.hideLoader();
if (!this._playbackStatus.active && this.playerInterface.isPlaying()) {
this._showUI();
this._playbackStatus.active = true;
}
}
break;
}
},
/**
* Starts the live progress.
*
* @private
*/
_setProgress: function () {
this._stopLiveProgressTimeout();
if (this._type === Constants.LIVE_VIDEO_TYPE) {
this._setLiveProgress();
} else {
this._setCurrentTimeToSeeker();
}
this._liveProgressInterval = setInterval(
Utils.bind(this._setLiveProgress, this),
LIVE_PROGRESS_TIMEOUT);
},
/**
* Sets the live progress.
*
* @param {boolean} [preventSeekingWhileLoading] - Prevent seeking on timeline while loading restart..
* @private
*/
_setLiveProgress: function (preventSeekingWhileLoading) {
var program = this._program,
startTime = new Date(program.getStartTime() * 1000),
endTime = new Date(program.getEndTime() * 1000),
progress = this._progress = ProgressManager.getLiveProgressPercentage(
startTime,
endTime,
this._pauseTime),
currentTime;
// Check if the progress is behind the current time.
if (this.playerInterface.isPlaying() && progress.behind < 0) {
currentTime = application.getDate();
this._pauseTime = currentTime.getTime() + progress.behind + 1000;
}
if (preventSeekingWhileLoading && !this._pauseTime && this._restartStarted) {
return;
}
this._restartStarted = false;
PlayerManager.setLivePlaybackPosition(this._pauseTime || application.getDate().getTime());
if (this.playerInterface.isPlaying()) {
if (this._seeker && typeof this._seeker.setCurrentTime === 'function') {
if (this._pauseTime) {
this._seeker.setCurrentTime(this._pauseTime);
} else {
this._seeker.setCurrentTime(application.getDate().getTime());
}
}
}
// Checks if second head has finished to request the next program.
if (progress.secondHead >= 100) {
// First cancel the timeout.
this._stopLiveProgressTimeout();
// Retrieve the new program.
this._updateProgram(program.getChannelId());
}
this._view.setProgress(progress);
},
/**
* Sets the live progress.
*
* @param {Date} fixedTime - Time when button was pressed.
* @private
*/
_setRestartProgress: function (fixedTime) {
var program = this._program,
startTime = new Date(program.getStartTime() * 1000),
endTime = new Date(program.getEndTime() * 1000),
currentTime = application.getDate(),
behind = fixedTime - startTime,
progress;
this._pauseTime = currentTime.getTime() - behind;
progress = this._progress = ProgressManager.getRestartProgressPercentage(
startTime,
endTime,
behind);
if (progress.secondHead >= 100) {
// First cancel the timeout.
this._stopRestartProgressTimeout();
// Retrieve the new program.
this._updateProgram(program.getChannelId());
}
this._view.setProgress(progress);
},
/**
* Retrieves current broadcast program from the given channelId.
* Note: If Restart is playing, request broadcast with time.
*
* @param {number} channelId - Channel Id to retrieve current program.
* @returns {Object} - The current broadcast program for the given channelId.
* @private
*/
_getCurrentBroadcastForChannel: function (channelId) {
if (this._pauseTime && this._progress) {
return channelManager.getBroadcastAtTime(channelId,
application.getDate() - Math.abs(this._progress.behind))
|| this.createMissingEpgData(channelId);
}
return channelManager.getCurrentBroadcastForChannel(channelId) || this.createMissingEpgData(channelId);
},
/**
* Creates any missing information for missing epgData item.
*
* @param {number} channelId - ChannelId of the missing epgData item.
* @returns {*} - The new epgItem created from channel.
*/
createMissingEpgData: function (channelId) {
return new EPGItem({}, channelManager.getChannelById(channelId));
},
/**
* KeyDown event.
*
* @param {Object} e - The event data.
* @private
*/
_onKeyDown: function _onKeyDown (e) {
// Prevents losing focus when an error is triggered but error component is loading.
if (this._errorState) {
return;
}
switch (e.keyCode) {
case KeyEvent.VK_CHANNEL_UP:
case KeyEvent.VK_CHANNEL_DOWN:
// Don't set keyHold while parental is being loaded. Prevents async triggers.
if (this._deviceBrand === 'samsung' && !this._checkingParental) {
this._setKeyHoldData(e, this.onKeyHoldHandler);
} else {
this._showUI(true);
this._zapChannel(e);
}
e.preventDefault();
e.stopPropagation();
break;
case KeyEvent.VK_REWIND:
case KeyEvent.VK_FAST_FWD:
if (this._program && this._program.hasEpgData()) {
_onKeyDown.base.call(this, e);
}
break;
case KeyEvent.VK_0:
case KeyEvent.VK_1:
case KeyEvent.VK_2:
case KeyEvent.VK_3:
case KeyEvent.VK_4:
case KeyEvent.VK_5:
case KeyEvent.VK_6:
case KeyEvent.VK_7:
case KeyEvent.VK_8:
case KeyEvent.VK_9:
this._handleSwitchChannel(e);
break;
default:
_onKeyDown.base.call(this, e);
}
},
/**
* KeyDown hold event. Currently supports channel up/down for Samsung RC.
*
* @param {Object} e - The event data.
* @param {boolean} keyHoldTriggered - True if triggered by keyHold timeout or cancel by keyup event.
* @private
*/
onKeyHoldHandler: function (e, keyHoldTriggered) {
var hideMiniEPG = this._view.getMiniEPG().isExpanded();
/**
* Prevents losing focus when an error is triggered but error component is loading.
* Key hold handler may be executed after showing error.
*/
if (this._errorState) {
return;
}
switch (e.keyCode) {
case KeyEvent.VK_CHANNEL_UP:
case KeyEvent.VK_CHANNEL_DOWN:
if (keyHoldTriggered && !this._checkingParental) {
this._view.showMiniEPG(hideMiniEPG);
if (hideMiniEPG) {
this._view.focus();
} else {
if (!this._view.isUIVisible()) {
this._showUI();
}
this._view.getMiniEPG().focus();
}
} else {
this._zapChannel(e);
}
break;
}
},
/**
* Prepares to zap to next or previous channel depending on key event.
*
* @param {Object} ev - Key Event.
*/
_zapChannel: function (ev) {
var channelToSwitch,
currentChannel = channelManager.getChannelById(this._channelId);
if (ev.keyCode === KeyEvent.VK_CHANNEL_UP) {
channelToSwitch = channelManager.getNextChannel(currentChannel);
} else {
channelToSwitch = channelManager.getPreviousChannel(currentChannel);
}
this._zapToChannel(channelToSwitch);
},
/**
* Zaps to the given channel.
*
* @param {Object} channel - Chanel to zap to..
*/
_zapToChannel: function (channel) {
this._switchChannelStartTime = application.getDate();
this._clearChannelInput();
this._preparePlayer(channel);
},
/**
* Handle switching the channel with numeric input.
*
* @param {Object} e - The event parameters.
* @private
*/
_handleSwitchChannel: function (e) {
if (this._keys.length >= 3) {
this._keys = '';
}
this._keys += e.keyChar;
if (this._view.isUIVisible()) {
this._view.hideUI({
duration: 500
});
}
this._setChannelSwitchNumber();
},
/**
* Sets the channel switching number.
*
* @private
*/
_setChannelSwitchNumber: function () {
var timeoutValue = CHANNEL_SWITCHER_TIMEOUT;
this._cancelChannelInput();
this._view.setChannelSwitcherLabel(this._keys);
this._inputTimeout = setTimeout(Utils.bind(function () {
this._zapToChannel(channelManager.getChannelByNumber(this._keys));
this._clearChannelInput();
}, this), timeoutValue);
},
/**
* Cancels the channel input zapping.
*
* @private
*/
_cancelChannelInput: function () {
if (this._inputTimeout) {
clearTimeout(this._inputTimeout);
this._inputTimeout = null;
}
},
/**
* Clears the channel input widget.
*/
_clearChannelInput: function () {
this._cancelChannelInput();
this._keys = '';
this._view.setChannelSwitcherLabel();
},
/**
* Attempts to tune previous channel from the given program.
*
* @private
*/
_tunePreviousChannel: function () {
var previousChannelId = channelManager.getLastWatchedChannel(),
channelToSwitch;
// Check if there's a previous channel id, otherwise go back.
if (previousChannelId && previousChannelId !== this._channelId) {
channelToSwitch = channelManager.getChannelById(previousChannelId);
this._zapToChannel(channelToSwitch);
} else {
this._onBack();
}
},
/**
* Select event.
*
* @param {Object} e - The event data.
* @private
*/
_onSelect: function _onSelect (e) {
var target = e.target,
dataItem,
dataItemChannel;
if (this._view.isUIVisible()) {
switch (target.id) {
case LiveView.CONTROLS.INFO:
case LiveView.CONTROLS.MENU:
case LiveView.CONTROLS.PLAYPAUSE:
// Falls through common actions
_onSelect.base.call(this, e);
break;
case LiveView.CONTROLS.REWIND:
case LiveView.CONTROLS.FORWARD:
if (this._program && this._program.hasEpgData()) {
_onSelect.base.call(this, e);
}
break;
case LiveView.CONTROLS.RESTART:
this._onRestart();
break;
case LiveView.CONTROLS.RECORD:
this._onRecord();
break;
case LiveView.CONTROLS.MINIEPG:
this._onMiniEPG();
break;
case LiveView.CONTROLS.BACK:
this._view.closeExpandedContents();
this._onBack();
break;
case LiveView.CONTROLS.LIVE:
this._onLive();
break;
}
if (target.hasClass('carouselItem')) {
dataItem = target.getChildWidgetByIndex(0).getDataItem().item;
dataItemChannel = channelManager.getChannelById(dataItem.getChannelId());
if (dataItem.isLocked() && !sessionManager.getUserPin()) {
this._showParental({
successCallback: Utils.bind(this._onMiniEPGProgram, this, dataItemChannel),
escapeCallback: Utils.bind(this._onMiniEPGCancelled, this)
});
} else {
this._onMiniEPGProgram(dataItemChannel);
}
}
} else {
this._showUI();
}
},
/**
* Builds the live seeker.
*
* @private
*/
_buildSeeker: function () {
var program = this._program,
playbackTime = application.getDate().getTime(),
startTime = program.getStartTime() * 1000,
endTime = program.getEndTime() * 1000;
if (this._seeker && this._seeker.isActive()) {
this._seeker.detach();
this._seeker = null;
}
this._seeker = Seeker();
this._seeker.attach({
onSpeedChanged: this._onSeekSpeedChangeBound,
onSeek: this._onSeekBound,
onCurrentTimeUpdated: this._onSeekCurrentTimeChangeBound,
steps: configuration.player.seekSteps
});
if (this._pauseTime) {
playbackTime = this._pauseTime;
}
this._seeker.setProgramTime(startTime, endTime, playbackTime);
},
/**
* Gets executed when the seek is confirmed.
*
* @param {Object} e - The seek event data.
* @private
*/
_onSeek: function (e) {
var isLive = this._type === Constants.LIVE_VIDEO_TYPE,
isRestart = this._type === Constants.RESTART_VIDEO_TYPE;
this._seekSpeed = null;
this._seekCurrentTime = null;
this._view.resetControls();
this._view.setProgressMaxPointerPosition();
this._setProgress();
// Below only gets executed for live trickplay.
if (e && e.seekTo) {
if (isLive) {
if (e.currentTime >= application.getDate()) {
this._onLive();
} else {
this._pauseTime = e.currentTime;
this._onRestart(e.seekTo);
}
} else if (isRestart) {
if (e.currentTime >= application.getDate()) {
this._onLive();
} else {
this.playerInterface.resume();
if (e.relativePlaybackTime === 0) {
this._pauseTime = this._program.getStartTime() * 1000;
this.playerInterface.seek(0);
} else {
this._pauseTime = e.currentTime;
this.playerInterface.seek(e.seekTo);
}
}
}
}
},
/**
* Gets executed when the current seek time changes for live video.
*
* @param {Object} data - The data.
* @param {number} data.currentTime - The current seek time.
* @param {number} data.relativePlaybackTime - The current relative playback time.
*
* @private
*/
_onSeekCurrentTime: function (data) {
var programStart = this._program.getStartTime() * 1000,
seeker = this._seeker,
currentSeekTime = data.currentTime,
maxSeekTime = PlayerManager.getMaxSeekValue() * 1000,
now = application.getDate();
if (currentSeekTime < programStart) {
this._stopLiveProgressTimeout();
if (this._type === Constants.LIVE_VIDEO_TYPE) {
this._pauseTime = programStart;
this._onRestart();
} else {
seeker.confirm(programStart);
}
return;
}
if (currentSeekTime >= now) {
this._confirmSeekerToLive();
}
if (!this._program.canSeek()
&& seeker.getDirection() === 1
&& data.relativePlaybackTime > maxSeekTime) {
seeker.confirm(programStart + maxSeekTime);
return;
}
this._pauseTime = currentSeekTime;
this._setLiveProgress();
},
/**
* Sets the value of time to seeker.
*
* @private
*/
_setCurrentTimeToSeeker: function () {
var timeValue,
program = this._program,
seeker = this._seeker,
currentTime = application.getDate();
timeValue = currentTime.getTime() / 1000 - program.getStartTime();
seeker.setCurrentTime(timeValue);
},
/**
* VOD Mouse Seek event.
*
* @param {Object} e - The event data.
* @param {number} e.percentage - The seek percentage.
* @param {boolean} e.finished - True if the mouse seek event has finished.
* @private
*/
_onMouseSeek: function (e) {
var start = this._program.getStartTime() * 1000,
end = this._program.getEndTime() * 1000,
now = application.getDate(),
seeker = this._seeker,
duration = end - start,
difference = (duration / 100) * (100 - e.percentage),
seekTo = end - difference;
this._pauseTime = Math.round(seekTo);
this._setLiveProgress();
if (!this._prevProgress) {
this._prevProgress = e.percentage;
}
if (e.finished) {
this._seeking = this._getMouseSeekDirection(this._prevProgress, e.percentage);
this._sendTrickplayAnalytics();
this._prevProgress = e.percentage;
if (seekTo < start) {
if (this._type === Constants.LIVE_VIDEO_TYPE) {
this._pauseTime = start;
this._onRestart();
} else {
seeker.confirm(start);
}
return;
}
// Because of timing add 10 seconds to this check.
if ((seekTo + 10000) >= now) {
this._confirmSeekerToLive();
} else {
seeker.confirm(seekTo);
}
}
},
/**
* Intentionally set the playfrom time higher than the current date.
* This way the seeker will think it's past the live moment and start
* playing from live.
*
* @private
*/
_confirmSeekerToLive: function () {
var seeker = this._seeker,
playFrom = application.getDate(); // now
playFrom.setMinutes(playFrom.getMinutes() + 1);
seeker.setCurrentTime(playFrom.getTime());
seeker.confirm(playFrom.getTime());
},
/**
* Returns the player manipulation decorator.
*
* @returns {Object} - Player manipulation decorator.
*/
getPlayerManipulation: function () {
return PlayerManipulation;
},
/**
* Gets the playback interface.
*
* @returns {Object} - The playback interface.
*/
getPlaybackInterface: function () {
return new PlaybackInterface();
},
/**
* Sends the zap analytics when video start playing.
*
* @private
*/
_sendZapAnalytics: function () {
var timeOfLoadingChannel;
if (this._switchChannelStartTime) {
timeOfLoadingChannel = application.getDate() - this._switchChannelStartTime;
GA.onEvent(Constants.ANALYTICS_EVENT_CATEGORY_PLAYER,
Constants.ANALYTICS_EVENT_ACTION_ZAP,
{
eventLabel: this._program.getChannelId(),
eventValue: timeOfLoadingChannel
}
);
this._switchChannelStartTime = null;
}
},
/**
* On back action.
*
* @private
*/
_onBack: function _onBack () {
GA.onEvent(Constants.ANALYTICS_EVENT_CATEGORY_ACTION,
Constants.ANALYTICS_EVENT_ACTION_STOP_VIDEO,
{
eventLabel: AppUtils.getAnalyticsEventLabel(this._type)
}
);
this._view.hideUI({
skipAnim: true
});
this._view.resetControls();
this.playerInterface.destroy();
_onBack.base.call(this);
this._stopProgressTimeouts();
this._clearChannelInput();
this._keys = '';
this._pauseTime = null;
this._delayedStreamTime = null;
this._delayedStartTime = null;
this._channelId = null;
this._playbackStatus.active = false;
},
/**
* Close player.
*/
closePlayer: function closePlayer () {
GA.onEvent(Constants.ANALYTICS_EVENT_CATEGORY_ACTION,
Constants.ANALYTICS_EVENT_ACTION_STOP_VIDEO,
{
eventLabel: AppUtils.getAnalyticsEventLabel(this._type)
}
);
this._view.hideUI({
skipAnim: true
});
this._view.resetControls();
this.playerInterface.destroy();
closePlayer.base.call(this);
this._stopProgressTimeouts();
this._clearChannelInput();
this._keys = '';
this._pauseTime = null;
this._delayedStreamTime = null;
this._delayedStartTime = null;
this._channelId = null;
this._playbackStatus.active = false;
}
});
});