2020-08-16 20:24:45 +02:00
|
|
|
import { playbackManager } from '../../../components/playback/playbackmanager';
|
2020-12-03 16:25:50 +01:00
|
|
|
import SyncPlay from '../../../components/syncPlay/core';
|
2020-08-14 08:46:34 +02:00
|
|
|
import dom from '../../../scripts/dom';
|
|
|
|
import inputManager from '../../../scripts/inputManager';
|
|
|
|
import mouseManager from '../../../scripts/mouseManager';
|
|
|
|
import datetime from '../../../scripts/datetime';
|
|
|
|
import itemHelper from '../../../components/itemHelper';
|
|
|
|
import mediaInfo from '../../../components/mediainfo/mediainfo';
|
|
|
|
import focusManager from '../../../components/focusManager';
|
2020-10-17 19:08:56 +01:00
|
|
|
import { Events } from 'jellyfin-apiclient';
|
2020-08-14 08:46:34 +02:00
|
|
|
import globalize from '../../../scripts/globalize';
|
2020-08-16 20:24:45 +02:00
|
|
|
import { appHost } from '../../../components/apphost';
|
2020-08-14 08:46:34 +02:00
|
|
|
import layoutManager from '../../../components/layoutManager';
|
|
|
|
import * as userSettings from '../../../scripts/settings/userSettings';
|
|
|
|
import keyboardnavigation from '../../../scripts/keyboardNavigation';
|
2021-01-26 15:31:58 -05:00
|
|
|
import '../../../assets/css/scrollstyles.scss';
|
2020-08-14 08:46:34 +02:00
|
|
|
import '../../../elements/emby-slider/emby-slider';
|
|
|
|
import '../../../elements/emby-button/paper-icon-button-light';
|
2021-01-26 15:31:58 -05:00
|
|
|
import '../../../assets/css/videoosd.scss';
|
2020-10-17 19:08:56 +01:00
|
|
|
import ServerConnections from '../../../components/ServerConnections';
|
2020-10-18 13:53:12 +01:00
|
|
|
import shell from '../../../scripts/shell';
|
|
|
|
import SubtitleSync from '../../../components/subtitlesync/subtitlesync';
|
2020-10-18 20:00:39 +01:00
|
|
|
import { appRouter } from '../../../components/appRouter';
|
2020-07-19 10:40:41 +01:00
|
|
|
|
|
|
|
/* eslint-disable indent */
|
2019-02-02 10:20:27 -05:00
|
|
|
|
2020-07-10 15:15:46 +03:00
|
|
|
function getOpenedDialog() {
|
|
|
|
return document.querySelector('.dialogContainer .dialog.opened');
|
|
|
|
}
|
|
|
|
|
2020-07-19 10:40:41 +01:00
|
|
|
export default function (view, params) {
|
2019-02-02 13:51:03 -05:00
|
|
|
function getDisplayItem(item) {
|
2020-07-30 16:07:13 +02:00
|
|
|
if (item.Type === 'TvChannel') {
|
2020-10-17 19:08:56 +01:00
|
|
|
const apiClient = ServerConnections.getApiClient(item.ServerId);
|
2019-02-02 13:51:03 -05:00
|
|
|
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) {
|
2020-07-30 16:07:13 +02:00
|
|
|
if (!item || item.Type !== 'Program') {
|
2019-02-02 13:51:03 -05:00
|
|
|
if (recordingButtonManager) {
|
|
|
|
recordingButtonManager.destroy();
|
|
|
|
recordingButtonManager = null;
|
|
|
|
}
|
|
|
|
|
2020-05-04 12:44:12 +02:00
|
|
|
return void view.querySelector('.btnRecord').classList.add('hide');
|
2019-02-02 13:51:03 -05:00
|
|
|
}
|
2019-02-02 10:20:27 -05:00
|
|
|
|
2020-10-17 19:08:56 +01:00
|
|
|
ServerConnections.getApiClient(item.ServerId).getCurrentUser().then(function (user) {
|
2019-02-02 13:51:03 -05:00
|
|
|
if (user.Policy.EnableLiveTvManagement) {
|
2020-11-08 11:11:43 +00:00
|
|
|
import('../../../components/recordingcreator/recordingbutton').then(({default: RecordingButton}) => {
|
2019-02-02 13:51:03 -05:00
|
|
|
if (recordingButtonManager) {
|
|
|
|
return void recordingButtonManager.refreshItem(item);
|
|
|
|
}
|
|
|
|
|
|
|
|
recordingButtonManager = new RecordingButton({
|
|
|
|
item: item,
|
2020-05-04 12:44:12 +02:00
|
|
|
button: view.querySelector('.btnRecord')
|
2019-02-02 13:51:03 -05:00
|
|
|
});
|
2020-05-04 12:44:12 +02:00
|
|
|
view.querySelector('.btnRecord').classList.remove('hide');
|
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 updateDisplayItem(itemInfo) {
|
2020-07-19 10:40:41 +01:00
|
|
|
const item = itemInfo.originalItem;
|
2019-02-02 13:51:03 -05:00
|
|
|
currentItem = item;
|
2020-07-19 10:40:41 +01:00
|
|
|
const displayItem = itemInfo.displayItem || item;
|
2019-02-02 13:51:03 -05:00
|
|
|
updateRecordingButton(displayItem);
|
2020-07-19 10:40:41 +01:00
|
|
|
let 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);
|
2019-02-02 10:20:27 -05:00
|
|
|
|
2020-07-19 10:40:41 +01:00
|
|
|
const secondaryMediaInfo = view.querySelector('.osdSecondaryMediaInfo');
|
|
|
|
const secondaryMediaInfoHtml = mediaInfo.getSecondaryMediaInfoHtml(displayItem, {
|
2019-02-02 13:51:03 -05:00
|
|
|
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) {
|
2020-05-04 12:44:12 +02:00
|
|
|
secondaryMediaInfo.classList.remove('hide');
|
2019-02-02 13:51:03 -05:00
|
|
|
} else {
|
2020-05-04 12:44:12 +02:00
|
|
|
secondaryMediaInfo.classList.add('hide');
|
2019-02-02 13:51:03 -05:00
|
|
|
}
|
2018-10-23 01:05:09 +03:00
|
|
|
|
2019-02-02 13:51:03 -05:00
|
|
|
if (enableProgressByTimeOfDay) {
|
|
|
|
setDisplayTime(startTimeText, displayItem.StartDate);
|
|
|
|
setDisplayTime(endTimeText, displayItem.EndDate);
|
2020-05-04 12:44:12 +02:00
|
|
|
startTimeText.classList.remove('hide');
|
|
|
|
endTimeText.classList.remove('hide');
|
2019-02-02 13:51:03 -05:00
|
|
|
programStartDateMs = displayItem.StartDate ? datetime.parseISO8601Date(displayItem.StartDate).getTime() : 0;
|
|
|
|
programEndDateMs = displayItem.EndDate ? datetime.parseISO8601Date(displayItem.EndDate).getTime() : 0;
|
|
|
|
} else {
|
2020-05-04 12:44:12 +02:00
|
|
|
startTimeText.classList.add('hide');
|
|
|
|
endTimeText.classList.add('hide');
|
|
|
|
startTimeText.innerHTML = '';
|
|
|
|
endTimeText.innerHTML = '';
|
2019-02-02 13:51:03 -05:00
|
|
|
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, {
|
2020-05-04 12:44:12 +02:00
|
|
|
hour: 'numeric',
|
|
|
|
minute: '2-digit',
|
|
|
|
second: '2-digit'
|
|
|
|
}).toLowerCase().replace('am', '').replace('pm', '').trim();
|
2019-02-02 13:51:03 -05:00
|
|
|
}
|
2019-02-02 10:20:27 -05:00
|
|
|
|
2020-05-04 12:44:12 +02:00
|
|
|
return datetime.getDisplayTime(date).toLowerCase().replace('am', '').replace('pm', '').trim();
|
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 setDisplayTime(elem, date) {
|
2020-07-19 10:40:41 +01:00
|
|
|
let html;
|
2019-02-02 13:51:03 -05:00
|
|
|
|
|
|
|
if (date) {
|
|
|
|
date = datetime.parseISO8601Date(date);
|
|
|
|
html = getDisplayTimeWithoutAmPm(date);
|
|
|
|
}
|
|
|
|
|
2020-05-04 12:44:12 +02:00
|
|
|
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) {
|
2020-07-30 16:07:13 +02:00
|
|
|
return !(item.Type !== 'TvChannel' || !item.CurrentProgram);
|
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 updateNowPlayingInfo(player, state) {
|
2020-07-19 10:40:41 +01:00
|
|
|
const item = state.NowPlayingItem;
|
2019-02-02 13:51:03 -05:00
|
|
|
|
2019-02-12 10:01:11 -05:00
|
|
|
currentItem = item;
|
|
|
|
if (!item) {
|
2019-02-02 13:51:03 -05:00
|
|
|
updateRecordingButton(null);
|
2020-10-18 20:00:39 +01:00
|
|
|
appRouter.setTitle('');
|
2019-02-02 13:51:03 -05:00
|
|
|
nowPlayingVolumeSlider.disabled = true;
|
|
|
|
nowPlayingPositionSlider.disabled = true;
|
|
|
|
btnFastForward.disabled = true;
|
|
|
|
btnRewind.disabled = true;
|
2020-05-04 12:44:12 +02:00
|
|
|
view.querySelector('.btnSubtitles').classList.add('hide');
|
|
|
|
view.querySelector('.btnAudio').classList.add('hide');
|
|
|
|
view.querySelector('.osdTitle').innerHTML = '';
|
|
|
|
view.querySelector('.osdMediaInfo').innerHTML = '';
|
2019-02-12 10:01:11 -05:00
|
|
|
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) {
|
2020-05-04 12:44:12 +02:00
|
|
|
view.querySelector('.btnSubtitles').classList.remove('hide');
|
2019-04-08 20:31:18 +02:00
|
|
|
toggleSubtitleSync();
|
2019-02-02 13:51:03 -05:00
|
|
|
} else {
|
2020-05-04 12:44:12 +02:00
|
|
|
view.querySelector('.btnSubtitles').classList.add('hide');
|
|
|
|
toggleSubtitleSync('forceToHide');
|
2019-02-02 13:51:03 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
if (playbackManager.audioTracks(player).length > 1) {
|
2020-05-04 12:44:12 +02:00
|
|
|
view.querySelector('.btnAudio').classList.remove('hide');
|
2019-02-02 13:51:03 -05:00
|
|
|
} else {
|
2020-05-04 12:44:12 +02:00
|
|
|
view.querySelector('.btnAudio').classList.add('hide');
|
2019-02-02 13:51:03 -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 setTitle(item, parentName) {
|
2020-08-20 12:27:25 +02:00
|
|
|
let itemName = itemHelper.getDisplayName(item, {
|
|
|
|
includeParentInfo: item.Type !== 'Program',
|
|
|
|
includeIndexNumber: item.Type !== 'Program'
|
|
|
|
});
|
2019-02-02 10:20:27 -05:00
|
|
|
|
2020-08-20 12:27:25 +02:00
|
|
|
if (itemName && parentName) {
|
|
|
|
itemName = `${parentName} - ${itemName}`;
|
|
|
|
}
|
2019-02-02 10:20:27 -05:00
|
|
|
|
2020-08-20 12:27:25 +02:00
|
|
|
if (!itemName) {
|
|
|
|
itemName = parentName || '';
|
2019-02-02 13:51:03 -05:00
|
|
|
}
|
2019-02-02 10:20:27 -05:00
|
|
|
|
2020-10-18 20:00:39 +01:00
|
|
|
appRouter.setTitle(itemName);
|
2019-02-02 13:51:03 -05:00
|
|
|
|
2020-08-20 12:27:25 +02:00
|
|
|
const documentTitle = parentName || (item ? item.Name : null);
|
2019-02-02 10:20:27 -05:00
|
|
|
|
2020-08-20 12:27:25 +02:00
|
|
|
if (documentTitle) {
|
|
|
|
document.title = documentTitle;
|
|
|
|
}
|
2019-02-02 13:51:03 -05:00
|
|
|
}
|
2018-10-23 01:05:09 +03:00
|
|
|
|
2020-07-09 19:05:24 +03:00
|
|
|
let mouseIsDown = false;
|
2020-06-28 20:50:11 +03:00
|
|
|
|
2019-02-02 13:51:03 -05:00
|
|
|
function showOsd() {
|
|
|
|
slideDownToShow(headerElement);
|
|
|
|
showMainOsdControls();
|
2020-07-10 15:15:46 +03:00
|
|
|
resetIdle();
|
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 hideOsd() {
|
|
|
|
slideUpToHide(headerElement);
|
|
|
|
hideMainOsdControls();
|
2020-07-30 13:42:07 +02:00
|
|
|
mouseManager.hideCursor();
|
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 toggleOsd() {
|
2020-07-30 16:07:13 +02:00
|
|
|
if (currentVisibleMenu === 'osd') {
|
2019-02-02 13:51:03 -05:00
|
|
|
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();
|
2020-03-07 12:01:36 -05:00
|
|
|
osdHideTimeout = setTimeout(hideOsd, 3e3);
|
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) {
|
2020-05-04 12:44:12 +02:00
|
|
|
elem.classList.remove('osdHeader-hidden');
|
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 slideUpToHide(elem) {
|
2020-05-04 12:44:12 +02:00
|
|
|
elem.classList.add('osdHeader-hidden');
|
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 clearHideAnimationEventListeners(elem) {
|
|
|
|
dom.removeEventListener(elem, transitionEndEventName, onHideAnimationComplete, {
|
|
|
|
once: true
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
function onHideAnimationComplete(e) {
|
2020-07-19 10:40:41 +01:00
|
|
|
const elem = e.target;
|
2019-12-07 14:20:09 +01:00
|
|
|
if (elem != osdBottomElement)
|
|
|
|
return;
|
2020-05-04 12:44:12 +02:00
|
|
|
elem.classList.add('hide');
|
2019-02-02 13:51:03 -05:00
|
|
|
dom.removeEventListener(elem, transitionEndEventName, onHideAnimationComplete, {
|
|
|
|
once: true
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
function showMainOsdControls() {
|
2018-10-23 01:05:09 +03:00
|
|
|
if (!currentVisibleMenu) {
|
2020-07-19 10:40:41 +01:00
|
|
|
const elem = osdBottomElement;
|
2020-05-04 12:44:12 +02:00
|
|
|
currentVisibleMenu = 'osd';
|
2019-02-02 13:51:03 -05:00
|
|
|
clearHideAnimationEventListeners(elem);
|
2020-05-04 12:44:12 +02:00
|
|
|
elem.classList.remove('hide');
|
|
|
|
elem.classList.remove('videoOsdBottom-hidden');
|
2019-02-02 13:51:03 -05:00
|
|
|
|
|
|
|
if (!layoutManager.mobile) {
|
|
|
|
setTimeout(function () {
|
2020-05-04 12:44:12 +02:00
|
|
|
focusManager.focus(elem.querySelector('.btnPause'));
|
2019-02-02 13:51:03 -05:00
|
|
|
}, 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() {
|
2020-07-30 16:07:13 +02:00
|
|
|
if (currentVisibleMenu === 'osd') {
|
2020-07-19 10:40:41 +01:00
|
|
|
const elem = osdBottomElement;
|
2019-02-02 13:51:03 -05:00
|
|
|
clearHideAnimationEventListeners(elem);
|
2020-05-04 12:44:12 +02:00
|
|
|
elem.classList.add('videoOsdBottom-hidden');
|
2020-07-29 21:08:50 +02:00
|
|
|
|
2019-02-02 13:51:03 -05:00
|
|
|
dom.addEventListener(elem, transitionEndEventName, onHideAnimationComplete, {
|
|
|
|
once: true
|
|
|
|
});
|
|
|
|
currentVisibleMenu = null;
|
2020-05-04 12:44:12 +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
|
|
|
|
2020-07-09 19:05:24 +03:00
|
|
|
// TODO: Move all idle-related code to `inputManager` or `idleManager` or `idleHelper` (per dialog thing) and listen event from there.
|
|
|
|
|
|
|
|
function resetIdle() {
|
2020-07-10 15:15:46 +03:00
|
|
|
// Restart hide timer if OSD is currently visible and there is no opened dialog
|
|
|
|
if (currentVisibleMenu && !mouseIsDown && !getOpenedDialog()) {
|
2020-07-09 19:05:24 +03:00
|
|
|
startOsdHideTimer();
|
|
|
|
} else {
|
|
|
|
stopOsdHideTimer();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-02-02 13:51:03 -05:00
|
|
|
function onPointerMove(e) {
|
2020-07-30 16:07:13 +02:00
|
|
|
if ((e.pointerType || (layoutManager.mobile ? 'touch' : 'mouse')) === 'mouse') {
|
2020-07-19 10:40:41 +01:00
|
|
|
const eventX = e.screenX || 0;
|
|
|
|
const eventY = e.screenY || 0;
|
|
|
|
const obj = lastPointerMoveData;
|
2019-02-02 13:51:03 -05:00
|
|
|
|
|
|
|
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) {
|
2020-07-19 10:40:41 +01:00
|
|
|
const player = currentPlayer;
|
2019-02-02 13:51:03 -05:00
|
|
|
|
|
|
|
switch (e.detail.command) {
|
2020-05-04 12:44:12 +02:00
|
|
|
case 'left':
|
2020-07-30 16:07:13 +02:00
|
|
|
if (currentVisibleMenu === 'osd') {
|
2019-11-23 00:29:38 +09:00
|
|
|
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
|
|
|
|
2020-05-04 12:44:12 +02:00
|
|
|
case 'right':
|
2020-07-30 16:07:13 +02:00
|
|
|
if (currentVisibleMenu === 'osd') {
|
2019-11-23 00:29:38 +09:00
|
|
|
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
|
|
|
|
2020-05-04 12:44:12 +02:00
|
|
|
case 'pageup':
|
2019-11-23 00:29:38 +09:00
|
|
|
playbackManager.nextChapter(player);
|
|
|
|
break;
|
2019-02-02 13:51:03 -05:00
|
|
|
|
2020-05-04 12:44:12 +02:00
|
|
|
case 'pagedown':
|
2019-11-23 00:29:38 +09:00
|
|
|
playbackManager.previousChapter(player);
|
|
|
|
break;
|
2019-02-02 13:51:03 -05:00
|
|
|
|
2020-05-04 12:44:12 +02: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
|
|
|
|
2020-05-04 12:44:12 +02:00
|
|
|
case 'record':
|
2019-11-23 00:29:38 +09:00
|
|
|
onRecordingCommand();
|
|
|
|
showOsd();
|
|
|
|
break;
|
2019-02-02 13:51:03 -05:00
|
|
|
|
2020-05-04 12:44:12 +02: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() {
|
2020-07-19 10:40:41 +01:00
|
|
|
const btnRecord = view.querySelector('.btnRecord');
|
2018-10-23 01:05:09 +03:00
|
|
|
|
2020-05-04 12:44:12 +02:00
|
|
|
if (!btnRecord.classList.contains('hide')) {
|
2019-02-02 13:51:03 -05:00
|
|
|
btnRecord.click();
|
|
|
|
}
|
|
|
|
}
|
2018-10-23 01:05:09 +03:00
|
|
|
|
2019-02-02 13:51:03 -05:00
|
|
|
function updateFullscreenIcon() {
|
2020-05-04 12:44:12 +02:00
|
|
|
const button = view.querySelector('.btnFullscreen');
|
|
|
|
const icon = button.querySelector('.material-icons');
|
2020-05-02 14:02:44 +03:00
|
|
|
|
2020-05-04 12:44:12 +02:00
|
|
|
icon.classList.remove('fullscreen_exit', 'fullscreen');
|
2020-05-02 14:02:44 +03:00
|
|
|
|
2019-02-02 13:51:03 -05:00
|
|
|
if (playbackManager.isFullscreen(currentPlayer)) {
|
2020-05-04 12:44:12 +02:00
|
|
|
button.setAttribute('title', globalize.translate('ExitFullscreen') + ' (f)');
|
|
|
|
icon.classList.add('fullscreen_exit');
|
2019-02-02 13:51:03 -05:00
|
|
|
} else {
|
2020-05-04 12:44:12 +02:00
|
|
|
button.setAttribute('title', globalize.translate('Fullscreen') + ' (f)');
|
|
|
|
icon.classList.add('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) {
|
2020-07-19 10:40:41 +01:00
|
|
|
const 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) {
|
2020-07-19 10:40:41 +01:00
|
|
|
const player = this;
|
2019-02-02 13:51:03 -05:00
|
|
|
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) {
|
2020-05-04 12:44:12 +02:00
|
|
|
console.debug('nowplaying event: ' + e.type);
|
2020-07-19 10:40:41 +01:00
|
|
|
const player = this;
|
2019-02-02 13:51:03 -05:00
|
|
|
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;
|
2020-07-19 10:40:41 +01:00
|
|
|
const 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();
|
2020-05-04 12:44:12 +02:00
|
|
|
console.debug('nowplaying event: ' + e.type);
|
2018-10-23 01:05:09 +03:00
|
|
|
|
2020-07-30 16:07:13 +02:00
|
|
|
if (state.NextMediaType !== 'Video') {
|
2020-05-04 12:44:12 +02:00
|
|
|
view.removeEventListener('viewbeforehide', onViewHideStopPlayback);
|
2020-10-18 20:00:39 +01:00
|
|
|
appRouter.back();
|
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 onMediaStreamsChanged(e) {
|
2020-07-19 10:40:41 +01:00
|
|
|
const player = this;
|
|
|
|
const state = playbackManager.getPlayerState(player);
|
2019-02-02 13:51:03 -05:00
|
|
|
onStateChanged.call(player, {
|
2020-05-04 12:44:12 +02:00
|
|
|
type: 'init'
|
2019-02-02 13:51:03 -05:00
|
|
|
}, state);
|
|
|
|
}
|
2019-02-02 10:20:27 -05:00
|
|
|
|
2019-09-12 21:24:16 +02:00
|
|
|
function onBeginFetch() {
|
2020-05-04 12:44:12 +02:00
|
|
|
document.querySelector('.osdMediaStatus').classList.remove('hide');
|
2019-09-12 21:24:16 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
function onEndFetch() {
|
2020-05-04 12:44:12 +02:00
|
|
|
document.querySelector('.osdMediaStatus').classList.add('hide');
|
2019-09-12 21:24:16 +02:00
|
|
|
}
|
|
|
|
|
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
|
|
|
}
|
2020-07-19 10:40:41 +01:00
|
|
|
const state = playbackManager.getPlayerState(player);
|
2019-02-12 10:01:11 -05:00
|
|
|
onStateChanged.call(player, {
|
2020-05-04 12:44:12 +02:00
|
|
|
type: 'init'
|
2019-02-12 10:01:11 -05:00
|
|
|
}, state);
|
2020-09-08 02:05:02 -04:00
|
|
|
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);
|
|
|
|
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();
|
2020-07-19 10:40:41 +01:00
|
|
|
const player = currentPlayer;
|
2019-02-02 13:51:03 -05:00
|
|
|
|
|
|
|
if (player) {
|
2020-09-08 02:05:02 -04:00
|
|
|
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);
|
2019-02-02 13:51:03 -05:00
|
|
|
currentPlayer = null;
|
|
|
|
}
|
|
|
|
}
|
2018-10-23 01:05:09 +03:00
|
|
|
|
2019-02-02 13:51:03 -05:00
|
|
|
function onTimeUpdate(e) {
|
2020-03-22 19:30:02 +03:00
|
|
|
// Test for 'currentItem' is required for Firefox since its player spams 'timeupdate' events even being at breakpoint
|
|
|
|
if (isEnabled && currentItem) {
|
2020-07-19 10:40:41 +01:00
|
|
|
const now = new Date().getTime();
|
2019-02-02 13:51:03 -05:00
|
|
|
|
|
|
|
if (!(now - lastUpdateTime < 700)) {
|
|
|
|
lastUpdateTime = now;
|
2020-07-19 10:40:41 +01:00
|
|
|
const player = this;
|
2019-02-02 13:51:03 -05:00
|
|
|
currentRuntimeTicks = playbackManager.duration(player);
|
2020-08-15 11:30:36 -04:00
|
|
|
const currentTime = playbackManager.currentTime(player) * 10000;
|
2019-02-02 13:51:03 -05:00
|
|
|
updateTimeDisplay(currentTime, currentRuntimeTicks, playbackManager.playbackStartTime(player), playbackManager.getBufferedRanges(player));
|
2020-07-19 10:40:41 +01:00
|
|
|
const item = currentItem;
|
2019-02-02 13:51:03 -05:00
|
|
|
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) {
|
2020-07-30 16:07:13 +02:00
|
|
|
if (runtimeTicks && currentTimeTicks && !comingUpNextDisplayed && !currentVisibleMenu && currentItem.Type === 'Episode' && userSettings.enableNextVideoInfoOverlay()) {
|
2020-07-19 10:40:41 +01:00
|
|
|
const showAtSecondsLeft = runtimeTicks >= 3e10 ? 40 : runtimeTicks >= 24e9 ? 35 : 30;
|
|
|
|
const showAtTicks = runtimeTicks - 1e3 * showAtSecondsLeft * 1e4;
|
|
|
|
const timeRemainingTicks = runtimeTicks - currentTimeTicks;
|
2019-02-02 13:51:03 -05:00
|
|
|
|
|
|
|
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() {
|
2020-07-30 16:07:13 +02:00
|
|
|
if (currentVisibleMenu === 'upnext') {
|
2019-02-02 13:51:03 -05:00
|
|
|
currentVisibleMenu = null;
|
|
|
|
}
|
|
|
|
}
|
2018-10-23 01:05:09 +03:00
|
|
|
|
2019-02-02 13:51:03 -05:00
|
|
|
function showComingUpNext(player) {
|
2020-11-08 11:12:23 +00:00
|
|
|
import('../../../components/upnextdialog/upnextdialog').then(({default: UpNextDialog}) => {
|
2019-02-02 13:51:03 -05:00
|
|
|
if (!(currentVisibleMenu || currentUpNextDialog)) {
|
2020-05-04 12:44:12 +02:00
|
|
|
currentVisibleMenu = 'upnext';
|
2019-02-02 13:51:03 -05:00
|
|
|
comingUpNextDisplayed = true;
|
|
|
|
playbackManager.nextItem(player).then(function (nextItem) {
|
|
|
|
currentUpNextDialog = new UpNextDialog({
|
2020-05-04 12:44:12 +02:00
|
|
|
parent: view.querySelector('.upNextContainer'),
|
2019-02-02 13:51:03 -05:00
|
|
|
player: player,
|
|
|
|
nextItem: nextItem
|
|
|
|
});
|
2020-09-08 02:05:02 -04:00
|
|
|
Events.on(currentUpNextDialog, 'hide', onUpNextHidden);
|
2019-02-02 13:51:03 -05:00
|
|
|
}, 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) {
|
2020-07-30 16:07:13 +02:00
|
|
|
if (item.Type === 'TvChannel') {
|
2020-07-19 10:40:41 +01:00
|
|
|
const program = item.CurrentProgram;
|
2019-02-02 13:51:03 -05:00
|
|
|
|
|
|
|
if (program && program.EndDate) {
|
|
|
|
try {
|
2020-07-19 10:40:41 +01:00
|
|
|
const endDate = datetime.parseISO8601Date(program.EndDate);
|
2019-02-02 13:51:03 -05:00
|
|
|
|
|
|
|
if (new Date().getTime() >= endDate.getTime()) {
|
2020-05-04 12:44:12 +02:00
|
|
|
console.debug('program info needs to be refreshed');
|
2020-07-19 10:40:41 +01:00
|
|
|
const state = playbackManager.getPlayerState(player);
|
2019-02-02 13:51:03 -05:00
|
|
|
onStateChanged.call(player, {
|
2020-05-04 12:44:12 +02:00
|
|
|
type: 'init'
|
2019-02-02 13:51:03 -05:00
|
|
|
}, state);
|
|
|
|
}
|
|
|
|
} catch (e) {
|
2020-05-04 12:44:12 +02:00
|
|
|
console.error('error parsing date: ' + program.EndDate);
|
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 updatePlayPauseState(isPaused) {
|
2020-05-04 12:44:12 +02:00
|
|
|
const btnPlayPause = view.querySelector('.btnPause');
|
|
|
|
const btnPlayPauseIcon = btnPlayPause.querySelector('.material-icons');
|
2020-05-02 14:02:44 +03:00
|
|
|
|
2020-05-04 12:44:12 +02:00
|
|
|
btnPlayPauseIcon.classList.remove('play_arrow', 'pause');
|
2020-05-02 14:02:44 +03:00
|
|
|
|
2019-04-25 12:35:02 -04:00
|
|
|
if (isPaused) {
|
2020-05-04 12:44:12 +02:00
|
|
|
btnPlayPauseIcon.classList.add('play_arrow');
|
2020-08-16 20:34:39 +09:00
|
|
|
btnPlayPause.setAttribute('title', globalize.translate('Play') + ' (k)');
|
2019-04-25 12:35:02 -04:00
|
|
|
} else {
|
2020-05-04 12:44:12 +02:00
|
|
|
btnPlayPauseIcon.classList.add('pause');
|
|
|
|
btnPlayPause.setAttribute('title', globalize.translate('ButtonPause') + ' (k)');
|
2019-04-25 12:35:02 -04:00
|
|
|
}
|
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) {
|
2020-07-19 10:40:41 +01:00
|
|
|
const playState = state.PlayState || {};
|
2019-02-02 13:51:03 -05:00
|
|
|
updatePlayPauseState(playState.IsPaused);
|
2020-07-19 10:40:41 +01:00
|
|
|
const supportedCommands = playbackManager.getSupportedCommands(player);
|
2019-02-02 13:51:03 -05:00
|
|
|
currentPlayerSupportedCommands = supportedCommands;
|
|
|
|
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;
|
2020-07-19 10:40:41 +01:00
|
|
|
const nowPlayingItem = state.NowPlayingItem || {};
|
2019-02-02 13:51:03 -05:00
|
|
|
playbackStartTimeTicks = playState.PlaybackStartTimeTicks;
|
|
|
|
updateTimeDisplay(playState.PositionTicks, nowPlayingItem.RunTimeTicks, playState.PlaybackStartTimeTicks, playState.BufferedRanges || []);
|
|
|
|
updateNowPlayingInfo(player, state);
|
2018-10-23 01:05:09 +03:00
|
|
|
|
2020-07-30 16:07:13 +02:00
|
|
|
if (state.MediaSource && state.MediaSource.SupportsTranscoding && supportedCommands.indexOf('SetMaxStreamingBitrate') !== -1) {
|
2020-05-04 12:44:12 +02:00
|
|
|
view.querySelector('.btnVideoOsdSettings').classList.remove('hide');
|
2019-02-02 13:51:03 -05:00
|
|
|
} else {
|
2020-05-04 12:44:12 +02:00
|
|
|
view.querySelector('.btnVideoOsdSettings').classList.add('hide');
|
2019-02-02 13:51:03 -05:00
|
|
|
}
|
2018-10-23 01:05:09 +03:00
|
|
|
|
2020-07-30 16:07:13 +02:00
|
|
|
const isProgressClear = state.MediaSource && state.MediaSource.RunTimeTicks == null;
|
2019-02-02 13:51:03 -05:00
|
|
|
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
|
|
|
}
|
|
|
|
|
2020-07-30 16:07:13 +02:00
|
|
|
if (supportedCommands.indexOf('ToggleFullscreen') === -1 || player.isLocalPlayer && layoutManager.tv && playbackManager.isFullscreen(player)) {
|
2020-05-04 12:44:12 +02:00
|
|
|
view.querySelector('.btnFullscreen').classList.add('hide');
|
2018-10-23 01:05:09 +03:00
|
|
|
} else {
|
2020-05-04 12:44:12 +02:00
|
|
|
view.querySelector('.btnFullscreen').classList.remove('hide');
|
2018-10-23 01:05:09 +03:00
|
|
|
}
|
|
|
|
|
2020-07-30 16:07:13 +02:00
|
|
|
if (supportedCommands.indexOf('PictureInPicture') === -1) {
|
2020-05-04 12:44:12 +02:00
|
|
|
view.querySelector('.btnPip').classList.add('hide');
|
2019-02-02 13:51:03 -05:00
|
|
|
} else {
|
2020-05-04 12:44:12 +02:00
|
|
|
view.querySelector('.btnPip').classList.remove('hide');
|
2019-02-02 13:51:03 -05:00
|
|
|
}
|
2019-02-02 10:20:27 -05:00
|
|
|
|
2020-07-30 16:07:13 +02:00
|
|
|
if (supportedCommands.indexOf('AirPlay') === -1) {
|
2020-05-04 12:44:12 +02:00
|
|
|
view.querySelector('.btnAirPlay').classList.add('hide');
|
2020-01-10 11:31:03 -05:00
|
|
|
} else {
|
2020-05-04 12:44:12 +02:00
|
|
|
view.querySelector('.btnAirPlay').classList.remove('hide');
|
2020-01-10 11:31:03 -05:00
|
|
|
}
|
|
|
|
|
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) {
|
2020-07-19 10:40:41 +01:00
|
|
|
const currentTimeMs = (playbackStartTimeTicks + (positionTicks || 0)) / 1e4;
|
|
|
|
const programRuntimeMs = programEndDateMs - programStartDateMs;
|
2019-02-02 13:51:03 -05:00
|
|
|
|
|
|
|
if (nowPlayingPositionSlider.value = getDisplayPercentByTimeOfDay(programStartDateMs, programRuntimeMs, currentTimeMs), bufferedRanges.length) {
|
2020-07-19 10:40:41 +01:00
|
|
|
const rangeStart = getDisplayPercentByTimeOfDay(programStartDateMs, programRuntimeMs, (playbackStartTimeTicks + (bufferedRanges[0].start || 0)) / 1e4);
|
|
|
|
const rangeEnd = getDisplayPercentByTimeOfDay(programStartDateMs, programRuntimeMs, (playbackStartTimeTicks + (bufferedRanges[0].end || 0)) / 1e4);
|
2019-02-02 13:51:03 -05:00
|
|
|
nowPlayingPositionSlider.setBufferedRanges([{
|
|
|
|
start: rangeStart,
|
|
|
|
end: rangeEnd
|
|
|
|
}]);
|
|
|
|
} else {
|
|
|
|
nowPlayingPositionSlider.setBufferedRanges([]);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
nowPlayingPositionSlider.value = 0;
|
|
|
|
nowPlayingPositionSlider.setBufferedRanges([]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-05-04 12:44:12 +02:00
|
|
|
nowPlayingPositionText.innerHTML = '';
|
|
|
|
nowPlayingDurationText.innerHTML = '';
|
2019-02-02 13:51:03 -05:00
|
|
|
} else {
|
|
|
|
if (nowPlayingPositionSlider && !nowPlayingPositionSlider.dragging) {
|
|
|
|
if (runtimeTicks) {
|
2020-07-19 10:40:41 +01:00
|
|
|
let pct = positionTicks / runtimeTicks;
|
2019-02-02 13:51:03 -05:00
|
|
|
pct *= 100;
|
|
|
|
nowPlayingPositionSlider.value = pct;
|
|
|
|
} else {
|
|
|
|
nowPlayingPositionSlider.value = 0;
|
|
|
|
}
|
|
|
|
|
2020-07-30 16:07:13 +02:00
|
|
|
if (runtimeTicks && positionTicks != null && currentRuntimeTicks && !enableProgressByTimeOfDay && currentItem.RunTimeTicks && currentItem.Type !== 'Recording') {
|
2020-11-17 22:34:02 +08:00
|
|
|
endsAtText.innerHTML = ' ' + mediaInfo.getEndsAtFromPosition(runtimeTicks, positionTicks, true);
|
2019-02-02 13:51:03 -05:00
|
|
|
} else {
|
2020-05-04 12:44:12 +02:00
|
|
|
endsAtText.innerHTML = '';
|
2019-02-02 13:51:03 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (nowPlayingPositionSlider) {
|
|
|
|
nowPlayingPositionSlider.setBufferedRanges(bufferedRanges, runtimeTicks, positionTicks);
|
|
|
|
}
|
|
|
|
|
2020-11-17 22:34:02 +08:00
|
|
|
if (positionTicks >= 0) {
|
|
|
|
updateTimeText(nowPlayingPositionText, positionTicks);
|
|
|
|
nowPlayingPositionText.classList.remove('hide');
|
|
|
|
} else {
|
|
|
|
nowPlayingPositionText.classList.add('hide');
|
|
|
|
}
|
|
|
|
|
|
|
|
const leftTicks = runtimeTicks - positionTicks;
|
|
|
|
if (leftTicks >= 0) {
|
|
|
|
updateTimeText(nowPlayingDurationText, leftTicks);
|
|
|
|
nowPlayingDurationText.classList.remove('hide');
|
|
|
|
} else {
|
|
|
|
nowPlayingPositionText.classList.add('hide');
|
|
|
|
}
|
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 updatePlayerVolumeState(player, isMuted, volumeLevel) {
|
2020-07-19 10:40:41 +01:00
|
|
|
const supportedCommands = currentPlayerSupportedCommands;
|
|
|
|
let showMuteButton = true;
|
|
|
|
let showVolumeSlider = true;
|
2018-10-23 01:05:09 +03:00
|
|
|
|
2020-07-30 16:07:13 +02:00
|
|
|
if (supportedCommands.indexOf('Mute') === -1) {
|
2019-02-02 13:51:03 -05:00
|
|
|
showMuteButton = false;
|
|
|
|
}
|
|
|
|
|
2020-07-30 16:07:13 +02:00
|
|
|
if (supportedCommands.indexOf('SetVolume') === -1) {
|
2019-02-02 13:51:03 -05:00
|
|
|
showVolumeSlider = false;
|
|
|
|
}
|
2019-02-02 10:20:27 -05:00
|
|
|
|
2020-08-06 22:09:24 +02:00
|
|
|
if (player.isLocalPlayer && appHost.supports('physicalvolumecontrol')) {
|
2019-02-02 13:51:03 -05:00
|
|
|
showMuteButton = false;
|
|
|
|
showVolumeSlider = false;
|
|
|
|
}
|
2019-02-02 10:20:27 -05:00
|
|
|
|
2020-05-04 12:44:12 +02:00
|
|
|
const buttonMute = view.querySelector('.buttonMute');
|
|
|
|
const buttonMuteIcon = buttonMute.querySelector('.material-icons');
|
2020-05-02 14:02:44 +03:00
|
|
|
|
2020-05-04 12:44:12 +02:00
|
|
|
buttonMuteIcon.classList.remove('volume_off', 'volume_up');
|
2020-05-02 14:02:44 +03:00
|
|
|
|
2019-02-02 13:51:03 -05:00
|
|
|
if (isMuted) {
|
2020-05-04 12:44:12 +02:00
|
|
|
buttonMute.setAttribute('title', globalize.translate('Unmute') + ' (m)');
|
|
|
|
buttonMuteIcon.classList.add('volume_off');
|
2019-02-02 13:51:03 -05:00
|
|
|
} else {
|
2020-05-04 12:44:12 +02:00
|
|
|
buttonMute.setAttribute('title', globalize.translate('Mute') + ' (m)');
|
|
|
|
buttonMuteIcon.classList.add('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 (showMuteButton) {
|
2020-05-04 12:44:12 +02:00
|
|
|
buttonMute.classList.remove('hide');
|
2019-02-02 13:51:03 -05:00
|
|
|
} else {
|
2020-05-04 12:44:12 +02:00
|
|
|
buttonMute.classList.add('hide');
|
2019-02-02 13:51:03 -05:00
|
|
|
}
|
2018-10-23 01:05:09 +03:00
|
|
|
|
2019-02-02 13:51:03 -05:00
|
|
|
if (nowPlayingVolumeSlider) {
|
|
|
|
if (showVolumeSlider) {
|
2020-05-04 12:44:12 +02:00
|
|
|
nowPlayingVolumeSliderContainer.classList.remove('hide');
|
2019-02-02 13:51:03 -05:00
|
|
|
} else {
|
2020-05-04 12:44:12 +02:00
|
|
|
nowPlayingVolumeSliderContainer.classList.add('hide');
|
2019-02-02 13:51:03 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
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) {
|
2020-07-19 10:40:41 +01:00
|
|
|
const btnPreviousTrack = view.querySelector('.btnPreviousTrack');
|
|
|
|
const btnNextTrack = view.querySelector('.btnNextTrack');
|
2020-05-04 12:44:12 +02:00
|
|
|
btnPreviousTrack.classList.remove('hide');
|
|
|
|
btnNextTrack.classList.remove('hide');
|
2019-02-02 13:51:03 -05:00
|
|
|
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) {
|
2020-07-30 16:07:13 +02:00
|
|
|
if (ticks == null) {
|
2020-05-04 12:44:12 +02:00
|
|
|
elem.innerHTML = '';
|
2019-02-12 10:01:11 -05:00
|
|
|
return;
|
2019-02-02 13:51:03 -05:00
|
|
|
}
|
2019-02-02 10:20:27 -05:00
|
|
|
|
2020-07-19 10:40:41 +01:00
|
|
|
let html = datetime.getDisplayRunningTime(ticks);
|
2019-02-02 13:51:03 -05:00
|
|
|
|
|
|
|
if (divider) {
|
2020-05-04 12:44:12 +02:00
|
|
|
html = ' / ' + html;
|
2019-02-02 13:51:03 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
elem.innerHTML = html;
|
|
|
|
}
|
2018-10-23 01:05:09 +03:00
|
|
|
|
2019-02-02 13:51:03 -05:00
|
|
|
function onSettingsButtonClick(e) {
|
2020-07-19 10:40:41 +01:00
|
|
|
const btn = this;
|
2019-02-02 13:51:03 -05:00
|
|
|
|
2020-08-14 08:46:34 +02:00
|
|
|
import('../../../components/playback/playersettingsmenu').then((playerSettingsMenu) => {
|
2020-07-19 10:40:41 +01:00
|
|
|
const player = currentPlayer;
|
2019-02-02 13:51:03 -05:00
|
|
|
|
|
|
|
if (player) {
|
2019-04-08 20:31:18 +02:00
|
|
|
// show subtitle offset feature only if player and media support it
|
2020-07-19 10:40:41 +01:00
|
|
|
const 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({
|
2020-05-04 12:44:12 +02:00
|
|
|
mediaType: 'Video',
|
2019-02-02 13:51:03 -05:00
|
|
|
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
|
2020-07-10 15:15:46 +03:00
|
|
|
}).finally(() => {
|
|
|
|
resetIdle();
|
2019-02-02 13:51:03 -05:00
|
|
|
});
|
2020-07-10 15:15:46 +03:00
|
|
|
|
|
|
|
setTimeout(resetIdle, 0);
|
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 onSettingsOption(selectedOption) {
|
2020-07-30 16:07:13 +02:00
|
|
|
if (selectedOption === 'stats') {
|
2019-02-02 13:51:03 -05:00
|
|
|
toggleStats();
|
2020-07-30 16:07:13 +02:00
|
|
|
} else if (selectedOption === 'suboffset') {
|
2020-07-19 10:40:41 +01:00
|
|
|
const player = currentPlayer;
|
2019-04-08 20:31:18 +02:00
|
|
|
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() {
|
2020-11-08 11:12:01 +00:00
|
|
|
import('../../../components/playerstats/playerstats').then(({default: PlayerStats}) => {
|
2020-07-19 10:40:41 +01:00
|
|
|
const player = currentPlayer;
|
2019-02-02 13:51:03 -05:00
|
|
|
|
|
|
|
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() {
|
2020-07-19 10:40:41 +01:00
|
|
|
const player = currentPlayer;
|
|
|
|
const audioTracks = playbackManager.audioTracks(player);
|
|
|
|
const currentIndex = playbackManager.getAudioStreamIndex(player);
|
|
|
|
const menuItems = audioTracks.map(function (stream) {
|
|
|
|
const opt = {
|
2019-02-02 13:51:03 -05:00
|
|
|
name: stream.DisplayTitle,
|
|
|
|
id: stream.Index
|
|
|
|
};
|
|
|
|
|
|
|
|
if (stream.Index === currentIndex) {
|
|
|
|
opt.selected = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
return opt;
|
|
|
|
});
|
2020-07-19 10:40:41 +01:00
|
|
|
const positionTo = this;
|
2019-02-02 13:51:03 -05:00
|
|
|
|
2020-08-14 08:46:34 +02:00
|
|
|
import('../../../components/actionSheet/actionSheet').then(({default: actionsheet}) => {
|
2019-02-02 13:51:03 -05:00
|
|
|
actionsheet.show({
|
|
|
|
items: menuItems,
|
2020-05-04 12:44:12 +02:00
|
|
|
title: globalize.translate('Audio'),
|
2019-02-02 13:51:03 -05:00
|
|
|
positionTo: positionTo
|
|
|
|
}).then(function (id) {
|
2020-07-19 10:40:41 +01:00
|
|
|
const index = parseInt(id);
|
2019-02-02 13:51:03 -05:00
|
|
|
|
|
|
|
if (index !== currentIndex) {
|
|
|
|
playbackManager.setAudioStreamIndex(index, player);
|
|
|
|
}
|
2020-07-10 15:15:46 +03:00
|
|
|
}).finally(() => {
|
|
|
|
resetIdle();
|
2019-02-02 13:51:03 -05:00
|
|
|
});
|
2020-07-10 15:15:46 +03:00
|
|
|
|
|
|
|
setTimeout(resetIdle, 0);
|
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 showSubtitleTrackSelection() {
|
2020-07-19 10:40:41 +01:00
|
|
|
const player = currentPlayer;
|
|
|
|
const streams = playbackManager.subtitleTracks(player);
|
|
|
|
let currentIndex = playbackManager.getSubtitleStreamIndex(player);
|
2019-02-02 10:20:27 -05:00
|
|
|
|
2020-07-30 16:07:13 +02:00
|
|
|
if (currentIndex == null) {
|
2019-02-02 13:51:03 -05:00
|
|
|
currentIndex = -1;
|
|
|
|
}
|
2018-10-23 01:05:09 +03:00
|
|
|
|
2019-02-02 13:51:03 -05:00
|
|
|
streams.unshift({
|
|
|
|
Index: -1,
|
2020-05-04 12:44:12 +02:00
|
|
|
DisplayTitle: globalize.translate('Off')
|
2019-02-02 13:51:03 -05:00
|
|
|
});
|
2020-07-19 10:40:41 +01:00
|
|
|
const menuItems = streams.map(function (stream) {
|
|
|
|
const opt = {
|
2019-02-02 13:51:03 -05:00
|
|
|
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;
|
|
|
|
});
|
2020-07-19 10:40:41 +01:00
|
|
|
const positionTo = this;
|
2019-02-02 13:51:03 -05:00
|
|
|
|
2020-08-14 08:46:34 +02:00
|
|
|
import('../../../components/actionSheet/actionSheet').then(({default: actionsheet}) => {
|
2019-02-02 13:51:03 -05:00
|
|
|
actionsheet.show({
|
2020-05-04 12:44:12 +02:00
|
|
|
title: globalize.translate('Subtitles'),
|
2019-02-02 13:51:03 -05:00
|
|
|
items: menuItems,
|
|
|
|
positionTo: positionTo
|
|
|
|
}).then(function (id) {
|
2020-07-19 10:40:41 +01:00
|
|
|
const index = parseInt(id);
|
2019-02-02 13:51:03 -05:00
|
|
|
|
|
|
|
if (index !== currentIndex) {
|
|
|
|
playbackManager.setSubtitleStreamIndex(index, player);
|
|
|
|
}
|
2019-03-30 22:11:39 +01:00
|
|
|
|
2019-10-03 02:36:33 +09:00
|
|
|
toggleSubtitleSync();
|
2020-07-10 15:15:46 +03:00
|
|
|
}).finally(() => {
|
|
|
|
resetIdle();
|
2019-02-02 13:51:03 -05:00
|
|
|
});
|
2020-07-10 15:15:46 +03:00
|
|
|
|
|
|
|
setTimeout(resetIdle, 0);
|
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) {
|
2020-10-18 13:53:12 +01:00
|
|
|
const player = currentPlayer;
|
|
|
|
if (subtitleSyncOverlay) {
|
|
|
|
subtitleSyncOverlay.toggle(action);
|
|
|
|
} else if (player) {
|
|
|
|
subtitleSyncOverlay = new SubtitleSync(player);
|
|
|
|
}
|
2019-04-08 20:31:18 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
function destroySubtitleSync() {
|
|
|
|
if (subtitleSyncOverlay) {
|
|
|
|
subtitleSyncOverlay.destroy();
|
|
|
|
subtitleSyncOverlay = null;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-01-25 17:35:16 +03:00
|
|
|
/**
|
|
|
|
* Clicked element.
|
|
|
|
* To skip 'click' handling on Firefox/Edge.
|
|
|
|
*/
|
2020-07-19 10:40:41 +01:00
|
|
|
let clickedElement;
|
2020-01-25 17:35:16 +03:00
|
|
|
|
2020-06-28 23:46:27 +03:00
|
|
|
function onKeyDown(e) {
|
2020-07-08 14:23:59 +03:00
|
|
|
clickedElement = e.target;
|
2020-01-25 17:35:16 +03:00
|
|
|
|
2020-07-19 10:40:41 +01:00
|
|
|
const key = keyboardnavigation.getKeyName(e);
|
2020-07-31 11:15:27 +01:00
|
|
|
const isKeyModified = e.ctrlKey || e.altKey || e.metaKey;
|
2020-01-19 01:09:42 +03:00
|
|
|
|
2020-07-30 16:07:13 +02:00
|
|
|
if (!currentVisibleMenu && e.keyCode === 32) {
|
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-02-05 15:20:48 +03:00
|
|
|
if (layoutManager.tv && keyboardnavigation.isNavigationKey(key)) {
|
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-05-04 12:44:12 +02:00
|
|
|
case 'Enter':
|
2020-01-17 12:09:27 +03:00
|
|
|
showOsd();
|
|
|
|
break;
|
2020-05-04 12:44:12 +02:00
|
|
|
case 'Escape':
|
|
|
|
case 'Back':
|
2020-01-17 12:09:27 +03:00
|
|
|
// Ignore key when some dialog is opened
|
2020-07-10 15:15:46 +03:00
|
|
|
if (currentVisibleMenu === 'osd' && !getOpenedDialog()) {
|
2020-01-17 12:09:27 +03:00
|
|
|
hideOsd();
|
|
|
|
e.stopPropagation();
|
|
|
|
}
|
|
|
|
break;
|
2020-05-04 12:44:12 +02:00
|
|
|
case 'k':
|
2019-04-25 12:35:02 -04:00
|
|
|
playbackManager.playPause(currentPlayer);
|
|
|
|
showOsd();
|
2019-11-23 00:29:38 +09:00
|
|
|
break;
|
2020-05-05 11:50:31 +03:00
|
|
|
case 'ArrowUp':
|
|
|
|
case 'Up':
|
2020-02-21 16:08:23 +11:00
|
|
|
playbackManager.volumeUp(currentPlayer);
|
|
|
|
break;
|
2020-05-05 11:50:31 +03:00
|
|
|
case 'ArrowDown':
|
|
|
|
case 'Down':
|
2020-02-21 16:08:23 +11:00
|
|
|
playbackManager.volumeDown(currentPlayer);
|
|
|
|
break;
|
2020-05-04 12:44:12 +02:00
|
|
|
case 'l':
|
|
|
|
case 'ArrowRight':
|
|
|
|
case 'Right':
|
2019-04-25 12:35:02 -04:00
|
|
|
playbackManager.fastForward(currentPlayer);
|
|
|
|
showOsd();
|
2019-11-23 00:29:38 +09:00
|
|
|
break;
|
2020-05-04 12:44:12 +02:00
|
|
|
case 'j':
|
|
|
|
case 'ArrowLeft':
|
|
|
|
case 'Left':
|
2019-04-25 12:35:02 -04:00
|
|
|
playbackManager.rewind(currentPlayer);
|
|
|
|
showOsd();
|
2019-11-23 00:29:38 +09:00
|
|
|
break;
|
2020-05-04 12:44:12 +02:00
|
|
|
case 'f':
|
2019-11-23 00:29:38 +09:00
|
|
|
if (!e.ctrlKey && !e.metaKey) {
|
|
|
|
playbackManager.toggleFullscreen(currentPlayer);
|
|
|
|
showOsd();
|
|
|
|
}
|
|
|
|
break;
|
2020-05-04 12:44:12 +02:00
|
|
|
case 'm':
|
2019-11-23 00:29:38 +09:00
|
|
|
playbackManager.toggleMute(currentPlayer);
|
|
|
|
showOsd();
|
|
|
|
break;
|
2020-05-05 11:50:31 +03:00
|
|
|
case 'p':
|
|
|
|
case 'P':
|
2020-02-21 16:08:23 +11:00
|
|
|
if (e.shiftKey) {
|
|
|
|
playbackManager.previousTrack(currentPlayer);
|
|
|
|
}
|
|
|
|
break;
|
2020-05-05 11:50:31 +03:00
|
|
|
case 'n':
|
|
|
|
case 'N':
|
2020-02-21 16:08:23 +11:00
|
|
|
if (e.shiftKey) {
|
|
|
|
playbackManager.nextTrack(currentPlayer);
|
|
|
|
}
|
|
|
|
break;
|
2020-05-04 12:44:12 +02: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.
|
2020-04-04 21:29:53 +02:00
|
|
|
if (document.hasFocus()) { /* eslint-disable-line compat/compat */
|
2019-11-23 00:29:38 +09:00
|
|
|
playbackManager.rewind(currentPlayer);
|
|
|
|
showOsd();
|
|
|
|
}
|
|
|
|
break;
|
2020-05-04 12:44:12 +02: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.
|
2020-04-04 21:29:53 +02:00
|
|
|
if (document.hasFocus()) { /* eslint-disable-line compat/compat */
|
2019-11-23 00:29:38 +09:00
|
|
|
playbackManager.fastForward(currentPlayer);
|
|
|
|
showOsd();
|
|
|
|
}
|
2020-05-04 18:13:34 +02:00
|
|
|
break;
|
2020-05-05 11:50:31 +03:00
|
|
|
case 'Home':
|
2020-02-21 16:08:23 +11:00
|
|
|
playbackManager.seekPercent(0, currentPlayer);
|
|
|
|
break;
|
2020-05-05 11:50:31 +03:00
|
|
|
case 'End':
|
2020-02-21 16:08:23 +11:00
|
|
|
playbackManager.seekPercent(100, currentPlayer);
|
|
|
|
break;
|
2020-05-05 11:50:31 +03:00
|
|
|
case '0':
|
|
|
|
case '1':
|
|
|
|
case '2':
|
|
|
|
case '3':
|
|
|
|
case '4':
|
|
|
|
case '5':
|
|
|
|
case '6':
|
|
|
|
case '7':
|
|
|
|
case '8':
|
2020-07-19 10:40:41 +01:00
|
|
|
case '9': {
|
2020-07-29 23:00:07 +01:00
|
|
|
if (!isKeyModified) {
|
|
|
|
const percent = parseInt(key, 10) * 10;
|
|
|
|
playbackManager.seekPercent(percent, currentPlayer);
|
|
|
|
}
|
2020-02-21 16:08:23 +11:00
|
|
|
break;
|
2020-07-19 10:40:41 +01:00
|
|
|
}
|
2020-05-22 22:23:18 -06:00
|
|
|
case '>':
|
|
|
|
playbackManager.increasePlaybackRate(currentPlayer);
|
|
|
|
break;
|
|
|
|
case '<':
|
|
|
|
playbackManager.decreasePlaybackRate(currentPlayer);
|
|
|
|
break;
|
2021-01-26 12:46:02 +00:00
|
|
|
case 'PageUp':
|
|
|
|
playbackManager.nextChapter(currentPlayer);
|
|
|
|
break;
|
|
|
|
case 'PageDown':
|
|
|
|
playbackManager.previousChapter(currentPlayer);
|
|
|
|
break;
|
2019-02-02 13:51:03 -05:00
|
|
|
}
|
|
|
|
}
|
2019-02-02 10:20:27 -05:00
|
|
|
|
2020-06-28 23:46:27 +03:00
|
|
|
function onKeyDownCapture() {
|
2020-07-09 19:05:24 +03:00
|
|
|
resetIdle();
|
2020-06-28 23:46:27 +03:00
|
|
|
}
|
|
|
|
|
2020-01-25 17:35:16 +03:00
|
|
|
function onWindowMouseDown(e) {
|
2020-07-08 14:23:59 +03:00
|
|
|
clickedElement = e.target;
|
2020-07-09 19:05:24 +03:00
|
|
|
mouseIsDown = true;
|
|
|
|
resetIdle();
|
2020-06-28 20:50:11 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
function onWindowMouseUp() {
|
2020-07-09 19:05:24 +03:00
|
|
|
mouseIsDown = false;
|
|
|
|
resetIdle();
|
2020-01-25 17:35:16 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
function onWindowTouchStart(e) {
|
2020-07-08 14:23:59 +03:00
|
|
|
clickedElement = e.target;
|
2020-07-09 19:05:24 +03:00
|
|
|
mouseIsDown = true;
|
|
|
|
resetIdle();
|
2020-06-28 20:50:11 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
function onWindowTouchEnd() {
|
2020-07-09 19:05:24 +03:00
|
|
|
mouseIsDown = false;
|
|
|
|
resetIdle();
|
|
|
|
}
|
|
|
|
|
|
|
|
function onWindowDragEnd() {
|
|
|
|
// mousedown -> dragstart -> dragend !!! no mouseup :(
|
|
|
|
mouseIsDown = false;
|
|
|
|
resetIdle();
|
2020-01-25 17:35:16 +03:00
|
|
|
}
|
|
|
|
|
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,
|
2020-05-04 12:44:12 +02:00
|
|
|
type: 'Chapter',
|
2019-02-02 13:51:03 -05:00
|
|
|
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) {
|
2020-07-19 10:40:41 +01:00
|
|
|
let chapter;
|
|
|
|
let index = -1;
|
2019-02-02 10:20:27 -05:00
|
|
|
|
2020-07-19 10:40:41 +01:00
|
|
|
for (let i = 0, length = chapters.length; i < length; i++) {
|
|
|
|
const 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
|
|
|
|
2020-07-19 10:40:41 +01:00
|
|
|
const src = getImgUrl(item, chapter, index, 400, apiClient);
|
2019-02-02 13:51:03 -05:00
|
|
|
|
|
|
|
if (src) {
|
2020-07-19 10:40:41 +01:00
|
|
|
let html = '<div class="chapterThumbContainer">';
|
2019-02-02 13:51:03 -05:00
|
|
|
html += '<img class="chapterThumb" src="' + src + '" />';
|
|
|
|
html += '<div class="chapterThumbTextContainer">';
|
|
|
|
html += '<div class="chapterThumbText chapterThumbText-dim">';
|
|
|
|
html += chapter.Name;
|
2020-05-04 12:44:12 +02:00
|
|
|
html += '</div>';
|
2019-02-02 13:51:03 -05:00
|
|
|
html += '<h2 class="chapterThumbText">';
|
|
|
|
html += datetime.getDisplayRunningTime(positionTicks);
|
2020-05-04 12:44:12 +02:00
|
|
|
html += '</h2>';
|
|
|
|
html += '</div>';
|
|
|
|
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
|
|
|
|
2020-07-19 10:40:41 +01:00
|
|
|
let playPauseClickTimeout;
|
2019-02-02 13:51:03 -05:00
|
|
|
function onViewHideStopPlayback() {
|
|
|
|
if (playbackManager.isPlayingVideo()) {
|
2020-10-18 13:53:12 +01:00
|
|
|
shell.disableFullscreen();
|
2019-02-02 10:20:27 -05:00
|
|
|
|
2020-02-19 16:09:00 +01:00
|
|
|
clearTimeout(playPauseClickTimeout);
|
2020-07-19 10:40:41 +01:00
|
|
|
const player = currentPlayer;
|
2020-05-04 12:44:12 +02:00
|
|
|
view.removeEventListener('viewbeforehide', onViewHideStopPlayback);
|
2019-02-02 13:51:03 -05:00
|
|
|
releaseCurrentPlayer();
|
|
|
|
playbackManager.stop(player);
|
|
|
|
}
|
|
|
|
}
|
2019-02-02 10:20:27 -05:00
|
|
|
|
2019-02-02 13:51:03 -05:00
|
|
|
function enableStopOnBack(enabled) {
|
2020-05-04 12:44:12 +02:00
|
|
|
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)) {
|
2020-05-04 12:44:12 +02:00
|
|
|
view.addEventListener('viewbeforehide', onViewHideStopPlayback);
|
2019-02-02 13:51:03 -05:00
|
|
|
}
|
2018-10-23 01:05:09 +03:00
|
|
|
}
|
2019-02-02 10:20:27 -05:00
|
|
|
|
2020-10-18 13:53:12 +01:00
|
|
|
shell.enableFullscreen();
|
2019-02-02 10:20:27 -05:00
|
|
|
|
2020-07-19 10:40:41 +01:00
|
|
|
let currentPlayer;
|
|
|
|
let comingUpNextDisplayed;
|
|
|
|
let currentUpNextDialog;
|
|
|
|
let isEnabled;
|
|
|
|
let currentItem;
|
|
|
|
let recordingButtonManager;
|
|
|
|
let enableProgressByTimeOfDay;
|
|
|
|
let currentVisibleMenu;
|
|
|
|
let statsOverlay;
|
|
|
|
let osdHideTimeout;
|
|
|
|
let lastPointerMoveData;
|
|
|
|
const self = this;
|
|
|
|
let currentPlayerSupportedCommands = [];
|
|
|
|
let currentRuntimeTicks = 0;
|
|
|
|
let lastUpdateTime = 0;
|
|
|
|
let programStartDateMs = 0;
|
|
|
|
let programEndDateMs = 0;
|
|
|
|
let playbackStartTimeTicks = 0;
|
|
|
|
let subtitleSyncOverlay;
|
|
|
|
const nowPlayingVolumeSlider = view.querySelector('.osdVolumeSlider');
|
|
|
|
const nowPlayingVolumeSliderContainer = view.querySelector('.osdVolumeSliderContainer');
|
|
|
|
const nowPlayingPositionSlider = view.querySelector('.osdPositionSlider');
|
|
|
|
const nowPlayingPositionText = view.querySelector('.osdPositionText');
|
|
|
|
const nowPlayingDurationText = view.querySelector('.osdDurationText');
|
|
|
|
const startTimeText = view.querySelector('.startTimeText');
|
|
|
|
const endTimeText = view.querySelector('.endTimeText');
|
|
|
|
const endsAtText = view.querySelector('.endsAtText');
|
|
|
|
const btnRewind = view.querySelector('.btnRewind');
|
|
|
|
const btnFastForward = view.querySelector('.btnFastForward');
|
|
|
|
const transitionEndEventName = dom.whichTransitionEvent();
|
|
|
|
const headerElement = document.querySelector('.skinHeader');
|
|
|
|
const osdBottomElement = document.querySelector('.videoOsdBottom-maincontrols');
|
2019-11-09 11:48:52 +03:00
|
|
|
|
2020-06-29 13:03:31 +03:00
|
|
|
nowPlayingPositionSlider.enableKeyboardDragging();
|
|
|
|
nowPlayingVolumeSlider.enableKeyboardDragging();
|
|
|
|
|
2019-11-09 11:48:52 +03:00
|
|
|
if (layoutManager.tv) {
|
2020-05-04 12:44:12 +02:00
|
|
|
nowPlayingPositionSlider.classList.add('focusable');
|
2019-11-09 11:48:52 +03:00
|
|
|
}
|
|
|
|
|
2020-05-04 12:44:12 +02:00
|
|
|
view.addEventListener('viewbeforeshow', function (e) {
|
|
|
|
headerElement.classList.add('osdHeader');
|
2020-10-18 20:00:39 +01:00
|
|
|
appRouter.setTransparency('full');
|
2019-02-02 13:51:03 -05:00
|
|
|
});
|
2020-05-04 12:44:12 +02:00
|
|
|
view.addEventListener('viewshow', function (e) {
|
2019-05-05 12:09:55 -04:00
|
|
|
try {
|
2020-09-08 02:05:02 -04:00
|
|
|
Events.on(playbackManager, 'playerchange', onPlayerChange);
|
2019-05-05 12:09:55 -04:00
|
|
|
bindToPlayer(playbackManager.getCurrentPlayer());
|
2020-07-05 12:54:25 +02:00
|
|
|
/* eslint-disable-next-line compat/compat */
|
2020-05-04 12:44:12 +02:00
|
|
|
dom.addEventListener(document, window.PointerEvent ? 'pointermove' : 'mousemove', onPointerMove, {
|
2019-05-05 12:09:55 -04:00
|
|
|
passive: true
|
|
|
|
});
|
|
|
|
showOsd();
|
|
|
|
inputManager.on(window, onInputCommand);
|
2020-06-28 23:46:27 +03:00
|
|
|
document.addEventListener('keydown', onKeyDown);
|
|
|
|
dom.addEventListener(document, 'keydown', onKeyDownCapture, {
|
2020-07-09 19:05:24 +03:00
|
|
|
capture: true,
|
|
|
|
passive: true
|
2019-05-05 12:09:55 -04:00
|
|
|
});
|
2020-07-05 12:54:25 +02:00
|
|
|
/* eslint-disable-next-line compat/compat */
|
2020-05-04 12:44:12 +02:00
|
|
|
dom.addEventListener(window, window.PointerEvent ? 'pointerdown' : 'mousedown', onWindowMouseDown, {
|
2020-07-09 19:05:24 +03:00
|
|
|
capture: true,
|
2020-01-25 17:35:16 +03:00
|
|
|
passive: true
|
|
|
|
});
|
2020-07-05 12:54:25 +02:00
|
|
|
/* eslint-disable-next-line compat/compat */
|
2020-06-28 20:50:11 +03:00
|
|
|
dom.addEventListener(window, window.PointerEvent ? 'pointerup' : 'mouseup', onWindowMouseUp, {
|
2020-07-09 19:05:24 +03:00
|
|
|
capture: true,
|
2020-06-28 20:50:11 +03:00
|
|
|
passive: true
|
|
|
|
});
|
2020-05-04 12:44:12 +02:00
|
|
|
dom.addEventListener(window, 'touchstart', onWindowTouchStart, {
|
2020-07-09 19:05:24 +03:00
|
|
|
capture: true,
|
2020-01-25 17:35:16 +03:00
|
|
|
passive: true
|
|
|
|
});
|
2020-06-28 20:50:11 +03:00
|
|
|
['touchend', 'touchcancel'].forEach((event) => {
|
|
|
|
dom.addEventListener(window, event, onWindowTouchEnd, {
|
2020-07-09 19:05:24 +03:00
|
|
|
capture: true,
|
2020-06-28 20:50:11 +03:00
|
|
|
passive: true
|
|
|
|
});
|
|
|
|
});
|
2020-07-09 19:05:24 +03:00
|
|
|
dom.addEventListener(window, 'dragend', onWindowDragEnd, {
|
|
|
|
capture: true,
|
|
|
|
passive: true
|
|
|
|
});
|
2019-11-23 00:29:38 +09:00
|
|
|
} catch (e) {
|
2020-10-22 00:36:38 +01:00
|
|
|
appRouter.goHome();
|
2019-05-05 12:09:55 -04:00
|
|
|
}
|
2019-02-02 13:51:03 -05:00
|
|
|
});
|
2020-05-04 12:44:12 +02:00
|
|
|
view.addEventListener('viewbeforehide', function () {
|
2019-02-02 13:51:03 -05:00
|
|
|
if (statsOverlay) {
|
|
|
|
statsOverlay.enabled(false);
|
|
|
|
}
|
|
|
|
|
2020-06-28 23:46:27 +03:00
|
|
|
document.removeEventListener('keydown', onKeyDown);
|
|
|
|
dom.removeEventListener(document, 'keydown', onKeyDownCapture, {
|
2020-07-09 19:05:24 +03:00
|
|
|
capture: true,
|
|
|
|
passive: true
|
2019-02-02 13:51:03 -05:00
|
|
|
});
|
2020-07-05 12:54:25 +02:00
|
|
|
/* eslint-disable-next-line compat/compat */
|
2020-05-04 12:44:12 +02:00
|
|
|
dom.removeEventListener(window, window.PointerEvent ? 'pointerdown' : 'mousedown', onWindowMouseDown, {
|
2020-07-09 19:05:24 +03:00
|
|
|
capture: true,
|
2020-01-25 17:35:16 +03:00
|
|
|
passive: true
|
|
|
|
});
|
2020-07-05 12:54:25 +02:00
|
|
|
/* eslint-disable-next-line compat/compat */
|
2020-06-28 20:50:11 +03:00
|
|
|
dom.removeEventListener(window, window.PointerEvent ? 'pointerup' : 'mouseup', onWindowMouseUp, {
|
2020-07-09 19:05:24 +03:00
|
|
|
capture: true,
|
2020-06-28 20:50:11 +03:00
|
|
|
passive: true
|
|
|
|
});
|
2020-05-04 12:44:12 +02:00
|
|
|
dom.removeEventListener(window, 'touchstart', onWindowTouchStart, {
|
2020-07-09 19:05:24 +03:00
|
|
|
capture: true,
|
2020-01-25 17:35:16 +03:00
|
|
|
passive: true
|
|
|
|
});
|
2020-06-28 20:50:11 +03:00
|
|
|
['touchend', 'touchcancel'].forEach((event) => {
|
|
|
|
dom.removeEventListener(window, event, onWindowTouchEnd, {
|
2020-07-09 19:05:24 +03:00
|
|
|
capture: true,
|
2020-06-28 20:50:11 +03:00
|
|
|
passive: true
|
|
|
|
});
|
|
|
|
});
|
2020-07-09 19:05:24 +03:00
|
|
|
dom.removeEventListener(window, 'dragend', onWindowDragEnd, {
|
|
|
|
capture: true,
|
|
|
|
passive: true
|
|
|
|
});
|
2019-02-02 13:51:03 -05:00
|
|
|
stopOsdHideTimer();
|
2020-05-04 12:44:12 +02:00
|
|
|
headerElement.classList.remove('osdHeader');
|
|
|
|
headerElement.classList.remove('osdHeader-hidden');
|
2020-07-05 12:54:25 +02:00
|
|
|
/* eslint-disable-next-line compat/compat */
|
2020-05-04 12:44:12 +02:00
|
|
|
dom.removeEventListener(document, window.PointerEvent ? 'pointermove' : 'mousemove', onPointerMove, {
|
2019-02-02 13:51:03 -05:00
|
|
|
passive: true
|
|
|
|
});
|
|
|
|
inputManager.off(window, onInputCommand);
|
2020-09-08 02:05:02 -04:00
|
|
|
Events.off(playbackManager, 'playerchange', onPlayerChange);
|
2019-02-02 13:51:03 -05:00
|
|
|
releaseCurrentPlayer();
|
|
|
|
});
|
2020-05-04 12:44:12 +02:00
|
|
|
view.querySelector('.btnFullscreen').addEventListener('click', function () {
|
2019-02-02 13:51:03 -05:00
|
|
|
playbackManager.toggleFullscreen(currentPlayer);
|
|
|
|
});
|
2020-05-04 12:44:12 +02:00
|
|
|
view.querySelector('.btnPip').addEventListener('click', function () {
|
2019-02-02 13:51:03 -05:00
|
|
|
playbackManager.togglePictureInPicture(currentPlayer);
|
|
|
|
});
|
2020-05-04 12:44:12 +02:00
|
|
|
view.querySelector('.btnAirPlay').addEventListener('click', function () {
|
2020-01-10 11:31:03 -05:00
|
|
|
playbackManager.toggleAirPlay(currentPlayer);
|
|
|
|
});
|
2020-05-04 12:44:12 +02:00
|
|
|
view.querySelector('.btnVideoOsdSettings').addEventListener('click', onSettingsButtonClick);
|
|
|
|
view.addEventListener('viewhide', function () {
|
|
|
|
headerElement.classList.remove('hide');
|
2019-02-02 13:51:03 -05:00
|
|
|
});
|
2020-05-04 12:44:12 +02:00
|
|
|
view.addEventListener('viewdestroy', function () {
|
2019-02-02 13:51:03 -05:00
|
|
|
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
|
|
|
});
|
2020-07-19 10:40:41 +01:00
|
|
|
let lastPointerDown = 0;
|
2020-07-05 12:54:25 +02:00
|
|
|
/* eslint-disable-next-line compat/compat */
|
2020-05-04 12:44:12 +02:00
|
|
|
dom.addEventListener(view, window.PointerEvent ? 'pointerdown' : 'click', function (e) {
|
|
|
|
if (dom.parentWithClass(e.target, ['videoOsdBottom', 'upNextContainer'])) {
|
2019-02-02 13:51:03 -05:00
|
|
|
return void showOsd();
|
|
|
|
}
|
2019-02-02 10:20:27 -05:00
|
|
|
|
2020-07-19 10:40:41 +01:00
|
|
|
const pointerType = e.pointerType || (layoutManager.mobile ? 'touch' : 'mouse');
|
|
|
|
const now = new Date().getTime();
|
2019-02-02 10:20:27 -05:00
|
|
|
|
2019-02-02 13:51:03 -05:00
|
|
|
switch (pointerType) {
|
2020-05-04 12:44:12 +02:00
|
|
|
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
|
|
|
|
2020-05-04 12:44:12 +02:00
|
|
|
case 'mouse':
|
2019-11-23 00:29:38 +09:00
|
|
|
if (!e.button) {
|
2020-02-19 16:07:06 +01:00
|
|
|
if (playPauseClickTimeout) {
|
|
|
|
clearTimeout(playPauseClickTimeout);
|
|
|
|
playPauseClickTimeout = 0;
|
2020-02-09 16:26:55 +01:00
|
|
|
} else {
|
2020-02-20 11:23:08 +01:00
|
|
|
playPauseClickTimeout = setTimeout(function() {
|
2020-02-09 16:26:55 +01:00
|
|
|
playbackManager.playPause(currentPlayer);
|
|
|
|
showOsd();
|
2020-02-19 16:07:06 +01:00
|
|
|
playPauseClickTimeout = 0;
|
2020-02-09 16:26:55 +01:00
|
|
|
}, 300);
|
|
|
|
}
|
2019-11-23 00:29:38 +09:00
|
|
|
}
|
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
|
|
|
|
2020-12-27 22:19:28 +09:00
|
|
|
dom.addEventListener(view, 'dblclick', (e) => {
|
2020-12-27 22:16:01 +09:00
|
|
|
if (e.target !== view) return;
|
2020-12-26 14:32:56 +09:00
|
|
|
playbackManager.toggleFullscreen(currentPlayer);
|
|
|
|
});
|
2019-02-02 10:20:27 -05:00
|
|
|
|
2020-05-04 12:44:12 +02:00
|
|
|
view.querySelector('.buttonMute').addEventListener('click', function () {
|
2020-02-19 11:10:12 +03:00
|
|
|
playbackManager.toggleMute(currentPlayer);
|
2019-02-07 08:09:49 -05:00
|
|
|
});
|
2020-06-29 13:03:31 +03:00
|
|
|
|
|
|
|
nowPlayingVolumeSlider.addEventListener('input', (e) => {
|
|
|
|
playbackManager.setVolume(e.target.value, currentPlayer);
|
|
|
|
});
|
2019-03-30 22:11:39 +01:00
|
|
|
|
2020-05-04 12:44:12 +02:00
|
|
|
nowPlayingPositionSlider.addEventListener('change', function () {
|
2020-07-19 10:40:41 +01:00
|
|
|
const player = currentPlayer;
|
2019-02-02 13:51:03 -05:00
|
|
|
|
|
|
|
if (player) {
|
2020-07-19 10:40:41 +01:00
|
|
|
const newPercent = parseFloat(this.value);
|
2019-02-02 13:51:03 -05:00
|
|
|
|
|
|
|
if (enableProgressByTimeOfDay) {
|
2020-07-19 10:40:41 +01:00
|
|
|
let seekAirTimeTicks = newPercent / 100 * (programEndDateMs - programStartDateMs) * 1e4;
|
2019-02-02 13:51:03 -05:00
|
|
|
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) {
|
2020-07-19 10:40:41 +01:00
|
|
|
let ms = programEndDateMs - programStartDateMs;
|
2019-02-02 13:51:03 -05:00
|
|
|
ms /= 100;
|
|
|
|
ms *= value;
|
|
|
|
ms += programStartDateMs;
|
2020-05-04 12:44:12 +02:00
|
|
|
return '<h1 class="sliderBubbleText">' + getDisplayTimeWithoutAmPm(new Date(parseInt(ms)), true) + '</h1>';
|
2019-02-02 13:51:03 -05:00
|
|
|
}
|
|
|
|
|
2020-05-04 12:44:12 +02:00
|
|
|
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
|
|
|
if (!currentRuntimeTicks) {
|
2020-05-04 12:44:12 +02:00
|
|
|
return '--:--';
|
2019-02-02 13:51:03 -05:00
|
|
|
}
|
2019-02-02 10:20:27 -05:00
|
|
|
|
2020-07-19 10:40:41 +01:00
|
|
|
let ticks = currentRuntimeTicks;
|
2019-02-02 13:51:03 -05:00
|
|
|
ticks /= 100;
|
|
|
|
ticks *= value;
|
2020-07-19 10:40:41 +01:00
|
|
|
const 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) {
|
2020-10-17 19:08:56 +01:00
|
|
|
const html = getChapterBubbleHtml(ServerConnections.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
|
|
|
|
2020-05-04 12:44:12 +02:00
|
|
|
return '<h1 class="sliderBubbleText">' + datetime.getDisplayRunningTime(ticks) + '</h1>';
|
2019-02-02 13:51:03 -05:00
|
|
|
};
|
2019-02-02 10:20:27 -05:00
|
|
|
|
2020-05-04 12:44:12 +02:00
|
|
|
view.querySelector('.btnPreviousTrack').addEventListener('click', function () {
|
2019-02-02 13:51:03 -05:00
|
|
|
playbackManager.previousTrack(currentPlayer);
|
2018-10-23 01:05:09 +03:00
|
|
|
});
|
2020-05-04 12:44:12 +02: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
|
|
|
});
|
2020-05-04 12:44:12 +02:00
|
|
|
view.querySelector('.btnNextTrack').addEventListener('click', function () {
|
2019-02-02 13:51:03 -05:00
|
|
|
playbackManager.nextTrack(currentPlayer);
|
|
|
|
});
|
2020-05-04 12:44:12 +02:00
|
|
|
btnRewind.addEventListener('click', function () {
|
2019-02-02 13:51:03 -05:00
|
|
|
playbackManager.rewind(currentPlayer);
|
|
|
|
});
|
2020-05-04 12:44:12 +02:00
|
|
|
btnFastForward.addEventListener('click', function () {
|
2019-02-02 13:51:03 -05:00
|
|
|
playbackManager.fastForward(currentPlayer);
|
|
|
|
});
|
2020-05-04 12:44:12 +02:00
|
|
|
view.querySelector('.btnAudio').addEventListener('click', showAudioTrackSelection);
|
|
|
|
view.querySelector('.btnSubtitles').addEventListener('click', showSubtitleTrackSelection);
|
2019-02-02 13:51:03 -05:00
|
|
|
|
2020-09-25 09:44:30 +02:00
|
|
|
// Register to SyncPlay playback events and show big animated icon
|
|
|
|
const showIcon = (action) => {
|
|
|
|
let primary_icon_name = '';
|
|
|
|
let secondary_icon_name = '';
|
|
|
|
let animation_class = 'oneShotPulse';
|
|
|
|
let iconVisibilityTime = 1500;
|
|
|
|
const syncPlayIcon = view.querySelector('#syncPlayIcon');
|
|
|
|
|
|
|
|
switch (action) {
|
|
|
|
case 'schedule-play':
|
|
|
|
primary_icon_name = 'sync spin';
|
|
|
|
secondary_icon_name = 'play_arrow centered';
|
|
|
|
animation_class = 'infinitePulse';
|
|
|
|
iconVisibilityTime = -1;
|
|
|
|
hideOsd();
|
|
|
|
break;
|
|
|
|
case 'unpause':
|
|
|
|
primary_icon_name = 'play_circle_outline';
|
|
|
|
break;
|
|
|
|
case 'pause':
|
|
|
|
primary_icon_name = 'pause_circle_outline';
|
|
|
|
showOsd();
|
|
|
|
break;
|
|
|
|
case 'seek':
|
|
|
|
primary_icon_name = 'update';
|
|
|
|
animation_class = 'infinitePulse';
|
|
|
|
iconVisibilityTime = -1;
|
|
|
|
break;
|
|
|
|
case 'buffering':
|
|
|
|
primary_icon_name = 'schedule';
|
|
|
|
animation_class = 'infinitePulse';
|
|
|
|
iconVisibilityTime = -1;
|
|
|
|
break;
|
|
|
|
case 'wait-pause':
|
|
|
|
primary_icon_name = 'schedule';
|
|
|
|
secondary_icon_name = 'pause shifted';
|
|
|
|
animation_class = 'infinitePulse';
|
|
|
|
iconVisibilityTime = -1;
|
|
|
|
break;
|
|
|
|
case 'wait-unpause':
|
|
|
|
primary_icon_name = 'schedule';
|
|
|
|
secondary_icon_name = 'play_arrow shifted';
|
|
|
|
animation_class = 'infinitePulse';
|
|
|
|
iconVisibilityTime = -1;
|
|
|
|
break;
|
|
|
|
default: {
|
|
|
|
syncPlayIcon.style.visibility = 'hidden';
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
syncPlayIcon.setAttribute('class', 'syncPlayIconCircle ' + animation_class);
|
|
|
|
|
|
|
|
const primaryIcon = syncPlayIcon.querySelector('.primary-icon');
|
|
|
|
primaryIcon.setAttribute('class', 'primary-icon material-icons ' + primary_icon_name);
|
|
|
|
|
|
|
|
const secondaryIcon = syncPlayIcon.querySelector('.secondary-icon');
|
|
|
|
secondaryIcon.setAttribute('class', 'secondary-icon material-icons ' + secondary_icon_name);
|
|
|
|
|
|
|
|
const clone = syncPlayIcon.cloneNode(true);
|
|
|
|
clone.style.visibility = 'visible';
|
|
|
|
syncPlayIcon.parentNode.replaceChild(clone, syncPlayIcon);
|
|
|
|
|
|
|
|
if (iconVisibilityTime < 0) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
setTimeout(() => {
|
|
|
|
clone.style.visibility = 'hidden';
|
|
|
|
}, iconVisibilityTime);
|
|
|
|
};
|
|
|
|
|
|
|
|
Events.on(SyncPlay.Manager, 'enabled', (event, enabled) => {
|
|
|
|
if (enabled) {
|
|
|
|
// SyncPlay enabled
|
|
|
|
} else {
|
|
|
|
const syncPlayIcon = view.querySelector('#syncPlayIcon');
|
|
|
|
syncPlayIcon.style.visibility = 'hidden';
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
Events.on(SyncPlay.Manager, 'notify-osd', (event, action) => {
|
|
|
|
showIcon(action);
|
|
|
|
});
|
|
|
|
|
|
|
|
Events.on(SyncPlay.Manager, 'group-state-update', (event, state, reason) => {
|
|
|
|
if (state === 'Playing' && reason === 'Unpause') {
|
|
|
|
showIcon('schedule-play');
|
|
|
|
} else if (state === 'Playing' && reason === 'Ready') {
|
|
|
|
showIcon('schedule-play');
|
|
|
|
} else if (state === 'Paused' && reason === 'Pause') {
|
|
|
|
showIcon('pause');
|
|
|
|
} else if (state === 'Paused' && reason === 'Ready') {
|
|
|
|
showIcon('clear');
|
|
|
|
} else if (state === 'Waiting' && reason === 'Seek') {
|
|
|
|
showIcon('seek');
|
|
|
|
} else if (state === 'Waiting' && reason === 'Buffer') {
|
|
|
|
showIcon('buffering');
|
|
|
|
} else if (state === 'Waiting' && reason === 'Pause') {
|
|
|
|
showIcon('wait-pause');
|
|
|
|
} else if (state === 'Waiting' && reason === 'Unpause') {
|
|
|
|
showIcon('wait-unpause');
|
|
|
|
}
|
|
|
|
});
|
2020-07-19 10:40:41 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/* eslint-enable indent */
|