optimize ambient mode

Reviewed-on: https://codeberg.org/ashley/poke/pulls/73
This commit is contained in:
Ashley //// 2024-03-20 16:05:53 +00:00
commit c3deb7947d
2 changed files with 79 additions and 19 deletions

View file

@ -1075,7 +1075,8 @@ display: block; !important;" autoplay controls>
</video> </video>
<% if (!a) { %> <% if (!a) { %>
<canvas width="12" height="6" id="ambient-canvas"></canvas> <canvas width="12" height="6" class="ambient-canvas" id="ambient-canvas-1"></canvas>
<canvas width="12" height="6" class="ambient-canvas" id="ambient-canvas-2"></canvas>
<% } %> <% } %>
@ -1930,29 +1931,43 @@ if (/[?&]autoplay=/.test(location.search)) {
<script> <script>
const AMvideo = document.getElementById("video") const AMvideo = document.getElementById("video")
const canvas = document.getElementById("ambient-canvas") const oddCanvas = document.getElementById("ambient-canvas-1")
const ctx = canvas.getContext("2d") const evenCanvas = document.getElementById("ambient-canvas-2")
const oddCtx = oddCanvas.getContext("2d")
const evenCtx = evenCanvas.getContext("2d")
let requestId; const frameIntervalMs = 200
let lastDrawTime = 0; // Timestamp of the last draw request const canvasOpacity = "0.4"
const loop = () => {
const now = performance.now(); let intervalId
const elapsed = now - lastDrawTime; let oddFrame = true
if (elapsed >= (1000 / 30)) { const drawFrame = () => {
lastDrawTime = now; if (oddFrame) {
ctx.drawImage(AMvideo, 0, 0, canvas.width, canvas.height); oddCtx.drawImage(AMvideo, 0, 0, oddCanvas.width, oddCanvas.height)
transitionToOddCanvas()
} else {
evenCtx.drawImage(AMvideo, 0, 0, evenCanvas.width, evenCanvas.height)
transitionToEvenCanvas()
} }
oddFrame = !oddFrame
requestId = window.requestAnimationFrame(loop);
}; };
const transitionToOddCanvas = () => {
oddCanvas.style.opacity = canvasOpacity
evenCanvas.style.opacity = "0"
}
const transitionToEvenCanvas = () => {
evenCanvas.style.opacity = canvasOpacity
oddCanvas.style.opacity = "0"
}
const drawStart = () => { const drawStart = () => {
requestId = window.requestAnimationFrame(loop) intervalId = window.setInterval(drawFrame, frameIntervalMs)
} }
const drawPause = () => { const drawPause = () => {
window.cancelAnimationFrame(requestId) if (intervalId) window.clearInterval(intervalId)
requestId = undefined
} }
const init = () => { const init = () => {
@ -1960,12 +1975,15 @@ const init = () => {
AMvideo.addEventListener("play", drawStart, false) AMvideo.addEventListener("play", drawStart, false)
AMvideo.addEventListener("pause", drawPause, false) AMvideo.addEventListener("pause", drawPause, false)
AMvideo.addEventListener("ended", drawPause, false) AMvideo.addEventListener("ended", drawPause, false)
oddCanvas.style.transition = evenCanvas.style.transition = `opacity ${frameIntervalMs}ms`
} }
const cleanup = () => { const cleanup = () => {
AMvideo.removeEventListener("play", drawStart) AMvideo.removeEventListener("play", drawStart)
AMvideo.removeEventListener("pause", drawPause) AMvideo.removeEventListener("pause", drawPause)
AMvideo.removeEventListener("ended", drawPause) AMvideo.removeEventListener("ended", drawPause)
drawPause();
} }
window.addEventListener("load", init) window.addEventListener("load", init)
@ -1977,7 +1995,7 @@ window.addEventListener("unload", cleanup)
z-index: 0; z-index: 0;
} }
.popup {z-index: 1} .popup {z-index: 1}
#ambient-canvas { .ambient-canvas {
width: 100%; width: 100%;
height: calc(100% - 18px); height: calc(100% - 18px);
position: absolute; position: absolute;
@ -1985,7 +2003,6 @@ window.addEventListener("unload", cleanup)
border-radius: 18px; border-radius: 18px;
filter: blur(20px); filter: blur(20px);
transform: scale(1.1); transform: scale(1.1);
opacity: 0.4;
z-index: -1; z-index: -1;
} }
</style> </style>

View file

@ -135,6 +135,49 @@ app.get("/avatars/:v", async function (req, res) {
res.send(body); res.send(body);
} catch {} } catch {}
}); });
app.use("/sb/i/:v/:imagePath/:img", async function (req, res) {
const { v, imagePath, img } = req.params;
const { sqp, xywh } = req.query;
const sighMatch = req.url.match(/&amp;sigh=([^&#]+)/);
const sigh = sighMatch ? sighMatch[1] : undefined;
const url = `https://yt.miruku.cafe/sb/i/${v}/${imagePath}/${img}?sqp=${sqp}&sigh=${sigh}&xywh=${req.query.xywh}`;
try {
let f = await modules.fetch(url + `?cachefixer=${btoa(Date.now())}`, {
method: req.method,
});
f.body.pipe(res);
console.log(url)
} catch (error) {
console.error("Error fetching image:", error);
res.status(500).send("Error fetching image");
}
});
app.get("/api/storyboards", async (req, res) => {
const { fetch } = await import("undici");
const id = req.query.v;
const l = req.query.h;
try {
let url = `https://yt.miruku.cafe/api/v1/storyboards/${id}?width=320&height=180`;
let f = await fetch(url);
let body = await f.text();
body = body.replace(/#xywh=(\d+),(\d+),(\d+),(\d+)/g, (match, x, y, w, h) => {
return `&xywh=${x},${y},${w},${h}`;
});
res.send(body);
} catch {}
});
app.get("/feeds/videos.xml", async (req, res) => { app.get("/feeds/videos.xml", async (req, res) => {
const id = req.query.channel_id; const id = req.query.channel_id;