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); } };