@whereby.com/browser-sdk 2.0.0-alpha1 → 2.0.0-alpha10
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.
- package/README.md +39 -2
- package/dist/{lib.cjs.js → lib.cjs} +543 -142
- package/dist/lib.esm.js +543 -144
- package/dist/types.d.ts +215 -11
- package/dist/v2-alpha10.js +43 -0
- package/package.json +12 -7
- package/dist/v2-alpha1.js +0 -105
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
4
|
|
|
5
5
|
var heresy = require('heresy');
|
|
6
|
-
var React = require('react');
|
|
7
6
|
var tslib = require('tslib');
|
|
7
|
+
var React = require('react');
|
|
8
8
|
var adapter = require('webrtc-adapter');
|
|
9
9
|
var io = require('socket.io-client');
|
|
10
10
|
var SDPUtils = require('sdp');
|
|
@@ -130,7 +130,7 @@ heresy.define("WherebyEmbed", {
|
|
|
130
130
|
if (!subdomain)
|
|
131
131
|
return this.html `Whereby: Missing subdomain attr.`;
|
|
132
132
|
const url = new URL(room, `https://${subdomain}.whereby.com`);
|
|
133
|
-
Object.entries(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({ jsApi: true, we: "2.0.0-
|
|
133
|
+
Object.entries(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({ jsApi: true, we: "2.0.0-alpha10", iframeSource: subdomain }, (displayName && { displayName })), (lang && { lang })), (metadata && { metadata })), (groups && { groups })), (virtualBackgroundUrl && { virtualBackgroundUrl })), (avatarUrl && { avatarUrl })), (minimal != null && { embed: minimal })), boolAttrs.reduce(
|
|
134
134
|
// add to URL if set in any way
|
|
135
135
|
(o, v) => (this[v.toLowerCase()] != null ? Object.assign(Object.assign({}, o), { [v]: this[v.toLowerCase()] }) : o), {}))).forEach(([k, v]) => {
|
|
136
136
|
if (!url.searchParams.has(k) && typeof v === "string") {
|
|
@@ -146,15 +146,261 @@ heresy.define("WherebyEmbed", {
|
|
|
146
146
|
},
|
|
147
147
|
});
|
|
148
148
|
|
|
149
|
-
var
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
149
|
+
var VideoView = (_a) => {
|
|
150
|
+
var { muted, stream } = _a, rest = tslib.__rest(_a, ["muted", "stream"]);
|
|
151
|
+
const videoEl = React.useRef(null);
|
|
152
|
+
React.useEffect(() => {
|
|
153
|
+
if (!videoEl.current) {
|
|
154
|
+
return;
|
|
153
155
|
}
|
|
154
|
-
|
|
155
|
-
|
|
156
|
+
if (videoEl.current.srcObject !== stream) {
|
|
157
|
+
videoEl.current.srcObject = stream;
|
|
158
|
+
}
|
|
159
|
+
// Handle muting programatically, not as video attribute
|
|
160
|
+
// https://stackoverflow.com/questions/14111917/html5-video-muted-but-still-playing
|
|
161
|
+
if (videoEl.current.muted !== muted) {
|
|
162
|
+
videoEl.current.muted = Boolean(muted);
|
|
163
|
+
}
|
|
164
|
+
}, [muted, stream, videoEl]);
|
|
165
|
+
return React__default["default"].createElement("video", Object.assign({ ref: videoEl, autoPlay: true, playsInline: true }, rest));
|
|
156
166
|
};
|
|
157
167
|
|
|
168
|
+
const TypedLocalMediaEventTarget = EventTarget;
|
|
169
|
+
class LocalMedia extends TypedLocalMediaEventTarget {
|
|
170
|
+
constructor(constraints) {
|
|
171
|
+
super();
|
|
172
|
+
this._constraints = constraints;
|
|
173
|
+
this.stream = new MediaStream();
|
|
174
|
+
this._rtcManagers = [];
|
|
175
|
+
navigator.mediaDevices.addEventListener("devicechange", this._updateDeviceList.bind(this));
|
|
176
|
+
}
|
|
177
|
+
addRtcManager(rtcManager) {
|
|
178
|
+
this._rtcManagers.push(rtcManager);
|
|
179
|
+
}
|
|
180
|
+
removeRtcManager(rtcManager) {
|
|
181
|
+
this._rtcManagers = this._rtcManagers.filter((r) => r !== rtcManager);
|
|
182
|
+
}
|
|
183
|
+
getCameraDeviceId() {
|
|
184
|
+
var _a;
|
|
185
|
+
return (_a = this.stream.getVideoTracks()[0]) === null || _a === void 0 ? void 0 : _a.getSettings().deviceId;
|
|
186
|
+
}
|
|
187
|
+
getMicrophoneDeviceId() {
|
|
188
|
+
var _a;
|
|
189
|
+
return (_a = this.stream.getAudioTracks()[0]) === null || _a === void 0 ? void 0 : _a.getSettings().deviceId;
|
|
190
|
+
}
|
|
191
|
+
isCameraEnabled() {
|
|
192
|
+
var _a;
|
|
193
|
+
return !!((_a = this.stream.getVideoTracks()[0]) === null || _a === void 0 ? void 0 : _a.enabled);
|
|
194
|
+
}
|
|
195
|
+
isMicrophoneEnabled() {
|
|
196
|
+
var _a;
|
|
197
|
+
return !!((_a = this.stream.getAudioTracks()[0]) === null || _a === void 0 ? void 0 : _a.enabled);
|
|
198
|
+
}
|
|
199
|
+
toggleCameraEnabled(enabled) {
|
|
200
|
+
const videoTrack = this.stream.getVideoTracks()[0];
|
|
201
|
+
if (!videoTrack) {
|
|
202
|
+
return;
|
|
203
|
+
}
|
|
204
|
+
const newValue = enabled !== null && enabled !== void 0 ? enabled : !videoTrack.enabled;
|
|
205
|
+
videoTrack.enabled = newValue;
|
|
206
|
+
this.dispatchEvent(new CustomEvent("camera_enabled", { detail: { enabled: newValue } }));
|
|
207
|
+
}
|
|
208
|
+
toggleMichrophoneEnabled(enabled) {
|
|
209
|
+
const audioTrack = this.stream.getAudioTracks()[0];
|
|
210
|
+
if (!audioTrack) {
|
|
211
|
+
return;
|
|
212
|
+
}
|
|
213
|
+
const newValue = enabled !== null && enabled !== void 0 ? enabled : !audioTrack.enabled;
|
|
214
|
+
audioTrack.enabled = newValue;
|
|
215
|
+
this.dispatchEvent(new CustomEvent("microphone_enabled", { detail: { enabled: newValue } }));
|
|
216
|
+
}
|
|
217
|
+
setCameraDevice(deviceId) {
|
|
218
|
+
return tslib.__awaiter(this, void 0, void 0, function* () {
|
|
219
|
+
const newStream = yield navigator.mediaDevices.getUserMedia({ video: { deviceId } });
|
|
220
|
+
const newVideoTrack = newStream.getVideoTracks()[0];
|
|
221
|
+
if (newVideoTrack) {
|
|
222
|
+
const oldVideoTrack = this.stream.getVideoTracks()[0];
|
|
223
|
+
newVideoTrack.enabled = oldVideoTrack.enabled;
|
|
224
|
+
oldVideoTrack === null || oldVideoTrack === void 0 ? void 0 : oldVideoTrack.stop();
|
|
225
|
+
this._rtcManagers.forEach((rtcManager) => {
|
|
226
|
+
rtcManager.replaceTrack(oldVideoTrack, newVideoTrack);
|
|
227
|
+
});
|
|
228
|
+
this.stream.removeTrack(oldVideoTrack);
|
|
229
|
+
this.stream.addTrack(newVideoTrack);
|
|
230
|
+
}
|
|
231
|
+
this.dispatchEvent(new CustomEvent("stream_updated", {
|
|
232
|
+
detail: { stream: this.stream },
|
|
233
|
+
}));
|
|
234
|
+
});
|
|
235
|
+
}
|
|
236
|
+
setMicrophoneDevice(deviceId) {
|
|
237
|
+
return tslib.__awaiter(this, void 0, void 0, function* () {
|
|
238
|
+
const newStream = yield navigator.mediaDevices.getUserMedia({ audio: { deviceId } });
|
|
239
|
+
const newAudioTrack = newStream.getAudioTracks()[0];
|
|
240
|
+
const oldAudioTrack = this.stream.getAudioTracks()[0];
|
|
241
|
+
if (oldAudioTrack) {
|
|
242
|
+
newAudioTrack.enabled = oldAudioTrack.enabled;
|
|
243
|
+
oldAudioTrack.stop();
|
|
244
|
+
this.stream.removeTrack(oldAudioTrack);
|
|
245
|
+
}
|
|
246
|
+
this._rtcManagers.forEach((rtcManager) => {
|
|
247
|
+
rtcManager.replaceTrack(oldAudioTrack, newAudioTrack);
|
|
248
|
+
});
|
|
249
|
+
this.stream.addTrack(newAudioTrack);
|
|
250
|
+
this.dispatchEvent(new CustomEvent("stream_updated", {
|
|
251
|
+
detail: { stream: this.stream },
|
|
252
|
+
}));
|
|
253
|
+
});
|
|
254
|
+
}
|
|
255
|
+
_updateDeviceList() {
|
|
256
|
+
return tslib.__awaiter(this, void 0, void 0, function* () {
|
|
257
|
+
try {
|
|
258
|
+
const devices = yield navigator.mediaDevices.enumerateDevices();
|
|
259
|
+
this.dispatchEvent(new CustomEvent("device_list_updated", {
|
|
260
|
+
detail: {
|
|
261
|
+
cameraDevices: devices.filter((d) => d.kind === "videoinput"),
|
|
262
|
+
microphoneDevices: devices.filter((d) => d.kind === "audioinput"),
|
|
263
|
+
speakerDevices: devices.filter((d) => d.kind === "audiooutput"),
|
|
264
|
+
},
|
|
265
|
+
}));
|
|
266
|
+
}
|
|
267
|
+
catch (error) {
|
|
268
|
+
this.dispatchEvent(new CustomEvent("device_list_update_error", {
|
|
269
|
+
detail: {
|
|
270
|
+
error,
|
|
271
|
+
},
|
|
272
|
+
}));
|
|
273
|
+
throw error;
|
|
274
|
+
}
|
|
275
|
+
});
|
|
276
|
+
}
|
|
277
|
+
start() {
|
|
278
|
+
return tslib.__awaiter(this, void 0, void 0, function* () {
|
|
279
|
+
const newStream = yield navigator.mediaDevices.getUserMedia(this._constraints);
|
|
280
|
+
newStream.getTracks().forEach((t) => this.stream.addTrack(t));
|
|
281
|
+
this._updateDeviceList();
|
|
282
|
+
this.dispatchEvent(new CustomEvent("stream_updated", {
|
|
283
|
+
detail: { stream: this.stream },
|
|
284
|
+
}));
|
|
285
|
+
return this.stream;
|
|
286
|
+
});
|
|
287
|
+
}
|
|
288
|
+
stop() {
|
|
289
|
+
var _a;
|
|
290
|
+
(_a = this.stream) === null || _a === void 0 ? void 0 : _a.getTracks().forEach((t) => {
|
|
291
|
+
t.stop();
|
|
292
|
+
});
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
const initialState$1 = {
|
|
297
|
+
cameraDeviceError: null,
|
|
298
|
+
cameraDevices: [],
|
|
299
|
+
isSettingCameraDevice: false,
|
|
300
|
+
isSettingMicrophoneDevice: false,
|
|
301
|
+
isStarting: false,
|
|
302
|
+
microphoneDeviceError: null,
|
|
303
|
+
microphoneDevices: [],
|
|
304
|
+
speakerDevices: [],
|
|
305
|
+
startError: null,
|
|
306
|
+
};
|
|
307
|
+
function reducer$1(state, action) {
|
|
308
|
+
switch (action.type) {
|
|
309
|
+
case "DEVICE_LIST_UPDATED":
|
|
310
|
+
return Object.assign(Object.assign({}, state), action.payload);
|
|
311
|
+
case "LOCAL_STREAM_UPDATED":
|
|
312
|
+
return Object.assign(Object.assign({}, state), { currentCameraDeviceId: action.payload.currentCameraDeviceId, currentMicrophoneDeviceId: action.payload.currentMicrophoneDeviceId, localStream: action.payload.stream });
|
|
313
|
+
case "SET_CAMERA_DEVICE":
|
|
314
|
+
return Object.assign(Object.assign({}, state), { cameraDeviceError: null, isSettingCameraDevice: true });
|
|
315
|
+
case "SET_CAMERA_DEVICE_COMPLETE":
|
|
316
|
+
return Object.assign(Object.assign({}, state), { isSettingCameraDevice: false });
|
|
317
|
+
case "SET_CAMERA_DEVICE_ERROR":
|
|
318
|
+
return Object.assign(Object.assign({}, state), { cameraDeviceError: action.payload, isSettingCameraDevice: false });
|
|
319
|
+
case "SET_MICROPHONE_DEVICE":
|
|
320
|
+
return Object.assign(Object.assign({}, state), { isSettingMicrophoneDevice: true, microphoneDeviceError: null });
|
|
321
|
+
case "SET_MICROPHONE_DEVICE_COMPLETE":
|
|
322
|
+
return Object.assign(Object.assign({}, state), { isSettingMicrophoneDevice: false });
|
|
323
|
+
case "SET_MICROPHONE_DEVICE_ERROR":
|
|
324
|
+
return Object.assign(Object.assign({}, state), { isSettingMicrophoneDevice: false, microphoneDeviceError: action.payload });
|
|
325
|
+
case "START":
|
|
326
|
+
return Object.assign(Object.assign({}, state), { isStarting: true, startError: null });
|
|
327
|
+
case "START_COMPLETE":
|
|
328
|
+
return Object.assign(Object.assign({}, state), { isStarting: false });
|
|
329
|
+
case "START_ERROR":
|
|
330
|
+
return Object.assign(Object.assign({}, state), { isStarting: false, startError: action.payload });
|
|
331
|
+
default:
|
|
332
|
+
return state;
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
function useLocalMedia(constraints = { audio: true, video: true }) {
|
|
336
|
+
const [localMedia] = React.useState(() => new LocalMedia(constraints));
|
|
337
|
+
const [state, dispatch] = React.useReducer(reducer$1, initialState$1);
|
|
338
|
+
React.useEffect(() => {
|
|
339
|
+
localMedia.addEventListener("device_list_updated", (e) => {
|
|
340
|
+
const { cameraDevices, microphoneDevices, speakerDevices } = e.detail;
|
|
341
|
+
dispatch({ type: "DEVICE_LIST_UPDATED", payload: { cameraDevices, microphoneDevices, speakerDevices } });
|
|
342
|
+
});
|
|
343
|
+
localMedia.addEventListener("stream_updated", (e) => {
|
|
344
|
+
const { stream } = e.detail;
|
|
345
|
+
dispatch({
|
|
346
|
+
type: "LOCAL_STREAM_UPDATED",
|
|
347
|
+
payload: {
|
|
348
|
+
stream,
|
|
349
|
+
currentCameraDeviceId: localMedia.getCameraDeviceId(),
|
|
350
|
+
currentMicrophoneDeviceId: localMedia.getMicrophoneDeviceId(),
|
|
351
|
+
},
|
|
352
|
+
});
|
|
353
|
+
});
|
|
354
|
+
const start = () => tslib.__awaiter(this, void 0, void 0, function* () {
|
|
355
|
+
dispatch({ type: "START" });
|
|
356
|
+
try {
|
|
357
|
+
yield localMedia.start();
|
|
358
|
+
dispatch({ type: "START_COMPLETE" });
|
|
359
|
+
}
|
|
360
|
+
catch (error) {
|
|
361
|
+
dispatch({ type: "START_ERROR", payload: error });
|
|
362
|
+
}
|
|
363
|
+
});
|
|
364
|
+
start();
|
|
365
|
+
// Perform cleanup on unmount
|
|
366
|
+
return () => {
|
|
367
|
+
localMedia.stop();
|
|
368
|
+
};
|
|
369
|
+
}, []);
|
|
370
|
+
return {
|
|
371
|
+
state,
|
|
372
|
+
actions: {
|
|
373
|
+
setCameraDevice: (...args) => tslib.__awaiter(this, void 0, void 0, function* () {
|
|
374
|
+
dispatch({ type: "SET_CAMERA_DEVICE" });
|
|
375
|
+
try {
|
|
376
|
+
yield localMedia.setCameraDevice(...args);
|
|
377
|
+
dispatch({ type: "SET_CAMERA_DEVICE_COMPLETE" });
|
|
378
|
+
}
|
|
379
|
+
catch (error) {
|
|
380
|
+
dispatch({ type: "SET_CAMERA_DEVICE_ERROR", payload: error });
|
|
381
|
+
}
|
|
382
|
+
}),
|
|
383
|
+
setMicrophoneDevice: (...args) => tslib.__awaiter(this, void 0, void 0, function* () {
|
|
384
|
+
dispatch({ type: "SET_MICROPHONE_DEVICE" });
|
|
385
|
+
try {
|
|
386
|
+
yield localMedia.setMicrophoneDevice(...args);
|
|
387
|
+
dispatch({ type: "SET_MICROPHONE_DEVICE_COMPLETE" });
|
|
388
|
+
}
|
|
389
|
+
catch (error) {
|
|
390
|
+
dispatch({ type: "SET_MICROPHONE_DEVICE_ERROR", payload: error });
|
|
391
|
+
}
|
|
392
|
+
}),
|
|
393
|
+
toggleCameraEnabled: (...args) => {
|
|
394
|
+
return localMedia.toggleCameraEnabled(...args);
|
|
395
|
+
},
|
|
396
|
+
toggleMicrophoneEnabled: (...args) => {
|
|
397
|
+
return localMedia.toggleMichrophoneEnabled(...args);
|
|
398
|
+
},
|
|
399
|
+
},
|
|
400
|
+
_ref: localMedia,
|
|
401
|
+
};
|
|
402
|
+
}
|
|
403
|
+
|
|
158
404
|
const EVENTS = {
|
|
159
405
|
CLIENT_CONNECTION_STATUS_CHANGED: "client_connection_status_changed",
|
|
160
406
|
STREAM_ADDED: "stream_added",
|
|
@@ -285,10 +531,10 @@ class ServerSocket {
|
|
|
285
531
|
}
|
|
286
532
|
|
|
287
533
|
this._socket = io__default["default"](hostName, options);
|
|
288
|
-
this._socket.on("reconnect", () => {
|
|
534
|
+
this._socket.io.on("reconnect", () => {
|
|
289
535
|
this._socket.sendBuffer = [];
|
|
290
536
|
});
|
|
291
|
-
this._socket.on("reconnect_attempt", () => {
|
|
537
|
+
this._socket.io.on("reconnect_attempt", () => {
|
|
292
538
|
if (this._wasConnectedUsingWebsocket) {
|
|
293
539
|
this._socket.io.opts.transports = ["websocket"];
|
|
294
540
|
// only fallback to polling if not safari
|
|
@@ -346,6 +592,10 @@ class ServerSocket {
|
|
|
346
592
|
);
|
|
347
593
|
}
|
|
348
594
|
|
|
595
|
+
getManager() {
|
|
596
|
+
return this._socket.io;
|
|
597
|
+
}
|
|
598
|
+
|
|
349
599
|
isConnecting() {
|
|
350
600
|
return this._socket && this._socket.connecting;
|
|
351
601
|
}
|
|
@@ -1979,10 +2229,11 @@ class VegaParser {
|
|
|
1979
2229
|
}
|
|
1980
2230
|
|
|
1981
2231
|
class VegaConnection extends EventEmitter.EventEmitter {
|
|
1982
|
-
constructor(wsUrl, logger) {
|
|
2232
|
+
constructor(wsUrl, logger, protocol = "whereby-sfu#v4") {
|
|
1983
2233
|
super();
|
|
1984
2234
|
|
|
1985
2235
|
this.wsUrl = wsUrl;
|
|
2236
|
+
this.protocol = protocol;
|
|
1986
2237
|
this.logger = logger;
|
|
1987
2238
|
|
|
1988
2239
|
// This is the map of sent requests that are waiting for a response
|
|
@@ -1991,7 +2242,7 @@ class VegaConnection extends EventEmitter.EventEmitter {
|
|
|
1991
2242
|
}
|
|
1992
2243
|
|
|
1993
2244
|
_setupSocket() {
|
|
1994
|
-
this.socket = new WebSocket(this.wsUrl,
|
|
2245
|
+
this.socket = new WebSocket(this.wsUrl, this.protocol);
|
|
1995
2246
|
this.socket.onopen = this._onOpen.bind(this);
|
|
1996
2247
|
this.socket.onmessage = this._onMessage.bind(this);
|
|
1997
2248
|
this.socket.onclose = this._onClose.bind(this);
|
|
@@ -2011,7 +2262,9 @@ class VegaConnection extends EventEmitter.EventEmitter {
|
|
|
2011
2262
|
}
|
|
2012
2263
|
|
|
2013
2264
|
close() {
|
|
2014
|
-
this.socket
|
|
2265
|
+
if (!this.socket) return;
|
|
2266
|
+
|
|
2267
|
+
this.socket.close();
|
|
2015
2268
|
}
|
|
2016
2269
|
|
|
2017
2270
|
_onOpen() {
|
|
@@ -2023,11 +2276,15 @@ class VegaConnection extends EventEmitter.EventEmitter {
|
|
|
2023
2276
|
_onMessage(event) {
|
|
2024
2277
|
const socketMessage = VegaParser.parse(event.data);
|
|
2025
2278
|
|
|
2279
|
+
if (!socketMessage) {
|
|
2280
|
+
return this.logger.log("VegaConnectionManager: Received invalid message", event.data);
|
|
2281
|
+
}
|
|
2282
|
+
|
|
2026
2283
|
this.logger.log("VegaConnectionManager: Received message", socketMessage);
|
|
2027
2284
|
|
|
2028
|
-
if (socketMessage
|
|
2285
|
+
if (socketMessage.response) {
|
|
2029
2286
|
this._handleResponse(socketMessage);
|
|
2030
|
-
} else if (socketMessage
|
|
2287
|
+
} else if (socketMessage.message) {
|
|
2031
2288
|
this.emit("message", socketMessage);
|
|
2032
2289
|
}
|
|
2033
2290
|
}
|
|
@@ -2134,7 +2391,7 @@ const VIDEO_SETTINGS_VP9 = {
|
|
|
2134
2391
|
codecOptions: {
|
|
2135
2392
|
videoGoogleStartBitrate: 500,
|
|
2136
2393
|
},
|
|
2137
|
-
encodings: [{ scalabilityMode: "
|
|
2394
|
+
encodings: [{ scalabilityMode: "L3T2_KEY", networkPriority: "high" }],
|
|
2138
2395
|
};
|
|
2139
2396
|
|
|
2140
2397
|
const SCREEN_SHARE_SETTINGS = {
|
|
@@ -2143,13 +2400,13 @@ const SCREEN_SHARE_SETTINGS = {
|
|
|
2143
2400
|
|
|
2144
2401
|
const SCREEN_SHARE_SIMULCAST_SETTINGS = {
|
|
2145
2402
|
encodings: [
|
|
2146
|
-
{ dtx: true, maxBitrate: 500000 },
|
|
2147
|
-
{ dtx: true, maxBitrate: 1500000 },
|
|
2403
|
+
{ scaleResolutionDownBy: 2, dtx: true, maxBitrate: 500000 },
|
|
2404
|
+
{ scaleResolutionDownBy: 1, dtx: true, maxBitrate: 1500000 },
|
|
2148
2405
|
],
|
|
2149
2406
|
};
|
|
2150
2407
|
|
|
2151
2408
|
const SCREEN_SHARE_SETTINGS_VP9 = {
|
|
2152
|
-
encodings: [{ scalabilityMode: "
|
|
2409
|
+
encodings: [{ scalabilityMode: "L1T1", dtx: true, networkPriority: "high" }],
|
|
2153
2410
|
};
|
|
2154
2411
|
|
|
2155
2412
|
const getMediaSettings = (kind, isScreenShare, features) => {
|
|
@@ -2165,8 +2422,8 @@ const getMediaSettings = (kind, isScreenShare, features) => {
|
|
|
2165
2422
|
|
|
2166
2423
|
return SCREEN_SHARE_SETTINGS;
|
|
2167
2424
|
} else {
|
|
2168
|
-
if (lowDataModeEnabled) return VIDEO_SETTINGS_SD;
|
|
2169
2425
|
if (vp9On) return VIDEO_SETTINGS_VP9;
|
|
2426
|
+
if (lowDataModeEnabled) return VIDEO_SETTINGS_SD;
|
|
2170
2427
|
|
|
2171
2428
|
return VIDEO_SETTINGS_HD;
|
|
2172
2429
|
}
|
|
@@ -5020,12 +5277,12 @@ class LocalParticipant extends RoomParticipant {
|
|
|
5020
5277
|
}
|
|
5021
5278
|
}
|
|
5022
5279
|
|
|
5023
|
-
const API_BASE_URL = "https://api.
|
|
5280
|
+
const API_BASE_URL = "https://api.whereby.dev";
|
|
5024
5281
|
const SIGNAL_BASE_URL = "wss://signal.appearin.net";
|
|
5025
5282
|
const NON_PERSON_ROLES = ["recorder", "streamer"];
|
|
5026
5283
|
function createSocket() {
|
|
5027
5284
|
const parsedUrl = new URL(SIGNAL_BASE_URL);
|
|
5028
|
-
const path = `${parsedUrl.pathname.replace(/^\/$/, "")}/protocol/socket.io/
|
|
5285
|
+
const path = `${parsedUrl.pathname.replace(/^\/$/, "")}/protocol/socket.io/v4`;
|
|
5029
5286
|
const SOCKET_HOST = parsedUrl.origin;
|
|
5030
5287
|
const socketConf = {
|
|
5031
5288
|
host: SOCKET_HOST,
|
|
@@ -5033,6 +5290,7 @@ function createSocket() {
|
|
|
5033
5290
|
reconnectionDelay: 5000,
|
|
5034
5291
|
reconnectionDelayMax: 30000,
|
|
5035
5292
|
timeout: 10000,
|
|
5293
|
+
withCredentials: true,
|
|
5036
5294
|
};
|
|
5037
5295
|
return new ServerSocket(SOCKET_HOST, socketConf);
|
|
5038
5296
|
}
|
|
@@ -5041,12 +5299,17 @@ const noop = () => {
|
|
|
5041
5299
|
};
|
|
5042
5300
|
const TypedEventTarget = EventTarget;
|
|
5043
5301
|
class RoomConnection extends TypedEventTarget {
|
|
5044
|
-
constructor(roomUrl, { displayName,
|
|
5302
|
+
constructor(roomUrl, { displayName, localMedia, localMediaConstraints, logger, roomKey }) {
|
|
5045
5303
|
super();
|
|
5046
5304
|
this.localParticipant = null;
|
|
5047
5305
|
this.remoteParticipants = [];
|
|
5048
|
-
this.
|
|
5306
|
+
this._ownsLocalMedia = false;
|
|
5307
|
+
this.organizationId = "";
|
|
5308
|
+
this.roomConnectionStatus = "";
|
|
5049
5309
|
this.roomUrl = new URL(roomUrl); // Throw if invalid Whereby room url
|
|
5310
|
+
const searchParams = new URLSearchParams(this.roomUrl.search);
|
|
5311
|
+
this._roomKey = roomKey || searchParams.get("roomKey");
|
|
5312
|
+
this.roomName = this.roomUrl.pathname;
|
|
5050
5313
|
this.logger = logger || {
|
|
5051
5314
|
debug: noop,
|
|
5052
5315
|
error: noop,
|
|
@@ -5054,10 +5317,20 @@ class RoomConnection extends TypedEventTarget {
|
|
|
5054
5317
|
warn: noop,
|
|
5055
5318
|
};
|
|
5056
5319
|
this.displayName = displayName;
|
|
5057
|
-
this.localStream = localStream;
|
|
5058
5320
|
this.localMediaConstraints = localMediaConstraints;
|
|
5059
5321
|
const urls = fromLocation({ host: this.roomUrl.host });
|
|
5060
|
-
//
|
|
5322
|
+
// Set up local media
|
|
5323
|
+
if (localMedia) {
|
|
5324
|
+
this.localMedia = localMedia;
|
|
5325
|
+
}
|
|
5326
|
+
else if (localMediaConstraints) {
|
|
5327
|
+
this.localMedia = new LocalMedia(localMediaConstraints);
|
|
5328
|
+
this._ownsLocalMedia = true;
|
|
5329
|
+
}
|
|
5330
|
+
else {
|
|
5331
|
+
throw new Error("Missing constraints");
|
|
5332
|
+
}
|
|
5333
|
+
// Set up services
|
|
5061
5334
|
this.credentialsService = CredentialsService.create({ baseUrl: API_BASE_URL });
|
|
5062
5335
|
this.apiClient = new ApiClient({
|
|
5063
5336
|
fetchDeviceCredentials: this.credentialsService.getCredentials.bind(this.credentialsService),
|
|
@@ -5079,10 +5352,30 @@ class RoomConnection extends TypedEventTarget {
|
|
|
5079
5352
|
// Create signal socket and set up event listeners
|
|
5080
5353
|
this.signalSocket = createSocket();
|
|
5081
5354
|
this.signalSocket.on("new_client", this._handleNewClient.bind(this));
|
|
5355
|
+
this.signalSocket.on("chat_message", this._handleNewChatMessage.bind(this));
|
|
5082
5356
|
this.signalSocket.on("client_left", this._handleClientLeft.bind(this));
|
|
5083
5357
|
this.signalSocket.on("audio_enabled", this._handleClientAudioEnabled.bind(this));
|
|
5084
5358
|
this.signalSocket.on("video_enabled", this._handleClientVideoEnabled.bind(this));
|
|
5085
5359
|
this.signalSocket.on("client_metadata_received", this._handleClientMetadataReceived.bind(this));
|
|
5360
|
+
this.signalSocket.on("knock_handled", this._handleKnockHandled.bind(this));
|
|
5361
|
+
this.signalSocket.on("knocker_left", this._handleKnockerLeft.bind(this));
|
|
5362
|
+
this.signalSocket.on("room_joined", this._handleRoomJoined.bind(this));
|
|
5363
|
+
this.signalSocket.on("room_knocked", this._handleRoomKnocked.bind(this));
|
|
5364
|
+
// Set up local media listeners
|
|
5365
|
+
this.localMedia.addEventListener("camera_enabled", (e) => {
|
|
5366
|
+
const { enabled } = e.detail;
|
|
5367
|
+
this.signalSocket.emit("enable_video", { enabled });
|
|
5368
|
+
});
|
|
5369
|
+
this.localMedia.addEventListener("microphone_enabled", (e) => {
|
|
5370
|
+
const { enabled } = e.detail;
|
|
5371
|
+
this.signalSocket.emit("enable_audio", { enabled });
|
|
5372
|
+
});
|
|
5373
|
+
}
|
|
5374
|
+
get roomKey() {
|
|
5375
|
+
return this._roomKey;
|
|
5376
|
+
}
|
|
5377
|
+
_handleNewChatMessage(message) {
|
|
5378
|
+
this.dispatchEvent(new CustomEvent("chat_message", { detail: message }));
|
|
5086
5379
|
}
|
|
5087
5380
|
_handleNewClient({ client }) {
|
|
5088
5381
|
if (NON_PERSON_ROLES.includes(client.role.roleName)) {
|
|
@@ -5128,6 +5421,70 @@ class RoomConnection extends TypedEventTarget {
|
|
|
5128
5421
|
detail: { participantId: remoteParticipant.id, displayName },
|
|
5129
5422
|
}));
|
|
5130
5423
|
}
|
|
5424
|
+
_handleKnockHandled(payload) {
|
|
5425
|
+
const { resolution } = payload;
|
|
5426
|
+
if (resolution === "accepted") {
|
|
5427
|
+
this.roomConnectionStatus = "accepted";
|
|
5428
|
+
this._roomKey = payload.metadata.roomKey;
|
|
5429
|
+
this._joinRoom();
|
|
5430
|
+
}
|
|
5431
|
+
else if (resolution === "rejected") {
|
|
5432
|
+
this.roomConnectionStatus = "rejected";
|
|
5433
|
+
this.dispatchEvent(new CustomEvent("room_connection_status_changed", {
|
|
5434
|
+
detail: {
|
|
5435
|
+
roomConnectionStatus: this.roomConnectionStatus,
|
|
5436
|
+
},
|
|
5437
|
+
}));
|
|
5438
|
+
}
|
|
5439
|
+
}
|
|
5440
|
+
_handleKnockerLeft(payload) {
|
|
5441
|
+
const { clientId } = payload;
|
|
5442
|
+
this.dispatchEvent(new CustomEvent("waiting_participant_left", {
|
|
5443
|
+
detail: { participantId: clientId },
|
|
5444
|
+
}));
|
|
5445
|
+
}
|
|
5446
|
+
_handleRoomJoined(event) {
|
|
5447
|
+
const { error, isLocked, room, selfId } = event;
|
|
5448
|
+
if (error === "room_locked" && isLocked) {
|
|
5449
|
+
this.roomConnectionStatus = "room_locked";
|
|
5450
|
+
this.dispatchEvent(new CustomEvent("room_connection_status_changed", {
|
|
5451
|
+
detail: {
|
|
5452
|
+
roomConnectionStatus: this.roomConnectionStatus,
|
|
5453
|
+
},
|
|
5454
|
+
}));
|
|
5455
|
+
return;
|
|
5456
|
+
}
|
|
5457
|
+
// Check if we have an error
|
|
5458
|
+
// Check if it is a room joined error
|
|
5459
|
+
// Set state to connect_failed_locked
|
|
5460
|
+
// Set state to connect_failed_no_host
|
|
5461
|
+
if (room) {
|
|
5462
|
+
const { clients, knockers } = room;
|
|
5463
|
+
const localClient = clients.find((c) => c.id === selfId);
|
|
5464
|
+
if (!localClient)
|
|
5465
|
+
throw new Error("Missing local client");
|
|
5466
|
+
this.localParticipant = new LocalParticipant(Object.assign(Object.assign({}, localClient), { stream: this.localMedia.stream || undefined }));
|
|
5467
|
+
this.remoteParticipants = clients
|
|
5468
|
+
.filter((c) => c.id !== selfId)
|
|
5469
|
+
.map((c) => new RemoteParticipant(Object.assign(Object.assign({}, c), { newJoiner: false })));
|
|
5470
|
+
this.roomConnectionStatus = "connected";
|
|
5471
|
+
this.dispatchEvent(new CustomEvent("room_joined", {
|
|
5472
|
+
detail: {
|
|
5473
|
+
localParticipant: this.localParticipant,
|
|
5474
|
+
remoteParticipants: this.remoteParticipants,
|
|
5475
|
+
waitingParticipants: knockers.map((knocker) => {
|
|
5476
|
+
return { id: knocker.clientId, displayName: knocker.displayName };
|
|
5477
|
+
}),
|
|
5478
|
+
},
|
|
5479
|
+
}));
|
|
5480
|
+
}
|
|
5481
|
+
}
|
|
5482
|
+
_handleRoomKnocked(event) {
|
|
5483
|
+
const { clientId, displayName } = event;
|
|
5484
|
+
this.dispatchEvent(new CustomEvent("waiting_participant_joined", {
|
|
5485
|
+
detail: { participantId: clientId, displayName },
|
|
5486
|
+
}));
|
|
5487
|
+
}
|
|
5131
5488
|
_handleRtcEvent(eventName, data) {
|
|
5132
5489
|
if (eventName === "rtc_manager_created") {
|
|
5133
5490
|
return this._handleRtcManagerCreated(data);
|
|
@@ -5140,10 +5497,14 @@ class RoomConnection extends TypedEventTarget {
|
|
|
5140
5497
|
}
|
|
5141
5498
|
}
|
|
5142
5499
|
_handleRtcManagerCreated({ rtcManager }) {
|
|
5143
|
-
var _a
|
|
5500
|
+
var _a;
|
|
5144
5501
|
this.rtcManager = rtcManager;
|
|
5145
|
-
|
|
5146
|
-
|
|
5502
|
+
this.localMedia.addRtcManager(rtcManager);
|
|
5503
|
+
if (this.localMedia.stream) {
|
|
5504
|
+
(_a = this.rtcManager) === null || _a === void 0 ? void 0 : _a.addNewStream("0", this.localMedia.stream, !this.localMedia.isMicrophoneEnabled(), !this.localMedia.isCameraEnabled());
|
|
5505
|
+
}
|
|
5506
|
+
if (this.remoteParticipants.length) {
|
|
5507
|
+
this._handleAcceptStreams(this.remoteParticipants);
|
|
5147
5508
|
}
|
|
5148
5509
|
}
|
|
5149
5510
|
_handleAcceptStreams(remoteParticipants) {
|
|
@@ -5168,8 +5529,6 @@ class RoomConnection extends TypedEventTarget {
|
|
|
5168
5529
|
if (!newState) {
|
|
5169
5530
|
return;
|
|
5170
5531
|
}
|
|
5171
|
-
// #endregion
|
|
5172
|
-
// #region doAcceptStreams
|
|
5173
5532
|
if (newState === "to_accept" ||
|
|
5174
5533
|
(newState === "new_accept" && shouldAcceptNewClients) ||
|
|
5175
5534
|
(newState === "old_accept" && !shouldAcceptNewClients)) {
|
|
@@ -5193,7 +5552,6 @@ class RoomConnection extends TypedEventTarget {
|
|
|
5193
5552
|
else ;
|
|
5194
5553
|
// Update stream state
|
|
5195
5554
|
participant.updateStreamState(streamId, streamState.replace(/to_|new_|old_/, "done_"));
|
|
5196
|
-
// #endregion
|
|
5197
5555
|
});
|
|
5198
5556
|
});
|
|
5199
5557
|
}
|
|
@@ -5205,35 +5563,51 @@ class RoomConnection extends TypedEventTarget {
|
|
|
5205
5563
|
}
|
|
5206
5564
|
this.dispatchEvent(new CustomEvent("participant_stream_added", { detail: { participantId: clientId, stream, streamId } }));
|
|
5207
5565
|
}
|
|
5208
|
-
|
|
5209
|
-
|
|
5210
|
-
|
|
5566
|
+
_joinRoom() {
|
|
5567
|
+
this.signalSocket.emit("join_room", {
|
|
5568
|
+
avatarUrl: null,
|
|
5569
|
+
config: {
|
|
5570
|
+
isAudioEnabled: this.localMedia.isMicrophoneEnabled(),
|
|
5571
|
+
isVideoEnabled: this.localMedia.isCameraEnabled(),
|
|
5572
|
+
},
|
|
5573
|
+
deviceCapabilities: { canScreenshare: true },
|
|
5574
|
+
displayName: this.displayName,
|
|
5575
|
+
isCoLocated: false,
|
|
5576
|
+
isDevicePermissionDenied: false,
|
|
5577
|
+
kickFromOtherRooms: false,
|
|
5578
|
+
organizationId: this.organizationId,
|
|
5579
|
+
roomKey: this.roomKey,
|
|
5580
|
+
roomName: this.roomName,
|
|
5581
|
+
selfId: "",
|
|
5582
|
+
userAgent: `browser-sdk:${sdkVersion }`,
|
|
5583
|
+
});
|
|
5584
|
+
}
|
|
5211
5585
|
join() {
|
|
5212
5586
|
return tslib.__awaiter(this, void 0, void 0, function* () {
|
|
5213
|
-
if (["connected", "connecting"].includes(this.
|
|
5214
|
-
console.warn(`Trying to join room state is ${this.
|
|
5587
|
+
if (["connected", "connecting"].includes(this.roomConnectionStatus)) {
|
|
5588
|
+
console.warn(`Trying to join when room state is already ${this.roomConnectionStatus}`);
|
|
5215
5589
|
return;
|
|
5216
5590
|
}
|
|
5217
5591
|
this.logger.log("Joining room");
|
|
5218
|
-
this.
|
|
5219
|
-
|
|
5220
|
-
|
|
5221
|
-
|
|
5222
|
-
|
|
5592
|
+
this.roomConnectionStatus = "connecting";
|
|
5593
|
+
this.dispatchEvent(new CustomEvent("room_connection_status_changed", {
|
|
5594
|
+
detail: {
|
|
5595
|
+
roomConnectionStatus: this.roomConnectionStatus,
|
|
5596
|
+
},
|
|
5597
|
+
}));
|
|
5223
5598
|
const organization = yield this.organizationServiceCache.fetchOrganization();
|
|
5224
5599
|
if (!organization) {
|
|
5225
5600
|
throw new Error("Invalid room url");
|
|
5226
5601
|
}
|
|
5227
|
-
|
|
5228
|
-
|
|
5602
|
+
this.organizationId = organization.organizationId;
|
|
5603
|
+
if (this._ownsLocalMedia) {
|
|
5604
|
+
yield this.localMedia.start();
|
|
5605
|
+
}
|
|
5229
5606
|
const webrtcProvider = {
|
|
5230
|
-
getMediaConstraints: () => {
|
|
5231
|
-
|
|
5232
|
-
|
|
5233
|
-
|
|
5234
|
-
video: !!((_b = this.localStream) === null || _b === void 0 ? void 0 : _b.getVideoTracks().find((t) => t.enabled)),
|
|
5235
|
-
});
|
|
5236
|
-
},
|
|
5607
|
+
getMediaConstraints: () => ({
|
|
5608
|
+
audio: this.localMedia.isMicrophoneEnabled(),
|
|
5609
|
+
video: this.localMedia.isCameraEnabled(),
|
|
5610
|
+
}),
|
|
5237
5611
|
deferrable(clientId) {
|
|
5238
5612
|
return !clientId;
|
|
5239
5613
|
},
|
|
@@ -5256,55 +5630,40 @@ class RoomConnection extends TypedEventTarget {
|
|
|
5256
5630
|
});
|
|
5257
5631
|
// Identify device on signal connection
|
|
5258
5632
|
const deviceCredentials = yield this.credentialsService.getCredentials();
|
|
5259
|
-
|
|
5260
|
-
|
|
5261
|
-
this.logger.log("Connected to signal socket");
|
|
5262
|
-
this.signalSocket.emit("identify_device", { deviceCredentials });
|
|
5263
|
-
}, 2000);
|
|
5633
|
+
this.logger.log("Connected to signal socket");
|
|
5634
|
+
this.signalSocket.emit("identify_device", { deviceCredentials });
|
|
5264
5635
|
this.signalSocket.once("device_identified", () => {
|
|
5265
|
-
|
|
5266
|
-
this.signalSocket.emit("join_room", {
|
|
5267
|
-
avatarUrl: null,
|
|
5268
|
-
config: {
|
|
5269
|
-
isAudioEnabled: !!((_a = this.localStream) === null || _a === void 0 ? void 0 : _a.getAudioTracks().find((t) => t.enabled)),
|
|
5270
|
-
isVideoEnabled: !!((_b = this.localStream) === null || _b === void 0 ? void 0 : _b.getVideoTracks().find((t) => t.enabled)),
|
|
5271
|
-
},
|
|
5272
|
-
deviceCapabilities: { canScreenshare: true },
|
|
5273
|
-
displayName: this.displayName,
|
|
5274
|
-
isCoLocated: false,
|
|
5275
|
-
isDevicePermissionDenied: false,
|
|
5276
|
-
kickFromOtherRooms: false,
|
|
5277
|
-
organizationId: organization.organizationId,
|
|
5278
|
-
roomKey: null,
|
|
5279
|
-
roomName: this.roomUrl.pathname,
|
|
5280
|
-
selfId: "",
|
|
5281
|
-
});
|
|
5282
|
-
});
|
|
5283
|
-
this.signalSocket.once("room_joined", (res) => {
|
|
5284
|
-
const { selfId, room: { clients }, } = res;
|
|
5285
|
-
const localClient = clients.find((c) => c.id === selfId);
|
|
5286
|
-
if (!localClient)
|
|
5287
|
-
throw new Error("Missing local client");
|
|
5288
|
-
this.localParticipant = new LocalParticipant(Object.assign(Object.assign({}, localClient), { stream: this.localStream }));
|
|
5289
|
-
this.remoteParticipants = clients
|
|
5290
|
-
.filter((c) => c.id !== selfId)
|
|
5291
|
-
.map((c) => new RemoteParticipant(Object.assign(Object.assign({}, c), { newJoiner: false })));
|
|
5292
|
-
// Accept remote streams if RTC manager has been initialized
|
|
5293
|
-
if (this.rtcManager) {
|
|
5294
|
-
this._handleAcceptStreams(this.remoteParticipants);
|
|
5295
|
-
}
|
|
5296
|
-
this.roomConnectionState = "connected";
|
|
5297
|
-
this.dispatchEvent(new CustomEvent("room_joined", {
|
|
5298
|
-
detail: {
|
|
5299
|
-
localParticipant: this.localParticipant,
|
|
5300
|
-
remoteParticipants: this.remoteParticipants,
|
|
5301
|
-
},
|
|
5302
|
-
}));
|
|
5636
|
+
this._joinRoom();
|
|
5303
5637
|
});
|
|
5304
5638
|
});
|
|
5305
5639
|
}
|
|
5640
|
+
knock() {
|
|
5641
|
+
this.roomConnectionStatus = "knocking";
|
|
5642
|
+
this.dispatchEvent(new CustomEvent("room_connection_status_changed", {
|
|
5643
|
+
detail: {
|
|
5644
|
+
roomConnectionStatus: this.roomConnectionStatus,
|
|
5645
|
+
},
|
|
5646
|
+
}));
|
|
5647
|
+
this.signalSocket.emit("knock_room", {
|
|
5648
|
+
displayName: this.displayName,
|
|
5649
|
+
imageUrl: null,
|
|
5650
|
+
kickFromOtherRooms: true,
|
|
5651
|
+
liveVideo: false,
|
|
5652
|
+
organizationId: this.organizationId,
|
|
5653
|
+
roomKey: this._roomKey,
|
|
5654
|
+
roomName: this.roomName,
|
|
5655
|
+
});
|
|
5656
|
+
}
|
|
5306
5657
|
leave() {
|
|
5307
5658
|
return new Promise((resolve) => {
|
|
5659
|
+
if (this._ownsLocalMedia) {
|
|
5660
|
+
this.localMedia.stop();
|
|
5661
|
+
}
|
|
5662
|
+
if (this.rtcManager) {
|
|
5663
|
+
this.localMedia.removeRtcManager(this.rtcManager);
|
|
5664
|
+
this.rtcManager.disconnectAll();
|
|
5665
|
+
this.rtcManager = undefined;
|
|
5666
|
+
}
|
|
5308
5667
|
if (!this.signalSocket) {
|
|
5309
5668
|
return resolve();
|
|
5310
5669
|
}
|
|
@@ -5319,29 +5678,10 @@ class RoomConnection extends TypedEventTarget {
|
|
|
5319
5678
|
});
|
|
5320
5679
|
});
|
|
5321
5680
|
}
|
|
5322
|
-
|
|
5323
|
-
|
|
5324
|
-
|
|
5325
|
-
|
|
5326
|
-
this.logger.log("Tried toggling non-existing video track");
|
|
5327
|
-
return;
|
|
5328
|
-
}
|
|
5329
|
-
// TODO: Do stopOrResumeVideo
|
|
5330
|
-
const newValue = enabled !== null && enabled !== void 0 ? enabled : !localVideoTrack.enabled;
|
|
5331
|
-
localVideoTrack.enabled = newValue;
|
|
5332
|
-
this.signalSocket.emit("enable_video", { enabled: newValue });
|
|
5333
|
-
}
|
|
5334
|
-
toggleMicrophone(enabled) {
|
|
5335
|
-
var _a;
|
|
5336
|
-
const localAudioTrack = (_a = this.localStream) === null || _a === void 0 ? void 0 : _a.getAudioTracks()[0];
|
|
5337
|
-
if (!localAudioTrack) {
|
|
5338
|
-
this.logger.log("Tried toggling non-existing audio track");
|
|
5339
|
-
return;
|
|
5340
|
-
}
|
|
5341
|
-
// TODO: Do stopOrResumeAudio
|
|
5342
|
-
const newValue = enabled !== null && enabled !== void 0 ? enabled : !localAudioTrack.enabled;
|
|
5343
|
-
localAudioTrack.enabled = newValue;
|
|
5344
|
-
this.signalSocket.emit("enable_audio", { enabled: newValue });
|
|
5681
|
+
sendChatMessage(text) {
|
|
5682
|
+
this.signalSocket.emit("chat_message", {
|
|
5683
|
+
text,
|
|
5684
|
+
});
|
|
5345
5685
|
}
|
|
5346
5686
|
setDisplayName(displayName) {
|
|
5347
5687
|
this.signalSocket.emit("send_client_metadata", {
|
|
@@ -5351,8 +5691,31 @@ class RoomConnection extends TypedEventTarget {
|
|
|
5351
5691
|
},
|
|
5352
5692
|
});
|
|
5353
5693
|
}
|
|
5694
|
+
acceptWaitingParticipant(participantId) {
|
|
5695
|
+
this.signalSocket.emit("handle_knock", {
|
|
5696
|
+
action: "accept",
|
|
5697
|
+
clientId: participantId,
|
|
5698
|
+
response: {},
|
|
5699
|
+
});
|
|
5700
|
+
}
|
|
5701
|
+
rejectWaitingParticipant(participantId) {
|
|
5702
|
+
this.signalSocket.emit("handle_knock", {
|
|
5703
|
+
action: "reject",
|
|
5704
|
+
clientId: participantId,
|
|
5705
|
+
response: {},
|
|
5706
|
+
});
|
|
5707
|
+
}
|
|
5354
5708
|
}
|
|
5355
5709
|
|
|
5710
|
+
const initialState = {
|
|
5711
|
+
chatMessages: [],
|
|
5712
|
+
roomConnectionStatus: "",
|
|
5713
|
+
isJoining: false,
|
|
5714
|
+
joinError: null,
|
|
5715
|
+
mostRecentChatMessage: null,
|
|
5716
|
+
remoteParticipants: [],
|
|
5717
|
+
waitingParticipants: [],
|
|
5718
|
+
};
|
|
5356
5719
|
function updateParticipant(remoteParticipants, participantId, updates) {
|
|
5357
5720
|
const existingParticipant = remoteParticipants.find((p) => p.id === participantId);
|
|
5358
5721
|
if (!existingParticipant) {
|
|
@@ -5367,8 +5730,12 @@ function updateParticipant(remoteParticipants, participantId, updates) {
|
|
|
5367
5730
|
}
|
|
5368
5731
|
function reducer(state, action) {
|
|
5369
5732
|
switch (action.type) {
|
|
5733
|
+
case "CHAT_MESSAGE":
|
|
5734
|
+
return Object.assign(Object.assign({}, state), { chatMessages: [...state.chatMessages, action.payload], mostRecentChatMessage: action.payload });
|
|
5370
5735
|
case "ROOM_JOINED":
|
|
5371
|
-
return Object.assign(Object.assign({}, state), { localParticipant: action.payload.localParticipant, remoteParticipants: action.payload.remoteParticipants, roomConnectionStatus: "connected" });
|
|
5736
|
+
return Object.assign(Object.assign({}, state), { localParticipant: action.payload.localParticipant, remoteParticipants: action.payload.remoteParticipants, waitingParticipants: action.payload.waitingParticipants, roomConnectionStatus: "connected" });
|
|
5737
|
+
case "ROOM_CONNECTION_STATUS_CHANGED":
|
|
5738
|
+
return Object.assign(Object.assign({}, state), { roomConnectionStatus: action.payload.roomConnectionStatus });
|
|
5372
5739
|
case "PARTICIPANT_AUDIO_ENABLED":
|
|
5373
5740
|
return Object.assign(Object.assign({}, state), { remoteParticipants: updateParticipant(state.remoteParticipants, action.payload.participantId, {
|
|
5374
5741
|
isAudioEnabled: action.payload.isAudioEnabled,
|
|
@@ -5393,21 +5760,28 @@ function reducer(state, action) {
|
|
|
5393
5760
|
if (!state.localParticipant)
|
|
5394
5761
|
return state;
|
|
5395
5762
|
return Object.assign(Object.assign({}, state), { localParticipant: Object.assign(Object.assign({}, state.localParticipant), { displayName: action.payload.displayName }) });
|
|
5763
|
+
case "WAITING_PARTICIPANT_JOINED":
|
|
5764
|
+
return Object.assign(Object.assign({}, state), { waitingParticipants: [
|
|
5765
|
+
...state.waitingParticipants,
|
|
5766
|
+
{ id: action.payload.participantId, displayName: action.payload.displayName },
|
|
5767
|
+
] });
|
|
5768
|
+
case "WAITING_PARTICIPANT_LEFT":
|
|
5769
|
+
return Object.assign(Object.assign({}, state), { waitingParticipants: state.waitingParticipants.filter((wp) => wp.id !== action.payload.participantId) });
|
|
5396
5770
|
default:
|
|
5397
5771
|
throw state;
|
|
5398
5772
|
}
|
|
5399
|
-
}
|
|
5400
|
-
|
|
5773
|
+
}
|
|
5401
5774
|
function useRoomConnection(roomUrl, roomConnectionOptions) {
|
|
5402
|
-
const [roomConnection
|
|
5403
|
-
|
|
5404
|
-
|
|
5405
|
-
|
|
5406
|
-
|
|
5775
|
+
const [roomConnection] = React.useState(() => {
|
|
5776
|
+
var _a;
|
|
5777
|
+
return new RoomConnection(roomUrl, Object.assign(Object.assign({}, roomConnectionOptions), { localMedia: ((_a = roomConnectionOptions === null || roomConnectionOptions === void 0 ? void 0 : roomConnectionOptions.localMedia) === null || _a === void 0 ? void 0 : _a._ref) || undefined }));
|
|
5778
|
+
});
|
|
5779
|
+
const [state, dispatch] = React.useReducer(reducer, initialState);
|
|
5407
5780
|
React.useEffect(() => {
|
|
5408
|
-
|
|
5409
|
-
|
|
5410
|
-
|
|
5781
|
+
roomConnection.addEventListener("chat_message", (e) => {
|
|
5782
|
+
const chatMessage = e.detail;
|
|
5783
|
+
dispatch({ type: "CHAT_MESSAGE", payload: chatMessage });
|
|
5784
|
+
});
|
|
5411
5785
|
roomConnection.addEventListener("participant_audio_enabled", (e) => {
|
|
5412
5786
|
const { participantId, isAudioEnabled } = e.detail;
|
|
5413
5787
|
dispatch({ type: "PARTICIPANT_AUDIO_ENABLED", payload: { participantId, isAudioEnabled } });
|
|
@@ -5424,9 +5798,13 @@ function useRoomConnection(roomUrl, roomConnectionOptions) {
|
|
|
5424
5798
|
const { participantId, stream } = e.detail;
|
|
5425
5799
|
dispatch({ type: "PARTICIPANT_STREAM_ADDED", payload: { participantId, stream } });
|
|
5426
5800
|
});
|
|
5801
|
+
roomConnection.addEventListener("room_connection_status_changed", (e) => {
|
|
5802
|
+
const { roomConnectionStatus } = e.detail;
|
|
5803
|
+
dispatch({ type: "ROOM_CONNECTION_STATUS_CHANGED", payload: { roomConnectionStatus } });
|
|
5804
|
+
});
|
|
5427
5805
|
roomConnection.addEventListener("room_joined", (e) => {
|
|
5428
|
-
const { localParticipant, remoteParticipants } = e.detail;
|
|
5429
|
-
dispatch({ type: "ROOM_JOINED", payload: { localParticipant, remoteParticipants } });
|
|
5806
|
+
const { localParticipant, remoteParticipants, waitingParticipants } = e.detail;
|
|
5807
|
+
dispatch({ type: "ROOM_JOINED", payload: { localParticipant, remoteParticipants, waitingParticipants } });
|
|
5430
5808
|
});
|
|
5431
5809
|
roomConnection.addEventListener("participant_video_enabled", (e) => {
|
|
5432
5810
|
const { participantId, isVideoEnabled } = e.detail;
|
|
@@ -5436,32 +5814,55 @@ function useRoomConnection(roomUrl, roomConnectionOptions) {
|
|
|
5436
5814
|
const { participantId, displayName } = e.detail;
|
|
5437
5815
|
dispatch({ type: "PARTICIPANT_METADATA_CHANGED", payload: { participantId, displayName } });
|
|
5438
5816
|
});
|
|
5817
|
+
roomConnection.addEventListener("waiting_participant_joined", (e) => {
|
|
5818
|
+
const { participantId, displayName } = e.detail;
|
|
5819
|
+
dispatch({ type: "WAITING_PARTICIPANT_JOINED", payload: { participantId, displayName } });
|
|
5820
|
+
});
|
|
5821
|
+
roomConnection.addEventListener("waiting_participant_left", (e) => {
|
|
5822
|
+
const { participantId } = e.detail;
|
|
5823
|
+
dispatch({ type: "WAITING_PARTICIPANT_LEFT", payload: { participantId } });
|
|
5824
|
+
});
|
|
5439
5825
|
roomConnection.join();
|
|
5440
5826
|
return () => {
|
|
5441
5827
|
roomConnection.leave();
|
|
5442
5828
|
};
|
|
5443
|
-
}, [
|
|
5444
|
-
return
|
|
5829
|
+
}, []);
|
|
5830
|
+
return {
|
|
5445
5831
|
state,
|
|
5446
|
-
{
|
|
5447
|
-
|
|
5448
|
-
roomConnection
|
|
5832
|
+
actions: {
|
|
5833
|
+
knock: () => {
|
|
5834
|
+
roomConnection.knock();
|
|
5449
5835
|
},
|
|
5450
|
-
|
|
5451
|
-
roomConnection
|
|
5836
|
+
sendChatMessage: (text) => {
|
|
5837
|
+
roomConnection.sendChatMessage(text);
|
|
5452
5838
|
},
|
|
5453
5839
|
setDisplayName: (displayName) => {
|
|
5454
|
-
roomConnection
|
|
5840
|
+
roomConnection.setDisplayName(displayName);
|
|
5455
5841
|
dispatch({ type: "LOCAL_CLIENT_DISPLAY_NAME_CHANGED", payload: { displayName } });
|
|
5456
5842
|
},
|
|
5843
|
+
toggleCamera: (enabled) => {
|
|
5844
|
+
roomConnection.localMedia.toggleCameraEnabled(enabled);
|
|
5845
|
+
},
|
|
5846
|
+
toggleMicrophone: (enabled) => {
|
|
5847
|
+
roomConnection.localMedia.toggleMichrophoneEnabled(enabled);
|
|
5848
|
+
},
|
|
5849
|
+
acceptWaitingParticipant: (participantId) => {
|
|
5850
|
+
roomConnection.acceptWaitingParticipant(participantId);
|
|
5851
|
+
},
|
|
5852
|
+
rejectWaitingParticipant: (participantId) => {
|
|
5853
|
+
roomConnection.rejectWaitingParticipant(participantId);
|
|
5854
|
+
},
|
|
5457
5855
|
},
|
|
5458
|
-
{
|
|
5459
|
-
VideoView
|
|
5856
|
+
components: {
|
|
5857
|
+
VideoView,
|
|
5460
5858
|
},
|
|
5461
|
-
|
|
5859
|
+
_ref: roomConnection,
|
|
5860
|
+
};
|
|
5462
5861
|
}
|
|
5463
5862
|
|
|
5464
|
-
const sdkVersion = "2.0.0-
|
|
5863
|
+
const sdkVersion = "2.0.0-alpha10";
|
|
5465
5864
|
|
|
5865
|
+
exports.VideoView = VideoView;
|
|
5466
5866
|
exports.sdkVersion = sdkVersion;
|
|
5867
|
+
exports.useLocalMedia = useLocalMedia;
|
|
5467
5868
|
exports.useRoomConnection = useRoomConnection;
|