Files
WLED/wled00/data/liveview.htm
Damian Schneider c4850aed08 Adding DDP over WS, moving duplicate WS-connection to common.js (#4997)
- Enabling DDP over WebSocket: this allows for UI or html tools to stream data to the LEDs much faster than through the JSON API.
- first byte of data array is used to determine protocol for future use
- Moved the duplicate function to establish a WS connection from the live-view htm files to common.js
- add better safety check for DDP: prevent OOB reads of buffer
2025-10-21 19:41:57 +02:00

87 lines
2.4 KiB
HTML

<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1">
<meta charset="utf-8">
<meta name="theme-color" content="#222222">
<title>WLED Live Preview</title>
<style>
body {
margin: 0;
}
#canv {
background: black;
filter: brightness(175%);
width: 100%;
height: 100%;
position: absolute;
}
</style>
<script src="common.js"></script>
<script>
var ws;
var tmout = null;
var c;
var ctx;
function draw(start, skip, leds, fill) {
c.width = d.documentElement.clientWidth;
let w = (c.width * skip) / (leds.length - start);
for (let i = start; i < leds.length; i += skip) {
ctx.fillStyle = fill(leds,i);
ctx.fillRect(Math.round((i - start) * w / skip), 0, Math.ceil(w), c.height);
}
}
function update() { // via HTTP (/json/live)
if (d.hidden) {
clearTimeout(tmout);
tmout = setTimeout(update, 250);
return;
}
fetch('./json/live')
.then(res => {
if (!res.ok) {
clearTimeout(tmout);
tmout = setTimeout(update, 2500);
}
return res.json();
})
.then(json => {
draw(0, 1, json.leds, (a,i) => "#" + ((a[i].length > 6) ? a[i].substring(2) : a[i]));
clearTimeout(tmout);
tmout = setTimeout(update, 40);
})
.catch((error)=>{
//console.error("Peek HTTP error:",error);
clearTimeout(tmout);
tmout = setTimeout(update, 2500);
})
}
function S() { // Startup function (onload)
c = d.getElementById('canv');
ctx = c.getContext('2d');
if (window.location.href.indexOf("?ws") == -1) {update(); return;}
// Initialize WebSocket connection
ws = connectWs(function () {
//console.info("Peek WS open");
ws.send('{"lv":true}');
});
ws.addEventListener('message', (e) => {
try {
if (toString.call(e.data) === '[object ArrayBuffer]') {
let leds = new Uint8Array(e.data);
if (leds[0] != 76) return; //'L'
// leds[1] = 1: 1D; leds[1] = 2: 1D/2D (leds[2]=w, leds[3]=h)
draw(leds[1]==2 ? 4 : 2, 3, leds, (a,i) => `rgb(${a[i]},${a[i+1]},${a[i+2]})`);
}
} catch (err) {
console.error("Peek WS error:",err);
}
});
}
</script>
</head>
<body onload="S()">
<canvas id="canv"></canvas>
</body>
</html>