@whereby.com/browser-sdk 2.0.0-alpha5 → 2.0.0-alpha6
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 +292 -60
- package/dist/lib.esm.js +291 -61
- package/dist/types.d.ts +84 -4
- package/dist/{v2-alpha5.js → v2-alpha6.js} +25 -25
- package/package.json +5 -4
package/README.md
CHANGED
|
@@ -20,6 +20,42 @@ yarn add @whereby.com/browser-sdk
|
|
|
20
20
|
|
|
21
21
|
### React hooks
|
|
22
22
|
|
|
23
|
+
#### useLocalMedia
|
|
24
|
+
The `useLocalMedia` hook enables preview and selection of local devices (camera & microphone) prior to establishing a connection within a Whereby room. Use this hook to build rich pre-call
|
|
25
|
+
experiences, allowing end users to confirm their device selection up-front. This hook works seamlessly with the `useRoomConnection` hook described below.
|
|
26
|
+
|
|
27
|
+
```
|
|
28
|
+
import { useLocalMedia, VideoView } from “@whereby.com/browser-sdk”;
|
|
29
|
+
|
|
30
|
+
function MyPreCallUX() {
|
|
31
|
+
const localMedia = useLocalMedia({ audio: false, video: true });
|
|
32
|
+
|
|
33
|
+
const { currentCameraDeviceId, cameraDevices, localStream } = localMedia.state;
|
|
34
|
+
const { setCameraDevice, toggleCameraEnabled } = localMedia.actions;
|
|
35
|
+
const { VideoView } = components;
|
|
36
|
+
|
|
37
|
+
return <div className="preCallView">
|
|
38
|
+
{ /* Render any UI, making use of state */ }
|
|
39
|
+
{ cameraDevices.map((d) => (
|
|
40
|
+
<p
|
|
41
|
+
key={d.deviceId}
|
|
42
|
+
onClick={() => {
|
|
43
|
+
if (d.deviceId !== currentCameraDeviceId) {
|
|
44
|
+
setCameraDevice(d.deviceId);
|
|
45
|
+
}
|
|
46
|
+
}}
|
|
47
|
+
>
|
|
48
|
+
{d.label}
|
|
49
|
+
</p>
|
|
50
|
+
)) }
|
|
51
|
+
<VideoView muted stream={localStream} />
|
|
52
|
+
</div>;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
#### useRoomConnection
|
|
23
59
|
The `useRoomConnection` hook provides a way to connect participants in a given room, subscribe to state updates, and perform actions on the connection, like toggling camera or microphone.
|
|
24
60
|
|
|
25
61
|
```
|
|
@@ -29,10 +65,11 @@ function MyCallUX( { roomUrl, localStream }) {
|
|
|
29
65
|
const [state, actions, components ] = useRoomConnection(
|
|
30
66
|
"<room_url>"
|
|
31
67
|
{
|
|
32
|
-
|
|
68
|
+
localMedia: null, // Supply localMedia from `useLocalMedia` hook, or constraints below
|
|
69
|
+
localMediaConstraints: {
|
|
33
70
|
audio: true,
|
|
34
71
|
video: true,
|
|
35
|
-
}
|
|
72
|
+
}
|
|
36
73
|
}
|
|
37
74
|
);
|
|
38
75
|
|
package/dist/lib.cjs.js
CHANGED
|
@@ -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-alpha6", 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") {
|
|
@@ -165,6 +165,242 @@ var VideoView = (_a) => {
|
|
|
165
165
|
return React__default["default"].createElement("video", Object.assign({ ref: videoEl, autoPlay: true, playsInline: true }, rest));
|
|
166
166
|
};
|
|
167
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 = {
|
|
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);
|
|
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
|
+
|
|
168
404
|
const EVENTS = {
|
|
169
405
|
CLIENT_CONNECTION_STATUS_CHANGED: "client_connection_status_changed",
|
|
170
406
|
STREAM_ADDED: "stream_added",
|
|
@@ -5051,11 +5287,12 @@ const noop = () => {
|
|
|
5051
5287
|
};
|
|
5052
5288
|
const TypedEventTarget = EventTarget;
|
|
5053
5289
|
class RoomConnection extends TypedEventTarget {
|
|
5054
|
-
constructor(roomUrl, { displayName, localMediaConstraints,
|
|
5290
|
+
constructor(roomUrl, { displayName, localMediaConstraints, logger, localMedia }) {
|
|
5055
5291
|
super();
|
|
5056
5292
|
this.localParticipant = null;
|
|
5057
5293
|
this.remoteParticipants = [];
|
|
5058
5294
|
this.roomConnectionState = "";
|
|
5295
|
+
this._ownsLocalMedia = false;
|
|
5059
5296
|
this.roomUrl = new URL(roomUrl); // Throw if invalid Whereby room url
|
|
5060
5297
|
this.logger = logger || {
|
|
5061
5298
|
debug: noop,
|
|
@@ -5064,10 +5301,19 @@ class RoomConnection extends TypedEventTarget {
|
|
|
5064
5301
|
warn: noop,
|
|
5065
5302
|
};
|
|
5066
5303
|
this.displayName = displayName;
|
|
5067
|
-
this.localStream = localStream;
|
|
5068
5304
|
this.localMediaConstraints = localMediaConstraints;
|
|
5069
5305
|
const urls = fromLocation({ host: this.roomUrl.host });
|
|
5070
|
-
//
|
|
5306
|
+
// Set up local media
|
|
5307
|
+
if (localMedia) {
|
|
5308
|
+
this.localMedia = localMedia;
|
|
5309
|
+
}
|
|
5310
|
+
else if (localMediaConstraints) {
|
|
5311
|
+
this.localMedia = new LocalMedia(localMediaConstraints);
|
|
5312
|
+
this._ownsLocalMedia = true;
|
|
5313
|
+
}
|
|
5314
|
+
else {
|
|
5315
|
+
throw new Error("Missing constraints");
|
|
5316
|
+
}
|
|
5071
5317
|
this.credentialsService = CredentialsService.create({ baseUrl: API_BASE_URL });
|
|
5072
5318
|
this.apiClient = new ApiClient({
|
|
5073
5319
|
fetchDeviceCredentials: this.credentialsService.getCredentials.bind(this.credentialsService),
|
|
@@ -5093,6 +5339,15 @@ class RoomConnection extends TypedEventTarget {
|
|
|
5093
5339
|
this.signalSocket.on("audio_enabled", this._handleClientAudioEnabled.bind(this));
|
|
5094
5340
|
this.signalSocket.on("video_enabled", this._handleClientVideoEnabled.bind(this));
|
|
5095
5341
|
this.signalSocket.on("client_metadata_received", this._handleClientMetadataReceived.bind(this));
|
|
5342
|
+
// Set up local media listeners
|
|
5343
|
+
this.localMedia.addEventListener("camera_enabled", (e) => {
|
|
5344
|
+
const { enabled } = e.detail;
|
|
5345
|
+
this.signalSocket.emit("enable_video", { enabled });
|
|
5346
|
+
});
|
|
5347
|
+
this.localMedia.addEventListener("microphone_enabled", (e) => {
|
|
5348
|
+
const { enabled } = e.detail;
|
|
5349
|
+
this.signalSocket.emit("enable_audio", { enabled });
|
|
5350
|
+
});
|
|
5096
5351
|
}
|
|
5097
5352
|
_handleNewClient({ client }) {
|
|
5098
5353
|
if (NON_PERSON_ROLES.includes(client.role.roleName)) {
|
|
@@ -5150,10 +5405,11 @@ class RoomConnection extends TypedEventTarget {
|
|
|
5150
5405
|
}
|
|
5151
5406
|
}
|
|
5152
5407
|
_handleRtcManagerCreated({ rtcManager }) {
|
|
5153
|
-
var _a
|
|
5408
|
+
var _a;
|
|
5154
5409
|
this.rtcManager = rtcManager;
|
|
5155
|
-
|
|
5156
|
-
|
|
5410
|
+
this.localMedia.addRtcManager(rtcManager);
|
|
5411
|
+
if (this.localMedia.stream) {
|
|
5412
|
+
(_a = this.rtcManager) === null || _a === void 0 ? void 0 : _a.addNewStream("0", this.localMedia.stream, !this.localMedia.isMicrophoneEnabled(), !this.localMedia.isCameraEnabled());
|
|
5157
5413
|
}
|
|
5158
5414
|
}
|
|
5159
5415
|
_handleAcceptStreams(remoteParticipants) {
|
|
@@ -5178,8 +5434,6 @@ class RoomConnection extends TypedEventTarget {
|
|
|
5178
5434
|
if (!newState) {
|
|
5179
5435
|
return;
|
|
5180
5436
|
}
|
|
5181
|
-
// #endregion
|
|
5182
|
-
// #region doAcceptStreams
|
|
5183
5437
|
if (newState === "to_accept" ||
|
|
5184
5438
|
(newState === "new_accept" && shouldAcceptNewClients) ||
|
|
5185
5439
|
(newState === "old_accept" && !shouldAcceptNewClients)) {
|
|
@@ -5203,7 +5457,6 @@ class RoomConnection extends TypedEventTarget {
|
|
|
5203
5457
|
else ;
|
|
5204
5458
|
// Update stream state
|
|
5205
5459
|
participant.updateStreamState(streamId, streamState.replace(/to_|new_|old_/, "done_"));
|
|
5206
|
-
// #endregion
|
|
5207
5460
|
});
|
|
5208
5461
|
});
|
|
5209
5462
|
}
|
|
@@ -5215,9 +5468,6 @@ class RoomConnection extends TypedEventTarget {
|
|
|
5215
5468
|
}
|
|
5216
5469
|
this.dispatchEvent(new CustomEvent("participant_stream_added", { detail: { participantId: clientId, stream, streamId } }));
|
|
5217
5470
|
}
|
|
5218
|
-
/**
|
|
5219
|
-
* Public API
|
|
5220
|
-
*/
|
|
5221
5471
|
join() {
|
|
5222
5472
|
return tslib.__awaiter(this, void 0, void 0, function* () {
|
|
5223
5473
|
if (["connected", "connecting"].includes(this.roomConnectionState)) {
|
|
@@ -5226,24 +5476,16 @@ class RoomConnection extends TypedEventTarget {
|
|
|
5226
5476
|
}
|
|
5227
5477
|
this.logger.log("Joining room");
|
|
5228
5478
|
this.roomConnectionState = "connecting";
|
|
5229
|
-
if (
|
|
5230
|
-
|
|
5231
|
-
this.localStream = localStream;
|
|
5232
|
-
}
|
|
5233
|
-
const organization = yield this.organizationServiceCache.fetchOrganization();
|
|
5234
|
-
if (!organization) {
|
|
5235
|
-
throw new Error("Invalid room url");
|
|
5479
|
+
if (this._ownsLocalMedia) {
|
|
5480
|
+
yield this.localMedia.start();
|
|
5236
5481
|
}
|
|
5237
5482
|
// TODO: Get room permissions
|
|
5238
5483
|
// TODO: Get room features
|
|
5239
5484
|
const webrtcProvider = {
|
|
5240
|
-
getMediaConstraints: () => {
|
|
5241
|
-
|
|
5242
|
-
|
|
5243
|
-
|
|
5244
|
-
video: !!((_b = this.localStream) === null || _b === void 0 ? void 0 : _b.getVideoTracks().find((t) => t.enabled)),
|
|
5245
|
-
});
|
|
5246
|
-
},
|
|
5485
|
+
getMediaConstraints: () => ({
|
|
5486
|
+
audio: this.localMedia.isMicrophoneEnabled(),
|
|
5487
|
+
video: this.localMedia.isCameraEnabled(),
|
|
5488
|
+
}),
|
|
5247
5489
|
deferrable(clientId) {
|
|
5248
5490
|
return !clientId;
|
|
5249
5491
|
},
|
|
@@ -5264,6 +5506,10 @@ class RoomConnection extends TypedEventTarget {
|
|
|
5264
5506
|
simulcastScreenshareOn: false,
|
|
5265
5507
|
},
|
|
5266
5508
|
});
|
|
5509
|
+
const organization = yield this.organizationServiceCache.fetchOrganization();
|
|
5510
|
+
if (!organization) {
|
|
5511
|
+
throw new Error("Invalid room url");
|
|
5512
|
+
}
|
|
5267
5513
|
// Identify device on signal connection
|
|
5268
5514
|
const deviceCredentials = yield this.credentialsService.getCredentials();
|
|
5269
5515
|
// TODO: Handle connection and failed connection properly
|
|
@@ -5272,12 +5518,11 @@ class RoomConnection extends TypedEventTarget {
|
|
|
5272
5518
|
this.signalSocket.emit("identify_device", { deviceCredentials });
|
|
5273
5519
|
}, 2000);
|
|
5274
5520
|
this.signalSocket.once("device_identified", () => {
|
|
5275
|
-
var _a, _b;
|
|
5276
5521
|
this.signalSocket.emit("join_room", {
|
|
5277
5522
|
avatarUrl: null,
|
|
5278
5523
|
config: {
|
|
5279
|
-
isAudioEnabled:
|
|
5280
|
-
isVideoEnabled:
|
|
5524
|
+
isAudioEnabled: this.localMedia.isMicrophoneEnabled(),
|
|
5525
|
+
isVideoEnabled: this.localMedia.isCameraEnabled(),
|
|
5281
5526
|
},
|
|
5282
5527
|
deviceCapabilities: { canScreenshare: true },
|
|
5283
5528
|
displayName: this.displayName,
|
|
@@ -5288,7 +5533,7 @@ class RoomConnection extends TypedEventTarget {
|
|
|
5288
5533
|
roomKey: null,
|
|
5289
5534
|
roomName: this.roomUrl.pathname,
|
|
5290
5535
|
selfId: "",
|
|
5291
|
-
userAgent: `browser-sdk:${sdkVersion }
|
|
5536
|
+
userAgent: `browser-sdk:${sdkVersion }`,
|
|
5292
5537
|
});
|
|
5293
5538
|
});
|
|
5294
5539
|
this.signalSocket.once("room_joined", (res) => {
|
|
@@ -5296,7 +5541,7 @@ class RoomConnection extends TypedEventTarget {
|
|
|
5296
5541
|
const localClient = clients.find((c) => c.id === selfId);
|
|
5297
5542
|
if (!localClient)
|
|
5298
5543
|
throw new Error("Missing local client");
|
|
5299
|
-
this.localParticipant = new LocalParticipant(Object.assign(Object.assign({}, localClient), { stream: this.
|
|
5544
|
+
this.localParticipant = new LocalParticipant(Object.assign(Object.assign({}, localClient), { stream: this.localMedia.stream || undefined }));
|
|
5300
5545
|
this.remoteParticipants = clients
|
|
5301
5546
|
.filter((c) => c.id !== selfId)
|
|
5302
5547
|
.map((c) => new RemoteParticipant(Object.assign(Object.assign({}, c), { newJoiner: false })));
|
|
@@ -5316,6 +5561,14 @@ class RoomConnection extends TypedEventTarget {
|
|
|
5316
5561
|
}
|
|
5317
5562
|
leave() {
|
|
5318
5563
|
return new Promise((resolve) => {
|
|
5564
|
+
if (this._ownsLocalMedia) {
|
|
5565
|
+
this.localMedia.stop();
|
|
5566
|
+
}
|
|
5567
|
+
if (this.rtcManager) {
|
|
5568
|
+
this.localMedia.removeRtcManager(this.rtcManager);
|
|
5569
|
+
this.rtcManager.disconnectAll();
|
|
5570
|
+
this.rtcManager = undefined;
|
|
5571
|
+
}
|
|
5319
5572
|
if (!this.signalSocket) {
|
|
5320
5573
|
return resolve();
|
|
5321
5574
|
}
|
|
@@ -5330,30 +5583,6 @@ class RoomConnection extends TypedEventTarget {
|
|
|
5330
5583
|
});
|
|
5331
5584
|
});
|
|
5332
5585
|
}
|
|
5333
|
-
toggleCamera(enabled) {
|
|
5334
|
-
var _a;
|
|
5335
|
-
const localVideoTrack = (_a = this.localStream) === null || _a === void 0 ? void 0 : _a.getVideoTracks()[0];
|
|
5336
|
-
if (!localVideoTrack) {
|
|
5337
|
-
this.logger.log("Tried toggling non-existing video track");
|
|
5338
|
-
return;
|
|
5339
|
-
}
|
|
5340
|
-
// TODO: Do stopOrResumeVideo
|
|
5341
|
-
const newValue = enabled !== null && enabled !== void 0 ? enabled : !localVideoTrack.enabled;
|
|
5342
|
-
localVideoTrack.enabled = newValue;
|
|
5343
|
-
this.signalSocket.emit("enable_video", { enabled: newValue });
|
|
5344
|
-
}
|
|
5345
|
-
toggleMicrophone(enabled) {
|
|
5346
|
-
var _a;
|
|
5347
|
-
const localAudioTrack = (_a = this.localStream) === null || _a === void 0 ? void 0 : _a.getAudioTracks()[0];
|
|
5348
|
-
if (!localAudioTrack) {
|
|
5349
|
-
this.logger.log("Tried toggling non-existing audio track");
|
|
5350
|
-
return;
|
|
5351
|
-
}
|
|
5352
|
-
// TODO: Do stopOrResumeAudio
|
|
5353
|
-
const newValue = enabled !== null && enabled !== void 0 ? enabled : !localAudioTrack.enabled;
|
|
5354
|
-
localAudioTrack.enabled = newValue;
|
|
5355
|
-
this.signalSocket.emit("enable_audio", { enabled: newValue });
|
|
5356
|
-
}
|
|
5357
5586
|
setDisplayName(displayName) {
|
|
5358
5587
|
this.signalSocket.emit("send_client_metadata", {
|
|
5359
5588
|
type: "UserData",
|
|
@@ -5413,7 +5642,8 @@ function useRoomConnection(roomUrl, roomConnectionOptions) {
|
|
|
5413
5642
|
const [roomConnection, setRoomConnection] = React.useState(null);
|
|
5414
5643
|
const [state, dispatch] = React.useReducer(reducer, { remoteParticipants: [] });
|
|
5415
5644
|
React.useEffect(() => {
|
|
5416
|
-
|
|
5645
|
+
var _a;
|
|
5646
|
+
setRoomConnection(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 })));
|
|
5417
5647
|
}, [roomUrl]);
|
|
5418
5648
|
React.useEffect(() => {
|
|
5419
5649
|
if (!roomConnection) {
|
|
@@ -5456,10 +5686,10 @@ function useRoomConnection(roomUrl, roomConnectionOptions) {
|
|
|
5456
5686
|
state,
|
|
5457
5687
|
{
|
|
5458
5688
|
toggleCamera: (enabled) => {
|
|
5459
|
-
roomConnection === null || roomConnection === void 0 ? void 0 : roomConnection.
|
|
5689
|
+
roomConnection === null || roomConnection === void 0 ? void 0 : roomConnection.localMedia.toggleCameraEnabled(enabled);
|
|
5460
5690
|
},
|
|
5461
5691
|
toggleMicrophone: (enabled) => {
|
|
5462
|
-
roomConnection === null || roomConnection === void 0 ? void 0 : roomConnection.
|
|
5692
|
+
roomConnection === null || roomConnection === void 0 ? void 0 : roomConnection.localMedia.toggleMichrophoneEnabled(enabled);
|
|
5463
5693
|
},
|
|
5464
5694
|
setDisplayName: (displayName) => {
|
|
5465
5695
|
roomConnection === null || roomConnection === void 0 ? void 0 : roomConnection.setDisplayName(displayName);
|
|
@@ -5472,7 +5702,9 @@ function useRoomConnection(roomUrl, roomConnectionOptions) {
|
|
|
5472
5702
|
];
|
|
5473
5703
|
}
|
|
5474
5704
|
|
|
5475
|
-
const sdkVersion = "2.0.0-
|
|
5705
|
+
const sdkVersion = "2.0.0-alpha6";
|
|
5476
5706
|
|
|
5707
|
+
exports.VideoView = VideoView;
|
|
5477
5708
|
exports.sdkVersion = sdkVersion;
|
|
5709
|
+
exports.useLocalMedia = useLocalMedia;
|
|
5478
5710
|
exports.useRoomConnection = useRoomConnection;
|