init
This commit is contained in:
@@ -0,0 +1,81 @@
|
||||
<!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>
|
||||
Reference in New Issue
Block a user