2020-01-19 01:09:42 +03:00
|
|
|
define(["playbackManager", "dom", "inputManager", "datetime", "itemHelper", "mediaInfo", "focusManager", "imageLoader", "scrollHelper", "events", "connectionManager", "browser", "globalize", "apphost", "layoutManager", "userSettings", "keyboardnavigation", "scrollStyles", "emby-slider", "paper-icon-button-light", "css!assets/css/videoosd"], function (playbackManager, dom, inputManager, datetime, itemHelper, mediaInfo, focusManager, imageLoader, scrollHelper, events, connectionManager, browser, globalize, appHost, layoutManager, userSettings, keyboardnavigation) {
|
2019-02-02 13:51:03 -05:00
|
|
|
"use strict";
|
2019-02-02 10:20:27 -05:00
|
|
|
|
2019-02-02 13:51:03 -05:00
|
|
|
function seriesImageUrl(item, options) {
|
|
|
|
if ("Episode" !== item.Type) {
|
|
|
|
return null;
|
|
|
|
}
|
2018-10-23 01:05:09 +03:00
|
|
|
|
2019-02-12 10:01:11 -05:00
|
|
|
options = options || {};
|
|
|
|
options.type = options.type || "Primary";
|
|
|
|
if ("Primary" === options.type && item.SeriesPrimaryImageTag) {
|
2019-02-02 13:51:03 -05:00
|
|
|
options.tag = item.SeriesPrimaryImageTag;
|
|
|
|
return connectionManager.getApiClient(item.ServerId).getScaledImageUrl(item.SeriesId, options);
|
|
|
|
}
|
2018-10-23 01:05:09 +03:00
|
|
|
|
2019-02-02 13:51:03 -05:00
|
|
|
if ("Thumb" === options.type) {
|
|
|
|
if (item.SeriesThumbImageTag) {
|
|
|
|
options.tag = item.SeriesThumbImageTag;
|
|
|
|
return connectionManager.getApiClient(item.ServerId).getScaledImageUrl(item.SeriesId, options);
|
|
|
|
}
|
2019-02-02 10:20:27 -05:00
|
|
|
|
2019-02-02 13:51:03 -05:00
|
|
|
if (item.ParentThumbImageTag) {
|
|
|
|
options.tag = item.ParentThumbImageTag;
|
|
|
|
return connectionManager.getApiClient(item.ServerId).getScaledImageUrl(item.ParentThumbItemId, options);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return null;
|
2018-10-23 01:05:09 +03:00
|
|
|
}
|
2019-01-15 19:53:30 +09:00
|
|
|
|
2019-02-02 13:51:03 -05:00
|
|
|
function imageUrl(item, options) {
|
|
|
|
options = options || {};
|
|
|
|
options.type = options.type || "Primary";
|
2018-10-23 01:05:09 +03:00
|
|
|
|
2019-02-02 13:51:03 -05:00
|
|
|
if (item.ImageTags && item.ImageTags[options.type]) {
|
|
|
|
options.tag = item.ImageTags[options.type];
|
|
|
|
return connectionManager.getApiClient(item.ServerId).getScaledImageUrl(item.PrimaryImageItemId || item.Id, options);
|
|
|
|
}
|
2018-10-23 01:05:09 +03:00
|
|
|
|
2019-02-02 13:51:03 -05:00
|
|
|
if ("Primary" === options.type && item.AlbumId && item.AlbumPrimaryImageTag) {
|
|
|
|
options.tag = item.AlbumPrimaryImageTag;
|
|
|
|
return connectionManager.getApiClient(item.ServerId).getScaledImageUrl(item.AlbumId, options);
|
|
|
|
}
|
2018-10-23 01:05:09 +03:00
|
|
|
|
2019-02-02 13:51:03 -05:00
|
|
|
return null;
|
2019-02-02 10:20:27 -05:00
|
|
|
}
|
2018-10-23 01:05:09 +03:00
|
|
|
|
2019-02-02 13:51:03 -05:00
|
|
|
function logoImageUrl(item, apiClient, options) {
|
|
|
|
options = options || {};
|
|
|
|
options.type = "Logo";
|
2018-10-23 01:05:09 +03:00
|
|
|
|
2019-02-02 13:51:03 -05:00
|
|
|
if (item.ImageTags && item.ImageTags.Logo) {
|
|
|
|
options.tag = item.ImageTags.Logo;
|
|
|
|
return apiClient.getScaledImageUrl(item.Id, options);
|
|
|
|
}
|
2018-10-23 01:05:09 +03:00
|
|
|
|
2019-02-02 13:51:03 -05:00
|
|
|
if (item.ParentLogoImageTag) {
|
|
|
|
options.tag = item.ParentLogoImageTag;
|
|
|
|
return apiClient.getScaledImageUrl(item.ParentLogoItemId, options);
|
|
|
|
}
|
2018-10-23 01:05:09 +03:00
|
|
|
|
2019-02-02 13:51:03 -05:00
|
|
|
return null;
|
2019-02-02 10:20:27 -05:00
|
|
|
}
|
2018-10-23 01:05:09 +03:00
|
|
|
|
2019-02-02 13:51:03 -05:00
|
|
|
return function (view, params) {
|
|
|
|
function onVerticalSwipe(e, elem, data) {
|
|
|
|
var player = currentPlayer;
|
2019-02-02 10:20:27 -05:00
|
|
|
|
2019-02-02 13:51:03 -05:00
|
|
|
if (player) {
|
|
|
|
var deltaY = data.currentDeltaY;
|
|
|
|
var windowSize = dom.getWindowSize();
|
2019-02-02 10:20:27 -05:00
|
|
|
|
2019-02-02 13:51:03 -05:00
|
|
|
if (supportsBrightnessChange && data.clientX < windowSize.innerWidth / 2) {
|
|
|
|
return void doBrightnessTouch(deltaY, player, windowSize.innerHeight);
|
|
|
|
}
|
2018-10-23 01:05:09 +03:00
|
|
|
|
2019-02-02 13:51:03 -05:00
|
|
|
doVolumeTouch(deltaY, player, windowSize.innerHeight);
|
|
|
|
}
|
2018-10-23 01:05:09 +03:00
|
|
|
}
|
|
|
|
|
2019-02-02 13:51:03 -05:00
|
|
|
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);
|
|
|
|
}
|
2019-02-02 10:20:27 -05:00
|
|
|
|
2019-02-02 13:51:03 -05:00
|
|
|
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);
|
|
|
|
}
|
2019-02-02 10:20:27 -05:00
|
|
|
|
2019-02-02 13:51:03 -05:00
|
|
|
function onDoubleClick(e) {
|
|
|
|
var clientX = e.clientX;
|
2019-02-02 10:20:27 -05:00
|
|
|
|
2019-02-02 13:51:03 -05:00
|
|
|
if (null != clientX) {
|
|
|
|
if (clientX < dom.getWindowSize().innerWidth / 2) {
|
|
|
|
playbackManager.rewind(currentPlayer);
|
|
|
|
} else {
|
|
|
|
playbackManager.fastForward(currentPlayer);
|
|
|
|
}
|
2019-02-02 10:20:27 -05:00
|
|
|
|
2019-02-02 13:51:03 -05:00
|
|
|
e.preventDefault();
|
|
|
|
e.stopPropagation();
|
|
|
|
}
|
2018-10-23 01:05:09 +03:00
|
|
|
}
|
|
|
|
|
2019-02-02 13:51:03 -05:00
|
|
|
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
|
|
|
|
};
|
|
|
|
});
|
|
|
|
}
|
2019-02-02 10:20:27 -05:00
|
|
|
|
2019-02-02 13:51:03 -05:00
|
|
|
return Promise.resolve({
|
|
|
|
originalItem: item
|
|
|
|
});
|
|
|
|
}
|
2019-02-02 10:20:27 -05:00
|
|
|
|
2019-02-02 13:51:03 -05:00
|
|
|
function updateRecordingButton(item) {
|
|
|
|
if (!item || "Program" !== item.Type) {
|
|
|
|
if (recordingButtonManager) {
|
|
|
|
recordingButtonManager.destroy();
|
|
|
|
recordingButtonManager = null;
|
|
|
|
}
|
|
|
|
|
|
|
|
return void view.querySelector(".btnRecord").classList.add("hide");
|
|
|
|
}
|
2019-02-02 10:20:27 -05:00
|
|
|
|
2019-02-02 13:51:03 -05:00
|
|
|
connectionManager.getApiClient(item.ServerId).getCurrentUser().then(function (user) {
|
|
|
|
if (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");
|
|
|
|
});
|
|
|
|
}
|
|
|
|
});
|
2018-10-23 01:05:09 +03:00
|
|
|
}
|
|
|
|
|
2019-02-02 13:51:03 -05:00
|
|
|
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;
|
2019-02-02 10:20:27 -05:00
|
|
|
|
2019-02-02 13:51:03 -05:00
|
|
|
if (displayItem.EpisodeTitle || displayItem.IsSeries) {
|
|
|
|
parentName = displayItem.Name;
|
2018-10-23 01:05:09 +03:00
|
|
|
}
|
|
|
|
|
2019-02-02 13:51:03 -05:00
|
|
|
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
|
2019-02-02 10:20:27 -05:00
|
|
|
});
|
2018-10-23 01:05:09 +03:00
|
|
|
|
2019-02-02 13:51:03 -05:00
|
|
|
if (!displayName) {
|
|
|
|
displayItem.Type;
|
|
|
|
}
|
2018-10-23 01:05:09 +03:00
|
|
|
|
2019-02-02 13:51:03 -05:00
|
|
|
titleElement.innerHTML = displayName;
|
2018-10-23 01:05:09 +03:00
|
|
|
|
2019-02-02 13:51:03 -05:00
|
|
|
if (displayName) {
|
|
|
|
titleElement.classList.remove("hide");
|
|
|
|
} else {
|
|
|
|
titleElement.classList.add("hide");
|
|
|
|
}
|
2019-02-02 10:20:27 -05:00
|
|
|
|
2019-02-02 13:51:03 -05:00
|
|
|
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;
|
2019-02-02 10:20:27 -05:00
|
|
|
|
2019-02-02 13:51:03 -05:00
|
|
|
if (mediaInfoHtml) {
|
|
|
|
osdMediaInfo.classList.remove("hide");
|
|
|
|
} else {
|
|
|
|
osdMediaInfo.classList.add("hide");
|
|
|
|
}
|
2019-02-02 10:20:27 -05:00
|
|
|
|
2019-02-02 13:51:03 -05:00
|
|
|
var secondaryMediaInfo = view.querySelector(".osdSecondaryMediaInfo");
|
|
|
|
var secondaryMediaInfoHtml = mediaInfo.getSecondaryMediaInfoHtml(displayItem, {
|
|
|
|
startDate: false,
|
|
|
|
programTime: false
|
|
|
|
});
|
|
|
|
secondaryMediaInfo.innerHTML = secondaryMediaInfoHtml;
|
2019-02-02 10:20:27 -05:00
|
|
|
|
2019-02-02 13:51:03 -05:00
|
|
|
if (secondaryMediaInfoHtml) {
|
|
|
|
secondaryMediaInfo.classList.remove("hide");
|
|
|
|
} else {
|
|
|
|
secondaryMediaInfo.classList.add("hide");
|
|
|
|
}
|
2018-10-23 01:05:09 +03:00
|
|
|
|
2019-02-02 13:51:03 -05:00
|
|
|
if (displayName) {
|
|
|
|
view.querySelector(".osdMainTextContainer").classList.remove("hide");
|
|
|
|
} else {
|
|
|
|
view.querySelector(".osdMainTextContainer").classList.add("hide");
|
|
|
|
}
|
2019-02-02 10:20:27 -05:00
|
|
|
|
2019-02-02 13:51:03 -05:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
}
|
2019-02-02 10:20:27 -05:00
|
|
|
|
2019-02-02 13:51:03 -05:00
|
|
|
function getDisplayTimeWithoutAmPm(date, showSeconds) {
|
|
|
|
if (showSeconds) {
|
|
|
|
return datetime.toLocaleTimeString(date, {
|
|
|
|
hour: "numeric",
|
|
|
|
minute: "2-digit",
|
|
|
|
second: "2-digit"
|
|
|
|
}).toLowerCase().replace("am", "").replace("pm", "").trim();
|
|
|
|
}
|
2019-02-02 10:20:27 -05:00
|
|
|
|
2019-02-02 13:51:03 -05:00
|
|
|
return datetime.getDisplayTime(date).toLowerCase().replace("am", "").replace("pm", "").trim();
|
|
|
|
}
|
2019-02-02 10:20:27 -05:00
|
|
|
|
2019-02-02 13:51:03 -05:00
|
|
|
function setDisplayTime(elem, date) {
|
|
|
|
var html;
|
|
|
|
|
|
|
|
if (date) {
|
|
|
|
date = datetime.parseISO8601Date(date);
|
|
|
|
html = getDisplayTimeWithoutAmPm(date);
|
|
|
|
}
|
|
|
|
|
|
|
|
elem.innerHTML = html || "";
|
2018-10-23 01:05:09 +03:00
|
|
|
}
|
2019-02-02 10:20:27 -05:00
|
|
|
|
2019-02-02 13:51:03 -05:00
|
|
|
function shouldEnableProgressByTimeOfDay(item) {
|
|
|
|
return !("TvChannel" !== item.Type || !item.CurrentProgram);
|
|
|
|
}
|
2019-02-02 10:20:27 -05:00
|
|
|
|
2019-02-02 13:51:03 -05:00
|
|
|
function updateNowPlayingInfo(player, state) {
|
|
|
|
var item = state.NowPlayingItem;
|
|
|
|
|
2019-02-12 10:01:11 -05:00
|
|
|
currentItem = item;
|
|
|
|
if (!item) {
|
2019-02-02 13:51:03 -05:00
|
|
|
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 = "";
|
2019-02-12 10:01:11 -05:00
|
|
|
view.querySelector(".osdMediaInfo").innerHTML = "";
|
|
|
|
return;
|
2019-02-02 13:51:03 -05:00
|
|
|
}
|
2019-02-02 10:20:27 -05:00
|
|
|
|
2019-02-02 13:51:03 -05:00
|
|
|
enableProgressByTimeOfDay = shouldEnableProgressByTimeOfDay(item);
|
|
|
|
getDisplayItem(item).then(updateDisplayItem);
|
|
|
|
nowPlayingVolumeSlider.disabled = false;
|
|
|
|
nowPlayingPositionSlider.disabled = false;
|
|
|
|
btnFastForward.disabled = false;
|
|
|
|
btnRewind.disabled = false;
|
2018-10-23 01:05:09 +03:00
|
|
|
|
2019-02-02 13:51:03 -05:00
|
|
|
if (playbackManager.subtitleTracks(player).length) {
|
|
|
|
view.querySelector(".btnSubtitles").classList.remove("hide");
|
2019-04-08 20:31:18 +02:00
|
|
|
toggleSubtitleSync();
|
2019-02-02 13:51:03 -05:00
|
|
|
} else {
|
|
|
|
view.querySelector(".btnSubtitles").classList.add("hide");
|
2019-04-08 20:31:18 +02:00
|
|
|
toggleSubtitleSync("forceToHide");
|
2019-02-02 13:51:03 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
if (playbackManager.audioTracks(player).length > 1) {
|
|
|
|
view.querySelector(".btnAudio").classList.remove("hide");
|
|
|
|
} else {
|
|
|
|
view.querySelector(".btnAudio").classList.add("hide");
|
|
|
|
}
|
2018-10-23 01:05:09 +03:00
|
|
|
}
|
2019-02-02 10:20:27 -05:00
|
|
|
|
2019-02-02 13:51:03 -05:00
|
|
|
function setTitle(item, parentName) {
|
|
|
|
var url = logoImageUrl(item, connectionManager.getApiClient(item.ServerId), {});
|
2019-02-02 10:20:27 -05:00
|
|
|
|
2019-02-02 13:51:03 -05:00
|
|
|
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 || "");
|
|
|
|
}
|
2019-02-02 10:20:27 -05:00
|
|
|
|
2019-02-02 13:51:03 -05:00
|
|
|
var documentTitle = parentName || (item ? item.Name : null);
|
2019-02-02 10:20:27 -05:00
|
|
|
|
2019-02-02 13:51:03 -05:00
|
|
|
if (documentTitle) {
|
|
|
|
document.title = documentTitle;
|
|
|
|
}
|
|
|
|
}
|
2019-02-02 10:20:27 -05:00
|
|
|
|
2019-02-02 13:51:03 -05:00
|
|
|
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 = '<img src="' + imgUrl + '" />');
|
|
|
|
}
|
|
|
|
}
|
2019-02-02 10:20:27 -05:00
|
|
|
|
2019-02-02 13:51:03 -05:00
|
|
|
osdPoster.innerHTML = "";
|
|
|
|
}
|
2018-10-23 01:05:09 +03:00
|
|
|
|
2019-02-02 13:51:03 -05:00
|
|
|
function showOsd() {
|
|
|
|
slideDownToShow(headerElement);
|
|
|
|
showMainOsdControls();
|
|
|
|
startOsdHideTimer();
|
|
|
|
}
|
2018-10-23 01:05:09 +03:00
|
|
|
|
2019-02-02 13:51:03 -05:00
|
|
|
function hideOsd() {
|
|
|
|
slideUpToHide(headerElement);
|
|
|
|
hideMainOsdControls();
|
|
|
|
}
|
2019-02-02 10:20:27 -05:00
|
|
|
|
2019-02-02 13:51:03 -05:00
|
|
|
function toggleOsd() {
|
|
|
|
if ("osd" === currentVisibleMenu) {
|
|
|
|
hideOsd();
|
2019-02-12 10:01:11 -05:00
|
|
|
} else if (!currentVisibleMenu) {
|
2019-04-25 11:50:44 -04:00
|
|
|
showOsd();
|
2019-02-02 13:51:03 -05:00
|
|
|
}
|
|
|
|
}
|
2019-02-02 10:20:27 -05:00
|
|
|
|
2019-02-02 13:51:03 -05:00
|
|
|
function startOsdHideTimer() {
|
|
|
|
stopOsdHideTimer();
|
|
|
|
osdHideTimeout = setTimeout(hideOsd, 5e3);
|
2018-10-23 01:05:09 +03:00
|
|
|
}
|
|
|
|
|
2019-02-02 13:51:03 -05:00
|
|
|
function stopOsdHideTimer() {
|
|
|
|
if (osdHideTimeout) {
|
|
|
|
clearTimeout(osdHideTimeout);
|
|
|
|
osdHideTimeout = null;
|
|
|
|
}
|
2018-10-23 01:05:09 +03:00
|
|
|
}
|
|
|
|
|
2019-02-02 13:51:03 -05:00
|
|
|
function slideDownToShow(elem) {
|
|
|
|
elem.classList.remove("osdHeader-hidden");
|
|
|
|
}
|
2019-02-02 10:20:27 -05:00
|
|
|
|
2019-02-02 13:51:03 -05:00
|
|
|
function slideUpToHide(elem) {
|
|
|
|
elem.classList.add("osdHeader-hidden");
|
|
|
|
}
|
2019-02-02 10:20:27 -05:00
|
|
|
|
2019-02-02 13:51:03 -05:00
|
|
|
function clearHideAnimationEventListeners(elem) {
|
|
|
|
dom.removeEventListener(elem, transitionEndEventName, onHideAnimationComplete, {
|
|
|
|
once: true
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
function onHideAnimationComplete(e) {
|
|
|
|
var elem = e.target;
|
2019-12-07 14:20:09 +01:00
|
|
|
if (elem != osdBottomElement)
|
|
|
|
return;
|
2019-02-02 13:51:03 -05:00
|
|
|
elem.classList.add("hide");
|
|
|
|
dom.removeEventListener(elem, transitionEndEventName, onHideAnimationComplete, {
|
|
|
|
once: true
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
function showMainOsdControls() {
|
2018-10-23 01:05:09 +03:00
|
|
|
if (!currentVisibleMenu) {
|
2019-02-02 13:51:03 -05:00
|
|
|
var elem = osdBottomElement;
|
|
|
|
currentVisibleMenu = "osd";
|
|
|
|
clearHideAnimationEventListeners(elem);
|
|
|
|
elem.classList.remove("hide");
|
|
|
|
elem.classList.remove("videoOsdBottom-hidden");
|
|
|
|
|
|
|
|
if (!layoutManager.mobile) {
|
|
|
|
setTimeout(function () {
|
|
|
|
focusManager.focus(elem.querySelector(".btnPause"));
|
|
|
|
}, 50);
|
|
|
|
}
|
2019-04-08 20:31:18 +02:00
|
|
|
toggleSubtitleSync();
|
2018-10-23 01:05:09 +03:00
|
|
|
}
|
2019-02-02 13:51:03 -05:00
|
|
|
}
|
2018-10-23 01:05:09 +03:00
|
|
|
|
2019-02-02 13:51:03 -05:00
|
|
|
function hideMainOsdControls() {
|
|
|
|
if ("osd" === currentVisibleMenu) {
|
|
|
|
var elem = osdBottomElement;
|
|
|
|
clearHideAnimationEventListeners(elem);
|
|
|
|
elem.classList.add("videoOsdBottom-hidden");
|
|
|
|
dom.addEventListener(elem, transitionEndEventName, onHideAnimationComplete, {
|
|
|
|
once: true
|
|
|
|
});
|
|
|
|
currentVisibleMenu = null;
|
2019-04-08 20:31:18 +02:00
|
|
|
toggleSubtitleSync("hide");
|
2020-01-25 17:35:16 +03:00
|
|
|
|
|
|
|
// Firefox does not blur by itself
|
|
|
|
if (document.activeElement) {
|
|
|
|
document.activeElement.blur();
|
|
|
|
}
|
2019-02-02 13:51:03 -05:00
|
|
|
}
|
|
|
|
}
|
2018-10-23 01:05:09 +03:00
|
|
|
|
2019-02-02 13:51:03 -05:00
|
|
|
function onPointerMove(e) {
|
|
|
|
if ("mouse" === (e.pointerType || (layoutManager.mobile ? "touch" : "mouse"))) {
|
|
|
|
var eventX = e.screenX || 0;
|
|
|
|
var eventY = e.screenY || 0;
|
|
|
|
var obj = lastPointerMoveData;
|
|
|
|
|
|
|
|
if (!obj) {
|
2019-02-12 10:01:11 -05:00
|
|
|
lastPointerMoveData = {
|
2019-02-02 13:51:03 -05:00
|
|
|
x: eventX,
|
|
|
|
y: eventY
|
2019-02-12 10:01:11 -05:00
|
|
|
};
|
|
|
|
return;
|
2019-02-02 13:51:03 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
if (Math.abs(eventX - obj.x) < 10 && Math.abs(eventY - obj.y) < 10) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
obj.x = eventX;
|
|
|
|
obj.y = eventY;
|
|
|
|
showOsd();
|
|
|
|
}
|
|
|
|
}
|
2018-10-23 01:05:09 +03:00
|
|
|
|
2019-02-02 13:51:03 -05:00
|
|
|
function onInputCommand(e) {
|
|
|
|
var player = currentPlayer;
|
|
|
|
|
|
|
|
switch (e.detail.command) {
|
|
|
|
case "left":
|
2019-11-23 00:29:38 +09:00
|
|
|
if ("osd" === currentVisibleMenu) {
|
|
|
|
showOsd();
|
|
|
|
} else {
|
|
|
|
if (!currentVisibleMenu) {
|
|
|
|
e.preventDefault();
|
|
|
|
playbackManager.rewind(player);
|
|
|
|
}
|
2019-02-02 13:51:03 -05:00
|
|
|
}
|
|
|
|
|
2019-11-23 00:29:38 +09:00
|
|
|
break;
|
2019-02-02 13:51:03 -05:00
|
|
|
|
|
|
|
case "right":
|
2019-11-23 00:29:38 +09:00
|
|
|
if ("osd" === currentVisibleMenu) {
|
|
|
|
showOsd();
|
|
|
|
} else if (!currentVisibleMenu) {
|
|
|
|
e.preventDefault();
|
|
|
|
playbackManager.fastForward(player);
|
|
|
|
}
|
2019-02-02 13:51:03 -05:00
|
|
|
|
2019-11-23 00:29:38 +09:00
|
|
|
break;
|
2019-02-02 13:51:03 -05:00
|
|
|
|
|
|
|
case "pageup":
|
2019-11-23 00:29:38 +09:00
|
|
|
playbackManager.nextChapter(player);
|
|
|
|
break;
|
2019-02-02 13:51:03 -05:00
|
|
|
|
|
|
|
case "pagedown":
|
2019-11-23 00:29:38 +09:00
|
|
|
playbackManager.previousChapter(player);
|
|
|
|
break;
|
2019-02-02 13:51:03 -05:00
|
|
|
|
|
|
|
case "up":
|
|
|
|
case "down":
|
|
|
|
case "select":
|
|
|
|
case "menu":
|
|
|
|
case "info":
|
|
|
|
case "play":
|
|
|
|
case "playpause":
|
|
|
|
case "pause":
|
|
|
|
case "fastforward":
|
|
|
|
case "rewind":
|
|
|
|
case "next":
|
|
|
|
case "previous":
|
2019-11-23 00:29:38 +09:00
|
|
|
showOsd();
|
|
|
|
break;
|
2019-02-02 13:51:03 -05:00
|
|
|
|
|
|
|
case "record":
|
2019-11-23 00:29:38 +09:00
|
|
|
onRecordingCommand();
|
|
|
|
showOsd();
|
|
|
|
break;
|
2019-02-02 13:51:03 -05:00
|
|
|
|
|
|
|
case "togglestats":
|
2019-11-23 00:29:38 +09:00
|
|
|
toggleStats();
|
2019-02-02 13:51:03 -05:00
|
|
|
}
|
|
|
|
}
|
2018-10-23 01:05:09 +03:00
|
|
|
|
2019-02-02 13:51:03 -05:00
|
|
|
function onRecordingCommand() {
|
|
|
|
var btnRecord = view.querySelector(".btnRecord");
|
2018-10-23 01:05:09 +03:00
|
|
|
|
2019-02-02 13:51:03 -05:00
|
|
|
if (!btnRecord.classList.contains("hide")) {
|
|
|
|
btnRecord.click();
|
|
|
|
}
|
|
|
|
}
|
2018-10-23 01:05:09 +03:00
|
|
|
|
2019-02-02 13:51:03 -05:00
|
|
|
function updateFullscreenIcon() {
|
|
|
|
if (playbackManager.isFullscreen(currentPlayer)) {
|
|
|
|
view.querySelector(".btnFullscreen").setAttribute("title", globalize.translate("ExitFullscreen"));
|
2019-11-20 00:24:54 +03:00
|
|
|
view.querySelector(".btnFullscreen i").innerHTML = "fullscreen_exit";
|
2019-02-02 13:51:03 -05:00
|
|
|
} else {
|
2019-04-25 12:35:02 -04:00
|
|
|
view.querySelector(".btnFullscreen").setAttribute("title", globalize.translate("Fullscreen") + " (f)");
|
2019-11-20 00:24:54 +03:00
|
|
|
view.querySelector(".btnFullscreen i").innerHTML = "fullscreen";
|
2019-02-02 13:51:03 -05:00
|
|
|
}
|
|
|
|
}
|
2018-10-23 01:05:09 +03:00
|
|
|
|
2019-02-02 13:51:03 -05:00
|
|
|
function onPlayerChange() {
|
|
|
|
bindToPlayer(playbackManager.getCurrentPlayer());
|
|
|
|
}
|
2018-10-23 01:05:09 +03:00
|
|
|
|
2019-02-02 13:51:03 -05:00
|
|
|
function onStateChanged(event, state) {
|
|
|
|
var player = this;
|
2018-10-23 01:05:09 +03:00
|
|
|
|
2019-02-02 13:51:03 -05:00
|
|
|
if (state.NowPlayingItem) {
|
|
|
|
isEnabled = true;
|
|
|
|
updatePlayerStateInternal(event, player, state);
|
|
|
|
updatePlaylist(player);
|
|
|
|
enableStopOnBack(true);
|
|
|
|
}
|
|
|
|
}
|
2018-10-23 01:05:09 +03:00
|
|
|
|
2019-02-02 13:51:03 -05:00
|
|
|
function onPlayPauseStateChanged(e) {
|
|
|
|
if (isEnabled) {
|
|
|
|
updatePlayPauseState(this.paused());
|
|
|
|
}
|
|
|
|
}
|
2018-10-23 01:05:09 +03:00
|
|
|
|
2019-02-02 13:51:03 -05:00
|
|
|
function onVolumeChanged(e) {
|
|
|
|
if (isEnabled) {
|
|
|
|
var player = this;
|
|
|
|
updatePlayerVolumeState(player, player.isMuted(), player.getVolume());
|
|
|
|
}
|
|
|
|
}
|
2018-10-23 01:05:09 +03:00
|
|
|
|
2019-02-02 13:51:03 -05:00
|
|
|
function onPlaybackStart(e, state) {
|
|
|
|
console.log("nowplaying event: " + e.type);
|
|
|
|
var player = this;
|
|
|
|
onStateChanged.call(player, e, state);
|
|
|
|
resetUpNextDialog();
|
|
|
|
}
|
2018-10-23 01:05:09 +03:00
|
|
|
|
2019-02-02 13:51:03 -05:00
|
|
|
function resetUpNextDialog() {
|
|
|
|
comingUpNextDisplayed = false;
|
|
|
|
var dlg = currentUpNextDialog;
|
2018-10-23 01:05:09 +03:00
|
|
|
|
2019-02-02 13:51:03 -05:00
|
|
|
if (dlg) {
|
|
|
|
dlg.destroy();
|
|
|
|
currentUpNextDialog = null;
|
|
|
|
}
|
|
|
|
}
|
2018-10-23 01:05:09 +03:00
|
|
|
|
2019-02-02 13:51:03 -05:00
|
|
|
function onPlaybackStopped(e, state) {
|
|
|
|
currentRuntimeTicks = null;
|
|
|
|
resetUpNextDialog();
|
|
|
|
console.log("nowplaying event: " + e.type);
|
2018-10-23 01:05:09 +03:00
|
|
|
|
2019-02-02 13:51:03 -05:00
|
|
|
if ("Video" !== state.NextMediaType) {
|
|
|
|
view.removeEventListener("viewbeforehide", onViewHideStopPlayback);
|
|
|
|
Emby.Page.back();
|
|
|
|
}
|
|
|
|
}
|
2018-10-23 01:05:09 +03:00
|
|
|
|
2019-02-02 13:51:03 -05:00
|
|
|
function onMediaStreamsChanged(e) {
|
|
|
|
var player = this;
|
|
|
|
var state = playbackManager.getPlayerState(player);
|
|
|
|
onStateChanged.call(player, {
|
|
|
|
type: "init"
|
|
|
|
}, state);
|
|
|
|
}
|
2019-02-02 10:20:27 -05:00
|
|
|
|
2019-09-12 21:24:16 +02:00
|
|
|
function onBeginFetch() {
|
|
|
|
document.querySelector(".osdMediaStatus").classList.remove("hide");
|
|
|
|
}
|
|
|
|
|
|
|
|
function onEndFetch() {
|
|
|
|
document.querySelector(".osdMediaStatus").classList.add("hide");
|
|
|
|
}
|
|
|
|
|
2019-02-02 13:51:03 -05:00
|
|
|
function bindToPlayer(player) {
|
2019-02-12 10:01:11 -05:00
|
|
|
if (player !== currentPlayer) {
|
|
|
|
releaseCurrentPlayer();
|
|
|
|
currentPlayer = player;
|
|
|
|
if (!player) return;
|
2019-02-02 13:51:03 -05:00
|
|
|
}
|
2019-02-12 10:01:11 -05:00
|
|
|
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);
|
2019-09-12 21:24:16 +02:00
|
|
|
events.on(player, "beginFetch", onBeginFetch);
|
|
|
|
events.on(player, "endFetch", onEndFetch);
|
2019-02-12 10:01:11 -05:00
|
|
|
resetUpNextDialog();
|
2019-09-12 21:24:16 +02:00
|
|
|
|
|
|
|
if (player.isFetching) {
|
|
|
|
onBeginFetch();
|
|
|
|
}
|
2019-02-02 13:51:03 -05:00
|
|
|
}
|
2019-02-02 10:20:27 -05:00
|
|
|
|
2019-02-02 13:51:03 -05:00
|
|
|
function releaseCurrentPlayer() {
|
|
|
|
destroyStats();
|
2019-04-08 20:31:18 +02:00
|
|
|
destroySubtitleSync();
|
2019-02-02 13:51:03 -05:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
}
|
2018-10-23 01:05:09 +03:00
|
|
|
|
2019-02-02 13:51:03 -05:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2019-02-02 10:20:27 -05:00
|
|
|
|
2019-02-02 13:51:03 -05:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
}
|
2018-10-23 01:05:09 +03:00
|
|
|
}
|
2019-02-02 10:20:27 -05:00
|
|
|
|
2019-02-02 13:51:03 -05:00
|
|
|
function onUpNextHidden() {
|
|
|
|
if ("upnext" === currentVisibleMenu) {
|
|
|
|
currentVisibleMenu = null;
|
|
|
|
}
|
|
|
|
}
|
2018-10-23 01:05:09 +03:00
|
|
|
|
2019-02-02 13:51:03 -05:00
|
|
|
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);
|
|
|
|
}
|
2019-02-02 10:20:27 -05:00
|
|
|
});
|
2018-10-23 01:05:09 +03:00
|
|
|
}
|
2019-02-02 10:20:27 -05:00
|
|
|
|
2019-02-02 13:51:03 -05:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2018-10-23 01:05:09 +03:00
|
|
|
|
2019-02-02 13:51:03 -05:00
|
|
|
function updatePlayPauseState(isPaused) {
|
2019-04-25 12:35:02 -04:00
|
|
|
var button = view.querySelector(".btnPause i");
|
|
|
|
if (isPaused) {
|
2019-11-20 00:24:54 +03:00
|
|
|
button.innerHTML = "play_arrow";
|
2019-04-25 12:35:02 -04:00
|
|
|
button.setAttribute("title", globalize.translate("ButtonPlay") + " (k)");
|
|
|
|
} else {
|
2019-11-20 00:24:54 +03:00
|
|
|
button.innerHTML = "pause";
|
2019-04-25 12:35:02 -04:00
|
|
|
button.setAttribute("title", globalize.translate("ButtonPause") + " (k)");
|
|
|
|
}
|
2019-02-02 13:51:03 -05:00
|
|
|
}
|
2019-02-02 10:20:27 -05:00
|
|
|
|
2019-02-02 13:51:03 -05:00
|
|
|
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;
|
2018-10-23 01:05:09 +03:00
|
|
|
}
|
|
|
|
|
2019-02-02 13:51:03 -05:00
|
|
|
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);
|
2018-10-23 01:05:09 +03:00
|
|
|
|
2019-02-02 13:51:03 -05:00
|
|
|
if (state.MediaSource && state.MediaSource.SupportsTranscoding && -1 !== supportedCommands.indexOf("SetMaxStreamingBitrate")) {
|
|
|
|
view.querySelector(".btnVideoOsdSettings").classList.remove("hide");
|
|
|
|
} else {
|
|
|
|
view.querySelector(".btnVideoOsdSettings").classList.add("hide");
|
|
|
|
}
|
2018-10-23 01:05:09 +03:00
|
|
|
|
2019-02-02 13:51:03 -05:00
|
|
|
var isProgressClear = state.MediaSource && null == state.MediaSource.RunTimeTicks;
|
|
|
|
nowPlayingPositionSlider.setIsClear(isProgressClear);
|
2018-10-23 01:05:09 +03:00
|
|
|
|
2019-11-09 11:48:52 +03:00
|
|
|
if (nowPlayingItem.RunTimeTicks) {
|
2019-11-13 00:30:33 +03:00
|
|
|
nowPlayingPositionSlider.setKeyboardSteps(userSettings.skipBackLength() * 1000000 / nowPlayingItem.RunTimeTicks,
|
|
|
|
userSettings.skipForwardLength() * 1000000 / nowPlayingItem.RunTimeTicks);
|
2019-11-09 11:48:52 +03:00
|
|
|
}
|
|
|
|
|
2019-02-02 13:51:03 -05:00
|
|
|
if (-1 === supportedCommands.indexOf("ToggleFullscreen") || player.isLocalPlayer && layoutManager.tv && playbackManager.isFullscreen(player)) {
|
|
|
|
view.querySelector(".btnFullscreen").classList.add("hide");
|
2018-10-23 01:05:09 +03:00
|
|
|
} else {
|
2019-02-02 13:51:03 -05:00
|
|
|
view.querySelector(".btnFullscreen").classList.remove("hide");
|
2018-10-23 01:05:09 +03:00
|
|
|
}
|
|
|
|
|
2019-02-02 13:51:03 -05:00
|
|
|
if (-1 === supportedCommands.indexOf("PictureInPicture")) {
|
|
|
|
view.querySelector(".btnPip").classList.add("hide");
|
|
|
|
} else {
|
|
|
|
view.querySelector(".btnPip").classList.remove("hide");
|
|
|
|
}
|
2019-02-02 10:20:27 -05:00
|
|
|
|
2020-01-10 11:31:03 -05:00
|
|
|
if (-1 === supportedCommands.indexOf("AirPlay")) {
|
|
|
|
view.querySelector(".btnAirPlay").classList.add("hide");
|
|
|
|
} else {
|
|
|
|
view.querySelector(".btnAirPlay").classList.remove("hide");
|
|
|
|
}
|
|
|
|
|
2019-02-02 13:51:03 -05:00
|
|
|
updateFullscreenIcon();
|
2018-10-23 01:05:09 +03:00
|
|
|
}
|
|
|
|
|
2019-02-02 13:51:03 -05:00
|
|
|
function getDisplayPercentByTimeOfDay(programStartDateMs, programRuntimeMs, currentTimeMs) {
|
|
|
|
return (currentTimeMs - programStartDateMs) / programRuntimeMs * 100;
|
2018-10-23 01:05:09 +03:00
|
|
|
}
|
|
|
|
|
2019-02-02 13:51:03 -05:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
}
|
2018-10-23 01:05:09 +03:00
|
|
|
|
2019-02-02 13:51:03 -05:00
|
|
|
function updatePlayerVolumeState(player, isMuted, volumeLevel) {
|
|
|
|
var supportedCommands = currentPlayerSupportedCommands;
|
|
|
|
var showMuteButton = true;
|
|
|
|
var showVolumeSlider = true;
|
|
|
|
var volumeSlider = view.querySelector('.osdVolumeSliderContainer');
|
|
|
|
var progressElement = volumeSlider.querySelector('.mdl-slider-background-lower');
|
2018-10-23 01:05:09 +03:00
|
|
|
|
2019-02-02 13:51:03 -05:00
|
|
|
if (-1 === supportedCommands.indexOf("Mute")) {
|
|
|
|
showMuteButton = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (-1 === supportedCommands.indexOf("SetVolume")) {
|
|
|
|
showVolumeSlider = false;
|
|
|
|
}
|
2019-02-02 10:20:27 -05:00
|
|
|
|
2019-02-02 13:51:03 -05:00
|
|
|
if (player.isLocalPlayer && appHost.supports("physicalvolumecontrol")) {
|
|
|
|
showMuteButton = false;
|
|
|
|
showVolumeSlider = false;
|
|
|
|
}
|
2019-02-02 10:20:27 -05:00
|
|
|
|
2019-02-02 13:51:03 -05:00
|
|
|
if (isMuted) {
|
2019-04-25 12:35:02 -04:00
|
|
|
view.querySelector(".buttonMute").setAttribute("title", globalize.translate("Unmute") + " (m)");
|
2019-11-20 00:24:54 +03:00
|
|
|
view.querySelector(".buttonMute i").innerHTML = "volume_off";
|
2019-02-02 13:51:03 -05:00
|
|
|
} else {
|
2019-04-25 12:35:02 -04:00
|
|
|
view.querySelector(".buttonMute").setAttribute("title", globalize.translate("Mute") + " (m)");
|
2019-11-20 00:24:54 +03:00
|
|
|
view.querySelector(".buttonMute i").innerHTML = "volume_up";
|
2019-02-02 13:51:03 -05:00
|
|
|
}
|
2019-02-02 10:20:27 -05:00
|
|
|
|
2019-02-02 13:51:03 -05:00
|
|
|
if (progressElement) {
|
|
|
|
progressElement.style.width = (volumeLevel || 0) + '%';
|
|
|
|
}
|
2019-02-02 10:20:27 -05:00
|
|
|
|
2019-02-02 13:51:03 -05:00
|
|
|
if (showMuteButton) {
|
|
|
|
view.querySelector(".buttonMute").classList.remove("hide");
|
|
|
|
} else {
|
|
|
|
view.querySelector(".buttonMute").classList.add("hide");
|
|
|
|
}
|
2018-10-23 01:05:09 +03:00
|
|
|
|
2019-02-02 13:51:03 -05:00
|
|
|
if (nowPlayingVolumeSlider) {
|
|
|
|
if (showVolumeSlider) {
|
|
|
|
nowPlayingVolumeSliderContainer.classList.remove("hide");
|
|
|
|
} else {
|
|
|
|
nowPlayingVolumeSliderContainer.classList.add("hide");
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!nowPlayingVolumeSlider.dragging) {
|
|
|
|
nowPlayingVolumeSlider.value = volumeLevel || 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2019-02-02 10:20:27 -05:00
|
|
|
|
2019-02-02 13:51:03 -05:00
|
|
|
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;
|
2018-10-23 01:05:09 +03:00
|
|
|
}
|
2019-02-02 10:20:27 -05:00
|
|
|
|
2019-02-02 13:51:03 -05:00
|
|
|
function updateTimeText(elem, ticks, divider) {
|
|
|
|
if (null == ticks) {
|
2019-02-12 10:01:11 -05:00
|
|
|
elem.innerHTML = "";
|
|
|
|
return;
|
2019-02-02 13:51:03 -05:00
|
|
|
}
|
2019-02-02 10:20:27 -05:00
|
|
|
|
2019-02-02 13:51:03 -05:00
|
|
|
var html = datetime.getDisplayRunningTime(ticks);
|
|
|
|
|
|
|
|
if (divider) {
|
|
|
|
html = " / " + html;
|
|
|
|
}
|
|
|
|
|
|
|
|
elem.innerHTML = html;
|
|
|
|
}
|
2018-10-23 01:05:09 +03:00
|
|
|
|
2019-02-02 13:51:03 -05:00
|
|
|
function onSettingsButtonClick(e) {
|
|
|
|
var btn = this;
|
|
|
|
|
|
|
|
require(["playerSettingsMenu"], function (playerSettingsMenu) {
|
|
|
|
var player = currentPlayer;
|
|
|
|
|
|
|
|
if (player) {
|
2019-04-08 20:31:18 +02:00
|
|
|
|
|
|
|
// show subtitle offset feature only if player and media support it
|
2019-10-03 02:36:33 +09:00
|
|
|
var showSubOffset = playbackManager.supportSubtitleOffset(player) &&
|
2019-04-08 20:31:18 +02:00
|
|
|
playbackManager.canHandleOffsetOnCurrentSubtitle(player);
|
|
|
|
|
2019-02-02 13:51:03 -05:00
|
|
|
playerSettingsMenu.show({
|
|
|
|
mediaType: "Video",
|
|
|
|
player: player,
|
|
|
|
positionTo: btn,
|
|
|
|
stats: true,
|
2019-04-08 20:31:18 +02:00
|
|
|
suboffset: showSubOffset,
|
2019-02-02 13:51:03 -05:00
|
|
|
onOption: onSettingsOption
|
|
|
|
});
|
|
|
|
}
|
2018-10-23 01:05:09 +03:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2019-02-02 13:51:03 -05:00
|
|
|
function onSettingsOption(selectedOption) {
|
|
|
|
if ("stats" === selectedOption) {
|
|
|
|
toggleStats();
|
2019-04-08 20:31:18 +02:00
|
|
|
} else if ("suboffset" === selectedOption) {
|
|
|
|
var player = currentPlayer;
|
|
|
|
if (player) {
|
|
|
|
playbackManager.enableShowingSubtitleOffset(player);
|
|
|
|
toggleSubtitleSync();
|
|
|
|
}
|
2019-02-02 13:51:03 -05:00
|
|
|
}
|
|
|
|
}
|
2018-10-23 01:05:09 +03:00
|
|
|
|
2019-02-02 13:51:03 -05:00
|
|
|
function toggleStats() {
|
|
|
|
require(["playerStats"], function (PlayerStats) {
|
|
|
|
var player = currentPlayer;
|
|
|
|
|
|
|
|
if (player) {
|
|
|
|
if (statsOverlay) {
|
|
|
|
statsOverlay.toggle();
|
|
|
|
} else {
|
|
|
|
statsOverlay = new PlayerStats({
|
|
|
|
player: player
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
2019-02-02 10:20:27 -05:00
|
|
|
|
2019-02-02 13:51:03 -05:00
|
|
|
function destroyStats() {
|
|
|
|
if (statsOverlay) {
|
|
|
|
statsOverlay.destroy();
|
|
|
|
statsOverlay = null;
|
|
|
|
}
|
2018-10-23 01:05:09 +03:00
|
|
|
}
|
|
|
|
|
2019-02-02 13:51:03 -05:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
2019-02-02 10:20:27 -05:00
|
|
|
|
2019-02-02 13:51:03 -05:00
|
|
|
function showSubtitleTrackSelection() {
|
|
|
|
var player = currentPlayer;
|
|
|
|
var streams = playbackManager.subtitleTracks(player);
|
|
|
|
var currentIndex = playbackManager.getSubtitleStreamIndex(player);
|
2019-02-02 10:20:27 -05:00
|
|
|
|
2019-02-02 13:51:03 -05:00
|
|
|
if (null == currentIndex) {
|
|
|
|
currentIndex = -1;
|
|
|
|
}
|
2018-10-23 01:05:09 +03:00
|
|
|
|
2019-02-02 13:51:03 -05:00
|
|
|
streams.unshift({
|
|
|
|
Index: -1,
|
|
|
|
DisplayTitle: globalize.translate("Off")
|
|
|
|
});
|
|
|
|
var menuItems = streams.map(function (stream) {
|
|
|
|
var opt = {
|
|
|
|
name: stream.DisplayTitle,
|
|
|
|
id: stream.Index
|
|
|
|
};
|
2019-02-02 10:20:27 -05:00
|
|
|
|
2019-02-02 13:51:03 -05:00
|
|
|
if (stream.Index === currentIndex) {
|
|
|
|
opt.selected = true;
|
|
|
|
}
|
2018-10-23 01:05:09 +03:00
|
|
|
|
2019-02-02 13:51:03 -05:00
|
|
|
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);
|
|
|
|
}
|
2019-03-30 22:11:39 +01:00
|
|
|
|
2019-10-03 02:36:33 +09:00
|
|
|
toggleSubtitleSync();
|
2019-02-02 13:51:03 -05:00
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
2019-02-02 10:20:27 -05:00
|
|
|
|
2019-04-08 20:31:18 +02:00
|
|
|
function toggleSubtitleSync(action) {
|
|
|
|
require(["subtitleSync"], function (SubtitleSync) {
|
|
|
|
var player = currentPlayer;
|
|
|
|
if (subtitleSyncOverlay) {
|
|
|
|
subtitleSyncOverlay.toggle(action);
|
2019-11-23 00:29:38 +09:00
|
|
|
} else if (player) {
|
2019-04-08 20:31:18 +02:00
|
|
|
subtitleSyncOverlay = new SubtitleSync(player);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
function destroySubtitleSync() {
|
|
|
|
if (subtitleSyncOverlay) {
|
|
|
|
subtitleSyncOverlay.destroy();
|
|
|
|
subtitleSyncOverlay = null;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-11-09 11:48:52 +03:00
|
|
|
/**
|
|
|
|
* Keys used for keyboard navigation.
|
|
|
|
*/
|
|
|
|
var NavigationKeys = ["ArrowLeft", "ArrowRight", "ArrowUp", "ArrowDown"];
|
|
|
|
|
2020-01-25 17:35:16 +03:00
|
|
|
/**
|
|
|
|
* Clicked element.
|
|
|
|
* To skip 'click' handling on Firefox/Edge.
|
|
|
|
*/
|
|
|
|
var clickedElement;
|
|
|
|
|
2019-02-02 13:51:03 -05:00
|
|
|
function onWindowKeyDown(e) {
|
2020-01-25 17:35:16 +03:00
|
|
|
clickedElement = e.srcElement;
|
|
|
|
|
2020-01-19 01:09:42 +03:00
|
|
|
var key = keyboardnavigation.getKeyName(e);
|
|
|
|
|
2019-04-25 12:35:02 -04:00
|
|
|
if (!currentVisibleMenu && 32 === e.keyCode) {
|
2019-02-02 13:51:03 -05:00
|
|
|
playbackManager.playPause(currentPlayer);
|
2019-11-18 17:31:09 +03:00
|
|
|
showOsd();
|
|
|
|
return;
|
2019-02-02 13:51:03 -05:00
|
|
|
}
|
2019-02-02 10:20:27 -05:00
|
|
|
|
2020-01-19 01:09:42 +03:00
|
|
|
if (layoutManager.tv && NavigationKeys.indexOf(key) != -1) {
|
2019-11-18 17:31:09 +03:00
|
|
|
showOsd();
|
|
|
|
return;
|
2019-11-09 11:48:52 +03:00
|
|
|
}
|
|
|
|
|
2020-01-19 01:09:42 +03:00
|
|
|
switch (key) {
|
2020-01-17 12:09:27 +03:00
|
|
|
case "Enter":
|
|
|
|
showOsd();
|
|
|
|
break;
|
|
|
|
case "Escape":
|
2020-01-19 01:09:42 +03:00
|
|
|
case "Back":
|
2020-01-17 12:09:27 +03:00
|
|
|
// Ignore key when some dialog is opened
|
|
|
|
if (currentVisibleMenu === "osd" && !document.querySelector(".dialogContainer")) {
|
|
|
|
hideOsd();
|
|
|
|
e.stopPropagation();
|
|
|
|
}
|
|
|
|
break;
|
2019-04-25 12:35:02 -04:00
|
|
|
case "k":
|
|
|
|
playbackManager.playPause(currentPlayer);
|
|
|
|
showOsd();
|
2019-11-23 00:29:38 +09:00
|
|
|
break;
|
2019-04-25 12:35:02 -04:00
|
|
|
case "l":
|
|
|
|
case "ArrowRight":
|
|
|
|
case "Right":
|
|
|
|
playbackManager.fastForward(currentPlayer);
|
|
|
|
showOsd();
|
2019-11-23 00:29:38 +09:00
|
|
|
break;
|
2019-04-25 12:35:02 -04:00
|
|
|
case "j":
|
|
|
|
case "ArrowLeft":
|
|
|
|
case "Left":
|
|
|
|
playbackManager.rewind(currentPlayer);
|
|
|
|
showOsd();
|
2019-11-23 00:29:38 +09:00
|
|
|
break;
|
2019-02-02 13:51:03 -05:00
|
|
|
case "f":
|
2019-11-23 00:29:38 +09:00
|
|
|
if (!e.ctrlKey && !e.metaKey) {
|
|
|
|
playbackManager.toggleFullscreen(currentPlayer);
|
|
|
|
showOsd();
|
|
|
|
}
|
|
|
|
break;
|
2019-02-02 13:51:03 -05:00
|
|
|
case "m":
|
2019-11-23 00:29:38 +09:00
|
|
|
playbackManager.toggleMute(currentPlayer);
|
|
|
|
showOsd();
|
|
|
|
break;
|
2019-02-02 13:51:03 -05:00
|
|
|
case "NavigationLeft":
|
|
|
|
case "GamepadDPadLeft":
|
|
|
|
case "GamepadLeftThumbstickLeft":
|
2020-01-24 16:44:45 +03:00
|
|
|
// Ignores gamepad events that are always triggered, even when not focused.
|
2019-11-23 00:29:38 +09:00
|
|
|
if (document.hasFocus()) {
|
|
|
|
playbackManager.rewind(currentPlayer);
|
|
|
|
showOsd();
|
|
|
|
}
|
|
|
|
break;
|
2019-02-02 13:51:03 -05:00
|
|
|
case "NavigationRight":
|
|
|
|
case "GamepadDPadRight":
|
|
|
|
case "GamepadLeftThumbstickRight":
|
2020-01-24 16:44:45 +03:00
|
|
|
// Ignores gamepad events that are always triggered, even when not focused.
|
2019-11-23 00:29:38 +09:00
|
|
|
if (document.hasFocus()) {
|
|
|
|
playbackManager.fastForward(currentPlayer);
|
|
|
|
showOsd();
|
|
|
|
}
|
2019-02-02 13:51:03 -05:00
|
|
|
}
|
|
|
|
}
|
2019-02-02 10:20:27 -05:00
|
|
|
|
2020-01-25 17:35:16 +03:00
|
|
|
function onWindowMouseDown(e) {
|
|
|
|
clickedElement = e.srcElement;
|
|
|
|
}
|
|
|
|
|
|
|
|
function onWindowTouchStart(e) {
|
|
|
|
clickedElement = e.srcElement;
|
|
|
|
}
|
|
|
|
|
2019-02-02 13:51:03 -05:00
|
|
|
function getImgUrl(item, chapter, index, maxWidth, apiClient) {
|
|
|
|
if (chapter.ImageTag) {
|
|
|
|
return apiClient.getScaledImageUrl(item.Id, {
|
|
|
|
maxWidth: maxWidth,
|
|
|
|
tag: chapter.ImageTag,
|
|
|
|
type: "Chapter",
|
|
|
|
index: index
|
|
|
|
});
|
|
|
|
}
|
2019-02-02 10:20:27 -05:00
|
|
|
|
2019-02-02 13:51:03 -05:00
|
|
|
return null;
|
|
|
|
}
|
2019-02-02 10:20:27 -05:00
|
|
|
|
2019-02-02 13:51:03 -05:00
|
|
|
function getChapterBubbleHtml(apiClient, item, chapters, positionTicks) {
|
|
|
|
var chapter;
|
|
|
|
var index = -1;
|
2019-02-02 10:20:27 -05:00
|
|
|
|
2019-02-02 13:51:03 -05:00
|
|
|
for (var i = 0, length = chapters.length; i < length; i++) {
|
|
|
|
var currentChapter = chapters[i];
|
2019-02-02 10:20:27 -05:00
|
|
|
|
2019-02-02 13:51:03 -05:00
|
|
|
if (positionTicks >= currentChapter.StartPositionTicks) {
|
|
|
|
chapter = currentChapter;
|
|
|
|
index = i;
|
|
|
|
}
|
|
|
|
}
|
2019-02-02 10:20:27 -05:00
|
|
|
|
2019-02-02 13:51:03 -05:00
|
|
|
if (!chapter) {
|
|
|
|
return null;
|
|
|
|
}
|
2019-02-02 10:20:27 -05:00
|
|
|
|
2019-02-02 13:51:03 -05:00
|
|
|
var src = getImgUrl(item, chapter, index, 400, apiClient);
|
|
|
|
|
|
|
|
if (src) {
|
|
|
|
var html = '<div class="chapterThumbContainer">';
|
|
|
|
html += '<img class="chapterThumb" src="' + src + '" />';
|
|
|
|
html += '<div class="chapterThumbTextContainer">';
|
|
|
|
html += '<div class="chapterThumbText chapterThumbText-dim">';
|
|
|
|
html += chapter.Name;
|
|
|
|
html += "</div>";
|
|
|
|
html += '<h2 class="chapterThumbText">';
|
|
|
|
html += datetime.getDisplayRunningTime(positionTicks);
|
|
|
|
html += "</h2>";
|
|
|
|
html += "</div>";
|
2019-02-12 10:01:11 -05:00
|
|
|
return html + "</div>";
|
2019-02-02 13:51:03 -05:00
|
|
|
}
|
2019-02-02 10:20:27 -05:00
|
|
|
|
2019-02-02 13:51:03 -05:00
|
|
|
return null;
|
|
|
|
}
|
2019-02-02 10:20:27 -05:00
|
|
|
|
2019-02-02 13:51:03 -05:00
|
|
|
function onViewHideStopPlayback() {
|
|
|
|
if (playbackManager.isPlayingVideo()) {
|
|
|
|
require(['shell'], function (shell) {
|
|
|
|
shell.disableFullscreen();
|
|
|
|
});
|
2019-02-02 10:20:27 -05:00
|
|
|
|
2019-02-02 13:51:03 -05:00
|
|
|
var player = currentPlayer;
|
|
|
|
view.removeEventListener("viewbeforehide", onViewHideStopPlayback);
|
|
|
|
releaseCurrentPlayer();
|
|
|
|
playbackManager.stop(player);
|
|
|
|
}
|
|
|
|
}
|
2019-02-02 10:20:27 -05:00
|
|
|
|
2019-02-02 13:51:03 -05:00
|
|
|
function enableStopOnBack(enabled) {
|
|
|
|
view.removeEventListener("viewbeforehide", onViewHideStopPlayback);
|
2019-02-02 10:20:27 -05:00
|
|
|
|
2019-02-02 13:51:03 -05:00
|
|
|
if (enabled && playbackManager.isPlayingVideo(currentPlayer)) {
|
|
|
|
view.addEventListener("viewbeforehide", onViewHideStopPlayback);
|
|
|
|
}
|
2018-10-23 01:05:09 +03:00
|
|
|
}
|
2019-02-02 10:20:27 -05:00
|
|
|
|
2019-01-15 19:53:30 +09:00
|
|
|
require(['shell'], function (shell) {
|
2019-02-02 13:51:03 -05:00
|
|
|
shell.enableFullscreen();
|
2019-01-15 19:53:30 +09:00
|
|
|
});
|
2019-02-02 10:20:27 -05:00
|
|
|
|
2019-02-02 13:51:03 -05:00
|
|
|
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;
|
2019-04-08 20:31:18 +02:00
|
|
|
var subtitleSyncOverlay;
|
2019-09-22 11:38:18 +02:00
|
|
|
var volumeSliderTimer;
|
2019-02-02 13:51:03 -05:00
|
|
|
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");
|
2019-11-09 11:48:52 +03:00
|
|
|
|
|
|
|
if (layoutManager.tv) {
|
|
|
|
nowPlayingPositionSlider.classList.add("focusable");
|
|
|
|
nowPlayingPositionSlider.enableKeyboardDragging();
|
|
|
|
}
|
|
|
|
|
2019-02-02 13:51:03 -05:00
|
|
|
view.addEventListener("viewbeforeshow", function (e) {
|
|
|
|
headerElement.classList.add("osdHeader");
|
|
|
|
Emby.Page.setTransparency("full");
|
|
|
|
});
|
|
|
|
view.addEventListener("viewshow", function (e) {
|
2019-05-05 12:09:55 -04:00
|
|
|
try {
|
|
|
|
events.on(playbackManager, "playerchange", onPlayerChange);
|
|
|
|
bindToPlayer(playbackManager.getCurrentPlayer());
|
|
|
|
dom.addEventListener(document, window.PointerEvent ? "pointermove" : "mousemove", onPointerMove, {
|
|
|
|
passive: true
|
|
|
|
});
|
|
|
|
showOsd();
|
|
|
|
inputManager.on(window, onInputCommand);
|
|
|
|
dom.addEventListener(window, "keydown", onWindowKeyDown, {
|
2020-01-17 12:09:27 +03:00
|
|
|
capture: true
|
2019-05-05 12:09:55 -04:00
|
|
|
});
|
2020-01-25 17:35:16 +03:00
|
|
|
dom.addEventListener(window, window.PointerEvent ? "pointerdown" : "mousedown", onWindowMouseDown, {
|
|
|
|
passive: true
|
|
|
|
});
|
|
|
|
dom.addEventListener(window, "touchstart", onWindowTouchStart, {
|
|
|
|
passive: true
|
|
|
|
});
|
2019-11-23 00:29:38 +09:00
|
|
|
} catch (e) {
|
2019-05-05 12:09:55 -04:00
|
|
|
require(['appRouter'], function(appRouter) {
|
|
|
|
appRouter.showDirect('/');
|
|
|
|
});
|
|
|
|
}
|
2019-02-02 13:51:03 -05:00
|
|
|
});
|
|
|
|
view.addEventListener("viewbeforehide", function () {
|
|
|
|
if (statsOverlay) {
|
|
|
|
statsOverlay.enabled(false);
|
|
|
|
}
|
|
|
|
|
|
|
|
dom.removeEventListener(window, "keydown", onWindowKeyDown, {
|
2020-01-17 12:09:27 +03:00
|
|
|
capture: true
|
2019-02-02 13:51:03 -05:00
|
|
|
});
|
2020-01-25 17:35:16 +03:00
|
|
|
dom.removeEventListener(window, window.PointerEvent ? "pointerdown" : "mousedown", onWindowMouseDown, {
|
|
|
|
passive: true
|
|
|
|
});
|
|
|
|
dom.removeEventListener(window, "touchstart", onWindowTouchStart, {
|
|
|
|
passive: true
|
|
|
|
});
|
2019-02-02 13:51:03 -05:00
|
|
|
stopOsdHideTimer();
|
|
|
|
headerElement.classList.remove("osdHeader");
|
|
|
|
headerElement.classList.remove("osdHeader-hidden");
|
|
|
|
dom.removeEventListener(document, window.PointerEvent ? "pointermove" : "mousemove", onPointerMove, {
|
|
|
|
passive: true
|
|
|
|
});
|
|
|
|
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);
|
|
|
|
});
|
2020-01-10 11:31:03 -05:00
|
|
|
view.querySelector(".btnAirPlay").addEventListener("click", function () {
|
|
|
|
playbackManager.toggleAirPlay(currentPlayer);
|
|
|
|
});
|
2019-02-02 13:51:03 -05:00
|
|
|
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;
|
|
|
|
}
|
2019-02-02 10:20:27 -05:00
|
|
|
|
2019-02-02 13:51:03 -05:00
|
|
|
if (recordingButtonManager) {
|
|
|
|
recordingButtonManager.destroy();
|
|
|
|
recordingButtonManager = null;
|
|
|
|
}
|
2019-02-02 10:20:27 -05:00
|
|
|
|
2019-02-02 13:51:03 -05:00
|
|
|
destroyStats();
|
2019-04-08 20:31:18 +02:00
|
|
|
destroySubtitleSync();
|
2019-02-02 13:51:03 -05:00
|
|
|
});
|
|
|
|
var lastPointerDown = 0;
|
|
|
|
dom.addEventListener(view, window.PointerEvent ? "pointerdown" : "click", function (e) {
|
|
|
|
if (dom.parentWithClass(e.target, ["videoOsdBottom", "upNextContainer"])) {
|
|
|
|
return void showOsd();
|
|
|
|
}
|
2019-02-02 10:20:27 -05:00
|
|
|
|
2019-02-02 13:51:03 -05:00
|
|
|
var pointerType = e.pointerType || (layoutManager.mobile ? "touch" : "mouse");
|
|
|
|
var now = new Date().getTime();
|
2019-02-02 10:20:27 -05:00
|
|
|
|
2019-02-02 13:51:03 -05:00
|
|
|
switch (pointerType) {
|
|
|
|
case "touch":
|
2019-11-23 00:29:38 +09:00
|
|
|
if (now - lastPointerDown > 300) {
|
|
|
|
lastPointerDown = now;
|
|
|
|
toggleOsd();
|
|
|
|
}
|
2019-02-02 10:20:27 -05:00
|
|
|
|
2019-11-23 00:29:38 +09:00
|
|
|
break;
|
2019-02-02 10:20:27 -05:00
|
|
|
|
2019-02-02 13:51:03 -05:00
|
|
|
case "mouse":
|
2019-11-23 00:29:38 +09:00
|
|
|
if (!e.button) {
|
|
|
|
playbackManager.playPause(currentPlayer);
|
|
|
|
showOsd();
|
|
|
|
}
|
2019-02-02 10:20:27 -05:00
|
|
|
|
2019-11-23 00:29:38 +09:00
|
|
|
break;
|
2019-02-02 10:20:27 -05:00
|
|
|
|
2019-02-02 13:51:03 -05:00
|
|
|
default:
|
2019-11-23 00:29:38 +09:00
|
|
|
playbackManager.playPause(currentPlayer);
|
|
|
|
showOsd();
|
2019-02-02 13:51:03 -05:00
|
|
|
}
|
|
|
|
}, {
|
|
|
|
passive: true
|
|
|
|
});
|
2019-02-02 10:20:27 -05:00
|
|
|
|
2019-02-02 13:51:03 -05:00
|
|
|
if (browser.touch) {
|
|
|
|
dom.addEventListener(view, "dblclick", onDoubleClick, {});
|
2019-04-25 11:50:44 -04:00
|
|
|
} else {
|
2019-04-26 08:46:01 -04:00
|
|
|
var options = { passive: true };
|
2019-11-23 00:29:38 +09:00
|
|
|
dom.addEventListener(view, "dblclick", function () {
|
|
|
|
playbackManager.toggleFullscreen(currentPlayer);
|
|
|
|
}, options);
|
2019-02-02 10:20:27 -05:00
|
|
|
}
|
|
|
|
|
2019-02-02 13:51:03 -05:00
|
|
|
view.querySelector(".buttonMute").addEventListener("click", function () {
|
|
|
|
playbackManager.toggleMute(currentPlayer);
|
|
|
|
});
|
2019-02-07 08:09:49 -05:00
|
|
|
nowPlayingVolumeSlider.addEventListener("change", function () {
|
2019-11-23 00:29:38 +09:00
|
|
|
if (volumeSliderTimer) {
|
2019-09-22 11:38:18 +02:00
|
|
|
// interupt and remove existing timer
|
|
|
|
clearTimeout(volumeSliderTimer);
|
|
|
|
volumeSliderTimer = null;
|
|
|
|
}
|
2019-02-07 08:09:49 -05:00
|
|
|
playbackManager.setVolume(this.value, currentPlayer);
|
|
|
|
});
|
2019-02-02 13:51:03 -05:00
|
|
|
nowPlayingVolumeSlider.addEventListener("mousemove", function () {
|
2019-11-23 00:29:38 +09:00
|
|
|
if (!volumeSliderTimer) {
|
2019-09-22 11:38:18 +02:00
|
|
|
var that = this;
|
|
|
|
// register new timer
|
2019-11-23 00:29:38 +09:00
|
|
|
volumeSliderTimer = setTimeout(function() {
|
2019-09-22 11:38:18 +02:00
|
|
|
playbackManager.setVolume(that.value, currentPlayer);
|
|
|
|
// delete timer after completion
|
|
|
|
volumeSliderTimer = null;
|
|
|
|
}, 700);
|
2019-09-19 23:11:32 +02:00
|
|
|
}
|
2019-02-02 13:51:03 -05:00
|
|
|
});
|
2019-02-07 08:09:49 -05:00
|
|
|
nowPlayingVolumeSlider.addEventListener("touchmove", function () {
|
2019-11-23 00:29:38 +09:00
|
|
|
if (!volumeSliderTimer) {
|
2019-09-22 11:38:18 +02:00
|
|
|
var that = this;
|
|
|
|
// register new timer
|
2019-11-23 00:29:38 +09:00
|
|
|
volumeSliderTimer = setTimeout(function() {
|
2019-09-22 11:38:18 +02:00
|
|
|
playbackManager.setVolume(that.value, currentPlayer);
|
|
|
|
// delete timer after completion
|
|
|
|
volumeSliderTimer = null;
|
|
|
|
}, 700);
|
2019-09-19 23:11:32 +02:00
|
|
|
}
|
2019-02-07 08:09:49 -05:00
|
|
|
});
|
2019-03-30 22:11:39 +01:00
|
|
|
|
2019-02-02 13:51:03 -05:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
2019-02-02 10:20:27 -05:00
|
|
|
|
2019-02-02 13:51:03 -05:00
|
|
|
nowPlayingPositionSlider.getBubbleHtml = function (value) {
|
2019-02-12 10:01:11 -05:00
|
|
|
showOsd();
|
|
|
|
if (enableProgressByTimeOfDay) {
|
2019-02-02 13:51:03 -05:00
|
|
|
if (programStartDateMs && programEndDateMs) {
|
|
|
|
var ms = programEndDateMs - programStartDateMs;
|
|
|
|
ms /= 100;
|
|
|
|
ms *= value;
|
|
|
|
ms += programStartDateMs;
|
|
|
|
return '<h1 class="sliderBubbleText">' + getDisplayTimeWithoutAmPm(new Date(parseInt(ms)), true) + "</h1>";
|
|
|
|
}
|
|
|
|
|
|
|
|
return "--:--";
|
|
|
|
}
|
2019-02-02 10:20:27 -05:00
|
|
|
|
2019-02-02 13:51:03 -05:00
|
|
|
if (!currentRuntimeTicks) {
|
|
|
|
return "--:--";
|
|
|
|
}
|
2019-02-02 10:20:27 -05:00
|
|
|
|
2019-02-02 13:51:03 -05:00
|
|
|
var ticks = currentRuntimeTicks;
|
|
|
|
ticks /= 100;
|
|
|
|
ticks *= value;
|
|
|
|
var item = currentItem;
|
2019-02-02 10:20:27 -05:00
|
|
|
|
2019-02-02 13:51:03 -05:00
|
|
|
if (item && item.Chapters && item.Chapters.length && item.Chapters[0].ImageTag) {
|
|
|
|
var html = getChapterBubbleHtml(connectionManager.getApiClient(item.ServerId), item, item.Chapters, ticks);
|
2019-02-02 10:20:27 -05:00
|
|
|
|
2019-02-02 13:51:03 -05:00
|
|
|
if (html) {
|
|
|
|
return html;
|
|
|
|
}
|
|
|
|
}
|
2019-02-02 10:20:27 -05:00
|
|
|
|
2019-02-02 13:51:03 -05:00
|
|
|
return '<h1 class="sliderBubbleText">' + datetime.getDisplayRunningTime(ticks) + "</h1>";
|
|
|
|
};
|
2019-02-02 10:20:27 -05:00
|
|
|
|
2019-02-02 13:51:03 -05:00
|
|
|
view.querySelector(".btnPreviousTrack").addEventListener("click", function () {
|
|
|
|
playbackManager.previousTrack(currentPlayer);
|
2018-10-23 01:05:09 +03:00
|
|
|
});
|
2019-02-02 13:51:03 -05:00
|
|
|
view.querySelector(".btnPause").addEventListener("click", function () {
|
2020-01-25 17:35:16 +03:00
|
|
|
// Ignore 'click' if another element was originally clicked (Firefox/Edge issue)
|
|
|
|
if (this.contains(clickedElement)) {
|
|
|
|
playbackManager.playPause(currentPlayer);
|
|
|
|
}
|
2019-02-02 13:51:03 -05:00
|
|
|
});
|
|
|
|
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);
|
|
|
|
});
|
|
|
|
})();
|
|
|
|
}
|
|
|
|
};
|
2019-02-02 10:20:27 -05:00
|
|
|
});
|