File size: 3,016 Bytes
ff9325e
 
 
fe66ec6
 
 
 
 
ff9325e
 
3207814
ff9325e
3207814
 
ff9325e
 
 
fe66ec6
 
 
 
 
 
 
d6fedfa
fe66ec6
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
488b360
3207814
fe66ec6
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
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<LCMLiveStatus>(initStatus);
export const streamId = writable<string | null>(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);
  }
};