(function () { function createVideoPlayer(self) { var initialVolume; var idleState = true; var muteButton = null; var unmuteButton = null; var volumeSlider = null; var positionSlider; 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.mozCancelFullScreen) { document.mozCancelFullScreen(); } 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; }; self.showChaptersFlyout = function () { function onFlyoutClose() { $('.itemVideo').css('visibility', 'visible'); } require(['jqmicons']); var html = getChaptersFlyoutHtml(); var elem = $('.videoChaptersPopup').html(html) .trigger('create') .popup("option", "positionTo", $('.videoChaptersButton')) .off('popupafterclose', onFlyoutClose) .on('popupafterclose', onFlyoutClose); elem.popup("open").parents(".ui-popup-container").css("margin-top", 30); }; self.showSubtitleMenu = function () { var streams = self.currentMediaSource.MediaStreams.filter(function (currentStream) { return currentStream.Type == "Subtitle"; }); var currentIndex = self.currentSubtitleStreamIndex || -1; streams.unshift({ Index: -1, Language: "Off" }); var menuItems = streams.map(function (stream) { var attributes = []; attributes.push(stream.Language || Globalize.translate('LabelUnknownLanguage')); if (stream.Codec) { attributes.push(stream.Codec); } var name = attributes.join(' - '); if (stream.IsDefault) { name += ' (D)'; } if (stream.IsForced) { name += ' (F)'; } if (stream.External) { name += ' (EXT)'; } var opt = { name: name, id: stream.Index }; if (stream.Index == currentIndex) { opt.ironIcon = "check"; } return opt; }); require(['actionsheet'], function () { ActionSheetElement.show({ items: menuItems, positionTo: $('.videoSubtitleButton')[0], callback: function (id) { var index = parseInt(id); if (index != currentIndex) { self.onSubtitleOptionSelected(index); } } }); }); }; self.showQualityFlyout = function () { var currentSrc = self.getCurrentSrc(self.currentMediaRenderer).toLowerCase(); var isStatic = currentSrc.indexOf('static=true') != -1; var videoStream = self.currentMediaSource.MediaStreams.filter(function (stream) { return stream.Type == "Video"; })[0]; var videoWidth = videoStream ? videoStream.Width : null; var videoHeight = videoStream ? videoStream.Height : null; var options = self.getVideoQualityOptions(videoWidth, videoHeight); if (isStatic) { options[0].name = "Direct"; } var menuItems = options.map(function (o) { var opt = { name: o.name, id: o.bitrate }; if (o.selected) { opt.ironIcon = "check"; } return opt; }); var selectedId = options.filter(function (o) { return o.selected; }); selectedId = selectedId.length ? selectedId[0].bitrate : null; require(['actionsheet'], function () { ActionSheetElement.show({ items: menuItems, positionTo: $('.videoQualityButton')[0], callback: function (id) { var bitrate = parseInt(id); if (bitrate != selectedId) { self.onQualityOptionSelected(bitrate); } } }); }); }; self.showAudioTracksFlyout = function () { var options = self.currentMediaSource.MediaStreams.filter(function (currentStream) { return currentStream.Type == "Audio"; }); var currentIndex = getParameterByName('AudioStreamIndex', self.getCurrentSrc(self.currentMediaRenderer)); var menuItems = options.map(function (stream) { var attributes = []; attributes.push(stream.Language || Globalize.translate('LabelUnknownLanguage')); 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'); } var name = attributes.join(' - '); if (stream.IsDefault) { name += ' (D)'; } var opt = { name: name, id: stream.Index }; if (stream.Index == currentIndex) { opt.ironIcon = "check"; } return opt; }); require(['actionsheet'], function () { ActionSheetElement.show({ items: menuItems, positionTo: $('.videoAudioButton')[0], callback: function (id) { var index = parseInt(id); if (index != currentIndex) { self.onAudioOptionSelected(index); } } }); }); }; self.setAudioStreamIndex = function (index) { self.changeStream(self.getCurrentTicks(), { AudioStreamIndex: index }); }; self.setSubtitleStreamIndex = function (index) { if (!self.currentMediaRenderer.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 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; self.currentMediaRenderer.setCurrentTrackElement(trackIndex); }; self.updateTextStreamUrls = function (startPositionTicks) { self.currentMediaRenderer.updateTextStreamUrls(startPositionTicks); }; self.updateNowPlayingInfo = function (item) { if (!item) { throw new Error('item cannot be null'); } var mediaControls = $("#videoPlayer"); var state = self.getPlayerStateInternal(self.currentMediaRenderer, 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 += '
'; html += ' '; if (item.Chapters && item.Chapters.length) { html += ' '; } if (item.People && item.People.length) { html += ' '; } return html; } function onPositionSliderChange() { var newPercent = parseInt(this.value); var newPositionTicks = (newPercent / 100) * self.currentMediaSource.RunTimeTicks; self.changeStream(Math.floor(newPositionTicks)); } self.onChapterOptionSelected = function (elem) { if (!$(elem).hasClass('selectedMediaPopupOption')) { var ticks = parseInt(elem.getAttribute('data-value') || '0'); self.changeStream(ticks); } $('.videoChaptersPopup').popup('close'); }; self.onAudioOptionSelected = function (index) { self.setAudioStreamIndex(index); }; self.onSubtitleOptionSelected = function (index) { self.setSubtitleStreamIndex(index); }; self.onQualityOptionSelected = function (bitrate) { AppSettings.maxStreamingBitrate(bitrate); $('.videoQualityPopup').popup('close'); self.changeStream(self.getCurrentTicks(), { Bitrate: bitrate }); }; function ensureVideoPlayerElements() { var html = ' '; // mediaPlayer var div = document.createElement('div'); div.innerHTML = html; document.body.appendChild(div); $(div).trigger('create'); } Dashboard.ready(function () { ensureVideoPlayerElements(); var parent = $("#mediaPlayer"); muteButton = $('.muteButton', parent); unmuteButton = $('.unmuteButton', parent); currentTimeElement = $('.currentTime', parent); positionSlider = $(".videoPositionSlider", parent).on('change', onPositionSliderChange)[0]; positionSlider._setPinValue = function (value) { if (!self.currentMediaSource || !self.currentMediaSource.RunTimeTicks) { this.pinValue = '--:--'; return; } var ticks = self.currentMediaSource.RunTimeTicks; ticks /= 100; ticks *= value; this.pinValue = Dashboard.getDisplayTime(ticks); }; volumeSlider = $('.videoVolumeSlider', parent).on('change', function () { var vol = this.value; updateVolumeButtons(vol); self.setVolume(vol); })[0]; }); var idleHandlerTimeout; function idleHandler() { if (idleHandlerTimeout) { window.clearTimeout(idleHandlerTimeout); } if (idleState == true) { $('.hiddenOnIdle').removeClass("inactive"); $('#videoPlayer').removeClass('idlePlayer'); } idleState = false; idleHandlerTimeout = window.setTimeout(function () { idleState = true; $('.hiddenOnIdle').addClass("inactive"); $('#videoPlayer').addClass('idlePlayer'); }, 3500); } function updateVolumeButtons(vol) { if (vol) { muteButton.show(); unmuteButton.hide(); } else { muteButton.hide(); unmuteButton.show(); } } function requestFullScreen(element) { // Supports most browsers and their versions. var requestMethod = element.requestFullscreen || element.webkitRequestFullscreen || element.mozRequestFullScreen || element.msRequestFullscreen; if (requestMethod) { // Native full screen. requestMethod.call(element); } else { enterFullScreen(); } } function enterFullScreen() { var player = $("#videoPlayer"); player.addClass("fullscreenVideo"); } function exitFullScreenToWindow() { var player = $("#videoPlayer"); player.removeClass("fullscreenVideo"); } function getChaptersFlyoutHtml() { var item = self.currentItem; var currentTicks = self.getCurrentTicks(); var chapters = item.Chapters || []; var html = ''; html += '';
var textLines = [];
textLines.push(chapter.Name);
textLines.push(Dashboard.getDisplayTime(chapter.StartPositionTicks));
optionHtml += textLines.join('
');
optionHtml += '
'; errorMsg += Globalize.translate('MessageEnsureOpenTuner'); errorMsg += '
'; } Dashboard.alert({ title: Globalize.translate('HeaderVideoError'), message: errorMsg }); }).on("click.mediaplayerevent", function (e) { if (!$.browser.mobile) { if (this.paused()) { self.unpause(); } else { self.pause(); } } }).on("dblclick.mediaplayerevent", function () { if (!$.browser.mobile) { self.toggleFullscreen(); } }); bindEventsForPlayback(mediaRenderer); self.currentSubtitleStreamIndex = mediaSource.DefaultSubtitleStreamIndex; $(document.body).addClass('bodyWithPopupOpen'); self.currentMediaRenderer = mediaRenderer; self.currentDurationTicks = self.currentMediaSource.RunTimeTicks; self.updateNowPlayingInfo(item); mediaRenderer.init().done(function () { self.setSrcIntoRenderer(mediaRenderer, videoUrl, item, self.currentMediaSource); if (callback) { callback(); } }); }; self.updatePlaylistUi = function () { var index = self.currentPlaylistIndex(null); var length = self.playlist.length; var requiresNativeControls = false; if (self.currentMediaRenderer && !self.currentMediaRenderer.enableCustomVideoControls) { requiresNativeControls = self.currentMediaRenderer.enableCustomVideoControls(); } if (length < 2) { $('.videoTrackControl').visible(false); return; } var controls = requiresNativeControls ? '.videoAdvancedControls' : '.videoControls'; controls = document.querySelector(controls); var previousTrackButton = controls.getElementsByClassName('previousTrackButton')[0]; var nextTrackButton = controls.getElementsByClassName('nextTrackButton')[0]; if (index === 0) { previousTrackButton.setAttribute('disabled', 'disabled'); } else { previousTrackButton.removeAttribute('disabled'); } if ((index + 1) >= length) { nextTrackButton.setAttribute('disabled', 'disabled'); } else { nextTrackButton.removeAttribute('disabled'); } $(previousTrackButton).visible(true); $(nextTrackButton).visible(true); }; } createVideoPlayer(MediaPlayer); })();