obscreen/views/player/player.jinja.html
2024-05-21 20:35:46 +02:00

215 lines
7.9 KiB
HTML
Executable File

<!DOCTYPE html>
<html lang="fr">
<head>
<title>Obscreen</title>
<meta name="robots" content="noindex, nofollow">
<meta name="google" content="notranslate">
<link rel="shortcut icon" href="{{ STATIC_PREFIX }}/favicon.ico">
{% if slide_animation_enabled.eval() %}
<link rel="stylesheet" href="{{ STATIC_PREFIX }}css/lib/animate.min.css" />
{% endif %}
<style>
html, body { margin: 0; padding: 0; height: 100%; overflow: hidden; background-color: white; display: flex; flex-direction: row; justify-content: center; align-items: center; }
.slide { display: flex; flex-direction: row; justify-content: center; align-items: center; background: black; }
.slide, iframe { position: absolute; top: 0; left: 0; width: 100%; height: 100%; border: none; padding-top: 0; box-sizing: border-box; -moz-box-sizing: border-box; -webkit-box-sizing: border-box; }
.slide iframe { background: white; }
.slide img { height: 100%; }
</style>
<script type="application/javascript" src="{{ STATIC_PREFIX }}js/lib/is-cron-now.js"></script>
</head>
<body>
<div id="FirstSlide" class="slide" style="z-index: 1000;">
{% if default_slide_duration.eval() > 0 %}
<iframe src="/player/default"></iframe>
{% endif %}
</div>
<div id="SecondSlide" class="slide" style="z-index: 500;">
{% if default_slide_duration.eval() > 0 %}
<iframe src="/player/default"></iframe>
{% endif %}
</div>
<script type="text/javascript">
var items = {{items | safe}};
var duration = {{ default_slide_duration.eval() * 1000 }};
var playlistCheck = {{ polling_interval.eval() * 1000 }};
var curItemIndex = 0;
var needHardRefresh = null;
var nextReady = true;
var itemCheck = setInterval(function () {
fetch('player/playlist').then(function(response) {
if (response.ok) {
return response.json();
}
}).then(function(data) {
items = data;
if (needHardRefresh === null) {
needHardRefresh = items.hard_refresh_request;
} else if (needHardRefresh != items.hard_refresh_request) {
document.location.reload();
}
}).catch(function(err) {
console.error(err);
});
}, playlistCheck);
var animate = {{ 'true' if slide_animation_enabled.eval() else 'false' }};
var animate_transitions = [
"animate__{{ slide_animation_entrance_effect.eval()|default("fadeIn") }}",
"animate__{{ slide_animation_exit_effect.eval()|default("none") }}"
];
var animate_speed = "animate__{{ slide_animation_speed.eval()|default("normal") }}";
var firstSlide = document.getElementById('FirstSlide');
var secondSlide = document.getElementById('SecondSlide');
var previousSlide = secondSlide;
var curSlide = firstSlide;
var cronState = {
active: false,
itemIndex: null,
interval: null
};
var cronTick = function() {
if ((new Date()).getSeconds() != 0) {
return;
}
for (var i = 0; i < items.cron.length; i++) {
var item = items.cron[i];
if (cron.isActive(item.cron_schedule) && cronState.itemIndex != i) {
cronState.active = true;
cronState.itemIndex = i;
var callbackReady = function (onSlideStart) {
onSlideStart();
moveToSlide(curSlide.attributes['id'].value, item);
var move = function () {
if (nextReady) {
curItemIndex = (curItemIndex + 1) === items.loop.length ? 0 : curItemIndex + 1;
cronState.active = false;
cronState.itemIndex = null;
} else {
setTimeout(move, 1000);
}
}
setTimeout(move, item.duration * 1000);
};
loadContent(curSlide, callbackReady, item);
}
}
};
function main() {
preloadSlide('SecondSlide', items.loop[curItemIndex])
cronState.interval = setInterval(cronTick, 1000);
}
function preloadSlide(slide, item) {
var element = document.getElementById(slide);
var callbackReady = function (onSlideStart) {
var move = function () {
if (nextReady && !cronState.active) {
moveToSlide(slide, item);
onSlideStart();
} else {
setTimeout(move, 1000);
}
}
setTimeout(move, duration);
};
loadContent(element, callbackReady, item);
}
function moveToSlide(slide, item) {
curSlide = document.getElementById(slide);
previousSlide = curSlide == firstSlide ? secondSlide : firstSlide;
duration = item.duration * 1000;
curItemIndex = (curItemIndex + 1) === items.loop.length ? 0 : curItemIndex + 1;
curSlide.style.zIndex = 1000;
previousSlide.style.zIndex = 500;
if (animate) {
curSlide.classList.add('animate__animated', animate_transitions[0], animate_speed);
curSlide.onanimationend = () => {
curSlide.classList.remove(animate_transitions[0], animate_speed);
preloadSlide(previousSlide.attributes['id'].value, items.loop[curItemIndex]);
};
previousSlide.classList.add('animate__animated', animate_transitions[1], animate_speed);
previousSlide.onanimationend = () => {
previousSlide.classList.remove(animate_transitions[1], animate_speed);
};
} else {
preloadSlide(previousSlide.attributes['id'].value, items.loop[curItemIndex]);
}
}
function loadContent(element, callbackReady, item) {
switch (item.type) {
case 'url':
loadUrl(element, callbackReady, item);
break;
case 'picture':
loadPicture(element, callbackReady, item);
break;
case 'video':
loadVideo(element, callbackReady, item);
break;
case 'youtube':
loadYoutube(element, callbackReady, item);
break;
default:
loadUrl(element, callbackReady, item);
break;
}
}
function loadUrl(element, callbackReady, item, delay) {
element.innerHTML = `<iframe src="${item.location}"></iframe>`;
callbackReady(function () {});
}
function loadPicture(element, callbackReady, item) {
element.innerHTML = `<img src="${item.location}" alt="" />`;
callbackReady(function () {});
}
function loadYoutube(element, callbackReady, item) {
element.innerHTML = ``;
callbackReady(function () {});
setTimeout(function() {
element.innerHTML = `<iframe src="https://www.youtube.com/embed/${item.location}?version=3&autoplay=1&showinfo=0&controls=0&modestbranding=1&fs=1&rel=0" frameborder="0" allow="autoplay" allowfullscreen></iframe>`;
}, Math.max(100, duration - 2000));
}
function loadVideo(element, callbackReady, item) {
element.innerHTML = `<video><source src=${item.location} type="video/mp4" /></video>`;
var video = element.querySelector('video');
video.addEventListener('loadedmetadata', function () {
item.duration = Math.ceil(video.duration);
});
var onSlideStart = function () {
nextReady = false;
video.play();
video.addEventListener('ended', function () {
nextReady = true;
});
setTimeout(function () {
nextReady = true;
}, Math.ceil(item.duration * 1.5));
};
callbackReady(onSlideStart);
}
main();
</script>
</body>
</html>