diff --git a/src/scripts/videoosd.js b/src/scripts/videoosd.js index d4c97bc128..56a8fcbf24 100644 --- a/src/scripts/videoosd.js +++ b/src/scripts/videoosd.js @@ -1,732 +1,1338 @@ -define(["playbackManager", "dom", "inputmanager", "datetime", "itemHelper", "mediaInfo", "focusManager", "imageLoader", "scrollHelper", "events", "connectionManager", "browser", "globalize", "apphost", "layoutManager", "userSettings", "scrollStyles", "emby-slider", "paper-icon-button-light", "css!css/videoosd"], function(playbackManager, dom, inputManager, datetime, itemHelper, mediaInfo, focusManager, imageLoader, scrollHelper, events, connectionManager, browser, globalize, appHost, layoutManager, userSettings) { - "use strict"; +define(["playbackManager", "dom", "inputmanager", "datetime", "itemHelper", "mediaInfo", "focusManager", "imageLoader", "scrollHelper", "events", "connectionManager", "browser", "globalize", "apphost", "layoutManager", "userSettings", "scrollStyles", "emby-slider", "paper-icon-button-light", "css!css/videoosd"], function (playbackManager, dom, inputManager, datetime, itemHelper, mediaInfo, focusManager, imageLoader, scrollHelper, events, connectionManager, browser, globalize, appHost, layoutManager, userSettings) { + "use strict"; - function seriesImageUrl(item, options) { - if ("Episode" !== item.Type) return null; - if (options = options || {}, options.type = options.type || "Primary", "Primary" === options.type && item.SeriesPrimaryImageTag) return options.tag = item.SeriesPrimaryImageTag, connectionManager.getApiClient(item.ServerId).getScaledImageUrl(item.SeriesId, options); - if ("Thumb" === options.type) { - if (item.SeriesThumbImageTag) return options.tag = item.SeriesThumbImageTag, connectionManager.getApiClient(item.ServerId).getScaledImageUrl(item.SeriesId, options); - if (item.ParentThumbImageTag) return options.tag = item.ParentThumbImageTag, connectionManager.getApiClient(item.ServerId).getScaledImageUrl(item.ParentThumbItemId, options) - } - return null + function seriesImageUrl(item, options) { + if ("Episode" !== item.Type) { + return null; } - function imageUrl(item, options) { - return options = options || {}, options.type = options.type || "Primary", item.ImageTags && item.ImageTags[options.type] ? (options.tag = item.ImageTags[options.type], connectionManager.getApiClient(item.ServerId).getScaledImageUrl(item.PrimaryImageItemId || item.Id, options)) : "Primary" === options.type && item.AlbumId && item.AlbumPrimaryImageTag ? (options.tag = item.AlbumPrimaryImageTag, connectionManager.getApiClient(item.ServerId).getScaledImageUrl(item.AlbumId, options)) : null + if (options = options || {}, options.type = options.type || "Primary", "Primary" === options.type && item.SeriesPrimaryImageTag) { + options.tag = item.SeriesPrimaryImageTag; + return connectionManager.getApiClient(item.ServerId).getScaledImageUrl(item.SeriesId, options); } - function logoImageUrl(item, apiClient, options) { - return options = options || {}, options.type = "Logo", item.ImageTags && item.ImageTags.Logo ? (options.tag = item.ImageTags.Logo, apiClient.getScaledImageUrl(item.Id, options)) : item.ParentLogoImageTag ? (options.tag = item.ParentLogoImageTag, apiClient.getScaledImageUrl(item.ParentLogoItemId, options)) : null + if ("Thumb" === options.type) { + if (item.SeriesThumbImageTag) { + options.tag = item.SeriesThumbImageTag; + return connectionManager.getApiClient(item.ServerId).getScaledImageUrl(item.SeriesId, options); + } + + if (item.ParentThumbImageTag) { + options.tag = item.ParentThumbImageTag; + return connectionManager.getApiClient(item.ServerId).getScaledImageUrl(item.ParentThumbItemId, options); + } } - return function(view, params) { - function onVerticalSwipe(e, elem, data) { - var player = currentPlayer; - if (player) { - var deltaY = data.currentDeltaY, - windowSize = dom.getWindowSize(); - if (supportsBrightnessChange && data.clientX < windowSize.innerWidth / 2) return void doBrightnessTouch(deltaY, player, windowSize.innerHeight); - doVolumeTouch(deltaY, player, windowSize.innerHeight) + return null; + } + + function imageUrl(item, options) { + options = options || {}; + options.type = options.type || "Primary"; + + if (item.ImageTags && item.ImageTags[options.type]) { + options.tag = item.ImageTags[options.type]; + return connectionManager.getApiClient(item.ServerId).getScaledImageUrl(item.PrimaryImageItemId || item.Id, options); + } + + if ("Primary" === options.type && item.AlbumId && item.AlbumPrimaryImageTag) { + options.tag = item.AlbumPrimaryImageTag; + return connectionManager.getApiClient(item.ServerId).getScaledImageUrl(item.AlbumId, options); + } + + return null; + } + + function logoImageUrl(item, apiClient, options) { + options = options || {}; + options.type = "Logo"; + + if (item.ImageTags && item.ImageTags.Logo) { + options.tag = item.ImageTags.Logo; + return apiClient.getScaledImageUrl(item.Id, options); + } + + if (item.ParentLogoImageTag) { + options.tag = item.ParentLogoImageTag; + return apiClient.getScaledImageUrl(item.ParentLogoItemId, options); + } + + return null; + } + + return function (view, params) { + function onVerticalSwipe(e__q, elem, data) { + var player = currentPlayer; + + if (player) { + var deltaY = data.currentDeltaY; + var windowSize = dom.getWindowSize(); + + if (supportsBrightnessChange && data.clientX < windowSize.innerWidth / 2) { + return void doBrightnessTouch(deltaY, player, windowSize.innerHeight); + } + + doVolumeTouch(deltaY, player, windowSize.innerHeight); + } + } + + function doBrightnessTouch(deltaY, player, viewHeight) { + var delta = -deltaY / viewHeight * 100; + var newValue = playbackManager.getBrightness(player) + delta; + newValue = Math.min(newValue, 100); + newValue = Math.max(newValue, 0); + playbackManager.setBrightness(newValue, player); + } + + function doVolumeTouch(deltaY, player, viewHeight) { + var delta = -deltaY / viewHeight * 100; + var newValue = playbackManager.getVolume(player) + delta; + newValue = Math.min(newValue, 100); + newValue = Math.max(newValue, 0); + playbackManager.setVolume(newValue, player); + } + + function onDoubleClick(e__w) { + var clientX = e__w.clientX; + + if (null != clientX) { + if (clientX < dom.getWindowSize().innerWidth / 2) { + playbackManager.rewind(currentPlayer); + } else { + playbackManager.fastForward(currentPlayer); + } + + e__w.preventDefault(); + e__w.stopPropagation(); + } + } + + function getDisplayItem(item) { + if ("TvChannel" === item.Type) { + var apiClient = connectionManager.getApiClient(item.ServerId); + return apiClient.getItem(apiClient.getCurrentUserId(), item.Id).then(function (refreshedItem) { + return { + originalItem: refreshedItem, + displayItem: refreshedItem.CurrentProgram + }; + }); + } + + return Promise.resolve({ + originalItem: item + }); + } + + function updateRecordingButton(item) { + if (!item || "Program" !== item.Type) { + if (recordingButtonManager) { + recordingButtonManager.destroy(); + recordingButtonManager = null; + } + + return void view.querySelector(".btnRecord").classList.add("hide"); + } + + connectionManager.getApiClient(item.ServerId).getCurrentUser().then(function (user) { + if (user.Policy.EnableLiveTvManagement) { + require(["recordingButton"], function (RecordingButton) { + if (recordingButtonManager) { + return void recordingButtonManager.refreshItem(item); } - } - function doBrightnessTouch(deltaY, player, viewHeight) { - var delta = -deltaY / viewHeight * 100, - newValue = playbackManager.getBrightness(player) + delta; - newValue = Math.min(newValue, 100), newValue = Math.max(newValue, 0), playbackManager.setBrightness(newValue, player) - } - - function doVolumeTouch(deltaY, player, viewHeight) { - var delta = -deltaY / viewHeight * 100, - newValue = playbackManager.getVolume(player) + delta; - newValue = Math.min(newValue, 100), newValue = Math.max(newValue, 0), playbackManager.setVolume(newValue, player) - } - - function onDoubleClick(e) { - var clientX = e.clientX; - if (null != clientX) { - clientX < dom.getWindowSize().innerWidth / 2 ? playbackManager.rewind(currentPlayer) : playbackManager.fastForward(currentPlayer), e.preventDefault(), e.stopPropagation() - } - } - - function getDisplayItem(item) { - if ("TvChannel" === item.Type) { - var apiClient = connectionManager.getApiClient(item.ServerId); - return apiClient.getItem(apiClient.getCurrentUserId(), item.Id).then(function(refreshedItem) { - return { - originalItem: refreshedItem, - displayItem: refreshedItem.CurrentProgram - } - }) - } - return Promise.resolve({ - originalItem: item - }) - } - - function updateRecordingButton(item) { - if (!item || "Program" !== item.Type) return recordingButtonManager && (recordingButtonManager.destroy(), recordingButtonManager = null), void view.querySelector(".btnRecord").classList.add("hide"); - connectionManager.getApiClient(item.ServerId).getCurrentUser().then(function(user) { - user.Policy.EnableLiveTvManagement && require(["recordingButton"], function(RecordingButton) { - if (recordingButtonManager) return void recordingButtonManager.refreshItem(item); - recordingButtonManager = new RecordingButton({ - item: item, - button: view.querySelector(".btnRecord") - }), view.querySelector(".btnRecord").classList.remove("hide") - }) - }) - } - - function updateDisplayItem(itemInfo) { - var item = itemInfo.originalItem; - currentItem = item; - var displayItem = itemInfo.displayItem || item; - updateRecordingButton(displayItem), setPoster(displayItem, item); - var parentName = displayItem.SeriesName || displayItem.Album; - (displayItem.EpisodeTitle || displayItem.IsSeries) && (parentName = displayItem.Name), setTitle(displayItem, parentName); - var titleElement, osdTitle = view.querySelector(".osdTitle"); - titleElement = osdTitle; - var displayName = itemHelper.getDisplayName(displayItem, { - includeParentInfo: "Program" !== displayItem.Type, - includeIndexNumber: "Program" !== displayItem.Type + recordingButtonManager = new RecordingButton({ + item: item, + button: view.querySelector(".btnRecord") }); - !displayName && displayItem.Type, titleElement.innerHTML = displayName, displayName ? titleElement.classList.remove("hide") : titleElement.classList.add("hide"); - var mediaInfoHtml = mediaInfo.getPrimaryMediaInfoHtml(displayItem, { - runtime: !1, - subtitles: !1, - tomatoes: !1, - endsAt: !1, - episodeTitle: !1, - originalAirDate: "Program" !== displayItem.Type, - episodeTitleIndexNumber: "Program" !== displayItem.Type, - programIndicator: !1 - }), - osdMediaInfo = view.querySelector(".osdMediaInfo"); - osdMediaInfo.innerHTML = mediaInfoHtml, mediaInfoHtml ? osdMediaInfo.classList.remove("hide") : osdMediaInfo.classList.add("hide"); - var secondaryMediaInfo = view.querySelector(".osdSecondaryMediaInfo"), - secondaryMediaInfoHtml = mediaInfo.getSecondaryMediaInfoHtml(displayItem, { - startDate: !1, - programTime: !1 - }); - secondaryMediaInfo.innerHTML = secondaryMediaInfoHtml, secondaryMediaInfoHtml ? secondaryMediaInfo.classList.remove("hide") : secondaryMediaInfo.classList.add("hide"), displayName ? view.querySelector(".osdMainTextContainer").classList.remove("hide") : view.querySelector(".osdMainTextContainer").classList.add("hide"), enableProgressByTimeOfDay ? (setDisplayTime(startTimeText, displayItem.StartDate), setDisplayTime(endTimeText, displayItem.EndDate), startTimeText.classList.remove("hide"), endTimeText.classList.remove("hide"), programStartDateMs = displayItem.StartDate ? datetime.parseISO8601Date(displayItem.StartDate).getTime() : 0, programEndDateMs = displayItem.EndDate ? datetime.parseISO8601Date(displayItem.EndDate).getTime() : 0) : (startTimeText.classList.add("hide"), endTimeText.classList.add("hide"), startTimeText.innerHTML = "", endTimeText.innerHTML = "", programStartDateMs = 0, programEndDateMs = 0) + view.querySelector(".btnRecord").classList.remove("hide"); + }); + } + }); + } + + function updateDisplayItem(itemInfo) { + var item = itemInfo.originalItem; + currentItem = item; + var displayItem = itemInfo.displayItem || item; + updateRecordingButton(displayItem); + setPoster(displayItem, item); + var parentName = displayItem.SeriesName || displayItem.Album; + + if (displayItem.EpisodeTitle || displayItem.IsSeries) { + parentName = displayItem.Name; + } + + setTitle(displayItem, parentName); + var titleElement; + var osdTitle = view.querySelector(".osdTitle"); + titleElement = osdTitle; + var displayName = itemHelper.getDisplayName(displayItem, { + includeParentInfo: "Program" !== displayItem.Type, + includeIndexNumber: "Program" !== displayItem.Type + }); + + if (!displayName) { + displayItem.Type; + } + + titleElement.innerHTML = displayName; + + if (displayName) { + titleElement.classList.remove("hide"); + } else { + titleElement.classList.add("hide"); + } + + var mediaInfoHtml = mediaInfo.getPrimaryMediaInfoHtml(displayItem, { + runtime: false, + subtitles: false, + tomatoes: false, + endsAt: false, + episodeTitle: false, + originalAirDate: "Program" !== displayItem.Type, + episodeTitleIndexNumber: "Program" !== displayItem.Type, + programIndicator: false + }); + var osdMediaInfo = view.querySelector(".osdMediaInfo"); + osdMediaInfo.innerHTML = mediaInfoHtml; + + if (mediaInfoHtml) { + osdMediaInfo.classList.remove("hide"); + } else { + osdMediaInfo.classList.add("hide"); + } + + var secondaryMediaInfo = view.querySelector(".osdSecondaryMediaInfo"); + var secondaryMediaInfoHtml = mediaInfo.getSecondaryMediaInfoHtml(displayItem, { + startDate: false, + programTime: false + }); + secondaryMediaInfo.innerHTML = secondaryMediaInfoHtml; + + if (secondaryMediaInfoHtml) { + secondaryMediaInfo.classList.remove("hide"); + } else { + secondaryMediaInfo.classList.add("hide"); + } + + if (displayName) { + view.querySelector(".osdMainTextContainer").classList.remove("hide"); + } else { + view.querySelector(".osdMainTextContainer").classList.add("hide"); + } + + if (enableProgressByTimeOfDay) { + setDisplayTime(startTimeText, displayItem.StartDate); + setDisplayTime(endTimeText, displayItem.EndDate); + startTimeText.classList.remove("hide"); + endTimeText.classList.remove("hide"); + programStartDateMs = displayItem.StartDate ? datetime.parseISO8601Date(displayItem.StartDate).getTime() : 0; + programEndDateMs = displayItem.EndDate ? datetime.parseISO8601Date(displayItem.EndDate).getTime() : 0; + } else { + startTimeText.classList.add("hide"); + endTimeText.classList.add("hide"); + startTimeText.innerHTML = ""; + endTimeText.innerHTML = ""; + programStartDateMs = 0; + programEndDateMs = 0; + } + } + + function getDisplayTimeWithoutAmPm(date, showSeconds) { + if (showSeconds) { + return datetime.toLocaleTimeString(date, { + hour: "numeric", + minute: "2-digit", + second: "2-digit" + }).toLowerCase().replace("am", "").replace("pm", "").trim(); + } + + return datetime.getDisplayTime(date).toLowerCase().replace("am", "").replace("pm", "").trim(); + } + + function setDisplayTime(elem, date) { + var html; + + if (date) { + date = datetime.parseISO8601Date(date); + html = getDisplayTimeWithoutAmPm(date); + } + + elem.innerHTML = html || ""; + } + + function shouldEnableProgressByTimeOfDay(item) { + return !("TvChannel" !== item.Type || !item.CurrentProgram); + } + + function updateNowPlayingInfo(player, state) { + var item = state.NowPlayingItem; + + if (currentItem = item, !item) { + setPoster(null); + updateRecordingButton(null); + Emby.Page.setTitle(""); + nowPlayingVolumeSlider.disabled = true; + nowPlayingPositionSlider.disabled = true; + btnFastForward.disabled = true; + btnRewind.disabled = true; + view.querySelector(".btnSubtitles").classList.add("hide"); + view.querySelector(".btnAudio").classList.add("hide"); + view.querySelector(".osdTitle").innerHTML = ""; + return void (view.querySelector(".osdMediaInfo").innerHTML = ""); + } + + enableProgressByTimeOfDay = shouldEnableProgressByTimeOfDay(item); + getDisplayItem(item).then(updateDisplayItem); + nowPlayingVolumeSlider.disabled = false; + nowPlayingPositionSlider.disabled = false; + btnFastForward.disabled = false; + btnRewind.disabled = false; + + if (playbackManager.subtitleTracks(player).length) { + view.querySelector(".btnSubtitles").classList.remove("hide"); + } else { + view.querySelector(".btnSubtitles").classList.add("hide"); + } + + if (playbackManager.audioTracks(player).length > 1) { + view.querySelector(".btnAudio").classList.remove("hide"); + } else { + view.querySelector(".btnAudio").classList.add("hide"); + } + } + + function setTitle(item, parentName) { + var url = logoImageUrl(item, connectionManager.getApiClient(item.ServerId), {}); + + if (url) { + Emby.Page.setTitle(""); + var pageTitle = document.querySelector(".pageTitle"); + pageTitle.style.backgroundImage = "url('" + url + "')"; + pageTitle.classList.add("pageTitleWithLogo"); + pageTitle.classList.remove("pageTitleWithDefaultLogo"); + pageTitle.innerHTML = ""; + } else { + Emby.Page.setTitle(parentName || ""); + } + + var documentTitle = parentName || (item ? item.Name : null); + + if (documentTitle) { + document.title = documentTitle; + } + } + + function setPoster(item, secondaryItem) { + var osdPoster = view.querySelector(".osdPoster"); + + if (item) { + var imgUrl = seriesImageUrl(item, { + type: "Primary" + }) || seriesImageUrl(item, { + type: "Thumb" + }) || imageUrl(item, { + type: "Primary" + }); + + if (!imgUrl && secondaryItem && (imgUrl = seriesImageUrl(secondaryItem, { + type: "Primary" + }) || seriesImageUrl(secondaryItem, { + type: "Thumb" + }) || imageUrl(secondaryItem, { + type: "Primary" + })), imgUrl) { + return void (osdPoster.innerHTML = ''); + } + } + + osdPoster.innerHTML = ""; + } + + function showOsd() { + slideDownToShow(headerElement); + showMainOsdControls(); + startOsdHideTimer(); + } + + function hideOsd() { + slideUpToHide(headerElement); + hideMainOsdControls(); + } + + function toggleOsd() { + if ("osd" === currentVisibleMenu) { + hideOsd(); + } else { + if (!currentVisibleMenu) { + showOsd(); + } + } + } + + function startOsdHideTimer() { + stopOsdHideTimer(); + osdHideTimeout = setTimeout(hideOsd, 5e3); + } + + function stopOsdHideTimer() { + if (osdHideTimeout) { + clearTimeout(osdHideTimeout); + osdHideTimeout = null; + } + } + + function slideDownToShow(elem) { + elem.classList.remove("osdHeader-hidden"); + } + + function slideUpToHide(elem) { + elem.classList.add("osdHeader-hidden"); + } + + function clearHideAnimationEventListeners(elem) { + dom.removeEventListener(elem, transitionEndEventName, onHideAnimationComplete, { + once: true + }); + } + + function onHideAnimationComplete(e__e) { + var elem = e__e.target; + elem.classList.add("hide"); + dom.removeEventListener(elem, transitionEndEventName, onHideAnimationComplete, { + once: true + }); + } + + function showMainOsdControls() { + if (!currentVisibleMenu) { + var elem = osdBottomElement; + currentVisibleMenu = "osd"; + clearHideAnimationEventListeners(elem); + elem.classList.remove("hide"); + elem.offsetWidth; + elem.classList.remove("videoOsdBottom-hidden"); + + if (!layoutManager.mobile) { + setTimeout(function () { + focusManager.focus(elem.querySelector(".btnPause")); + }, 50); + } + } + } + + function hideMainOsdControls() { + if ("osd" === currentVisibleMenu) { + var elem = osdBottomElement; + clearHideAnimationEventListeners(elem); + elem.offsetWidth; + elem.classList.add("videoOsdBottom-hidden"); + dom.addEventListener(elem, transitionEndEventName, onHideAnimationComplete, { + once: true + }); + currentVisibleMenu = null; + } + } + + function onPointerMove(e__r) { + if ("mouse" === (e__r.pointerType || (layoutManager.mobile ? "touch" : "mouse"))) { + var eventX = e__r.screenX || 0; + var eventY = e__r.screenY || 0; + var obj = lastPointerMoveData; + + if (!obj) { + return void (lastPointerMoveData = { + x: eventX, + y: eventY + }); } - function getDisplayTimeWithoutAmPm(date, showSeconds) { - return showSeconds ? datetime.toLocaleTimeString(date, { - hour: "numeric", - minute: "2-digit", - second: "2-digit" - }).toLowerCase().replace("am", "").replace("pm", "").trim() : datetime.getDisplayTime(date).toLowerCase().replace("am", "").replace("pm", "").trim() + if (Math.abs(eventX - obj.x) < 10 && Math.abs(eventY - obj.y) < 10) { + return; } - function setDisplayTime(elem, date) { - var html; - date && (date = datetime.parseISO8601Date(date), html = getDisplayTimeWithoutAmPm(date)), elem.innerHTML = html || "" - } + obj.x = eventX; + obj.y = eventY; + showOsd(); + } + } - function shouldEnableProgressByTimeOfDay(item) { - return !("TvChannel" !== item.Type || !item.CurrentProgram) - } + function onInputCommand(e__t) { + var player = currentPlayer; - function updateNowPlayingInfo(player, state) { - var item = state.NowPlayingItem; - if (currentItem = item, !item) return setPoster(null), updateRecordingButton(null), Emby.Page.setTitle(""), nowPlayingVolumeSlider.disabled = !0, nowPlayingPositionSlider.disabled = !0, btnFastForward.disabled = !0, btnRewind.disabled = !0, view.querySelector(".btnSubtitles").classList.add("hide"), view.querySelector(".btnAudio").classList.add("hide"), view.querySelector(".osdTitle").innerHTML = "", void(view.querySelector(".osdMediaInfo").innerHTML = ""); - enableProgressByTimeOfDay = shouldEnableProgressByTimeOfDay(item), getDisplayItem(item).then(updateDisplayItem), nowPlayingVolumeSlider.disabled = !1, nowPlayingPositionSlider.disabled = !1, btnFastForward.disabled = !1, btnRewind.disabled = !1, playbackManager.subtitleTracks(player).length ? view.querySelector(".btnSubtitles").classList.remove("hide") : view.querySelector(".btnSubtitles").classList.add("hide"), playbackManager.audioTracks(player).length > 1 ? view.querySelector(".btnAudio").classList.remove("hide") : view.querySelector(".btnAudio").classList.add("hide") - } - - function setTitle(item, parentName) { - var url = logoImageUrl(item, connectionManager.getApiClient(item.ServerId), {}); - if (url) { - Emby.Page.setTitle(""); - var pageTitle = document.querySelector(".pageTitle"); - pageTitle.style.backgroundImage = "url('" + url + "')", pageTitle.classList.add("pageTitleWithLogo"), pageTitle.classList.remove("pageTitleWithDefaultLogo"), pageTitle.innerHTML = "" - } else Emby.Page.setTitle(parentName || ""); - var documentTitle = parentName || (item ? item.Name : null); - documentTitle && (document.title = documentTitle) - } - - function setPoster(item, secondaryItem) { - var osdPoster = view.querySelector(".osdPoster"); - if (item) { - var imgUrl = seriesImageUrl(item, { - type: "Primary" - }) || seriesImageUrl(item, { - type: "Thumb" - }) || imageUrl(item, { - type: "Primary" - }); - if (!imgUrl && secondaryItem && (imgUrl = seriesImageUrl(secondaryItem, { - type: "Primary" - }) || seriesImageUrl(secondaryItem, { - type: "Thumb" - }) || imageUrl(secondaryItem, { - type: "Primary" - })), imgUrl) return void(osdPoster.innerHTML = '') - } - osdPoster.innerHTML = "" - } - - function showOsd() { - slideDownToShow(headerElement), showMainOsdControls(), startOsdHideTimer() - } - - function hideOsd() { - slideUpToHide(headerElement), hideMainOsdControls() - } - - function toggleOsd() { - "osd" === currentVisibleMenu ? hideOsd() : currentVisibleMenu || showOsd() - } - - function startOsdHideTimer() { - stopOsdHideTimer(), osdHideTimeout = setTimeout(hideOsd, 5e3) - } - - function stopOsdHideTimer() { - osdHideTimeout && (clearTimeout(osdHideTimeout), osdHideTimeout = null) - } - - function slideDownToShow(elem) { - elem.classList.remove("osdHeader-hidden") - } - - function slideUpToHide(elem) { - elem.classList.add("osdHeader-hidden") - } - - function clearHideAnimationEventListeners(elem) { - dom.removeEventListener(elem, transitionEndEventName, onHideAnimationComplete, { - once: !0 - }) - } - - function onHideAnimationComplete(e) { - var elem = e.target; - elem.classList.add("hide"), dom.removeEventListener(elem, transitionEndEventName, onHideAnimationComplete, { - once: !0 - }) - } - - function showMainOsdControls() { + switch (e__t.detail.command) { + case "left": + if ("osd" === currentVisibleMenu) { + showOsd(); + } else { if (!currentVisibleMenu) { - var elem = osdBottomElement; - currentVisibleMenu = "osd", clearHideAnimationEventListeners(elem), elem.classList.remove("hide"), elem.offsetWidth, elem.classList.remove("videoOsdBottom-hidden"), layoutManager.mobile || setTimeout(function() { - focusManager.focus(elem.querySelector(".btnPause")) - }, 50) + e__t.preventDefault(); + playbackManager.rewind(player); } - } + } - function hideMainOsdControls() { - if ("osd" === currentVisibleMenu) { - var elem = osdBottomElement; - clearHideAnimationEventListeners(elem), elem.offsetWidth, elem.classList.add("videoOsdBottom-hidden"), dom.addEventListener(elem, transitionEndEventName, onHideAnimationComplete, { - once: !0 - }), currentVisibleMenu = null + break; + + case "right": + if ("osd" === currentVisibleMenu) { + showOsd(); + } else { + if (!currentVisibleMenu) { + e__t.preventDefault(); + playbackManager.fastForward(player); } - } + } - function onPointerMove(e) { - if ("mouse" === (e.pointerType || (layoutManager.mobile ? "touch" : "mouse"))) { - var eventX = e.screenX || 0, - eventY = e.screenY || 0, - obj = lastPointerMoveData; - if (!obj) return void(lastPointerMoveData = { - x: eventX, - y: eventY - }); - if (Math.abs(eventX - obj.x) < 10 && Math.abs(eventY - obj.y) < 10) return; - obj.x = eventX, obj.y = eventY, showOsd() - } - } + break; - function onInputCommand(e) { - var player = currentPlayer; - switch (e.detail.command) { - case "left": - "osd" === currentVisibleMenu ? showOsd() : currentVisibleMenu || (e.preventDefault(), playbackManager.rewind(player)); - break; - case "right": - "osd" === currentVisibleMenu ? showOsd() : currentVisibleMenu || (e.preventDefault(), playbackManager.fastForward(player)); - break; - case "pageup": - playbackManager.nextChapter(player); - break; - case "pagedown": - playbackManager.previousChapter(player); - break; - case "up": - case "down": - case "select": - case "menu": - case "info": - case "play": - case "playpause": - case "pause": - case "fastforward": - case "rewind": - case "next": - case "previous": - showOsd(); - break; - case "record": - onRecordingCommand(), showOsd(); - break; - case "togglestats": - toggleStats() - } - } + case "pageup": + playbackManager.nextChapter(player); + break; - function onRecordingCommand() { - var btnRecord = view.querySelector(".btnRecord"); - btnRecord.classList.contains("hide") || btnRecord.click() - } + case "pagedown": + playbackManager.previousChapter(player); + break; - function updateFullscreenIcon() { - playbackManager.isFullscreen(currentPlayer) ? (view.querySelector(".btnFullscreen").setAttribute("title", globalize.translate("ExitFullscreen")), view.querySelector(".btnFullscreen i").innerHTML = "") : (view.querySelector(".btnFullscreen").setAttribute("title", globalize.translate("Fullscreen")), view.querySelector(".btnFullscreen i").innerHTML = "") - } + case "up": + case "down": + case "select": + case "menu": + case "info": + case "play": + case "playpause": + case "pause": + case "fastforward": + case "rewind": + case "next": + case "previous": + showOsd(); + break; - function onPlayerChange() { - bindToPlayer(playbackManager.getCurrentPlayer()) - } + case "record": + onRecordingCommand(); + showOsd(); + break; - function onStateChanged(event, state) { - var player = this; - state.NowPlayingItem && (isEnabled = !0, updatePlayerStateInternal(event, player, state), updatePlaylist(player), enableStopOnBack(!0)) - } - - function onPlayPauseStateChanged(e) { - if (isEnabled) { - updatePlayPauseState(this.paused()) - } - } - - function onVolumeChanged(e) { - if (isEnabled) { - var player = this; - updatePlayerVolumeState(player, player.isMuted(), player.getVolume()) - } - } - - function onPlaybackStart(e, state) { - console.log("nowplaying event: " + e.type); - var player = this; - onStateChanged.call(player, e, state), resetUpNextDialog() - } - - function resetUpNextDialog() { - comingUpNextDisplayed = !1; - var dlg = currentUpNextDialog; - dlg && (dlg.destroy(), currentUpNextDialog = null) - } - - function onPlaybackStopped(e, state) { - currentRuntimeTicks = null, resetUpNextDialog(), console.log("nowplaying event: " + e.type), "Video" !== state.NextMediaType && (view.removeEventListener("viewbeforehide", onViewHideStopPlayback), Emby.Page.back()) - } - - function onMediaStreamsChanged(e) { - var player = this, - state = playbackManager.getPlayerState(player); - onStateChanged.call(player, { - type: "init" - }, state) - } - - function bindToPlayer(player) { - if (player !== currentPlayer && (releaseCurrentPlayer(), currentPlayer = player, player)) { - var state = playbackManager.getPlayerState(player); - onStateChanged.call(player, { - type: "init" - }, state), events.on(player, "playbackstart", onPlaybackStart), events.on(player, "playbackstop", onPlaybackStopped), events.on(player, "volumechange", onVolumeChanged), events.on(player, "pause", onPlayPauseStateChanged), events.on(player, "unpause", onPlayPauseStateChanged), events.on(player, "timeupdate", onTimeUpdate), events.on(player, "fullscreenchange", updateFullscreenIcon), events.on(player, "mediastreamschange", onMediaStreamsChanged), resetUpNextDialog() - } - } - - function releaseCurrentPlayer() { - destroyStats(), resetUpNextDialog(); - var player = currentPlayer; - player && (events.off(player, "playbackstart", onPlaybackStart), events.off(player, "playbackstop", onPlaybackStopped), events.off(player, "volumechange", onVolumeChanged), events.off(player, "pause", onPlayPauseStateChanged), events.off(player, "unpause", onPlayPauseStateChanged), events.off(player, "timeupdate", onTimeUpdate), events.off(player, "fullscreenchange", updateFullscreenIcon), events.off(player, "mediastreamschange", onMediaStreamsChanged), currentPlayer = null) - } - - function onTimeUpdate(e) { - if (isEnabled) { - var now = (new Date).getTime(); - if (!(now - lastUpdateTime < 700)) { - lastUpdateTime = now; - var player = this; - currentRuntimeTicks = playbackManager.duration(player); - var currentTime = playbackManager.currentTime(player); - updateTimeDisplay(currentTime, currentRuntimeTicks, playbackManager.playbackStartTime(player), playbackManager.getBufferedRanges(player)); - var item = currentItem; - refreshProgramInfoIfNeeded(player, item), showComingUpNextIfNeeded(player, item, currentTime, currentRuntimeTicks) - } - } - } - - function showComingUpNextIfNeeded(player, currentItem, currentTimeTicks, runtimeTicks) { - if (runtimeTicks && currentTimeTicks && !comingUpNextDisplayed && !currentVisibleMenu && "Episode" === currentItem.Type && userSettings.enableNextVideoInfoOverlay()) { - var showAtSecondsLeft = runtimeTicks >= 3e10 ? 40 : runtimeTicks >= 24e9 ? 35 : 30, - showAtTicks = runtimeTicks - 1e3 * showAtSecondsLeft * 1e4, - timeRemainingTicks = runtimeTicks - currentTimeTicks; - currentTimeTicks >= showAtTicks && runtimeTicks >= 6e9 && timeRemainingTicks >= 2e8 && showComingUpNext(player) - } - } - - function onUpNextHidden() { - "upnext" === currentVisibleMenu && (currentVisibleMenu = null) - } - - function showComingUpNext(player) { - require(["upNextDialog"], function(UpNextDialog) { - currentVisibleMenu || currentUpNextDialog || (currentVisibleMenu = "upnext", comingUpNextDisplayed = !0, playbackManager.nextItem(player).then(function(nextItem) { - currentUpNextDialog = new UpNextDialog({ - parent: view.querySelector(".upNextContainer"), - player: player, - nextItem: nextItem - }), events.on(currentUpNextDialog, "hide", onUpNextHidden) - }, onUpNextHidden)) - }) - } - - function refreshProgramInfoIfNeeded(player, item) { - if ("TvChannel" === item.Type) { - var program = item.CurrentProgram; - if (program && program.EndDate) try { - var endDate = datetime.parseISO8601Date(program.EndDate); - if ((new Date).getTime() >= endDate.getTime()) { - console.log("program info needs to be refreshed"); - var state = playbackManager.getPlayerState(player); - onStateChanged.call(player, { - type: "init" - }, state) - } - } catch (e) { - console.log("Error parsing date: " + program.EndDate) - } - } - } - - function updatePlayPauseState(isPaused) { - view.querySelector(".btnPause i").innerHTML = isPaused ? "" : "" - } - - function updatePlayerStateInternal(event, player, state) { - var playState = state.PlayState || {}; - updatePlayPauseState(playState.IsPaused); - var supportedCommands = playbackManager.getSupportedCommands(player); - currentPlayerSupportedCommands = supportedCommands, supportsBrightnessChange = -1 !== supportedCommands.indexOf("SetBrightness"), updatePlayerVolumeState(player, playState.IsMuted, playState.VolumeLevel), nowPlayingPositionSlider && !nowPlayingPositionSlider.dragging && (nowPlayingPositionSlider.disabled = !playState.CanSeek), btnFastForward.disabled = !playState.CanSeek, btnRewind.disabled = !playState.CanSeek; - var nowPlayingItem = state.NowPlayingItem || {}; - playbackStartTimeTicks = playState.PlaybackStartTimeTicks, updateTimeDisplay(playState.PositionTicks, nowPlayingItem.RunTimeTicks, playState.PlaybackStartTimeTicks, playState.BufferedRanges || []), updateNowPlayingInfo(player, state), state.MediaSource && state.MediaSource.SupportsTranscoding && -1 !== supportedCommands.indexOf("SetMaxStreamingBitrate") ? view.querySelector(".btnVideoOsdSettings").classList.remove("hide") : view.querySelector(".btnVideoOsdSettings").classList.add("hide"); - var isProgressClear = state.MediaSource && null == state.MediaSource.RunTimeTicks; - nowPlayingPositionSlider.setIsClear(isProgressClear), -1 === supportedCommands.indexOf("ToggleFullscreen") || player.isLocalPlayer && layoutManager.tv && playbackManager.isFullscreen(player) ? view.querySelector(".btnFullscreen").classList.add("hide") : view.querySelector(".btnFullscreen").classList.remove("hide"), -1 === supportedCommands.indexOf("PictureInPicture") ? view.querySelector(".btnPip").classList.add("hide") : view.querySelector(".btnPip").classList.remove("hide"), updateFullscreenIcon() - } - - function getDisplayPercentByTimeOfDay(programStartDateMs, programRuntimeMs, currentTimeMs) { - return (currentTimeMs - programStartDateMs) / programRuntimeMs * 100 - } - - function updateTimeDisplay(positionTicks, runtimeTicks, playbackStartTimeTicks, bufferedRanges) { - if (enableProgressByTimeOfDay) { - if (nowPlayingPositionSlider && !nowPlayingPositionSlider.dragging) - if (programStartDateMs && programEndDateMs) { - var currentTimeMs = (playbackStartTimeTicks + (positionTicks || 0)) / 1e4, - programRuntimeMs = programEndDateMs - programStartDateMs; - if (nowPlayingPositionSlider.value = getDisplayPercentByTimeOfDay(programStartDateMs, programRuntimeMs, currentTimeMs), bufferedRanges.length) { - var rangeStart = getDisplayPercentByTimeOfDay(programStartDateMs, programRuntimeMs, (playbackStartTimeTicks + (bufferedRanges[0].start || 0)) / 1e4), - rangeEnd = getDisplayPercentByTimeOfDay(programStartDateMs, programRuntimeMs, (playbackStartTimeTicks + (bufferedRanges[0].end || 0)) / 1e4); - nowPlayingPositionSlider.setBufferedRanges([{ - start: rangeStart, - end: rangeEnd - }]) - } else nowPlayingPositionSlider.setBufferedRanges([]) - } else nowPlayingPositionSlider.value = 0, nowPlayingPositionSlider.setBufferedRanges([]); - nowPlayingPositionText.innerHTML = "", nowPlayingDurationText.innerHTML = "" - } else { - if (nowPlayingPositionSlider && !nowPlayingPositionSlider.dragging) { - if (runtimeTicks) { - var pct = positionTicks / runtimeTicks; - pct *= 100, nowPlayingPositionSlider.value = pct - } else nowPlayingPositionSlider.value = 0; - runtimeTicks && null != positionTicks && currentRuntimeTicks && !enableProgressByTimeOfDay && currentItem.RunTimeTicks && "Recording" !== currentItem.Type ? endsAtText.innerHTML = "  -  " + mediaInfo.getEndsAtFromPosition(runtimeTicks, positionTicks, !0) : endsAtText.innerHTML = "" - } - nowPlayingPositionSlider && nowPlayingPositionSlider.setBufferedRanges(bufferedRanges, runtimeTicks, positionTicks), updateTimeText(nowPlayingPositionText, positionTicks), updateTimeText(nowPlayingDurationText, runtimeTicks, !0) - } - } - - function updatePlayerVolumeState(player, isMuted, volumeLevel) { - var supportedCommands = currentPlayerSupportedCommands, - showMuteButton = !0, - showVolumeSlider = !0; - 1 === supportedCommands.indexOf("Mute") && (showMuteButton = !1), -1 === supportedCommands.indexOf("SetVolume") && (showVolumeSlider = !1), player.isLocalPlayer && appHost.supports("physicalvolumecontrol") && (showMuteButton = !1, showVolumeSlider = !1), isMuted ? (view.querySelector(".buttonMute").setAttribute("title", globalize.translate("Unmute")), view.querySelector(".buttonMute i").innerHTML = "") : (view.querySelector(".buttonMute").setAttribute("title", globalize.translate("Mute")), view.querySelector(".buttonMute i").innerHTML = ""), showMuteButton ? view.querySelector(".buttonMute").classList.remove("hide") : view.querySelector(".buttonMute").classList.add("hide"), nowPlayingVolumeSlider && (showVolumeSlider ? nowPlayingVolumeSliderContainer.classList.remove("hide") : nowPlayingVolumeSliderContainer.classList.add("hide"), nowPlayingVolumeSlider.dragging || (nowPlayingVolumeSlider.value = volumeLevel || 0)) - } - - function updatePlaylist(player) { - var btnPreviousTrack = view.querySelector(".btnPreviousTrack"), - btnNextTrack = view.querySelector(".btnNextTrack"); - btnPreviousTrack.classList.remove("hide"), btnNextTrack.classList.remove("hide"), btnNextTrack.disabled = !1, btnPreviousTrack.disabled = !1 - } - - function updateTimeText(elem, ticks, divider) { - if (null == ticks) return void(elem.innerHTML = ""); - var html = datetime.getDisplayRunningTime(ticks); - divider && (html = " / " + html), elem.innerHTML = html - } - - function onSettingsButtonClick(e) { - var btn = this; - require(["playerSettingsMenu"], function(playerSettingsMenu) { - var player = currentPlayer; - player && playerSettingsMenu.show({ - mediaType: "Video", - player: player, - positionTo: btn, - stats: !0, - onOption: onSettingsOption - }) - }) - } - - function onSettingsOption(selectedOption) { - "stats" === selectedOption && toggleStats() - } - - function toggleStats() { - require(["playerStats"], function(PlayerStats) { - var player = currentPlayer; - player && (statsOverlay ? statsOverlay.toggle() : statsOverlay = new PlayerStats({ - player: player - })) - }) - } - - function destroyStats() { - statsOverlay && (statsOverlay.destroy(), statsOverlay = null) - } - - function showAudioTrackSelection() { - var player = currentPlayer, - audioTracks = playbackManager.audioTracks(player), - currentIndex = playbackManager.getAudioStreamIndex(player), - menuItems = audioTracks.map(function(stream) { - var opt = { - name: stream.DisplayTitle, - id: stream.Index - }; - return stream.Index === currentIndex && (opt.selected = !0), opt - }), - positionTo = this; - require(["actionsheet"], function(actionsheet) { - actionsheet.show({ - items: menuItems, - title: globalize.translate("Audio"), - positionTo: positionTo - }).then(function(id) { - var index = parseInt(id); - index !== currentIndex && playbackManager.setAudioStreamIndex(index, player) - }) - }) - } - - function showSubtitleTrackSelection() { - var player = currentPlayer, - streams = playbackManager.subtitleTracks(player), - currentIndex = playbackManager.getSubtitleStreamIndex(player); - null == currentIndex && (currentIndex = -1), streams.unshift({ - Index: -1, - DisplayTitle: globalize.translate("Off") - }); - var menuItems = streams.map(function(stream) { - var opt = { - name: stream.DisplayTitle, - id: stream.Index - }; - return stream.Index === currentIndex && (opt.selected = !0), opt - }), - positionTo = this; - require(["actionsheet"], function(actionsheet) { - actionsheet.show({ - title: globalize.translate("Subtitles"), - items: menuItems, - positionTo: positionTo - }).then(function(id) { - var index = parseInt(id); - index !== currentIndex && playbackManager.setSubtitleStreamIndex(index, player) - }) - }) - } - - function onWindowKeyDown(e) { - if (!currentVisibleMenu && (32 === e.keyCode || 13 === e.keyCode)) return playbackManager.playPause(currentPlayer), void showOsd(); - switch (e.key) { - case "f": - e.ctrlKey || playbackManager.toggleFullscreen(currentPlayer); - break; - case "m": - playbackManager.toggleMute(currentPlayer); - break; - case "ArrowLeft": - case "Left": - case "NavigationLeft": - case "GamepadDPadLeft": - case "GamepadLeftThumbstickLeft": - e.shiftKey && playbackManager.rewind(currentPlayer); - break; - case "ArrowRight": - case "Right": - case "NavigationRight": - case "GamepadDPadRight": - case "GamepadLeftThumbstickRight": - e.shiftKey && playbackManager.fastForward(currentPlayer) - } - } - - function getImgUrl(item, chapter, index, maxWidth, apiClient) { - return chapter.ImageTag ? apiClient.getScaledImageUrl(item.Id, { - maxWidth: maxWidth, - tag: chapter.ImageTag, - type: "Chapter", - index: index - }) : null - } - - function getChapterBubbleHtml(apiClient, item, chapters, positionTicks) { - for (var chapter, index = -1, i = 0, length = chapters.length; i < length; i++) { - var currentChapter = chapters[i]; - positionTicks >= currentChapter.StartPositionTicks && (chapter = currentChapter, index = i) - } - if (!chapter) return null; - var src = getImgUrl(item, chapter, index, 400, apiClient); - if (src) { - var html = '
'; - return html += '', html += '
', html += '
', html += chapter.Name, html += "
", html += '

', html += datetime.getDisplayRunningTime(positionTicks), html += "

", html += "
", html += "
" - } - return null - } - - function onViewHideStopPlayback() { - if (playbackManager.isPlayingVideo()) { - require(['shell'], function (shell) { - shell.disableFullscreen(); - }); - var player = currentPlayer; - view.removeEventListener("viewbeforehide", onViewHideStopPlayback), releaseCurrentPlayer(), playbackManager.stop(player) - } - } - - function enableStopOnBack(enabled) { - view.removeEventListener("viewbeforehide", onViewHideStopPlayback), enabled && playbackManager.isPlayingVideo(currentPlayer) && view.addEventListener("viewbeforehide", onViewHideStopPlayback) - } - - require(['shell'], function (shell) { - shell.enableFullscreen(); - }); - var currentPlayer, comingUpNextDisplayed, currentUpNextDialog, isEnabled, currentItem, recordingButtonManager, enableProgressByTimeOfDay, supportsBrightnessChange, currentVisibleMenu, statsOverlay, osdHideTimeout, lastPointerMoveData, self = this, - currentPlayerSupportedCommands = [], - currentRuntimeTicks = 0, - lastUpdateTime = 0, - programStartDateMs = 0, - programEndDateMs = 0, - playbackStartTimeTicks = 0, - nowPlayingVolumeSlider = view.querySelector(".osdVolumeSlider"), - nowPlayingVolumeSliderContainer = view.querySelector(".osdVolumeSliderContainer"), - nowPlayingPositionSlider = view.querySelector(".osdPositionSlider"), - nowPlayingPositionText = view.querySelector(".osdPositionText"), - nowPlayingDurationText = view.querySelector(".osdDurationText"), - startTimeText = view.querySelector(".startTimeText"), - endTimeText = view.querySelector(".endTimeText"), - endsAtText = view.querySelector(".endsAtText"), - btnRewind = view.querySelector(".btnRewind"), - btnFastForward = view.querySelector(".btnFastForward"), - transitionEndEventName = dom.whichTransitionEvent(), - headerElement = document.querySelector(".skinHeader"), - osdBottomElement = document.querySelector(".videoOsdBottom-maincontrols"); - view.addEventListener("viewbeforeshow", function(e) { - headerElement.classList.add("osdHeader"), Emby.Page.setTransparency("full") - }), view.addEventListener("viewshow", function(e) { - events.on(playbackManager, "playerchange", onPlayerChange), bindToPlayer(playbackManager.getCurrentPlayer()), dom.addEventListener(document, window.PointerEvent ? "pointermove" : "mousemove", onPointerMove, { - passive: !0 - }), document.body.classList.add("autoScrollY"), showOsd(), inputManager.on(window, onInputCommand), dom.addEventListener(window, "keydown", onWindowKeyDown, { - passive: !0 - }) - }), view.addEventListener("viewbeforehide", function() { - statsOverlay && statsOverlay.enabled(!1), dom.removeEventListener(window, "keydown", onWindowKeyDown, { - passive: !0 - }), stopOsdHideTimer(), headerElement.classList.remove("osdHeader"), headerElement.classList.remove("osdHeader-hidden"), dom.removeEventListener(document, window.PointerEvent ? "pointermove" : "mousemove", onPointerMove, { - passive: !0 - }), document.body.classList.remove("autoScrollY"), inputManager.off(window, onInputCommand), events.off(playbackManager, "playerchange", onPlayerChange), releaseCurrentPlayer() - }), view.querySelector(".btnFullscreen").addEventListener("click", function() { - playbackManager.toggleFullscreen(currentPlayer) - }), view.querySelector(".btnPip").addEventListener("click", function() { - playbackManager.togglePictureInPicture(currentPlayer) - }), view.querySelector(".btnVideoOsdSettings").addEventListener("click", onSettingsButtonClick), view.addEventListener("viewhide", function() { - headerElement.classList.remove("hide") - }), view.addEventListener("viewdestroy", function() { - self.touchHelper && (self.touchHelper.destroy(), self.touchHelper = null), recordingButtonManager && (recordingButtonManager.destroy(), recordingButtonManager = null), destroyStats() - }); - var lastPointerDown = 0; - dom.addEventListener(view, window.PointerEvent ? "pointerdown" : "click", function(e) { - if (dom.parentWithClass(e.target, ["videoOsdBottom", "upNextContainer"])) return void showOsd(); - var pointerType = e.pointerType || (layoutManager.mobile ? "touch" : "mouse"), - now = (new Date).getTime(); - switch (pointerType) { - case "touch": - now - lastPointerDown > 300 && (lastPointerDown = now, toggleOsd()); - break; - case "mouse": - e.button || (playbackManager.playPause(currentPlayer), showOsd()); - break; - default: - playbackManager.playPause(currentPlayer), showOsd() - } - }, { - passive: !0 - }), browser.touch && dom.addEventListener(view, "dblclick", onDoubleClick, {}), view.querySelector(".buttonMute").addEventListener("click", function() { - playbackManager.toggleMute(currentPlayer) - }), nowPlayingVolumeSlider.addEventListener("change", function() { - playbackManager.setVolume(this.value, currentPlayer) - }), nowPlayingPositionSlider.addEventListener("change", function() { - var player = currentPlayer; - if (player) { - var newPercent = parseFloat(this.value); - if (enableProgressByTimeOfDay) { - var seekAirTimeTicks = newPercent / 100 * (programEndDateMs - programStartDateMs) * 1e4; - seekAirTimeTicks += 1e4 * programStartDateMs, seekAirTimeTicks -= playbackStartTimeTicks, playbackManager.seek(seekAirTimeTicks, player) - } else playbackManager.seekPercent(newPercent, player) - } - }), nowPlayingPositionSlider.getBubbleHtml = function(value) { - if (showOsd(), enableProgressByTimeOfDay) { - if (programStartDateMs && programEndDateMs) { - var ms = programEndDateMs - programStartDateMs; - ms /= 100, ms *= value, ms += programStartDateMs; - return '

' + getDisplayTimeWithoutAmPm(new Date(parseInt(ms)), !0) + "

" - } - return "--:--" - } - if (!currentRuntimeTicks) return "--:--"; - var ticks = currentRuntimeTicks; - ticks /= 100, ticks *= value; - var item = currentItem; - if (item && item.Chapters && item.Chapters.length && item.Chapters[0].ImageTag) { - var html = getChapterBubbleHtml(connectionManager.getApiClient(item.ServerId), item, item.Chapters, ticks); - if (html) return html - } - return '

' + datetime.getDisplayRunningTime(ticks) + "

" - }, view.querySelector(".btnPreviousTrack").addEventListener("click", function() { - playbackManager.previousTrack(currentPlayer) - }), view.querySelector(".btnPause").addEventListener("click", function() { - playbackManager.playPause(currentPlayer) - }), view.querySelector(".btnNextTrack").addEventListener("click", function() { - playbackManager.nextTrack(currentPlayer) - }), btnRewind.addEventListener("click", function() { - playbackManager.rewind(currentPlayer) - }), btnFastForward.addEventListener("click", function() { - playbackManager.fastForward(currentPlayer) - }), view.querySelector(".btnAudio").addEventListener("click", showAudioTrackSelection), view.querySelector(".btnSubtitles").addEventListener("click", showSubtitleTrackSelection), browser.touch && function() { - require(["touchHelper"], function(TouchHelper) { - self.touchHelper = new TouchHelper(view, { - swipeYThreshold: 30, - triggerOnMove: !0, - preventDefaultOnMove: !0, - ignoreTagNames: ["BUTTON", "INPUT", "TEXTAREA"] - }), events.on(self.touchHelper, "swipeup", onVerticalSwipe), events.on(self.touchHelper, "swipedown", onVerticalSwipe) - }) - }() + case "togglestats": + toggleStats(); + } } -}); \ No newline at end of file + + function onRecordingCommand() { + var btnRecord = view.querySelector(".btnRecord"); + + if (!btnRecord.classList.contains("hide")) { + btnRecord.click(); + } + } + + function updateFullscreenIcon() { + if (playbackManager.isFullscreen(currentPlayer)) { + view.querySelector(".btnFullscreen").setAttribute("title", globalize.translate("ExitFullscreen")); + view.querySelector(".btnFullscreen i").innerHTML = ""; + } else { + view.querySelector(".btnFullscreen").setAttribute("title", globalize.translate("Fullscreen")); + view.querySelector(".btnFullscreen i").innerHTML = ""; + } + } + + function onPlayerChange() { + bindToPlayer(playbackManager.getCurrentPlayer()); + } + + function onStateChanged(event, state) { + var player = this; + + if (state.NowPlayingItem) { + isEnabled = true; + updatePlayerStateInternal(event, player, state); + updatePlaylist(player); + enableStopOnBack(true); + } + } + + function onPlayPauseStateChanged(e__y) { + if (isEnabled) { + updatePlayPauseState(this.paused()); + } + } + + function onVolumeChanged(e__u) { + if (isEnabled) { + var player = this; + updatePlayerVolumeState(player, player.isMuted(), player.getVolume()); + } + } + + function onPlaybackStart(e__i, state) { + console.log("nowplaying event: " + e__i.type); + var player = this; + onStateChanged.call(player, e__i, state); + resetUpNextDialog(); + } + + function resetUpNextDialog() { + comingUpNextDisplayed = false; + var dlg = currentUpNextDialog; + + if (dlg) { + dlg.destroy(); + currentUpNextDialog = null; + } + } + + function onPlaybackStopped(e__o, state) { + currentRuntimeTicks = null; + resetUpNextDialog(); + console.log("nowplaying event: " + e__o.type); + + if ("Video" !== state.NextMediaType) { + view.removeEventListener("viewbeforehide", onViewHideStopPlayback); + Emby.Page.back(); + } + } + + function onMediaStreamsChanged(e__p) { + var player = this; + var state = playbackManager.getPlayerState(player); + onStateChanged.call(player, { + type: "init" + }, state); + } + + function bindToPlayer(player) { + if (player !== currentPlayer && (releaseCurrentPlayer(), currentPlayer = player, player)) { + var state = playbackManager.getPlayerState(player); + onStateChanged.call(player, { + type: "init" + }, state); + events.on(player, "playbackstart", onPlaybackStart); + events.on(player, "playbackstop", onPlaybackStopped); + events.on(player, "volumechange", onVolumeChanged); + events.on(player, "pause", onPlayPauseStateChanged); + events.on(player, "unpause", onPlayPauseStateChanged); + events.on(player, "timeupdate", onTimeUpdate); + events.on(player, "fullscreenchange", updateFullscreenIcon); + events.on(player, "mediastreamschange", onMediaStreamsChanged); + resetUpNextDialog(); + } + } + + function releaseCurrentPlayer() { + destroyStats(); + resetUpNextDialog(); + var player = currentPlayer; + + if (player) { + events.off(player, "playbackstart", onPlaybackStart); + events.off(player, "playbackstop", onPlaybackStopped); + events.off(player, "volumechange", onVolumeChanged); + events.off(player, "pause", onPlayPauseStateChanged); + events.off(player, "unpause", onPlayPauseStateChanged); + events.off(player, "timeupdate", onTimeUpdate); + events.off(player, "fullscreenchange", updateFullscreenIcon); + events.off(player, "mediastreamschange", onMediaStreamsChanged); + currentPlayer = null; + } + } + + function onTimeUpdate(e__a) { + if (isEnabled) { + var now = new Date().getTime(); + + if (!(now - lastUpdateTime < 700)) { + lastUpdateTime = now; + var player = this; + currentRuntimeTicks = playbackManager.duration(player); + var currentTime = playbackManager.currentTime(player); + updateTimeDisplay(currentTime, currentRuntimeTicks, playbackManager.playbackStartTime(player), playbackManager.getBufferedRanges(player)); + var item = currentItem; + refreshProgramInfoIfNeeded(player, item); + showComingUpNextIfNeeded(player, item, currentTime, currentRuntimeTicks); + } + } + } + + function showComingUpNextIfNeeded(player, currentItem, currentTimeTicks, runtimeTicks) { + if (runtimeTicks && currentTimeTicks && !comingUpNextDisplayed && !currentVisibleMenu && "Episode" === currentItem.Type && userSettings.enableNextVideoInfoOverlay()) { + var showAtSecondsLeft = runtimeTicks >= 3e10 ? 40 : runtimeTicks >= 24e9 ? 35 : 30; + var showAtTicks = runtimeTicks - 1e3 * showAtSecondsLeft * 1e4; + var timeRemainingTicks = runtimeTicks - currentTimeTicks; + + if (currentTimeTicks >= showAtTicks && runtimeTicks >= 6e9 && timeRemainingTicks >= 2e8) { + showComingUpNext(player); + } + } + } + + function onUpNextHidden() { + if ("upnext" === currentVisibleMenu) { + currentVisibleMenu = null; + } + } + + function showComingUpNext(player) { + require(["upNextDialog"], function (UpNextDialog) { + if (!(currentVisibleMenu || currentUpNextDialog)) { + currentVisibleMenu = "upnext"; + comingUpNextDisplayed = true; + playbackManager.nextItem(player).then(function (nextItem) { + currentUpNextDialog = new UpNextDialog({ + parent: view.querySelector(".upNextContainer"), + player: player, + nextItem: nextItem + }); + events.on(currentUpNextDialog, "hide", onUpNextHidden); + }, onUpNextHidden); + } + }); + } + + function refreshProgramInfoIfNeeded(player, item) { + if ("TvChannel" === item.Type) { + var program = item.CurrentProgram; + + if (program && program.EndDate) { + try { + var endDate = datetime.parseISO8601Date(program.EndDate); + + if (new Date().getTime() >= endDate.getTime()) { + console.log("program info needs to be refreshed"); + var state = playbackManager.getPlayerState(player); + onStateChanged.call(player, { + type: "init" + }, state); + } + } catch (e) { + console.log("Error parsing date: " + program.EndDate); + } + } + } + } + + function updatePlayPauseState(isPaused) { + view.querySelector(".btnPause i").innerHTML = isPaused ? "" : ""; + } + + function updatePlayerStateInternal(event, player, state) { + var playState = state.PlayState || {}; + updatePlayPauseState(playState.IsPaused); + var supportedCommands = playbackManager.getSupportedCommands(player); + currentPlayerSupportedCommands = supportedCommands; + supportsBrightnessChange = -1 !== supportedCommands.indexOf("SetBrightness"); + updatePlayerVolumeState(player, playState.IsMuted, playState.VolumeLevel); + + if (nowPlayingPositionSlider && !nowPlayingPositionSlider.dragging) { + nowPlayingPositionSlider.disabled = !playState.CanSeek; + } + + btnFastForward.disabled = !playState.CanSeek; + btnRewind.disabled = !playState.CanSeek; + var nowPlayingItem = state.NowPlayingItem || {}; + playbackStartTimeTicks = playState.PlaybackStartTimeTicks; + updateTimeDisplay(playState.PositionTicks, nowPlayingItem.RunTimeTicks, playState.PlaybackStartTimeTicks, playState.BufferedRanges || []); + updateNowPlayingInfo(player, state); + + if (state.MediaSource && state.MediaSource.SupportsTranscoding && -1 !== supportedCommands.indexOf("SetMaxStreamingBitrate")) { + view.querySelector(".btnVideoOsdSettings").classList.remove("hide"); + } else { + view.querySelector(".btnVideoOsdSettings").classList.add("hide"); + } + + var isProgressClear = state.MediaSource && null == state.MediaSource.RunTimeTicks; + nowPlayingPositionSlider.setIsClear(isProgressClear); + + if (-1 === supportedCommands.indexOf("ToggleFullscreen") || player.isLocalPlayer && layoutManager.tv && playbackManager.isFullscreen(player)) { + view.querySelector(".btnFullscreen").classList.add("hide"); + } else { + view.querySelector(".btnFullscreen").classList.remove("hide"); + } + + if (-1 === supportedCommands.indexOf("PictureInPicture")) { + view.querySelector(".btnPip").classList.add("hide"); + } else { + view.querySelector(".btnPip").classList.remove("hide"); + } + + updateFullscreenIcon(); + } + + function getDisplayPercentByTimeOfDay(programStartDateMs, programRuntimeMs, currentTimeMs) { + return (currentTimeMs - programStartDateMs) / programRuntimeMs * 100; + } + + function updateTimeDisplay(positionTicks, runtimeTicks, playbackStartTimeTicks, bufferedRanges) { + if (enableProgressByTimeOfDay) { + if (nowPlayingPositionSlider && !nowPlayingPositionSlider.dragging) { + if (programStartDateMs && programEndDateMs) { + var currentTimeMs = (playbackStartTimeTicks + (positionTicks || 0)) / 1e4; + var programRuntimeMs = programEndDateMs - programStartDateMs; + + if (nowPlayingPositionSlider.value = getDisplayPercentByTimeOfDay(programStartDateMs, programRuntimeMs, currentTimeMs), bufferedRanges.length) { + var rangeStart = getDisplayPercentByTimeOfDay(programStartDateMs, programRuntimeMs, (playbackStartTimeTicks + (bufferedRanges[0].start || 0)) / 1e4); + var rangeEnd = getDisplayPercentByTimeOfDay(programStartDateMs, programRuntimeMs, (playbackStartTimeTicks + (bufferedRanges[0].end || 0)) / 1e4); + nowPlayingPositionSlider.setBufferedRanges([{ + start: rangeStart, + end: rangeEnd + }]); + } else { + nowPlayingPositionSlider.setBufferedRanges([]); + } + } else { + nowPlayingPositionSlider.value = 0; + nowPlayingPositionSlider.setBufferedRanges([]); + } + } + + nowPlayingPositionText.innerHTML = ""; + nowPlayingDurationText.innerHTML = ""; + } else { + if (nowPlayingPositionSlider && !nowPlayingPositionSlider.dragging) { + if (runtimeTicks) { + var pct = positionTicks / runtimeTicks; + pct *= 100; + nowPlayingPositionSlider.value = pct; + } else { + nowPlayingPositionSlider.value = 0; + } + + if (runtimeTicks && null != positionTicks && currentRuntimeTicks && !enableProgressByTimeOfDay && currentItem.RunTimeTicks && "Recording" !== currentItem.Type) { + endsAtText.innerHTML = "  -  " + mediaInfo.getEndsAtFromPosition(runtimeTicks, positionTicks, true); + } else { + endsAtText.innerHTML = ""; + } + } + + if (nowPlayingPositionSlider) { + nowPlayingPositionSlider.setBufferedRanges(bufferedRanges, runtimeTicks, positionTicks); + } + + updateTimeText(nowPlayingPositionText, positionTicks); + updateTimeText(nowPlayingDurationText, runtimeTicks, true); + } + } + + function updatePlayerVolumeState(player, isMuted, volumeLevel) { + var supportedCommands = currentPlayerSupportedCommands; + var showMuteButton = true; + var showVolumeSlider = true; + + if (-1 === supportedCommands.indexOf("Mute")) { + showMuteButton = false; + } + + if (-1 === supportedCommands.indexOf("SetVolume")) { + showVolumeSlider = false; + } + + if (player.isLocalPlayer && appHost.supports("physicalvolumecontrol")) { + showMuteButton = false; + showVolumeSlider = false; + } + + if (isMuted) { + view.querySelector(".buttonMute").setAttribute("title", globalize.translate("Unmute")); + view.querySelector(".buttonMute i").innerHTML = ""; + } else { + view.querySelector(".buttonMute").setAttribute("title", globalize.translate("Mute")); + view.querySelector(".buttonMute i").innerHTML = ""; + } + + if (showMuteButton) { + view.querySelector(".buttonMute").classList.remove("hide"); + } else { + view.querySelector(".buttonMute").classList.add("hide"); + } + + if (nowPlayingVolumeSlider) { + if (showVolumeSlider) { + nowPlayingVolumeSliderContainer.classList.remove("hide"); + } else { + nowPlayingVolumeSliderContainer.classList.add("hide"); + } + + if (!nowPlayingVolumeSlider.dragging) { + nowPlayingVolumeSlider.value = volumeLevel || 0; + } + } + } + + function updatePlaylist(player) { + var btnPreviousTrack = view.querySelector(".btnPreviousTrack"); + var btnNextTrack = view.querySelector(".btnNextTrack"); + btnPreviousTrack.classList.remove("hide"); + btnNextTrack.classList.remove("hide"); + btnNextTrack.disabled = false; + btnPreviousTrack.disabled = false; + } + + function updateTimeText(elem, ticks, divider) { + if (null == ticks) { + return void (elem.innerHTML = ""); + } + + var html = datetime.getDisplayRunningTime(ticks); + + if (divider) { + html = " / " + html; + } + + elem.innerHTML = html; + } + + function onSettingsButtonClick(e__s) { + var btn = this; + + require(["playerSettingsMenu"], function (playerSettingsMenu) { + var player = currentPlayer; + + if (player) { + playerSettingsMenu.show({ + mediaType: "Video", + player: player, + positionTo: btn, + stats: true, + onOption: onSettingsOption + }); + } + }); + } + + function onSettingsOption(selectedOption) { + if ("stats" === selectedOption) { + toggleStats(); + } + } + + function toggleStats() { + require(["playerStats"], function (PlayerStats) { + var player = currentPlayer; + + if (player) { + if (statsOverlay) { + statsOverlay.toggle(); + } else { + statsOverlay = new PlayerStats({ + player: player + }); + } + } + }); + } + + function destroyStats() { + if (statsOverlay) { + statsOverlay.destroy(); + statsOverlay = null; + } + } + + function showAudioTrackSelection() { + var player = currentPlayer; + var audioTracks = playbackManager.audioTracks(player); + var currentIndex = playbackManager.getAudioStreamIndex(player); + var menuItems = audioTracks.map(function (stream) { + var opt = { + name: stream.DisplayTitle, + id: stream.Index + }; + + if (stream.Index === currentIndex) { + opt.selected = true; + } + + return opt; + }); + var positionTo = this; + + require(["actionsheet"], function (actionsheet) { + actionsheet.show({ + items: menuItems, + title: globalize.translate("Audio"), + positionTo: positionTo + }).then(function (id) { + var index = parseInt(id); + + if (index !== currentIndex) { + playbackManager.setAudioStreamIndex(index, player); + } + }); + }); + } + + function showSubtitleTrackSelection() { + var player = currentPlayer; + var streams = playbackManager.subtitleTracks(player); + var currentIndex = playbackManager.getSubtitleStreamIndex(player); + + if (null == currentIndex) { + currentIndex = -1; + } + + streams.unshift({ + Index: -1, + DisplayTitle: globalize.translate("Off") + }); + var menuItems = streams.map(function (stream) { + var opt = { + name: stream.DisplayTitle, + id: stream.Index + }; + + if (stream.Index === currentIndex) { + opt.selected = true; + } + + return opt; + }); + var positionTo = this; + + require(["actionsheet"], function (actionsheet) { + actionsheet.show({ + title: globalize.translate("Subtitles"), + items: menuItems, + positionTo: positionTo + }).then(function (id) { + var index = parseInt(id); + + if (index !== currentIndex) { + playbackManager.setSubtitleStreamIndex(index, player); + } + }); + }); + } + + function onWindowKeyDown(e__d) { + if (!currentVisibleMenu && (32 === e__d.keyCode || 13 === e__d.keyCode)) { + playbackManager.playPause(currentPlayer); + return void showOsd(); + } + + switch (e__d.key) { + case "f": + if (!e__d.ctrlKey) { + playbackManager.toggleFullscreen(currentPlayer); + } + + break; + + case "m": + playbackManager.toggleMute(currentPlayer); + break; + + case "ArrowLeft": + case "Left": + case "NavigationLeft": + case "GamepadDPadLeft": + case "GamepadLeftThumbstickLeft": + if (e__d.shiftKey) { + playbackManager.rewind(currentPlayer); + } + + break; + + case "ArrowRight": + case "Right": + case "NavigationRight": + case "GamepadDPadRight": + case "GamepadLeftThumbstickRight": + if (e__d.shiftKey) { + playbackManager.fastForward(currentPlayer); + } + + } + } + + function getImgUrl(item, chapter, index, maxWidth, apiClient) { + if (chapter.ImageTag) { + return apiClient.getScaledImageUrl(item.Id, { + maxWidth: maxWidth, + tag: chapter.ImageTag, + type: "Chapter", + index: index + }); + } + + return null; + } + + function getChapterBubbleHtml(apiClient, item, chapters, positionTicks) { + var chapter; + var index = -1; + + for (var i__f = 0, length = chapters.length; i__f < length; i__f++) { + var currentChapter = chapters[i__f]; + + if (positionTicks >= currentChapter.StartPositionTicks) { + chapter = currentChapter; + index = i__f; + } + } + + if (!chapter) { + return null; + } + + var src = getImgUrl(item, chapter, index, 400, apiClient); + + if (src) { + var html = '
'; + html += ''; + html += '
'; + html += '
'; + html += chapter.Name; + html += "
"; + html += '

'; + html += datetime.getDisplayRunningTime(positionTicks); + html += "

"; + html += "
"; + return html += "
"; + } + + return null; + } + + function onViewHideStopPlayback() { + if (playbackManager.isPlayingVideo()) { + require(['shell'], function (shell) { + shell.disableFullscreen(); + }); + + var player = currentPlayer; + view.removeEventListener("viewbeforehide", onViewHideStopPlayback); + releaseCurrentPlayer(); + playbackManager.stop(player); + } + } + + function enableStopOnBack(enabled) { + view.removeEventListener("viewbeforehide", onViewHideStopPlayback); + + if (enabled && playbackManager.isPlayingVideo(currentPlayer)) { + view.addEventListener("viewbeforehide", onViewHideStopPlayback); + } + } + + require(['shell'], function (shell) { + shell.enableFullscreen(); + }); + + var currentPlayer; + var comingUpNextDisplayed; + var currentUpNextDialog; + var isEnabled; + var currentItem; + var recordingButtonManager; + var enableProgressByTimeOfDay; + var supportsBrightnessChange; + var currentVisibleMenu; + var statsOverlay; + var osdHideTimeout; + var lastPointerMoveData; + var self = this; + var currentPlayerSupportedCommands = []; + var currentRuntimeTicks = 0; + var lastUpdateTime = 0; + var programStartDateMs = 0; + var programEndDateMs = 0; + var playbackStartTimeTicks = 0; + var nowPlayingVolumeSlider = view.querySelector(".osdVolumeSlider"); + var nowPlayingVolumeSliderContainer = view.querySelector(".osdVolumeSliderContainer"); + var nowPlayingPositionSlider = view.querySelector(".osdPositionSlider"); + var nowPlayingPositionText = view.querySelector(".osdPositionText"); + var nowPlayingDurationText = view.querySelector(".osdDurationText"); + var startTimeText = view.querySelector(".startTimeText"); + var endTimeText = view.querySelector(".endTimeText"); + var endsAtText = view.querySelector(".endsAtText"); + var btnRewind = view.querySelector(".btnRewind"); + var btnFastForward = view.querySelector(".btnFastForward"); + var transitionEndEventName = dom.whichTransitionEvent(); + var headerElement = document.querySelector(".skinHeader"); + var osdBottomElement = document.querySelector(".videoOsdBottom-maincontrols"); + view.addEventListener("viewbeforeshow", function (e__g) { + headerElement.classList.add("osdHeader"); + Emby.Page.setTransparency("full"); + }); + view.addEventListener("viewshow", function (e__h) { + events.on(playbackManager, "playerchange", onPlayerChange); + bindToPlayer(playbackManager.getCurrentPlayer()); + dom.addEventListener(document, window.PointerEvent ? "pointermove" : "mousemove", onPointerMove, { + passive: true + }); + document.body.classList.add("autoScrollY"); + showOsd(); + inputManager.on(window, onInputCommand); + dom.addEventListener(window, "keydown", onWindowKeyDown, { + passive: true + }); + }); + view.addEventListener("viewbeforehide", function () { + if (statsOverlay) { + statsOverlay.enabled(false); + } + + dom.removeEventListener(window, "keydown", onWindowKeyDown, { + passive: true + }); + stopOsdHideTimer(); + headerElement.classList.remove("osdHeader"); + headerElement.classList.remove("osdHeader-hidden"); + dom.removeEventListener(document, window.PointerEvent ? "pointermove" : "mousemove", onPointerMove, { + passive: true + }); + document.body.classList.remove("autoScrollY"); + inputManager.off(window, onInputCommand); + events.off(playbackManager, "playerchange", onPlayerChange); + releaseCurrentPlayer(); + }); + view.querySelector(".btnFullscreen").addEventListener("click", function () { + playbackManager.toggleFullscreen(currentPlayer); + }); + view.querySelector(".btnPip").addEventListener("click", function () { + playbackManager.togglePictureInPicture(currentPlayer); + }); + view.querySelector(".btnVideoOsdSettings").addEventListener("click", onSettingsButtonClick); + view.addEventListener("viewhide", function () { + headerElement.classList.remove("hide"); + }); + view.addEventListener("viewdestroy", function () { + if (self.touchHelper) { + self.touchHelper.destroy(); + self.touchHelper = null; + } + + if (recordingButtonManager) { + recordingButtonManager.destroy(); + recordingButtonManager = null; + } + + destroyStats(); + }); + var lastPointerDown = 0; + dom.addEventListener(view, window.PointerEvent ? "pointerdown" : "click", function (e__j) { + if (dom.parentWithClass(e__j.target, ["videoOsdBottom", "upNextContainer"])) { + return void showOsd(); + } + + var pointerType = e__j.pointerType || (layoutManager.mobile ? "touch" : "mouse"); + var now = new Date().getTime(); + + switch (pointerType) { + case "touch": + if (now - lastPointerDown > 300) { + lastPointerDown = now; + toggleOsd(); + } + + break; + + case "mouse": + if (!e__j.button) { + playbackManager.playPause(currentPlayer); + showOsd(); + } + + break; + + default: + playbackManager.playPause(currentPlayer); + showOsd(); + } + }, { + passive: true + }); + + if (browser.touch) { + dom.addEventListener(view, "dblclick", onDoubleClick, {}); + } + + view.querySelector(".buttonMute").addEventListener("click", function () { + playbackManager.toggleMute(currentPlayer); + }); + nowPlayingVolumeSlider.addEventListener("change", function () { + playbackManager.setVolume(this.value, currentPlayer); + }); + nowPlayingPositionSlider.addEventListener("change", function () { + var player = currentPlayer; + + if (player) { + var newPercent = parseFloat(this.value); + + if (enableProgressByTimeOfDay) { + var seekAirTimeTicks = newPercent / 100 * (programEndDateMs - programStartDateMs) * 1e4; + seekAirTimeTicks += 1e4 * programStartDateMs; + seekAirTimeTicks -= playbackStartTimeTicks; + playbackManager.seek(seekAirTimeTicks, player); + } else { + playbackManager.seekPercent(newPercent, player); + } + } + }); + + nowPlayingPositionSlider.getBubbleHtml = function (value) { + if (showOsd(), enableProgressByTimeOfDay) { + if (programStartDateMs && programEndDateMs) { + var ms = programEndDateMs - programStartDateMs; + ms /= 100; + ms *= value; + ms += programStartDateMs; + return '

' + getDisplayTimeWithoutAmPm(new Date(parseInt(ms)), true) + "

"; + } + + return "--:--"; + } + + if (!currentRuntimeTicks) { + return "--:--"; + } + + var ticks = currentRuntimeTicks; + ticks /= 100; + ticks *= value; + var item = currentItem; + + if (item && item.Chapters && item.Chapters.length && item.Chapters[0].ImageTag) { + var html = getChapterBubbleHtml(connectionManager.getApiClient(item.ServerId), item, item.Chapters, ticks); + + if (html) { + return html; + } + } + + return '

' + datetime.getDisplayRunningTime(ticks) + "

"; + }; + + view.querySelector(".btnPreviousTrack").addEventListener("click", function () { + playbackManager.previousTrack(currentPlayer); + }); + view.querySelector(".btnPause").addEventListener("click", function () { + playbackManager.playPause(currentPlayer); + }); + view.querySelector(".btnNextTrack").addEventListener("click", function () { + playbackManager.nextTrack(currentPlayer); + }); + btnRewind.addEventListener("click", function () { + playbackManager.rewind(currentPlayer); + }); + btnFastForward.addEventListener("click", function () { + playbackManager.fastForward(currentPlayer); + }); + view.querySelector(".btnAudio").addEventListener("click", showAudioTrackSelection); + view.querySelector(".btnSubtitles").addEventListener("click", showSubtitleTrackSelection); + + if (browser.touch) { + (function () { + require(["touchHelper"], function (TouchHelper) { + self.touchHelper = new TouchHelper(view, { + swipeYThreshold: 30, + triggerOnMove: true, + preventDefaultOnMove: true, + ignoreTagNames: ["BUTTON", "INPUT", "TEXTAREA"] + }); + events.on(self.touchHelper, "swipeup", onVerticalSwipe); + events.on(self.touchHelper, "swipedown", onVerticalSwipe); + }); + })(); + } + }; +});