livekit-client 0.18.6 → 1.0.2
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 +1 -1
- package/dist/livekit-client.esm.mjs +1034 -438
- package/dist/livekit-client.esm.mjs.map +1 -1
- package/dist/livekit-client.umd.js +1 -1
- package/dist/livekit-client.umd.js.map +1 -1
- package/dist/{api → src/api}/RequestQueue.d.ts +0 -0
- package/dist/src/api/RequestQueue.d.ts.map +1 -0
- package/dist/{api → src/api}/SignalClient.d.ts +3 -3
- package/dist/src/api/SignalClient.d.ts.map +1 -0
- package/dist/{index.d.ts → src/index.d.ts} +3 -4
- package/dist/src/index.d.ts.map +1 -0
- package/dist/{logger.d.ts → src/logger.d.ts} +0 -0
- package/dist/src/logger.d.ts.map +1 -0
- package/dist/src/options.d.ts +61 -0
- package/dist/src/options.d.ts.map +1 -0
- package/dist/{proto → src/proto}/google/protobuf/timestamp.d.ts +0 -0
- package/dist/src/proto/google/protobuf/timestamp.d.ts.map +1 -0
- package/dist/{proto → src/proto}/livekit_models.d.ts +80 -0
- package/dist/src/proto/livekit_models.d.ts.map +1 -0
- package/dist/{proto → src/proto}/livekit_rtc.d.ts +661 -0
- package/dist/src/proto/livekit_rtc.d.ts.map +1 -0
- package/dist/{room → src/room}/DeviceManager.d.ts +0 -0
- package/dist/src/room/DeviceManager.d.ts.map +1 -0
- package/dist/{room → src/room}/PCTransport.d.ts +0 -0
- package/dist/src/room/PCTransport.d.ts.map +1 -0
- package/dist/{room → src/room}/RTCEngine.d.ts +4 -2
- package/dist/src/room/RTCEngine.d.ts.map +1 -0
- package/dist/{room → src/room}/Room.d.ts +13 -7
- package/dist/src/room/Room.d.ts.map +1 -0
- package/dist/{room → src/room}/errors.d.ts +0 -0
- package/dist/src/room/errors.d.ts.map +1 -0
- package/dist/{room → src/room}/events.d.ts +11 -13
- package/dist/src/room/events.d.ts.map +1 -0
- package/dist/{room → src/room}/participant/LocalParticipant.d.ts +4 -1
- package/dist/src/room/participant/LocalParticipant.d.ts.map +1 -0
- package/dist/{room → src/room}/participant/Participant.d.ts +0 -4
- package/dist/src/room/participant/Participant.d.ts.map +1 -0
- package/dist/{room → src/room}/participant/ParticipantTrackPermission.d.ts +0 -0
- package/dist/src/room/participant/ParticipantTrackPermission.d.ts.map +1 -0
- package/dist/{room → src/room}/participant/RemoteParticipant.d.ts +3 -2
- package/dist/src/room/participant/RemoteParticipant.d.ts.map +1 -0
- package/dist/{room → src/room}/participant/publishUtils.d.ts +0 -0
- package/dist/src/room/participant/publishUtils.d.ts.map +1 -0
- package/dist/{room → src/room}/stats.d.ts +1 -0
- package/dist/src/room/stats.d.ts.map +1 -0
- package/dist/{room → src/room}/track/LocalAudioTrack.d.ts +0 -0
- package/dist/src/room/track/LocalAudioTrack.d.ts.map +1 -0
- package/dist/{room → src/room}/track/LocalTrack.d.ts +3 -0
- package/dist/src/room/track/LocalTrack.d.ts.map +1 -0
- package/dist/{room → src/room}/track/LocalTrackPublication.d.ts +0 -0
- package/dist/src/room/track/LocalTrackPublication.d.ts.map +1 -0
- package/dist/{room → src/room}/track/LocalVideoTrack.d.ts +17 -2
- package/dist/src/room/track/LocalVideoTrack.d.ts.map +1 -0
- package/dist/{room → src/room}/track/RemoteAudioTrack.d.ts +0 -0
- package/dist/src/room/track/RemoteAudioTrack.d.ts.map +1 -0
- package/dist/{room → src/room}/track/RemoteTrack.d.ts +0 -1
- package/dist/src/room/track/RemoteTrack.d.ts.map +1 -0
- package/dist/{room → src/room}/track/RemoteTrackPublication.d.ts +0 -0
- package/dist/src/room/track/RemoteTrackPublication.d.ts.map +1 -0
- package/dist/{room → src/room}/track/RemoteVideoTrack.d.ts +25 -1
- package/dist/src/room/track/RemoteVideoTrack.d.ts.map +1 -0
- package/dist/{room → src/room}/track/Track.d.ts +6 -1
- package/dist/src/room/track/Track.d.ts.map +1 -0
- package/dist/{room → src/room}/track/TrackPublication.d.ts +0 -0
- package/dist/src/room/track/TrackPublication.d.ts.map +1 -0
- package/dist/{room → src/room}/track/create.d.ts +0 -0
- package/dist/src/room/track/create.d.ts.map +1 -0
- package/dist/{room → src/room}/track/defaults.d.ts +0 -0
- package/dist/src/room/track/defaults.d.ts.map +1 -0
- package/dist/{room → src/room}/track/options.d.ts +2 -31
- package/dist/src/room/track/options.d.ts.map +1 -0
- package/dist/{room → src/room}/track/types.d.ts +5 -0
- package/dist/src/room/track/types.d.ts.map +1 -0
- package/dist/{room → src/room}/track/utils.d.ts +0 -0
- package/dist/src/room/track/utils.d.ts.map +1 -0
- package/dist/{room → src/room}/utils.d.ts +0 -0
- package/dist/src/room/utils.d.ts.map +1 -0
- package/dist/src/test/MockMediaStreamTrack.d.ts +26 -0
- package/dist/src/test/MockMediaStreamTrack.d.ts.map +1 -0
- package/dist/{test → src/test}/mocks.d.ts +0 -0
- package/dist/src/test/mocks.d.ts.map +1 -0
- package/dist/src/version.d.ts +3 -0
- package/dist/src/version.d.ts.map +1 -0
- package/package.json +6 -2
- package/src/api/SignalClient.ts +34 -9
- package/src/index.ts +4 -3
- package/src/options.ts +0 -82
- package/src/proto/livekit_models.ts +90 -0
- package/src/proto/livekit_rtc.ts +235 -1
- package/src/room/DeviceManager.ts +4 -1
- package/src/room/RTCEngine.ts +46 -9
- package/src/room/Room.ts +122 -53
- package/src/room/events.ts +12 -14
- package/src/room/participant/LocalParticipant.ts +108 -23
- package/src/room/participant/Participant.ts +0 -5
- package/src/room/participant/RemoteParticipant.ts +17 -5
- package/src/room/participant/publishUtils.test.ts +2 -2
- package/src/room/stats.ts +2 -0
- package/src/room/track/LocalAudioTrack.ts +4 -0
- package/src/room/track/LocalTrack.ts +12 -5
- package/src/room/track/LocalVideoTrack.ts +144 -56
- package/src/room/track/RemoteTrack.ts +0 -2
- package/src/room/track/RemoteVideoTrack.test.ts +149 -0
- package/src/room/track/RemoteVideoTrack.ts +118 -37
- package/src/room/track/Track.ts +23 -2
- package/src/room/track/create.ts +1 -1
- package/src/room/track/options.ts +2 -31
- package/src/room/track/types.ts +5 -0
- package/src/room/track/utils.test.ts +6 -6
- package/src/test/MockMediaStreamTrack.ts +83 -0
- package/src/version.ts +4 -2
- package/dist/api/RequestQueue.d.ts.map +0 -1
- package/dist/api/SignalClient.d.ts.map +0 -1
- package/dist/connect.d.ts +0 -24
- package/dist/connect.d.ts.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/logger.d.ts.map +0 -1
- package/dist/options.d.ts +0 -128
- package/dist/options.d.ts.map +0 -1
- package/dist/proto/google/protobuf/timestamp.d.ts.map +0 -1
- package/dist/proto/livekit_models.d.ts.map +0 -1
- package/dist/proto/livekit_rtc.d.ts.map +0 -1
- package/dist/room/DeviceManager.d.ts.map +0 -1
- package/dist/room/PCTransport.d.ts.map +0 -1
- package/dist/room/RTCEngine.d.ts.map +0 -1
- package/dist/room/Room.d.ts.map +0 -1
- package/dist/room/errors.d.ts.map +0 -1
- package/dist/room/events.d.ts.map +0 -1
- package/dist/room/participant/LocalParticipant.d.ts.map +0 -1
- package/dist/room/participant/Participant.d.ts.map +0 -1
- package/dist/room/participant/ParticipantTrackPermission.d.ts.map +0 -1
- package/dist/room/participant/RemoteParticipant.d.ts.map +0 -1
- package/dist/room/participant/publishUtils.d.ts.map +0 -1
- package/dist/room/stats.d.ts.map +0 -1
- package/dist/room/track/LocalAudioTrack.d.ts.map +0 -1
- package/dist/room/track/LocalTrack.d.ts.map +0 -1
- package/dist/room/track/LocalTrackPublication.d.ts.map +0 -1
- package/dist/room/track/LocalVideoTrack.d.ts.map +0 -1
- package/dist/room/track/RemoteAudioTrack.d.ts.map +0 -1
- package/dist/room/track/RemoteTrack.d.ts.map +0 -1
- package/dist/room/track/RemoteTrackPublication.d.ts.map +0 -1
- package/dist/room/track/RemoteVideoTrack.d.ts.map +0 -1
- package/dist/room/track/Track.d.ts.map +0 -1
- package/dist/room/track/TrackPublication.d.ts.map +0 -1
- package/dist/room/track/create.d.ts.map +0 -1
- package/dist/room/track/defaults.d.ts.map +0 -1
- package/dist/room/track/options.d.ts.map +0 -1
- package/dist/room/track/types.d.ts.map +0 -1
- package/dist/room/track/utils.d.ts.map +0 -1
- package/dist/room/utils.d.ts.map +0 -1
- package/dist/test/mocks.d.ts.map +0 -1
- package/dist/version.d.ts +0 -3
- package/dist/version.d.ts.map +0 -1
- package/src/connect.ts +0 -98
package/src/room/Room.ts
CHANGED
@@ -27,7 +27,9 @@ import Participant, { ConnectionQuality } from './participant/Participant';
|
|
27
27
|
import RemoteParticipant from './participant/RemoteParticipant';
|
28
28
|
import RTCEngine, { maxICEConnectTimeout } from './RTCEngine';
|
29
29
|
import { audioDefaults, publishDefaults, videoDefaults } from './track/defaults';
|
30
|
+
import LocalAudioTrack from './track/LocalAudioTrack';
|
30
31
|
import LocalTrackPublication from './track/LocalTrackPublication';
|
32
|
+
import LocalVideoTrack from './track/LocalVideoTrack';
|
31
33
|
import RemoteTrackPublication from './track/RemoteTrackPublication';
|
32
34
|
import { Track } from './track/Track';
|
33
35
|
import { TrackPublication } from './track/TrackPublication';
|
@@ -35,12 +37,16 @@ import { AdaptiveStreamSettings, RemoteTrack } from './track/types';
|
|
35
37
|
import { getNewAudioContext } from './track/utils';
|
36
38
|
import { isWeb, unpackStreamId } from './utils';
|
37
39
|
|
38
|
-
export enum
|
40
|
+
export enum ConnectionState {
|
39
41
|
Disconnected = 'disconnected',
|
42
|
+
Connecting = 'connecting',
|
40
43
|
Connected = 'connected',
|
41
44
|
Reconnecting = 'reconnecting',
|
42
45
|
}
|
43
46
|
|
47
|
+
/** @deprecated RoomState has been renamed to [[ConnectionState]] */
|
48
|
+
export const RoomState = ConnectionState;
|
49
|
+
|
44
50
|
/**
|
45
51
|
* In LiveKit, a room is the logical grouping for a list of participants.
|
46
52
|
* Participants in a room can publish tracks, and subscribe to others' tracks.
|
@@ -50,7 +56,7 @@ export enum RoomState {
|
|
50
56
|
* @noInheritDoc
|
51
57
|
*/
|
52
58
|
class Room extends (EventEmitter as new () => TypedEmitter<RoomEventCallbacks>) {
|
53
|
-
state:
|
59
|
+
state: ConnectionState = ConnectionState.Disconnected;
|
54
60
|
|
55
61
|
/** map of sid: [[RemoteParticipant]] */
|
56
62
|
participants: Map<string, RemoteParticipant>;
|
@@ -80,6 +86,8 @@ class Room extends (EventEmitter as new () => TypedEmitter<RoomEventCallbacks>)
|
|
80
86
|
/** options of room */
|
81
87
|
options: RoomOptions;
|
82
88
|
|
89
|
+
private identityToSid: Map<string, string>;
|
90
|
+
|
83
91
|
/** connect options of room */
|
84
92
|
private connOptions?: RoomConnectOptions;
|
85
93
|
|
@@ -87,6 +95,9 @@ class Room extends (EventEmitter as new () => TypedEmitter<RoomEventCallbacks>)
|
|
87
95
|
|
88
96
|
private audioContext?: AudioContext;
|
89
97
|
|
98
|
+
/** used for aborting pending connections to a LiveKit server */
|
99
|
+
private abortController?: AbortController;
|
100
|
+
|
90
101
|
/**
|
91
102
|
* Creates a new Room, the primary construct for a LiveKit session.
|
92
103
|
* @param options
|
@@ -94,6 +105,7 @@ class Room extends (EventEmitter as new () => TypedEmitter<RoomEventCallbacks>)
|
|
94
105
|
constructor(options?: RoomOptions) {
|
95
106
|
super();
|
96
107
|
this.participants = new Map();
|
108
|
+
this.identityToSid = new Map();
|
97
109
|
this.options = options || {};
|
98
110
|
|
99
111
|
switch (this.options?.publishDefaults?.videoCodec) {
|
@@ -150,18 +162,17 @@ class Room extends (EventEmitter as new () => TypedEmitter<RoomEventCallbacks>)
|
|
150
162
|
.on(EngineEvent.ActiveSpeakersUpdate, this.handleActiveSpeakersUpdate)
|
151
163
|
.on(EngineEvent.DataPacketReceived, this.handleDataPacket)
|
152
164
|
.on(EngineEvent.Resuming, () => {
|
153
|
-
this.
|
154
|
-
|
155
|
-
|
165
|
+
if (this.setAndEmitConnectionState(ConnectionState.Reconnecting)) {
|
166
|
+
this.emit(RoomEvent.Reconnecting);
|
167
|
+
}
|
156
168
|
})
|
157
169
|
.on(EngineEvent.Resumed, () => {
|
158
|
-
this.
|
170
|
+
this.setAndEmitConnectionState(ConnectionState.Connected);
|
159
171
|
this.emit(RoomEvent.Reconnected);
|
160
|
-
this.emit(RoomEvent.StateChanged, this.state);
|
161
172
|
this.updateSubscriptions();
|
162
173
|
})
|
163
174
|
.on(EngineEvent.SignalResumed, () => {
|
164
|
-
if (this.state ===
|
175
|
+
if (this.state === ConnectionState.Reconnecting) {
|
165
176
|
this.sendSyncState();
|
166
177
|
}
|
167
178
|
})
|
@@ -186,11 +197,17 @@ class Room extends (EventEmitter as new () => TypedEmitter<RoomEventCallbacks>)
|
|
186
197
|
|
187
198
|
connect = async (url: string, token: string, opts?: RoomConnectOptions) => {
|
188
199
|
// guard against calling connect
|
189
|
-
if (this.state !==
|
200
|
+
if (this.state !== ConnectionState.Disconnected) {
|
190
201
|
log.warn(`already connected to room ${this.name}`);
|
191
202
|
return;
|
192
203
|
}
|
193
204
|
|
205
|
+
this.setAndEmitConnectionState(ConnectionState.Connecting);
|
206
|
+
|
207
|
+
if (!this.abortController || this.abortController.signal.aborted) {
|
208
|
+
this.abortController = new AbortController();
|
209
|
+
}
|
210
|
+
|
194
211
|
// recreate engine if previously disconnected
|
195
212
|
this.createEngine();
|
196
213
|
|
@@ -203,12 +220,17 @@ class Room extends (EventEmitter as new () => TypedEmitter<RoomEventCallbacks>)
|
|
203
220
|
this.connOptions = opts;
|
204
221
|
|
205
222
|
try {
|
206
|
-
const joinResponse = await this.engine.join(
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
223
|
+
const joinResponse = await this.engine.join(
|
224
|
+
url,
|
225
|
+
token,
|
226
|
+
{
|
227
|
+
autoSubscribe: opts?.autoSubscribe,
|
228
|
+
publishOnly: opts?.publishOnly,
|
229
|
+
adaptiveStream:
|
230
|
+
typeof this.options?.adaptiveStream === 'object' ? true : this.options?.adaptiveStream,
|
231
|
+
},
|
232
|
+
this.abortController.signal,
|
233
|
+
);
|
212
234
|
log.debug(
|
213
235
|
`connected to Livekit Server version: ${joinResponse.serverVersion}, region: ${joinResponse.serverRegion}`,
|
214
236
|
);
|
@@ -223,7 +245,6 @@ class Room extends (EventEmitter as new () => TypedEmitter<RoomEventCallbacks>)
|
|
223
245
|
this.options.dynacast = false;
|
224
246
|
}
|
225
247
|
|
226
|
-
this.state = RoomState.Connected;
|
227
248
|
const pi = joinResponse.participant!;
|
228
249
|
|
229
250
|
this.localParticipant.sid = pi.sid;
|
@@ -232,9 +253,6 @@ class Room extends (EventEmitter as new () => TypedEmitter<RoomEventCallbacks>)
|
|
232
253
|
this.localParticipant.updateInfo(pi);
|
233
254
|
// forward metadata changed for the local participant
|
234
255
|
this.localParticipant
|
235
|
-
.on(ParticipantEvent.MetadataChanged, (metadata: string | undefined) => {
|
236
|
-
this.emit(RoomEvent.MetadataChanged, metadata, this.localParticipant);
|
237
|
-
})
|
238
256
|
.on(ParticipantEvent.ParticipantMetadataChanged, (metadata: string | undefined) => {
|
239
257
|
this.emit(RoomEvent.ParticipantMetadataChanged, metadata, this.localParticipant);
|
240
258
|
})
|
@@ -275,9 +293,10 @@ class Room extends (EventEmitter as new () => TypedEmitter<RoomEventCallbacks>)
|
|
275
293
|
this.name = joinResponse.room!.name;
|
276
294
|
this.sid = joinResponse.room!.sid;
|
277
295
|
this.metadata = joinResponse.room!.metadata;
|
278
|
-
this.emit(RoomEvent.
|
296
|
+
this.emit(RoomEvent.SignalConnected);
|
279
297
|
} catch (err) {
|
280
298
|
this.engine.close();
|
299
|
+
this.setAndEmitConnectionState(ConnectionState.Disconnected);
|
281
300
|
throw err;
|
282
301
|
}
|
283
302
|
|
@@ -286,18 +305,30 @@ class Room extends (EventEmitter as new () => TypedEmitter<RoomEventCallbacks>)
|
|
286
305
|
const connectTimeout = setTimeout(() => {
|
287
306
|
// timeout
|
288
307
|
this.engine.close();
|
308
|
+
this.setAndEmitConnectionState(ConnectionState.Disconnected);
|
289
309
|
reject(new ConnectionError('could not connect after timeout'));
|
290
310
|
}, maxICEConnectTimeout);
|
311
|
+
const abortHandler = () => {
|
312
|
+
log.warn('closing engine');
|
313
|
+
clearTimeout(connectTimeout);
|
314
|
+
this.engine.close();
|
315
|
+
this.setAndEmitConnectionState(ConnectionState.Disconnected);
|
316
|
+
reject(new ConnectionError('room connection has been cancelled'));
|
317
|
+
};
|
318
|
+
if (this.abortController?.signal.aborted) {
|
319
|
+
abortHandler();
|
320
|
+
}
|
321
|
+
this.abortController?.signal.addEventListener('abort', abortHandler);
|
291
322
|
|
292
323
|
this.engine.once(EngineEvent.Connected, () => {
|
293
324
|
clearTimeout(connectTimeout);
|
294
|
-
|
325
|
+
this.abortController?.signal.removeEventListener('abort', abortHandler);
|
295
326
|
// also hook unload event
|
296
327
|
if (isWeb()) {
|
297
328
|
window.addEventListener('beforeunload', this.onBeforeUnload);
|
298
329
|
navigator.mediaDevices?.addEventListener('devicechange', this.handleDeviceChange);
|
299
330
|
}
|
300
|
-
|
331
|
+
this.setAndEmitConnectionState(ConnectionState.Connected);
|
301
332
|
resolve(this);
|
302
333
|
});
|
303
334
|
});
|
@@ -307,11 +338,21 @@ class Room extends (EventEmitter as new () => TypedEmitter<RoomEventCallbacks>)
|
|
307
338
|
* disconnects the room, emits [[RoomEvent.Disconnected]]
|
308
339
|
*/
|
309
340
|
disconnect = (stopTracks = true) => {
|
341
|
+
if (this.state === ConnectionState.Connecting) {
|
342
|
+
// try aborting pending connection attempt
|
343
|
+
log.warn('abort connection attempt');
|
344
|
+
this.abortController?.abort();
|
345
|
+
return;
|
346
|
+
}
|
310
347
|
// send leave
|
311
|
-
if (this.engine) {
|
348
|
+
if (this.engine?.client.isConnected) {
|
312
349
|
this.engine.client.sendLeave();
|
350
|
+
}
|
351
|
+
// close engine (also closes client)
|
352
|
+
if (this.engine) {
|
313
353
|
this.engine.close();
|
314
354
|
}
|
355
|
+
|
315
356
|
this.handleDisconnect(stopTracks);
|
316
357
|
/* @ts-ignore */
|
317
358
|
this.engine = undefined;
|
@@ -323,20 +364,20 @@ class Room extends (EventEmitter as new () => TypedEmitter<RoomEventCallbacks>)
|
|
323
364
|
* @returns
|
324
365
|
*/
|
325
366
|
getParticipantByIdentity(identity: string): Participant | undefined {
|
326
|
-
for (const [, p] of this.participants) {
|
327
|
-
if (p.identity === identity) {
|
328
|
-
return p;
|
329
|
-
}
|
330
|
-
}
|
331
367
|
if (this.localParticipant.identity === identity) {
|
332
368
|
return this.localParticipant;
|
333
369
|
}
|
370
|
+
const sid = this.identityToSid.get(identity);
|
371
|
+
if (sid) {
|
372
|
+
return this.participants.get(sid);
|
373
|
+
}
|
334
374
|
}
|
335
375
|
|
336
376
|
/**
|
337
377
|
* @internal for testing
|
338
378
|
*/
|
339
379
|
simulateScenario(scenario: string) {
|
380
|
+
let postAction = () => {};
|
340
381
|
let req: SimulateScenario | undefined;
|
341
382
|
switch (scenario) {
|
342
383
|
case 'speaker':
|
@@ -359,10 +400,19 @@ class Room extends (EventEmitter as new () => TypedEmitter<RoomEventCallbacks>)
|
|
359
400
|
migration: true,
|
360
401
|
});
|
361
402
|
break;
|
403
|
+
case 'switch-candidate':
|
404
|
+
req = SimulateScenario.fromPartial({
|
405
|
+
switchCandidateProtocol: 1,
|
406
|
+
});
|
407
|
+
postAction = () => {
|
408
|
+
this.engine.publisher?.createAndSendOffer({ iceRestart: true });
|
409
|
+
};
|
410
|
+
break;
|
362
411
|
default:
|
363
412
|
}
|
364
413
|
if (req) {
|
365
414
|
this.engine.client.sendSimulateScenario(req);
|
415
|
+
postAction();
|
366
416
|
}
|
367
417
|
}
|
368
418
|
|
@@ -482,9 +532,9 @@ class Room extends (EventEmitter as new () => TypedEmitter<RoomEventCallbacks>)
|
|
482
532
|
}
|
483
533
|
|
484
534
|
private handleRestarting = () => {
|
485
|
-
this.
|
486
|
-
|
487
|
-
|
535
|
+
if (this.setAndEmitConnectionState(ConnectionState.Reconnecting)) {
|
536
|
+
this.emit(RoomEvent.Reconnecting);
|
537
|
+
}
|
488
538
|
|
489
539
|
// also unwind existing participants & existing subscriptions
|
490
540
|
for (const p of this.participants.values()) {
|
@@ -493,10 +543,11 @@ class Room extends (EventEmitter as new () => TypedEmitter<RoomEventCallbacks>)
|
|
493
543
|
};
|
494
544
|
|
495
545
|
private handleRestarted = async (joinResponse: JoinResponse) => {
|
496
|
-
log.debug(`reconnected to server
|
497
|
-
|
546
|
+
log.debug(`reconnected to server`, {
|
547
|
+
region: joinResponse.serverRegion,
|
548
|
+
});
|
549
|
+
this.setAndEmitConnectionState(ConnectionState.Connected);
|
498
550
|
this.emit(RoomEvent.Reconnected);
|
499
|
-
this.emit(RoomEvent.StateChanged, this.state);
|
500
551
|
|
501
552
|
// rehydrate participants
|
502
553
|
if (joinResponse.participant) {
|
@@ -518,15 +569,22 @@ class Room extends (EventEmitter as new () => TypedEmitter<RoomEventCallbacks>)
|
|
518
569
|
localPubs.map(async (pub) => {
|
519
570
|
const track = pub.track!;
|
520
571
|
this.localParticipant.unpublishTrack(track, false);
|
521
|
-
|
572
|
+
if (!track.isMuted) {
|
573
|
+
if (track instanceof LocalAudioTrack || track instanceof LocalVideoTrack) {
|
574
|
+
// we need to restart the track before publishing, often a full reconnect
|
575
|
+
// is necessary because computer had gone to sleep.
|
576
|
+
log.debug('restarting existing track', {
|
577
|
+
track: pub.trackSid,
|
578
|
+
});
|
579
|
+
await track.restartTrack();
|
580
|
+
}
|
581
|
+
await this.localParticipant.publishTrack(track, pub.options);
|
582
|
+
}
|
522
583
|
}),
|
523
584
|
);
|
524
585
|
};
|
525
586
|
|
526
587
|
private handleDisconnect(shouldStopTracks = true) {
|
527
|
-
if (this.state === RoomState.Disconnected) {
|
528
|
-
return;
|
529
|
-
}
|
530
588
|
this.participants.forEach((p) => {
|
531
589
|
p.tracks.forEach((pub) => {
|
532
590
|
p.unpublishTrack(pub.trackSid);
|
@@ -535,7 +593,7 @@ class Room extends (EventEmitter as new () => TypedEmitter<RoomEventCallbacks>)
|
|
535
593
|
|
536
594
|
this.localParticipant.tracks.forEach((pub) => {
|
537
595
|
if (pub.track) {
|
538
|
-
this.localParticipant.unpublishTrack(pub.track);
|
596
|
+
this.localParticipant.unpublishTrack(pub.track, shouldStopTracks);
|
539
597
|
}
|
540
598
|
if (shouldStopTracks) {
|
541
599
|
pub.track?.detach();
|
@@ -553,9 +611,8 @@ class Room extends (EventEmitter as new () => TypedEmitter<RoomEventCallbacks>)
|
|
553
611
|
window.removeEventListener('beforeunload', this.onBeforeUnload);
|
554
612
|
navigator.mediaDevices?.removeEventListener('devicechange', this.handleDeviceChange);
|
555
613
|
}
|
556
|
-
this.
|
614
|
+
this.setAndEmitConnectionState(ConnectionState.Disconnected);
|
557
615
|
this.emit(RoomEvent.Disconnected);
|
558
|
-
this.emit(RoomEvent.StateChanged, this.state);
|
559
616
|
}
|
560
617
|
|
561
618
|
private handleParticipantUpdates = (participantInfos: ParticipantInfo[]) => {
|
@@ -569,6 +626,13 @@ class Room extends (EventEmitter as new () => TypedEmitter<RoomEventCallbacks>)
|
|
569
626
|
return;
|
570
627
|
}
|
571
628
|
|
629
|
+
// ensure identity <=> sid mapping
|
630
|
+
const sid = this.identityToSid.get(info.identity);
|
631
|
+
if (sid && sid !== info.sid) {
|
632
|
+
// sid had changed, need to remove previous participant
|
633
|
+
this.handleParticipantDisconnected(sid, this.participants.get(sid));
|
634
|
+
}
|
635
|
+
|
572
636
|
let remoteParticipant = this.participants.get(info.sid);
|
573
637
|
const isNewParticipant = !remoteParticipant;
|
574
638
|
|
@@ -579,6 +643,7 @@ class Room extends (EventEmitter as new () => TypedEmitter<RoomEventCallbacks>)
|
|
579
643
|
if (info.state === ParticipantInfo_State.DISCONNECTED) {
|
580
644
|
this.handleParticipantDisconnected(info.sid, remoteParticipant);
|
581
645
|
} else if (isNewParticipant) {
|
646
|
+
this.identityToSid.set(info.identity, info.sid);
|
582
647
|
// fire connected event
|
583
648
|
this.emit(RoomEvent.ParticipantConnected, remoteParticipant);
|
584
649
|
} else {
|
@@ -595,8 +660,9 @@ class Room extends (EventEmitter as new () => TypedEmitter<RoomEventCallbacks>)
|
|
595
660
|
return;
|
596
661
|
}
|
597
662
|
|
663
|
+
this.identityToSid.delete(participant.identity);
|
598
664
|
participant.tracks.forEach((publication) => {
|
599
|
-
participant.unpublishTrack(publication.trackSid);
|
665
|
+
participant.unpublishTrack(publication.trackSid, true);
|
600
666
|
});
|
601
667
|
this.emit(RoomEvent.ParticipantDisconnected, participant);
|
602
668
|
}
|
@@ -821,9 +887,6 @@ class Room extends (EventEmitter as new () => TypedEmitter<RoomEventCallbacks>)
|
|
821
887
|
.on(ParticipantEvent.TrackUnmuted, (pub: TrackPublication) => {
|
822
888
|
this.emit(RoomEvent.TrackUnmuted, pub, participant);
|
823
889
|
})
|
824
|
-
.on(ParticipantEvent.MetadataChanged, (metadata: string | undefined) => {
|
825
|
-
this.emit(RoomEvent.MetadataChanged, metadata, participant);
|
826
|
-
})
|
827
890
|
.on(ParticipantEvent.ParticipantMetadataChanged, (metadata: string | undefined) => {
|
828
891
|
this.emit(RoomEvent.ParticipantMetadataChanged, metadata, participant);
|
829
892
|
})
|
@@ -892,6 +955,16 @@ class Room extends (EventEmitter as new () => TypedEmitter<RoomEventCallbacks>)
|
|
892
955
|
}
|
893
956
|
}
|
894
957
|
|
958
|
+
private setAndEmitConnectionState(state: ConnectionState): boolean {
|
959
|
+
if (state === this.state) {
|
960
|
+
// unchanged
|
961
|
+
return false;
|
962
|
+
}
|
963
|
+
this.state = state;
|
964
|
+
this.emit(RoomEvent.ConnectionStateChanged, this.state);
|
965
|
+
return true;
|
966
|
+
}
|
967
|
+
|
895
968
|
// /** @internal */
|
896
969
|
emit<E extends keyof RoomEventCallbacks>(
|
897
970
|
event: E,
|
@@ -908,7 +981,9 @@ export type RoomEventCallbacks = {
|
|
908
981
|
reconnecting: () => void;
|
909
982
|
reconnected: () => void;
|
910
983
|
disconnected: () => void;
|
911
|
-
stateChanged
|
984
|
+
/** @deprecated stateChanged has been renamed to connectionStateChanged */
|
985
|
+
stateChanged: (state: ConnectionState) => void;
|
986
|
+
connectionStateChanged: (state: ConnectionState) => void;
|
912
987
|
mediaDevicesChanged: () => void;
|
913
988
|
participantConnected: (participant: RemoteParticipant) => void;
|
914
989
|
participantDisconnected: (participant: RemoteParticipant) => void;
|
@@ -932,13 +1007,6 @@ export type RoomEventCallbacks = {
|
|
932
1007
|
publication: LocalTrackPublication,
|
933
1008
|
participant: LocalParticipant,
|
934
1009
|
) => void;
|
935
|
-
/**
|
936
|
-
* @deprecated use [[participantMetadataChanged]] instead
|
937
|
-
*/
|
938
|
-
metadataChanged: (
|
939
|
-
metadata: string | undefined,
|
940
|
-
participant?: RemoteParticipant | LocalParticipant,
|
941
|
-
) => void;
|
942
1010
|
participantMetadataChanged: (
|
943
1011
|
metadata: string | undefined,
|
944
1012
|
participant: RemoteParticipant | LocalParticipant,
|
@@ -967,4 +1035,5 @@ export type RoomEventCallbacks = {
|
|
967
1035
|
participant: RemoteParticipant,
|
968
1036
|
) => void;
|
969
1037
|
audioPlaybackChanged: (playing: boolean) => void;
|
1038
|
+
signalConnected: () => void;
|
970
1039
|
};
|
package/src/room/events.ts
CHANGED
@@ -29,9 +29,14 @@ export enum RoomEvent {
|
|
29
29
|
/**
|
30
30
|
* Whenever the connection state of the room changes
|
31
31
|
*
|
32
|
-
* args: ([[
|
32
|
+
* args: ([[ConnectionState]])
|
33
33
|
*/
|
34
|
-
|
34
|
+
ConnectionStateChanged = 'connectionStateChanged',
|
35
|
+
|
36
|
+
/**
|
37
|
+
* @deprecated StateChanged has been renamed to ConnectionStateChanged
|
38
|
+
*/
|
39
|
+
StateChanged = 'connectionStateChanged',
|
35
40
|
|
36
41
|
/**
|
37
42
|
* When input or output devices on the machine have changed.
|
@@ -139,12 +144,6 @@ export enum RoomEvent {
|
|
139
144
|
*/
|
140
145
|
ActiveSpeakersChanged = 'activeSpeakersChanged',
|
141
146
|
|
142
|
-
/**
|
143
|
-
* @deprecated Use ParticipantMetadataChanged instead
|
144
|
-
* @internal
|
145
|
-
*/
|
146
|
-
MetadataChanged = 'metadataChanged',
|
147
|
-
|
148
147
|
/**
|
149
148
|
* Participant metadata is a simple way for app-specific state to be pushed to
|
150
149
|
* all users.
|
@@ -231,6 +230,11 @@ export enum RoomEvent {
|
|
231
230
|
* args: (prevPermissions: [[ParticipantPermission]], participant: [[Participant]])
|
232
231
|
*/
|
233
232
|
ParticipantPermissionsChanged = 'participantPermissionsChanged',
|
233
|
+
|
234
|
+
/**
|
235
|
+
* Signal connected, can publish tracks.
|
236
|
+
*/
|
237
|
+
SignalConnected = 'signalConnected',
|
234
238
|
}
|
235
239
|
|
236
240
|
export enum ParticipantEvent {
|
@@ -308,12 +312,6 @@ export enum ParticipantEvent {
|
|
308
312
|
*/
|
309
313
|
LocalTrackUnpublished = 'localTrackUnpublished',
|
310
314
|
|
311
|
-
/**
|
312
|
-
* @deprecated Use ParticipantMetadataChanged instead
|
313
|
-
* @internal
|
314
|
-
*/
|
315
|
-
MetadataChanged = 'metadataChanged',
|
316
|
-
|
317
315
|
/**
|
318
316
|
* Participant metadata is a simple way for app-specific state to be pushed to
|
319
317
|
* all users.
|