@snapcall/stream-ui 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,290 @@
1
+ import * as mediasoupClient from "mediasoup-client";
2
+ import { types } from "mediasoup-client";
3
+ import * as protooClient from "protoo-client";
4
+ import { Transport } from "mediasoup-client/lib/Transport";
5
+ import { MediaKind } from "mediasoup-client/lib/RtpParameters";
6
+ interface MenuItem {
7
+ id: string;
8
+ title: string;
9
+ jsxIcon?: JSX.Element;
10
+ srcIcon?: string;
11
+ action: () => void;
12
+ danger?: boolean;
13
+ isNew?: boolean;
14
+ }
15
+ interface MenuCategory {
16
+ id: string;
17
+ title?: string;
18
+ items: MenuItem[];
19
+ }
20
+ interface SettingsCategory extends MenuCategory {
21
+ position?: number;
22
+ items: SettingsItem[];
23
+ }
24
+ interface SettingsItem extends MenuItem {
25
+ position?: number;
26
+ }
27
+ type VideoResolution = 'qvga' | 'vga' | 'hd';
28
+ type PeerId = string;
29
+ type DeviceType = 'webcam' | 'screen' | 'microphone';
30
+ interface JoinOptions {
31
+ apiKey?: string;
32
+ email?: string;
33
+ displayName?: string;
34
+ }
35
+ interface ProducerData {
36
+ producerId: string;
37
+ deviceType: DeviceType;
38
+ paused: boolean;
39
+ }
40
+ interface PeerInfo {
41
+ id: PeerId;
42
+ displayName: string;
43
+ producersData: Array<ProducerData>;
44
+ }
45
+ type ConsumerId = string;
46
+ type ProducerId = string;
47
+ interface ConsumerData {
48
+ mediaSoupConsumer: types.Consumer;
49
+ deviceType?: DeviceType;
50
+ }
51
+ interface DevicesState {
52
+ microphone: {
53
+ enabled: boolean;
54
+ muted: boolean;
55
+ };
56
+ camera: {
57
+ enabled: boolean;
58
+ };
59
+ screenshare: {
60
+ enabled: boolean;
61
+ };
62
+ }
63
+ declare global {
64
+ interface Window {
65
+ webkitAudioContext: Function;
66
+ }
67
+ interface MediaTrackConstraintSet {
68
+ displaySurface?: ConstrainDOMString;
69
+ logicalSurface?: ConstrainBoolean;
70
+ zoom?: number;
71
+ }
72
+ interface MediaTrackCapabilities {
73
+ zoom: {
74
+ min: number;
75
+ max: number;
76
+ step: number;
77
+ };
78
+ }
79
+ }
80
+ interface AudioLevelListener {
81
+ onAudioLevel?(audioLevel: number, id: string): void;
82
+ onMuteDetection?(id: string): void;
83
+ onStartSpeak(): void;
84
+ onStopSpeak(): void;
85
+ }
86
+ declare class AudioLevel {
87
+ readonly id: string;
88
+ constructor(stream: MediaStream, listener?: AudioLevelListener);
89
+ /**
90
+ * return the median of the audio levels (60 per second) for the
91
+ * current second
92
+ */
93
+ getAudioLevelMedian(): number;
94
+ getCurrentAudioLevel(): number;
95
+ analyse(): void;
96
+ release(): void;
97
+ static isAPIAvailable(): boolean;
98
+ }
99
+ interface DeviceRequest {
100
+ requestId: string;
101
+ deviceType: DeviceType;
102
+ }
103
+ interface WebRTCTransportData {
104
+ kind: MediaKind;
105
+ transport: Transport;
106
+ disconnectTimeout: number | undefined;
107
+ }
108
+ interface CustomMessage {
109
+ chunks: Array<{
110
+ index: number;
111
+ data: string;
112
+ }>;
113
+ totalChunks: number;
114
+ }
115
+ declare class StreamerClient implements AudioLevelListener {
116
+ iceServers: Array<RTCIceServer>;
117
+ peers: Map<PeerId, PeerInfo>;
118
+ consumers: Map<ConsumerId, ConsumerData>;
119
+ webcams: Map<string, MediaDeviceInfo>;
120
+ webcam: {
121
+ device: MediaDeviceInfo | null;
122
+ resolution: VideoResolution;
123
+ };
124
+ webcamTrack: MediaStreamTrack | null;
125
+ webcamZoom: {
126
+ available: boolean;
127
+ min: number;
128
+ max: number;
129
+ };
130
+ audioLevel: AudioLevel | undefined;
131
+ muted: boolean;
132
+ roomId: string;
133
+ peerId: PeerId;
134
+ displayName?: string;
135
+ protooTransport: protooClient.WebSocketTransport;
136
+ protoo: protooClient.Peer;
137
+ mediasoupDevice: mediasoupClient.types.Device;
138
+ routerRtpCapabilities: mediasoupClient.types.RtpCapabilities;
139
+ recvVideoTransports?: WebRTCTransportData;
140
+ sendVideoTransports?: WebRTCTransportData;
141
+ recvAudioTransports?: WebRTCTransportData;
142
+ sendAudioTransports?: WebRTCTransportData;
143
+ micProducer?: mediasoupClient.types.Producer;
144
+ webcamProducer: mediasoupClient.types.Producer | null;
145
+ screenshareProducer: mediasoupClient.types.Producer | null;
146
+ pendingDeviceRequest: Record<string, DeviceRequest>;
147
+ joinOptions: JoinOptions;
148
+ customMessages: Map<string, CustomMessage>;
149
+ constructor();
150
+ onStartSpeak(): void;
151
+ onStopSpeak(): void;
152
+ generateToken(bid: string): Promise<string>;
153
+ init(room?: string, options?: JoinOptions): Promise<void>;
154
+ joinRoom(): Promise<void>;
155
+ enableMicrophone(): Promise<void>;
156
+ muteMicrophone(): Promise<void>;
157
+ unMuteMicrophone(): Promise<void>;
158
+ toggleMute(): Promise<{
159
+ muted: boolean;
160
+ }>;
161
+ endCall(): void;
162
+ terminateRoom(): void;
163
+ updateWebcams(): Promise<void>;
164
+ isVideoZoomAvailable(): boolean;
165
+ handleGetUserMediaError(deviceType: DeviceType, getUserMediaPromise: Promise<MediaStream>): Promise<MediaStream>;
166
+ restartIce(transport: Transport): Promise<void>;
167
+ enableVideo(): Promise<void>;
168
+ rotateVideo(): Promise<void>;
169
+ zoomVideo(): Promise<void>;
170
+ unzoomVideo(): Promise<void>;
171
+ disableVideo(): Promise<void>;
172
+ enableScreenshare(): Promise<void>;
173
+ disableScreenshare(): Promise<void>;
174
+ onConsumerClose({ consumerId }: {
175
+ consumerId: ConsumerId;
176
+ }): void;
177
+ requestVoice({ consumerId, element }: {
178
+ consumerId: string;
179
+ element: HTMLAudioElement;
180
+ }): void;
181
+ requestVideo({ consumerId, element }: {
182
+ consumerId: string;
183
+ element: HTMLVideoElement;
184
+ }): void;
185
+ captureVideo(videoElement?: HTMLVideoElement): Promise<string>;
186
+ requestLocalVideo(element: HTMLVideoElement): {
187
+ facingMode: string;
188
+ };
189
+ requestLocalScreenshare(element: HTMLVideoElement): void;
190
+ consumePeer({ peerId, producersData, }: {
191
+ peerId: PeerId;
192
+ producersData: Array<ProducerData>;
193
+ }): void;
194
+ consumeProducer({ peerId, producerId, deviceType, paused, }: {
195
+ peerId: PeerId;
196
+ producerId: ProducerId;
197
+ deviceType: DeviceType;
198
+ paused: boolean;
199
+ }): Promise<void>;
200
+ setDisplayName(displayName: string): Promise<void>;
201
+ requestPeerDevice(remotePeerId: string, deviceType: DeviceType): Promise<void>;
202
+ denyDeviceRequest(deviceType: DeviceType): void;
203
+ getCallId(): Promise<number>;
204
+ getConsumers(): Map<string, ConsumerData>;
205
+ getDevicesState(): DevicesState;
206
+ sendCustomMessageToAll(event: any): Promise<void>;
207
+ sendCustomMessage(peerId: string, event: any): Promise<void>;
208
+ }
209
+ declare const streamerClient: StreamerClient;
210
+ interface StreamUIMethods {
211
+ init: (options: StreamUIInitOptions) => void;
212
+ setExtraSettingsOptions: (extraOptions: SettingsCategory[]) => void;
213
+ joinRoom: typeof streamerClient.init;
214
+ leaveRoom: typeof streamerClient.endCall;
215
+ terminateRoom: typeof streamerClient.terminateRoom;
216
+ generateToken: typeof streamerClient.generateToken;
217
+ }
218
+ interface ControlSettings {
219
+ available?: boolean;
220
+ enabled?: boolean;
221
+ }
222
+ interface StreamUIBaseOptions {
223
+ sharedURL?: string;
224
+ audioTiles?: boolean;
225
+ settingsShortcuts?: string[];
226
+ extraSettingsOptions?: SettingsCategory[];
227
+ controls?: {
228
+ microphone?: ControlSettings;
229
+ camera?: ControlSettings;
230
+ screenshare?: ControlSettings;
231
+ };
232
+ logo?: {
233
+ text?: string;
234
+ size?: 'small' | 'medium' | 'large';
235
+ };
236
+ showMenuButton?: boolean;
237
+ GDPRDisclaimer?: boolean;
238
+ }
239
+ interface StreamUIInitOptions extends StreamUIBaseOptions {
240
+ element: HTMLElement;
241
+ }
242
+ declare global {
243
+ interface Window {
244
+ streamUI: StreamUIMethods;
245
+ snapcallAPI: {
246
+ join: typeof streamerClient.init;
247
+ endCall: typeof streamerClient.endCall;
248
+ terminateRoom: typeof streamerClient.terminateRoom;
249
+ generateToken: typeof streamerClient.generateToken;
250
+ setDisplayName: typeof streamerClient.setDisplayName;
251
+ };
252
+ }
253
+ interface MediaSession {
254
+ setMicrophoneActive: (active: boolean) => void;
255
+ setCameraActive: (active: boolean) => void;
256
+ }
257
+ interface WindowEventMap {
258
+ streamUISetExtraSettingsOptions: CustomEvent;
259
+ enterRoom: CustomEvent;
260
+ newPeer: CustomEvent;
261
+ peerClosed: CustomEvent;
262
+ newConsumer: CustomEvent;
263
+ consumerClose: CustomEvent;
264
+ screenshareEnabled: CustomEvent;
265
+ screenshareDisabled: CustomEvent;
266
+ producerPaused: CustomEvent;
267
+ producerResumed: CustomEvent;
268
+ displayName: CustomEvent;
269
+ selfDisplayName: CustomEvent;
270
+ requestDevice: CustomEvent;
271
+ requestDeviceResult: CustomEvent;
272
+ webcamsUpdate: CustomEvent;
273
+ microphoneEnabled: CustomEvent;
274
+ microphoneMute: CustomEvent;
275
+ microphoneUnmute: CustomEvent;
276
+ peerStartSpeak: CustomEvent;
277
+ peerStopSpeak: CustomEvent;
278
+ agentIdentity: CustomEvent;
279
+ customMessage: CustomEvent;
280
+ }
281
+ }
282
+ declare global {
283
+ interface Window {
284
+ onYouTubeIframeAPIReady: () => void;
285
+ YT?: {
286
+ loaded?: boolean;
287
+ };
288
+ }
289
+ }
290
+ export const streamUI: StreamUIMethods;
package/package.json ADDED
@@ -0,0 +1,82 @@
1
+ {
2
+ "name": "@snapcall/stream-ui",
3
+ "version": "1.0.0",
4
+ "description": "",
5
+ "source": "src/index.tsx",
6
+ "main": "dist/stream-ui.js",
7
+ "module": "dist/stream-ui.esm.js",
8
+ "umd": "dist/stream-ui.umd.js",
9
+ "types": "dist/types.d.ts",
10
+ "targets": {
11
+ "umd": {
12
+ "context": "browser",
13
+ "outputFormat": "global",
14
+ "includeNodeModules": true,
15
+ "isLibrary": false,
16
+ "optimize": true,
17
+ "sourceMap": false
18
+ }
19
+ },
20
+ "publishConfig": {
21
+ "access": "public"
22
+ },
23
+ "files": [
24
+ "dist"
25
+ ],
26
+ "scripts": {
27
+ "watch": "parcel watch",
28
+ "serve": "parcel serve --https example/index.html",
29
+ "build": "parcel build",
30
+ "build:npm": "parcel build --no-source-maps",
31
+ "build:s3": "parcel build --no-source-maps --target umd",
32
+ "typecheck": "tsc --noEmit",
33
+ "lint": "eslint src --ext .ts,.tsx",
34
+ "prettier": "prettier --check ."
35
+ },
36
+ "keywords": [],
37
+ "author": "Seampl",
38
+ "license": "ISC",
39
+ "peerDependencies": {
40
+ "@sentry/browser": "^7.0.0",
41
+ "bowser": "^2.11.0",
42
+ "inobounce": "^0.2.1",
43
+ "mediasoup-client": "^3.6.52",
44
+ "protoo-client": "^4.0.6",
45
+ "qrcode": "^1.5.0",
46
+ "react": "^17.0.2",
47
+ "react-dom": "^17.0.2",
48
+ "react-hot-toast": "^2.2.0",
49
+ "styled-components": "^5.3.3"
50
+ },
51
+ "devDependencies": {
52
+ "@parcel/packager-ts": "^2.6.0",
53
+ "@parcel/transformer-typescript-types": "^2.6.0",
54
+ "@types/protoo-client": "^4.0.1",
55
+ "@types/qrcode": "^1.4.2",
56
+ "@types/react": "^17.0.43",
57
+ "@types/react-dom": "^17.0.14",
58
+ "@types/styled-components": "^5.1.25",
59
+ "@types/uuid": "^8.3.4",
60
+ "eslint": "^8.16.0",
61
+ "eslint-config-prettier": "^8.5.0",
62
+ "eslint-config-react-app": "^7.0.1",
63
+ "parcel": "^2.6.0",
64
+ "prettier": "2.6.2",
65
+ "process": "^0.11.10",
66
+ "typescript": "^4.7.2"
67
+ },
68
+ "dependencies": {
69
+ "@sentry/browser": "^7.0.0",
70
+ "@types/youtube": "^0.0.46",
71
+ "bowser": "^2.11.0",
72
+ "inobounce": "^0.2.1",
73
+ "mediasoup-client": "^3.6.52",
74
+ "protoo-client": "^4.0.6",
75
+ "qrcode": "^1.5.0",
76
+ "react": "^17.0.2",
77
+ "react-dom": "^17.0.2",
78
+ "react-hot-toast": "^2.2.0",
79
+ "styled-components": "^5.3.3",
80
+ "uuid": "^8.3.2"
81
+ }
82
+ }