(function () {
function createVideoPlayer(self) {
var timeout;
var initialVolume;
var idleState = true;
var muteButton = null;
var unmuteButton = null;
var volumeSlider = null;
var positionSlider;
var isPositionSliderActive;
var currentTimeElement;
self.currentSubtitleStreamIndex = null;
self.getCurrentSubtitleStream = function () {
return self.getSubtitleStream(self.currentSubtitleStreamIndex);
};
self.getSubtitleStream = function (index) {
return self.currentMediaSource.MediaStreams.filter(function (s) {
return s.Type == 'Subtitle' && s.Index == index;
})[0];
};
self.toggleFullscreen = function () {
if (self.isFullScreen()) {
self.exitFullScreen();
} else {
requestFullScreen(document.body);
}
};
self.resetEnhancements = function () {
$("#mediaPlayer").hide();
$('#videoPlayer').removeClass('fullscreenVideo').removeClass('idlePlayer');
$('.hiddenOnIdle').removeClass("inactive");
$("video").remove();
};
self.exitFullScreen = function () {
if (document.exitFullscreen) {
document.exitFullscreen();
} else if (document.mozExitFullScreen) {
document.mozExitFullScreen();
} else if (document.webkitExitFullscreen) {
document.webkitExitFullscreen();
} else if (document.msExitFullscreen) {
document.msExitFullscreen();
}
$('#videoPlayer').removeClass('fullscreenVideo');
};
self.isFullScreen = function () {
return document.fullscreen || document.mozFullScreen || document.webkitIsFullScreen || document.msFullscreenElement ? true : false;
};
function onFlyoutClose() {
$('.itemVideo').css('visibility', 'visible');
}
function onPopupOpen(elem) {
elem.popup("open").parents(".ui-popup-container").css("margin-top", 30);
if ($.browser.safari) {
$('.itemVideo').css('visibility', 'hidden');
}
}
self.showChaptersFlyout = function () {
var html = getChaptersFlyoutHtml();
var elem = $('.videoChaptersPopup').html(html)
.trigger('create')
.popup("option", "positionTo", $('.videoChaptersButton'))
.off('popupafterclose', onFlyoutClose)
.on('popupafterclose', onFlyoutClose);
onPopupOpen(elem);
};
self.showSubtitleMenu = function () {
var html = getSubtitleTracksHtml();
if (!supportsContentOverVideoPlayer()) {
showPopupUsingSelect(html, 'subtitles');
return;
}
var elem = $('.videoSubtitlePopup').html(html)
.trigger('create')
.popup("option", "positionTo", $('.videoSubtitleButton'))
.off('popupafterclose', onFlyoutClose)
.on('popupafterclose', onFlyoutClose);
onPopupOpen(elem);
};
self.showQualityFlyout = function () {
var html = getQualityFlyoutHtml();
if (!supportsContentOverVideoPlayer()) {
showPopupUsingSelect(html, 'quality');
return;
}
var elem = $('.videoQualityPopup').html(html)
.trigger('create')
.popup("option", "positionTo", $('.videoQualityButton'))
.off('popupafterclose', onFlyoutClose)
.on('popupafterclose', onFlyoutClose);
onPopupOpen(elem);
};
self.showAudioTracksFlyout = function () {
var html = getAudioTracksHtml();
if (!supportsContentOverVideoPlayer()) {
showPopupUsingSelect(html, 'audio');
return;
}
var elem = $('.videoAudioPopup').html(html)
.trigger('create')
.popup("option", "positionTo", $('.videoAudioButton'))
.off('popupafterclose', onFlyoutClose)
.on('popupafterclose', onFlyoutClose);
onPopupOpen(elem);
};
function openSelect(selector) {
var element = $(selector)[0], worked = false;
if (document.createEvent) { // all browsers
var e = document.createEvent("MouseEvents");
e.initMouseEvent("mousedown", true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
worked = element.dispatchEvent(e);
} else if (element.fireEvent) { // ie
worked = element.fireEvent("onmousedown");
}
if (!worked) { // unknown browser / error
}
}
function showPopupUsingSelect(html, type) {
var re = new RegExp('
', 'g');
html = html.replace(re, ' ');
var options = $('.mediaPopupOption', $(html)).get().map(function (e) {
var selected = $(e).hasClass('selectedMediaPopupOption') ? ' selected="selected"' : '';
return '';
});
html = '';
var select = $(html).appendTo(document.body).on('change', function () {
var value = this.value;
$(this).remove();
if (type == 'audio') {
onAudioOptionSelected(value);
}
else if (type == 'subtitles') {
onSubtitleOptionSelected(value);
}
else if (type == 'quality') {
onQualityOptionSelected(value);
}
}).on('blur', function () {
$(this).remove();
});
openSelect(select);
}
self.setAudioStreamIndex = function (index) {
self.changeStream(self.getCurrentTicks(), { AudioStreamIndex: index });
};
self.setSubtitleStreamIndex = function (index) {
if (!self.supportsTextTracks()) {
self.changeStream(self.getCurrentTicks(), { SubtitleStreamIndex: index });
self.currentSubtitleStreamIndex = index;
return;
}
var currentStream = self.getCurrentSubtitleStream();
var newStream = self.getSubtitleStream(index);
if (!currentStream && !newStream) return;
var selectedTrackElementIndex = -1;
if (currentStream && !newStream) {
if (currentStream.DeliveryMethod != 'External') {
// Need to change the transcoded stream to remove subs
self.changeStream(self.getCurrentTicks(), { SubtitleStreamIndex: -1 });
}
}
else if (!currentStream && newStream) {
if (newStream.DeliveryMethod == 'External') {
selectedTrackElementIndex = index;
} else {
// Need to change the transcoded stream to add subs
self.changeStream(self.getCurrentTicks(), { SubtitleStreamIndex: index });
}
}
else if (currentStream && newStream) {
if (newStream.DeliveryMethod == 'External') {
selectedTrackElementIndex = index;
if (currentStream.DeliveryMethod != 'External') {
self.changeStream(self.getCurrentTicks(), { SubtitleStreamIndex: -1 });
}
} else {
// Need to change the transcoded stream to add subs
self.changeStream(self.getCurrentTicks(), { SubtitleStreamIndex: index });
}
}
self.setCurrentTrackElement(selectedTrackElementIndex);
self.currentSubtitleStreamIndex = index;
};
self.setCurrentTrackElement = function (index) {
var modes = ['disabled', 'showing', 'hidden'];
var textStreams = self.currentMediaSource.MediaStreams.filter(function (s) {
return s.DeliveryMethod == 'External';
});
var newStream = textStreams.filter(function (s) {
return s.Index == index;
})[0];
var trackIndex = newStream ? textStreams.indexOf(newStream) : -1;
console.log('Setting new text track index to: ' + trackIndex);
var allTracks = self.currentMediaElement.textTracks; // get list of tracks
for (var i = 0; i < allTracks.length; i++) {
var mode;
if (trackIndex == i) {
mode = 1; // show this track
} else {
mode = 0; // hide all other tracks
}
console.log('Setting track ' + i + ' mode to: ' + mode);
// Safari uses integers for the mode property
// http://www.jwplayer.com/html5/scripting/
var useNumericMode = false;
if (!isNaN(allTracks[i].mode)) {
useNumericMode = true;
}
if (useNumericMode) {
allTracks[i].mode = mode;
} else {
allTracks[i].mode = modes[mode];
}
}
};
self.updateTextStreamUrls = function (startPositionTicks) {
if (!self.supportsTextTracks()) {
return;
}
var allTracks = self.currentMediaElement.textTracks; // get list of tracks
for (var i = 0; i < allTracks.length; i++) {
var track = allTracks[i];
// This throws an error in IE, but is fine in chrome
// In IE it's not necessary anyway because changing the src seems to be enough
try {
while (track.cues.length) {
track.removeCue(track.cues[0]);
}
} catch (e) {
console.log('Error removing cue from textTrack');
}
}
$('track', self.currentMediaElement).each(function () {
var currentSrc = this.src;
currentSrc = replaceQueryString(currentSrc, 'startPositionTicks', startPositionTicks);
this.src = currentSrc;
});
};
self.updateNowPlayingInfo = function (item) {
if (!item) {
throw new Error('item cannot be null');
}
var mediaControls = $("#videoPlayer");
var state = self.getPlayerStateInternal(self.currentMediaElement, item, self.currentMediaSource);
var url = "";
var imageWidth = 400;
var imageHeight = 300;
if (state.NowPlayingItem.PrimaryImageTag) {
url = ApiClient.getScaledImageUrl(state.NowPlayingItem.PrimaryImageItemId, {
type: "Primary",
width: imageWidth,
tag: state.NowPlayingItem.PrimaryImageTag
});
}
else if (state.NowPlayingItem.PrimaryImageTag) {
url = ApiClient.getScaledImageUrl(state.NowPlayingItem.PrimaryImageItemId, {
type: "Primary",
width: imageWidth,
tag: state.NowPlayingItem.PrimaryImageTag
});
}
else if (state.NowPlayingItem.BackdropImageTag) {
url = ApiClient.getScaledImageUrl(state.NowPlayingItem.BackdropItemId, {
type: "Backdrop",
height: imageHeight,
tag: state.NowPlayingItem.BackdropImageTag,
index: 0
});
}
else if (state.NowPlayingItem.ThumbImageTag) {
url = ApiClient.getScaledImageUrl(state.NowPlayingItem.ThumbImageItemId, {
type: "Thumb",
height: imageHeight,
tag: state.NowPlayingItem.ThumbImageTag
});
}
if (url) {
$('.nowPlayingImage', mediaControls).html('');
} else {
$('.nowPlayingImage', mediaControls).html('');
}
if (state.NowPlayingItem.LogoItemId) {
url = ApiClient.getScaledImageUrl(state.NowPlayingItem.LogoItemId, {
type: "Logo",
height: 42,
tag: state.NowPlayingItem.LogoImageTag
});
$('.videoTopControlsLogo', mediaControls).html('');
} else {
$('.videoTopControlsLogo', mediaControls).html('');
}
var elem = $('.nowPlayingTabs', mediaControls).html(getNowPlayingTabsHtml(item)).lazyChildren();
$('.nowPlayingTabButton', elem).on('click', function () {
if (!$(this).hasClass('selectedNowPlayingTabButton')) {
$('.selectedNowPlayingTabButton').removeClass('selectedNowPlayingTabButton');
$(this).addClass('selectedNowPlayingTabButton');
$('.nowPlayingTab').hide();
$('.' + this.getAttribute('data-tab')).show().trigger('scroll');
}
});
$('.chapterCard', elem).on('click', function () {
self.seek(parseInt(this.getAttribute('data-position')));
});
};
function getNowPlayingTabsHtml(item) {
var html = '';
html += '
';
var textLines = [];
textLines.push(chapter.Name);
textLines.push(Dashboard.getDisplayTime(chapter.StartPositionTicks));
optionHtml += textLines.join('
');
optionHtml += '
';
if (selected) {
optionHtml += '';
}
var textLines = [];
textLines.push(stream.Language || Globalize.translate('LabelUnknownLanguage'));
var attributes = [];
if (stream.Codec) {
attributes.push(stream.Codec);
}
if (stream.Profile) {
attributes.push(stream.Profile);
}
if (stream.BitRate) {
attributes.push((Math.floor(stream.BitRate / 1000)) + ' kbps');
}
if (stream.Channels) {
attributes.push(stream.Channels + ' ch');
}
if (stream.IsDefault) {
attributes.push('(D)');
}
if (attributes.length) {
textLines.push(attributes.join(' '));
}
optionHtml += textLines.join('
');
optionHtml += '
';
if (selected) {
optionHtml += '';
}
var textLines = [];
textLines.push(stream.Language || Globalize.translate('LabelUnknownLanguage'));
if (stream.Codec) {
textLines.push(stream.Codec);
}
var attributes = [];
if (stream.IsDefault) {
attributes.push('Default');
}
if (stream.IsForced) {
attributes.push('Forced');
}
if (stream.IsExternal) {
attributes.push('External');
}
if (attributes.length) {
textLines.push(attributes.join(' '));
}
optionHtml += textLines.join('
');
optionHtml += '
'; if (option.selected) { optionHtml += ''; } optionHtml += option.name; optionHtml += '
'; optionHtml += '