Files
2026-05-30 00:08:59 +05:00

82 lines
3.6 KiB
HTML
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!doctype html>
<html lang="ru">
<head>
<meta charset="utf-8">
<title>hevc.js Worker (OffscreenCanvas) — CoRE.Vision</title>
<style>
body { background:#0d0d0d; color:#ddd; font:13px system-ui,Arial; margin:0; padding:12px; }
#cv { background:#000; border:1px solid #333; display:block; margin:10px 0; width:100%; max-width:900px; height:auto; }
#log { white-space:pre-wrap; font:12px Consolas,monospace; color:#9f9; max-height:240px; overflow:auto; }
button { font:13px system-ui; padding:4px 10px; }
#stat { color:#ffd479; font-weight:bold; margin-left:12px; }
</style>
</head>
<body>
<div>
<button id="gomain">▶ main 3200×1800</button>
<button id="gosub">▶ sub 640×360</button>
<button id="stop">⏹ Stop</button>
<span id="stat"></span>
</div>
<canvas id="cv" width="1600" height="900"></canvas>
<div id="log"></div>
<script>
const logEl = document.getElementById("log"), statEl = document.getElementById("stat");
const log = (...a) => { logEl.textContent += a.map((x) => typeof x === "object" ? JSON.stringify(x) : String(x)).join(" ") + "\n"; logEl.scrollTop = 1e9; console.log("[hevcw]", ...a); };
window.onerror = (m, s, l) => log("‼ onerror", m, "@", l);
let worker = null, ws = null;
function stop() {
try { ws && ws.close(); } catch (e) {} ws = null;
if (worker) { try { worker.postMessage({ type: "stop" }); } catch (e) {} worker.terminate(); worker = null; }
statEl.textContent = "";
}
function start(stream) {
stop();
// canvas можно отдать в OffscreenCanvas только один раз → пересоздаём элемент при каждом старте
const old = document.getElementById("cv");
const cv = document.createElement("canvas");
cv.id = "cv";
cv.width = stream === "main" ? 1600 : 640;
cv.height = stream === "main" ? 900 : 360;
old.replaceWith(cv);
const off = cv.transferControlToOffscreen();
worker = new Worker("/static/vendor/hevcjs/hevc-player-worker.js", { type: "module" });
worker.onmessage = (e) => {
const m = e.data;
if (m.type === "ready") { log("worker ready → открываю WS"); openWS(stream); }
else if (m.type === "stat") { statEl.textContent = "декод/показ = " + m.fps + "/с"; if (m.fps) log("fps≈", m.fps); }
else if (m.type === "err") { log("‼ worker:", m.msg); }
};
worker.onerror = (e) => log("‼ worker.onerror:", e.message, "@", (e.filename || "") + ":" + (e.lineno || ""));
log("init worker (canvas " + cv.width + "x" + cv.height + ")");
worker.postMessage({
type: "init",
canvas: off,
wasmUrl: "/static/vendor/hevcjs/hevc-decode.esm.js",
wasmBinaryUrl: "/static/vendor/hevcjs/dist/wasm/hevc-decode.wasm",
}, [off]);
}
function openWS(stream) {
const proto = location.protocol === "https:" ? "wss" : "ws";
const url = `${proto}://${location.host}/api/cameras/cam32/flv?stream=${stream}`;
log("WS →", url);
ws = new WebSocket(url); ws.binaryType = "arraybuffer";
ws.onopen = () => log("WS open");
ws.onmessage = (e) => { if (worker) worker.postMessage({ type: "data", buf: e.data }, [e.data]); };
ws.onclose = (ev) => log("WS closed", ev.code);
ws.onerror = () => log("WS error");
}
document.getElementById("gomain").onclick = () => start("main");
document.getElementById("gosub").onclick = () => start("sub");
document.getElementById("stop").onclick = stop;
log("загружено. secure=", isSecureContext, "| COI=", crossOriginIsolated);
</script>
</body>
</html>