frontend: stream and fullscreen cleanup

This commit is contained in:
2025-08-09 14:22:34 -06:00
parent 9f9bb68e22
commit d4777fcf08
2 changed files with 81 additions and 80 deletions
+8 -2
View File
@@ -12,13 +12,19 @@
let loading = $state(true); let loading = $state(true);
let fullscreen = $state(false); let fullscreen = $state(false);
let gameplayView: HTMLDivElement; let gameplayView: HTMLDivElement;
let gameplayCanvas: HTMLCanvasElement;
async function startStream() { async function startStream() {
console.log(`Connecting to stream at ${url} with cert_hash ${certHash}`); console.log(`Connecting to stream at ${url} with cert_hash ${certHash}`);
await streamUrl(url, certHash); await streamUrl(url, certHash, gameplayCanvas);
} }
async function requestFullscreen() { async function requestFullscreen() {
// Update fullscreen var if fullscreen was exited outside our control
if (document.fullscreenElement == null) {
fullscreen = false;
}
if (fullscreen) { if (fullscreen) {
await document.exitFullscreen(); await document.exitFullscreen();
fullscreen = false; fullscreen = false;
@@ -36,7 +42,7 @@
</script> </script>
<div id="gameplay-view" class="gameplay-view" bind:this={gameplayView}> <div id="gameplay-view" class="gameplay-view" bind:this={gameplayView}>
<canvas id="gamestream-canvas" class="gamestream-canvas"></canvas> <canvas id="gamestream-canvas" class="gamestream-canvas" bind:this={gameplayCanvas}></canvas>
<StreamUi fullscreenFunc={requestFullscreen}></StreamUi> <StreamUi fullscreenFunc={requestFullscreen}></StreamUi>
</div> </div>
+23 -28
View File
@@ -26,12 +26,8 @@ type DecodeUnitPacket = {
DecodeUnit: DecodeUnit DecodeUnit: DecodeUnit
} }
async function connectToUrl(url: string, certHash: Uint8Array): Promise<WebTransport> {
console.log('Hash: ', certHash);
export async function streamUrl(url: string, cert_hash: Array<number>) {
const buffer = new Uint8Array(cert_hash);
console.log('Hash: ', buffer);
try {
console.log(`Connecting to stream`); console.log(`Connecting to stream`);
// Check if WebTransport is supported // Check if WebTransport is supported
@@ -39,12 +35,11 @@ export async function streamUrl(url: string, cert_hash: Array<number>) {
throw new Error('WebTransport is not supported in this browser'); throw new Error('WebTransport is not supported in this browser');
} }
//const url = new URL();
const transport = new WebTransport(url, { const transport = new WebTransport(url, {
serverCertificateHashes: [ serverCertificateHashes: [
{ {
algorithm: "sha-256", algorithm: "sha-256",
value: buffer, value: certHash,
} }
] ]
}); });
@@ -54,12 +49,8 @@ export async function streamUrl(url: string, cert_hash: Array<number>) {
await transport.ready; await transport.ready;
console.log('WebTransport connection established'); console.log('WebTransport connection established');
return transport;
console.log('Creating WebTransport bidirectional stream'); }
const stream = await transport.createBidirectionalStream();
console.log('Bidirectional stream created');
const reader = stream.readable.getReader();
function parseData(newBuffer: Uint8Array, oldBuffer: Uint8Array): [Array<Object>, Uint8Array<ArrayBuffer>] { function parseData(newBuffer: Uint8Array, oldBuffer: Uint8Array): [Array<Object>, Uint8Array<ArrayBuffer>] {
let packets = new Array<Object>(); let packets = new Array<Object>();
@@ -93,25 +84,31 @@ export async function streamUrl(url: string, cert_hash: Array<number>) {
return [packets, unparsedData]; return [packets, unparsedData];
} }
let unparsedData = new Uint8Array(); export async function streamUrl(url: string, certHash: Array<number>, canvasElement: HTMLCanvasElement) {
const certHashArray = new Uint8Array(certHash);
const canvas: HTMLCanvasElement | null = <HTMLCanvasElement>document.getElementById('gamestream-canvas'); const transport = await connectToUrl(url, certHashArray);
if (canvas == null) { console.log('Creating WebTransport bidirectional stream');
throw new Error(`Could not find canvas`); const stream = await transport.createBidirectionalStream();
} console.log('Bidirectional stream created');
const ctx: CanvasRenderingContext2D | null = canvas.getContext('2d');
if (ctx == null) { const canvasCtx: CanvasRenderingContext2D | null = canvasElement.getContext('2d');
if (canvasCtx == null) {
throw new Error(`Could not get 2d canvas context`); throw new Error(`Could not get 2d canvas context`);
} }
const reader = stream.readable.getReader();
try {
let unparsedData = new Uint8Array();
const videoDecoder = new VideoDecoder({ const videoDecoder = new VideoDecoder({
output: (frame) => { output: (frame) => {
// Set canvas dimensions to match the frame // Set canvas dimensions to match the frame
canvas.width = frame.displayWidth; canvasElement.width = frame.displayWidth;
canvas.height = frame.displayHeight; canvasElement.height = frame.displayHeight;
// Draw the decoded frame to canvas // Draw the decoded frame to canvas
ctx.drawImage(frame, 0, 0); canvasCtx.drawImage(frame, 0, 0);
// Important: close the frame to free memory // Important: close the frame to free memory
frame.close(); frame.close();
@@ -174,9 +171,6 @@ export async function streamUrl(url: string, cert_hash: Array<number>) {
} }
// Handle connection close // Handle connection close
transport.closed.then(() => { transport.closed.then(() => {
console.log('WebTransport connection closed'); console.log('WebTransport connection closed');
@@ -187,7 +181,8 @@ export async function streamUrl(url: string, cert_hash: Array<number>) {
// You can add more WebTransport handling logic here // You can add more WebTransport handling logic here
// For example, handling incoming streams, sending data, etc. // For example, handling incoming streams, sending data, etc.
} catch (error) { } catch (e) {
var error = <Error>e;
console.error('Error connecting to stream:', error); console.error('Error connecting to stream:', error);
alert('Failed to connect to stream: ' + error.message); alert('Failed to connect to stream: ' + error.message);
} }