@whereby.com/browser-sdk 2.0.0-alpha4 → 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 -59
- package/dist/lib.esm.js +291 -60
- package/dist/types.d.ts +84 -4
- package/dist/{v2-alpha4.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,6 +5533,7 @@ class RoomConnection extends TypedEventTarget {
|
|
|
5288
5533
|
roomKey: null,
|
|
5289
5534
|
roomName: this.roomUrl.pathname,
|
|
5290
5535
|
selfId: "",
|
|
5536
|
+
userAgent: `browser-sdk:${sdkVersion }`,
|
|
5291
5537
|
});
|
|
5292
5538
|
});
|
|
5293
5539
|
this.signalSocket.once("room_joined", (res) => {
|
|
@@ -5295,7 +5541,7 @@ class RoomConnection extends TypedEventTarget {
|
|
|
5295
5541
|
const localClient = clients.find((c) => c.id === selfId);
|
|
5296
5542
|
if (!localClient)
|
|
5297
5543
|
throw new Error("Missing local client");
|
|
5298
|
-
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 }));
|
|
5299
5545
|
this.remoteParticipants = clients
|
|
5300
5546
|
.filter((c) => c.id !== selfId)
|
|
5301
5547
|
.map((c) => new RemoteParticipant(Object.assign(Object.assign({}, c), { newJoiner: false })));
|
|
@@ -5315,6 +5561,14 @@ class RoomConnection extends TypedEventTarget {
|
|
|
5315
5561
|
}
|
|
5316
5562
|
leave() {
|
|
5317
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
|
+
}
|
|
5318
5572
|
if (!this.signalSocket) {
|
|
5319
5573
|
return resolve();
|
|
5320
5574
|
}
|
|
@@ -5329,30 +5583,6 @@ class RoomConnection extends TypedEventTarget {
|
|
|
5329
5583
|
});
|
|
5330
5584
|
});
|
|
5331
5585
|
}
|
|
5332
|
-
toggleCamera(enabled) {
|
|
5333
|
-
var _a;
|
|
5334
|
-
const localVideoTrack = (_a = this.localStream) === null || _a === void 0 ? void 0 : _a.getVideoTracks()[0];
|
|
5335
|
-
if (!localVideoTrack) {
|
|
5336
|
-
this.logger.log("Tried toggling non-existing video track");
|
|
5337
|
-
return;
|
|
5338
|
-
}
|
|
5339
|
-
// TODO: Do stopOrResumeVideo
|
|
5340
|
-
const newValue = enabled !== null && enabled !== void 0 ? enabled : !localVideoTrack.enabled;
|
|
5341
|
-
localVideoTrack.enabled = newValue;
|
|
5342
|
-
this.signalSocket.emit("enable_video", { enabled: newValue });
|
|
5343
|
-
}
|
|
5344
|
-
toggleMicrophone(enabled) {
|
|
5345
|
-
var _a;
|
|
5346
|
-
const localAudioTrack = (_a = this.localStream) === null || _a === void 0 ? void 0 : _a.getAudioTracks()[0];
|
|
5347
|
-
if (!localAudioTrack) {
|
|
5348
|
-
this.logger.log("Tried toggling non-existing audio track");
|
|
5349
|
-
return;
|
|
5350
|
-
}
|
|
5351
|
-
// TODO: Do stopOrResumeAudio
|
|
5352
|
-
const newValue = enabled !== null && enabled !== void 0 ? enabled : !localAudioTrack.enabled;
|
|
5353
|
-
localAudioTrack.enabled = newValue;
|
|
5354
|
-
this.signalSocket.emit("enable_audio", { enabled: newValue });
|
|
5355
|
-
}
|
|
5356
5586
|
setDisplayName(displayName) {
|
|
5357
5587
|
this.signalSocket.emit("send_client_metadata", {
|
|
5358
5588
|
type: "UserData",
|
|
@@ -5412,7 +5642,8 @@ function useRoomConnection(roomUrl, roomConnectionOptions) {
|
|
|
5412
5642
|
const [roomConnection, setRoomConnection] = React.useState(null);
|
|
5413
5643
|
const [state, dispatch] = React.useReducer(reducer, { remoteParticipants: [] });
|
|
5414
5644
|
React.useEffect(() => {
|
|
5415
|
-
|
|
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 })));
|
|
5416
5647
|
}, [roomUrl]);
|
|
5417
5648
|
React.useEffect(() => {
|
|
5418
5649
|
if (!roomConnection) {
|
|
@@ -5455,10 +5686,10 @@ function useRoomConnection(roomUrl, roomConnectionOptions) {
|
|
|
5455
5686
|
state,
|
|
5456
5687
|
{
|
|
5457
5688
|
toggleCamera: (enabled) => {
|
|
5458
|
-
roomConnection === null || roomConnection === void 0 ? void 0 : roomConnection.
|
|
5689
|
+
roomConnection === null || roomConnection === void 0 ? void 0 : roomConnection.localMedia.toggleCameraEnabled(enabled);
|
|
5459
5690
|
},
|
|
5460
5691
|
toggleMicrophone: (enabled) => {
|
|
5461
|
-
roomConnection === null || roomConnection === void 0 ? void 0 : roomConnection.
|
|
5692
|
+
roomConnection === null || roomConnection === void 0 ? void 0 : roomConnection.localMedia.toggleMichrophoneEnabled(enabled);
|
|
5462
5693
|
},
|
|
5463
5694
|
setDisplayName: (displayName) => {
|
|
5464
5695
|
roomConnection === null || roomConnection === void 0 ? void 0 : roomConnection.setDisplayName(displayName);
|
|
@@ -5471,7 +5702,9 @@ function useRoomConnection(roomUrl, roomConnectionOptions) {
|
|
|
5471
5702
|
];
|
|
5472
5703
|
}
|
|
5473
5704
|
|
|
5474
|
-
const sdkVersion = "2.0.0-
|
|
5705
|
+
const sdkVersion = "2.0.0-alpha6";
|
|
5475
5706
|
|
|
5707
|
+
exports.VideoView = VideoView;
|
|
5476
5708
|
exports.sdkVersion = sdkVersion;
|
|
5709
|
+
exports.useLocalMedia = useLocalMedia;
|
|
5477
5710
|
exports.useRoomConnection = useRoomConnection;
|