mirror of
https://github.com/nestriness/nestri.git
synced 2025-12-12 08:45:38 +02:00
try to work with capacitor
This commit is contained in:
157
packages/play-standalone/src/pages/play.astro
Normal file
157
packages/play-standalone/src/pages/play.astro
Normal file
@@ -0,0 +1,157 @@
|
||||
---
|
||||
import DefaultLayout from "../layouts/DefaultLayout.astro";
|
||||
|
||||
// Passing of environment variables to the client side
|
||||
// gotta love node and it's ecosystem..
|
||||
const envs_map: Map<string, string | undefined> = new Map();
|
||||
import { PEER_URL, getSecret } from "astro:env/server";
|
||||
if (PEER_URL) {
|
||||
envs_map.set("PEER_URL", getSecret("PEER_URL"));
|
||||
}
|
||||
|
||||
let envs: string = "";
|
||||
if (envs_map.size > 0) {
|
||||
envs = JSON.stringify(Array.from(envs_map.entries()));
|
||||
}
|
||||
---
|
||||
|
||||
<DefaultLayout>
|
||||
<h1 id="offlineText" class="offline">Offline</h1>
|
||||
<h1 id="loadingText" class="loading">Warming up the GPU...</h1>
|
||||
<canvas id="playCanvas" class="playCanvas"></canvas>
|
||||
<div id="ENVS" data-envs={envs}></div>
|
||||
</DefaultLayout>
|
||||
|
||||
<script>
|
||||
import { Mouse, Keyboard, WebRTCStream } from "@nestri/input";
|
||||
const ENVS = document.getElementById("ENVS")!.dataset.envs as string;
|
||||
let ENVS_MAP: Map<string, string | undefined> | null = null;
|
||||
if (ENVS && ENVS.length > 0) {
|
||||
ENVS_MAP = new Map(JSON.parse(ENVS));
|
||||
console.debug("ENVS_MAP:", ENVS_MAP);
|
||||
}
|
||||
|
||||
// Elements
|
||||
const canvas = document.getElementById("playCanvas")! as HTMLCanvasElement;
|
||||
const offlineText = document.getElementById("offlineText")! as HTMLHeadingElement;
|
||||
const loadingText = document.getElementById("loadingText")! as HTMLHeadingElement;
|
||||
|
||||
const room = window.location.hash.substring(1);
|
||||
if (!room || room.length <= 0) {
|
||||
throw new Error("Room parameter is required in URL hash");
|
||||
}
|
||||
|
||||
offlineText.style.display = "flex";
|
||||
loadingText.style.display = "none";
|
||||
|
||||
// Get query parameter "peerURL" from the URL
|
||||
let peerURL = new URLSearchParams(window.location.search).get("peerURL");
|
||||
if (!peerURL || peerURL.length <= 0) {
|
||||
peerURL = (ENVS_MAP && ENVS_MAP.get("PEER_URL")) ?? "/dnsaddr/relay.dathorse.com/p2p/12D3KooWPK4v5wKYNYx9oXWjqLM8Xix6nm13o91j1Feqq98fLBsw";
|
||||
}
|
||||
|
||||
console.debug("Using Peer URL:", peerURL);
|
||||
|
||||
// Stream
|
||||
const stream = new WebRTCStream(peerURL, room, async (mediaStream) => {
|
||||
if (mediaStream && video.srcObject === null) {
|
||||
video.srcObject = mediaStream;
|
||||
offlineText.style.display = "none";
|
||||
loadingText.style.display = "flex";
|
||||
|
||||
await video.play().catch((e) => {
|
||||
console.error("Failed to play video:", e);
|
||||
});
|
||||
|
||||
canvas.width = video.videoWidth;
|
||||
canvas.height = video.videoHeight;
|
||||
const ctx = canvas.getContext("2d");
|
||||
const renderer = () => {
|
||||
if (ctx && video.srcObject) {
|
||||
ctx.drawImage(video, 0, 0);
|
||||
video.requestVideoFrameCallback(renderer);
|
||||
}
|
||||
};
|
||||
video.requestVideoFrameCallback(renderer);
|
||||
loadingText.style.display = "none";
|
||||
}
|
||||
});
|
||||
const video = document.createElement("video") as HTMLVideoElement;
|
||||
|
||||
// Input
|
||||
let nestriMouse: Mouse | null = null;
|
||||
let nestriKeyboard: Keyboard | null = null;
|
||||
|
||||
document.addEventListener("pointerlockchange", () => {
|
||||
if (document.pointerLockElement === canvas) {
|
||||
if (nestriMouse || nestriKeyboard)
|
||||
return;
|
||||
|
||||
nestriMouse = new Mouse({
|
||||
canvas: canvas,
|
||||
webrtc: stream,
|
||||
});
|
||||
nestriKeyboard = new Keyboard({
|
||||
canvas: canvas,
|
||||
webrtc: stream,
|
||||
});
|
||||
} else {
|
||||
if (nestriMouse) {
|
||||
nestriMouse.dispose();
|
||||
nestriMouse = null;
|
||||
}
|
||||
if (nestriKeyboard) {
|
||||
nestriKeyboard.dispose();
|
||||
nestriKeyboard = null;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
const lockPlay = async function () {
|
||||
await canvas.requestFullscreen();
|
||||
await canvas.requestPointerLock();
|
||||
|
||||
if (document.fullscreenElement !== null) {
|
||||
if ("keyboard" in navigator && "lock" in (navigator.keyboard as any)) {
|
||||
const keys = [
|
||||
"AltLeft", "AltRight", "Tab", "Escape",
|
||||
"ContextMenu", "MetaLeft", "MetaRight"
|
||||
];
|
||||
|
||||
try {
|
||||
await (navigator.keyboard as any).lock(keys);
|
||||
console.log("Keyboard lock acquired");
|
||||
} catch (e) {
|
||||
console.warn("Keyboard lock failed:", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
canvas.addEventListener("click", lockPlay);
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.playCanvas {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
max-height: 100vh;
|
||||
object-fit: contain;
|
||||
aspect-ratio: 16 / 9;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.offline, .loading {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
align-items: center;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
color: lightgray;
|
||||
font-size: 1.5rem;
|
||||
line-height: 2rem;
|
||||
font-weight: 600;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user