(function () { videoPlayer = function (mediaPlayer, item, mediaSource, startPosition, user) { if (mediaPlayer == null) { throw new Error("mediaPlayer cannot be null"); } if (item == null) { throw new Error("item cannot be null"); } if (user == null) { throw new Error("user cannot be null"); } var self = mediaPlayer; var timeout; var video; 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.initVideoPlayer = function () { video = playVideo(item, mediaSource, startPosition); return video; }; 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 () { var videoControls = $("#videoControls"); if (remoteFullscreen) { exitFullScreenToWindow(); videoControls.removeClass("inactive"); } else { enterFullScreen(); videoControls.addClass("inactive"); } 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'); $("#videoControls").removeClass("inactive"); $("video").remove(); $("html").css("cursor", "default"); }; 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; }; self.showSubtitleMenu = function () { var flyout = $('#video-subtitleFlyout'); if (!flyout.is(':visible')) { flyout.html(getSubtitleTracksHtml()).trigger('create').scrollTop(0); toggleFlyout(flyout, '#video-subtitleButton'); } else { toggleFlyout(flyout, '#video-subtitleButton'); } }; self.showQualityFlyout = function () { var flyout = $('#video-qualityFlyout'); if (!flyout.is(':visible')) { flyout.html(getQualityFlyoutHtml()).scrollTop(0); } toggleFlyout(flyout, '#video-qualityButton'); }; self.showChaptersFlyout = function () { var flyout = $('#video-chaptersFlyout'); if (!flyout.is(':visible')) { flyout.html(getChaptersFlyoutHtml()).scrollTop(0); } toggleFlyout(flyout, '#video-chaptersButton'); }; self.showAudioTracksFlyout = function () { var flyout = $('#video-audioTracksFlyout'); if (!flyout.is(':visible')) { flyout.html(getAudioTracksHtml()).trigger('create').scrollTop(0); toggleFlyout(flyout, '#video-audioTracksButton'); } else { toggleFlyout(flyout, '#video-audioTracksButton'); } }; 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 textStreams = self.currentMediaSource.MediaStreams.filter(function (s) { return s.Type == 'Subtitle' && s.IsTextSubtitleStream; }); var allTracks = video.textTracks; // get list of tracks for (var i = 0; i < allTracks.length; i++) { var trackIndex = textStreams[i].Index; if (trackIndex == index) { allTracks[i].mode = "showing"; // show this track } else { allTracks[i].mode = "disabled"; // hide all other tracks } } }; self.updateTextStreamUrls = function (startPositionTicks) { $('track', video).each(function () { var currentSrc = this.src; currentSrc = replaceQueryString(currentSrc, 'startPositionTicks', startPositionTicks); this.src = currentSrc; }); }; $(document).on('webkitfullscreenchange mozfullscreenchange fullscreenchange', function (e) { var videoControls = $('#videoControls'); $('.itemVideo').off('mousemove keydown scroll', idleHandler); if (self.isFullScreen()) { enterFullScreen(); idleState = true; $('.itemVideo').on('mousemove keydown scroll', idleHandler).trigger('mousemove'); } else { videoControls.removeClass("active inactive"); exitFullScreenToWindow(); } }); 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); }); $('#video-chaptersFlyout').on('click', '.mediaFlyoutOption', function () { var ticks = parseInt(this.getAttribute('data-positionticks')); self.changeStream(ticks); hideFlyout($('#video-chaptersFlyout')); }); $('#video-audioTracksFlyout').on('click', '.mediaFlyoutOption', function () { if (!$(this).hasClass('selectedMediaFlyoutOption')) { var index = parseInt(this.getAttribute('data-index')); self.setAudioStreamIndex(index); } hideFlyout($('#video-audioTracksFlyout')); }); $('#video-subtitleFlyout').on('click', '.mediaFlyoutOption', function () { if (!$(this).hasClass('selectedMediaFlyoutOption')) { var index = parseInt(this.getAttribute('data-index')); self.setSubtitleStreamIndex(index); } hideFlyout($('#video-subtitleFlyout')); }); $('#video-qualityFlyout').on('click', '.mediaFlyoutOption', function () { if (!$(this).hasClass('selectedMediaFlyoutOption')) { var maxWidth = parseInt(this.getAttribute('data-maxwidth')); var bitrate = parseInt(this.getAttribute('data-bitrate')); localStorage.setItem('preferredVideoBitrate', bitrate); self.changeStream(self.getCurrentTicks(), { MaxWidth: maxWidth, Bitrate: bitrate }); } hideFlyout($('#video-qualityFlyout')); }); $("body").on("mousemove", "#videoPlayer.fullscreenVideo #itemVideo", function () { idleHandler(this); }); var trackChange = false; var tooltip = $('
'); $("#videoControls .positionSliderContainer .slider").on("change", function (e) { if (!trackChange) return; var pct = $(this).val(); var time = self.currentDurationTicks * (Number(pct) * .01); var tooltext = Dashboard.getDisplayTime(time) tooltip.text(tooltext); console.log("slidin", pct, self.currentDurationTicks, time); }).on("slidestart", function (e) { trackChange = true; var handle = $("#videoControls .positionSliderContainer .ui-slider-handle"); handle.after(tooltip); }).on("slidestop", function (e) { trackChange = false; tooltip.remove(); }); }); function idleHandler() { var video = $(".itemVideo"); var videoControls = $("#videoControls"); if (timeout) { window.clearTimeout(timeout); } if (idleState == true) { video.removeClass("cursor-inactive"); videoControls.removeClass("inactive").addClass("active"); } idleState = false; timeout = window.setTimeout(function () { idleState = true; video.addClass("cursor-inactive"); videoControls.removeClass("active").addClass("inactive"); }, 4000); } 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.webkitRequestFullScreen || element.mozRequestFullScreen; if (requestMethod) { // Native full screen. requestMethod.call(element); } else { enterFullScreen(); } } function changeHandler(event) { document.addEventListener(event, function () { fullscreenExited = self.isFullScreen() == false; }); } function enterFullScreen() { var player = $("#videoPlayer"); player.addClass("fullscreenVideo"); remoteFullscreen = true; } function exitFullScreenToWindow() { var player = $("#videoPlayer"); player.removeClass("fullscreenVideo"); remoteFullscreen = false; } function toggleFlyout(flyout, button) { $(document.body).off("mousedown.mediaflyout").on("mousedown.mediaflyout", function (e) { var elem = $(e.target); var flyoutId = flyout[0].id; var safeItems = button + ',#' + flyoutId; if (!elem.is(safeItems) && !elem.parents(safeItems).length) { hideFlyout(flyout); } }); var visible = $(flyout).is(":visible"); if (!visible) { flyout.slideDown(); } else { $(button).blur(); hideFlyout(flyout); } } function hideFlyout(flyout) { flyout.slideUp().empty(); $(document.body).off("mousedown.hidesearchhints"); } function getChaptersFlyoutHtml() { var html = ''; var currentTicks = self.getCurrentTicks(); var chapters = self.currentItem.Chapters || []; for (var i = 0, length = chapters.length; i < length; i++) { var chapter = chapters[i]; var isSelected = false; if (currentTicks >= chapter.StartPositionTicks) { var nextChapter = chapters[i + 1]; isSelected = !nextChapter || currentTicks < nextChapter.StartPositionTicks; } if (isSelected) { html += '