import { writable } from 'svelte/store'; export enum LCMLiveStatus { CONNECTED = "connected", DISCONNECTED = "disconnected", WAIT = "wait", SEND_FRAME = "send_frame", TIMEOUT = "timeout", } const initStatus: LCMLiveStatus = LCMLiveStatus.DISCONNECTED; export const lcmLiveStatus = writable(initStatus); export const streamId = writable(null); let websocket: WebSocket | null = null; export const lcmLiveActions = { async start(getSreamdata: () => any[]) { return new Promise((resolve, reject) => { try { const userId = crypto.randomUUID(); const websocketURL = `${window.location.protocol === "https:" ? "wss" : "ws" }:${window.location.host}/api/ws/${userId}`; websocket = new WebSocket(websocketURL); websocket.onopen = () => { console.log("Connected to websocket"); }; websocket.onclose = () => { lcmLiveStatus.set(LCMLiveStatus.DISCONNECTED); console.log("Disconnected from websocket"); }; websocket.onerror = (err) => { console.error(err); }; websocket.onmessage = (event) => { const data = JSON.parse(event.data); switch (data.status) { case "connected": lcmLiveStatus.set(LCMLiveStatus.CONNECTED); streamId.set(userId); resolve({ status: "connected", userId }); break; case "send_frame": lcmLiveStatus.set(LCMLiveStatus.SEND_FRAME); const streamData = getSreamdata(); websocket?.send(JSON.stringify({ status: "next_frame" })); for (const d of streamData) { this.send(d); } break; case "wait": lcmLiveStatus.set(LCMLiveStatus.WAIT); break; case "timeout": console.log("timeout"); lcmLiveStatus.set(LCMLiveStatus.TIMEOUT); streamId.set(null); reject(new Error("timeout")); break; case "error": console.log(data.message); lcmLiveStatus.set(LCMLiveStatus.DISCONNECTED); streamId.set(null); reject(new Error(data.message)); break; } }; } catch (err) { console.error(err); lcmLiveStatus.set(LCMLiveStatus.DISCONNECTED); streamId.set(null); reject(err); } }); }, send(data: Blob | { [key: string]: any }) { if (websocket && websocket.readyState === WebSocket.OPEN) { if (data instanceof Blob) { websocket.send(data); } else { websocket.send(JSON.stringify(data)); } } else { console.log("WebSocket not connected"); } }, async stop() { lcmLiveStatus.set(LCMLiveStatus.DISCONNECTED); if (websocket) { websocket.close(); } websocket = null; streamId.set(null); }, };