2023-10-12 01:45:07 -07:00

147 lines
3.6 KiB
HTML

<!DOCTYPE html>
<html onclick="videoplayer.muted = false">
<head>
<link href="https://fonts.googleapis.com/css2?family=Noto+Sans+Symbols+2&display=swap" rel="stylesheet" />
<style>
body {
margin: 0;
background-color: black;
}
#videoplayer {
max-width: 100%;
max-height: 100%;
transform: translate(-50%, -50%);
position: absolute;
top: 50%;
left: 50%;
}
#mousie_layer {
user-select: none;
position: fixed;
top: 0%;
left: 0%;
width: 100%;
height: 100%;
}
.mousie {
position: fixed;
user-select: none;
}
</style>
</head>
<body>
<video id="videoplayer"></video>
<div id="mousie_layer">
<template id="mousie_template">
<div class="mousie">
<span style='font-family: "Noto Sans Symbols 2"; color: gray;'>🮰</span>
</div>
</template>
</div>
<script>
var playlist;
async function nowPlaying() {
if (!playlist || Date.now() > playlist.timestamp + playlist.totalDuration*1000) {
playlist = await fetch("playlist").then(res => res.json());
}
for (var i = 0, pastDurations = 0; i < playlist.videos.length; i++) {
var video = playlist.videos[i];
var videoDurationMs = video.duration * 1000;
if (Date.now() < playlist.timestamp + pastDurations + videoDurationMs) {
break;
}
pastDurations += videoDurationMs;
}
return {
name: video.name,
position: (Date.now() - pastDurations - playlist.timestamp) / 1000
};
}
async function sync(force) {
var {name, position} = await nowPlaying();
var src = `videos/${encodeURIComponent(name)}`;
if (!videoplayer.src.endsWith(src)) {
console.debug("change src", videoplayer.src, "to", src);
videoplayer.src = src;
videoplayer.load();
}
console.debug("desync", Math.abs(videoplayer.currentTime - position) * 1000, "ms");
if (force || Math.abs(position - videoplayer.currentTime) >= 0.5) {
console.debug("change pos", videoplayer.currentTime, "to", position);
console.time("set pos");
videoplayer.currentTime = position;
console.timeEnd("set pos");
}
if (videoplayer.paused) try {
await videoplayer.play();
} catch (error) {
videoplayer.muted = true;
await videoplayer.play();
}
}
sync();
setInterval(sync, 5000);
videoplayer.addEventListener("ended", () => {
console.debug("ended");
sync();
});
</script>
<script> // mousies
var ws;
(function createWs() {
ws = new WebSocket(location.href.replace('http','ws'));
ws.binaryType = "arraybuffer";
ws.onmessage = evt => {
if (typeof evt.data == "string") {
switch (evt.data[0]) {
case "join":
break;
case "gone":
document.getElementById("mousie"+evt.data[1])?.remove();
break;
case "type":
break;
}
} else {
var dv = new DataView(evt.data);
var id = dv.getUint16(0, true);
var x = dv.getUint16(1, true);
var y = dv.getUint16(2, true);
//console.debug(id, x, y);
var mousie_element = document.getElementById("mousie"+id);
if (!mousie_element) {
mousie_element = mousie_template.content.firstElementChild.cloneNode(true);
mousie_element.id = "mousie"+id;
mousie_layer.appendChild(mousie_element);
}
mousie_element.style.left = (x / 65535 * innerWidth) + "px";
mousie_element.style.top = (y / 65535 * innerHeight) + "px";
}
};
ws.onclose = () => {
setTimeout(createWs, 5000);
};
})();
onmousemove = evt => {
if (ws.readyState != WebSocket.OPEN) return;
var d = new Uint16Array([
evt.pageX / innerWidth * 65535,
evt.pageY / innerHeight * 65535
]);
ws.send(d);
};
</script>
</body>
</html>