(function () {
function createVideoPlayer(self) {
var timeout;
var initialVolume;
var fullscreenExited = false;
var idleState = true;
var remoteFullscreen = false;
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.remoteFullscreen = function () {
if (remoteFullscreen) {
exitFullScreenToWindow();
} else {
enterFullScreen();
}
remoteFullscreen = !remoteFullscreen;
};
self.toggleFullscreen = function () {
if (self.isFullScreen()) {
if (document.cancelFullScreen) {
document.cancelFullScreen();
}
else if (document.mozCancelFullScreen) {
document.mozCancelFullScreen();
}
else if (document.webkitExitFullscreen) {
document.webkitExitFullscreen();
}
else if (document.webkitCancelFullScreen) {
document.webkitCancelFullScreen();
}
$('#videoPlayer').removeClass('fullscreenVideo');
} 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();
}
$('#videoPlayer').removeClass('fullscreenVideo');
fullscreenExited = true;
};
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.showSubtitleMenu = function () {
var elem = $('.videoSubtitlePopup').html(getSubtitleTracksHtml())
.trigger('create')
.popup("option", "positionTo", $('.videoSubtitleButton'))
.off('popupafterclose', onFlyoutClose)
.on('popupafterclose', onFlyoutClose);
onPopupOpen(elem);
};
self.showQualityFlyout = function () {
var elem = $('.videoQualityPopup').html(getQualityFlyoutHtml())
.trigger('create')
.popup("option", "positionTo", $('.videoQualityButton'))
.off('popupafterclose', onFlyoutClose)
.on('popupafterclose', onFlyoutClose);
onPopupOpen(elem);
};
self.showChaptersFlyout = function () {
var elem = $('.videoChaptersPopup').html(getChaptersFlyoutHtml())
.trigger('create')
.popup("option", "positionTo", $('.videoChaptersButton'))
.off('popupafterclose', onFlyoutClose)
.on('popupafterclose', onFlyoutClose);
onPopupOpen(elem);
};
self.showAudioTracksFlyout = function () {
var elem = $('.videoAudioPopup').html(getAudioTracksHtml())
.trigger('create')
.popup("option", "positionTo", $('.videoAudioButton'))
.off('popupafterclose', onFlyoutClose)
.on('popupafterclose', onFlyoutClose);
onPopupOpen(elem);
};
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.IsTextSubtitleStream) {
// Need to change the transcoded stream to remove subs
self.changeStream(self.getCurrentTicks(), { SubtitleStreamIndex: -1 });
}
}
else if (!currentStream && newStream) {
if (newStream.IsTextSubtitleStream) {
selectedTrackElementIndex = index;
} else {
// Need to change the transcoded stream to add subs
self.changeStream(self.getCurrentTicks(), { SubtitleStreamIndex: index });
}
}
else if (currentStream && newStream) {
if (newStream.IsTextSubtitleStream) {
selectedTrackElementIndex = index;
if (!currentStream.IsTextSubtitleStream) {
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.Type == 'Subtitle' && s.IsTextSubtitleStream;
});
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 = "";
if (state.NowPlayingItem.PrimaryImageTag) {
url = ApiClient.getScaledImageUrl(state.NowPlayingItem.PrimaryImageItemId, {
type: "Primary",
width: 150,
tag: state.NowPlayingItem.PrimaryImageTag
});
}
else if (state.NowPlayingItem.PrimaryImageTag) {
url = ApiClient.getScaledImageUrl(state.NowPlayingItem.PrimaryImageItemId, {
type: "Primary",
width: 150,
tag: state.NowPlayingItem.PrimaryImageTag
});
}
else if (state.NowPlayingItem.BackdropImageTag) {
url = ApiClient.getScaledImageUrl(state.NowPlayingItem.BackdropItemId, {
type: "Backdrop",
height: 300,
tag: state.NowPlayingItem.BackdropImageTag,
index: 0
});
}
else if (state.NowPlayingItem.ThumbImageTag) {
url = ApiClient.getScaledImageUrl(state.NowPlayingItem.ThumbImageItemId, {
type: "Thumb",
height: 300,
tag: state.NowPlayingItem.ThumbImageTag
});
}
var nowPlayingTextElement = $('.nowPlayingText', mediaControls);
var nameHtml = self.getNowPlayingNameHtml(state);
if (nameHtml.indexOf('
') != -1) {
nowPlayingTextElement.addClass('nowPlayingDoubleText');
} else {
nowPlayingTextElement.removeClass('nowPlayingDoubleText');
}
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('');
}
nowPlayingTextElement.html(nameHtml);
};
function onPositionSliderChange() {
isPositionSliderActive = false;
var newPercent = parseInt(this.value);
var newPositionTicks = (newPercent / 100) * self.currentMediaSource.RunTimeTicks;
self.changeStream(Math.floor(newPositionTicks));
}
$(function () {
var parent = $("#mediaPlayer");
muteButton = $('.muteButton', parent);
unmuteButton = $('.unmuteButton', parent);
currentTimeElement = $('.currentTime', parent);
positionSlider = $(".positionSlider", parent).on('slidestart', function (e) {
isPositionSliderActive = true;
}).on('slidestop', onPositionSliderChange);
volumeSlider = $('.volumeSlider', parent).on('slidestop', function () {
var vol = this.value;
updateVolumeButtons(vol);
self.setVolume(vol * 100);
});
$('.videoChaptersPopup').on('click', '.mediaPopupOption', function () {
var ticks = parseInt(this.getAttribute('data-positionticks'));
self.changeStream(ticks);
$('.videoChaptersPopup').popup('close');
});
$('.videoAudioPopup').on('click', '.mediaPopupOption', function () {
if (!$(this).hasClass('selectedMediaPopupOption')) {
var index = parseInt(this.getAttribute('data-index'));
self.setAudioStreamIndex(index);
}
$('.videoAudioPopup').popup('close');
});
$('.videoSubtitlePopup').on('click', '.mediaPopupOption', function () {
$('.videoSubtitlePopup').popup('close');
if (!$(this).hasClass('selectedMediaPopupOption')) {
var index = parseInt(this.getAttribute('data-index'));
self.setSubtitleStreamIndex(index);
}
});
$('.videoQualityPopup').on('click', '.mediaPopupOption', function () {
if (!$(this).hasClass('selectedMediaPopupOption')) {
var maxWidth = parseInt(this.getAttribute('data-maxwidth'));
var bitrate = parseInt(this.getAttribute('data-bitrate'));
AppSettings.maxStreamingBitrate(bitrate);
self.changeStream(self.getCurrentTicks(), {
MaxWidth: maxWidth,
Bitrate: bitrate
});
}
$('.videoQualityPopup').popup('close');
});
var trackChange = false;
var tooltip = $('
';
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 += '