livekit-client 0.18.6 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/api/SignalClient.d.ts +2 -2
- package/dist/api/SignalClient.d.ts.map +1 -1
- package/dist/index.d.ts +2 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/livekit-client.esm.mjs +131 -215
- 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/options.d.ts +1 -68
- package/dist/options.d.ts.map +1 -1
- package/dist/room/DeviceManager.d.ts.map +1 -1
- package/dist/room/RTCEngine.d.ts +3 -2
- package/dist/room/RTCEngine.d.ts.map +1 -1
- package/dist/room/Room.d.ts +11 -7
- package/dist/room/Room.d.ts.map +1 -1
- package/dist/room/events.d.ts +6 -12
- package/dist/room/events.d.ts.map +1 -1
- package/dist/room/participant/LocalParticipant.d.ts.map +1 -1
- package/dist/room/participant/Participant.d.ts +0 -4
- package/dist/room/participant/Participant.d.ts.map +1 -1
- package/dist/room/participant/RemoteParticipant.d.ts +3 -2
- package/dist/room/participant/RemoteParticipant.d.ts.map +1 -1
- package/dist/room/track/options.d.ts +0 -30
- package/dist/room/track/options.d.ts.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/api/SignalClient.ts +32 -7
- package/src/index.ts +2 -2
- package/src/options.ts +0 -82
- package/src/room/DeviceManager.ts +4 -1
- package/src/room/RTCEngine.ts +16 -7
- package/src/room/Room.ts +65 -41
- package/src/room/events.ts +7 -14
- package/src/room/participant/LocalParticipant.ts +4 -0
- package/src/room/participant/Participant.ts +0 -5
- package/src/room/participant/RemoteParticipant.ts +16 -5
- package/src/room/participant/publishUtils.test.ts +2 -2
- package/src/room/track/create.ts +1 -1
- package/src/room/track/options.ts +0 -30
- package/src/room/track/utils.test.ts +6 -6
- package/src/version.ts +1 -1
- package/dist/connect.d.ts +0 -24
- package/dist/connect.d.ts.map +0 -1
- package/src/connect.ts +0 -98
package/src/room/RTCEngine.ts
CHANGED
@@ -48,6 +48,10 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit
|
|
48
48
|
|
49
49
|
rtcConfig: RTCConfiguration = {};
|
50
50
|
|
51
|
+
get isClosed() {
|
52
|
+
return this._isClosed;
|
53
|
+
}
|
54
|
+
|
51
55
|
private lossyDC?: RTCDataChannel;
|
52
56
|
|
53
57
|
// @ts-ignore noUnusedLocals
|
@@ -64,7 +68,7 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit
|
|
64
68
|
|
65
69
|
private pcState: PCState = PCState.New;
|
66
70
|
|
67
|
-
private
|
71
|
+
private _isClosed: boolean = true;
|
68
72
|
|
69
73
|
private pendingTrackResolvers: { [key: string]: (info: TrackInfo) => void } = {};
|
70
74
|
|
@@ -94,13 +98,18 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit
|
|
94
98
|
this.client = new SignalClient();
|
95
99
|
}
|
96
100
|
|
97
|
-
async join(
|
101
|
+
async join(
|
102
|
+
url: string,
|
103
|
+
token: string,
|
104
|
+
opts?: SignalOptions,
|
105
|
+
abortSignal?: AbortSignal,
|
106
|
+
): Promise<JoinResponse> {
|
98
107
|
this.url = url;
|
99
108
|
this.token = token;
|
100
109
|
this.signalOpts = opts;
|
101
110
|
|
102
|
-
const joinResponse = await this.client.join(url, token, opts);
|
103
|
-
this.
|
111
|
+
const joinResponse = await this.client.join(url, token, opts, abortSignal);
|
112
|
+
this._isClosed = false;
|
104
113
|
|
105
114
|
this.subscriberPrimary = joinResponse.subscriberPrimary;
|
106
115
|
if (!this.publisher) {
|
@@ -117,7 +126,7 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit
|
|
117
126
|
}
|
118
127
|
|
119
128
|
close() {
|
120
|
-
this.
|
129
|
+
this._isClosed = true;
|
121
130
|
|
122
131
|
this.removeAllListeners();
|
123
132
|
if (this.publisher && this.publisher.pc.signalingState !== 'closed') {
|
@@ -403,7 +412,7 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit
|
|
403
412
|
// continues to work, we can reconnect to websocket to continue the session
|
404
413
|
// after a number of retries, we'll close and give up permanently
|
405
414
|
private handleDisconnect = (connection: string) => {
|
406
|
-
if (this.
|
415
|
+
if (this._isClosed) {
|
407
416
|
return;
|
408
417
|
}
|
409
418
|
log.debug(`${connection} disconnected`);
|
@@ -414,7 +423,7 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit
|
|
414
423
|
|
415
424
|
const delay = this.reconnectAttempts * this.reconnectAttempts * 300;
|
416
425
|
setTimeout(async () => {
|
417
|
-
if (this.
|
426
|
+
if (this._isClosed) {
|
418
427
|
return;
|
419
428
|
}
|
420
429
|
if (
|
package/src/room/Room.ts
CHANGED
@@ -35,12 +35,16 @@ import { AdaptiveStreamSettings, RemoteTrack } from './track/types';
|
|
35
35
|
import { getNewAudioContext } from './track/utils';
|
36
36
|
import { isWeb, unpackStreamId } from './utils';
|
37
37
|
|
38
|
-
export enum
|
38
|
+
export enum ConnectionState {
|
39
39
|
Disconnected = 'disconnected',
|
40
|
+
Connecting = 'connecting',
|
40
41
|
Connected = 'connected',
|
41
42
|
Reconnecting = 'reconnecting',
|
42
43
|
}
|
43
44
|
|
45
|
+
/** @deprecated RoomState has been renamed to [[ConnectionState]] */
|
46
|
+
export const RoomState = ConnectionState;
|
47
|
+
|
44
48
|
/**
|
45
49
|
* In LiveKit, a room is the logical grouping for a list of participants.
|
46
50
|
* Participants in a room can publish tracks, and subscribe to others' tracks.
|
@@ -50,7 +54,7 @@ export enum RoomState {
|
|
50
54
|
* @noInheritDoc
|
51
55
|
*/
|
52
56
|
class Room extends (EventEmitter as new () => TypedEmitter<RoomEventCallbacks>) {
|
53
|
-
state:
|
57
|
+
state: ConnectionState = ConnectionState.Disconnected;
|
54
58
|
|
55
59
|
/** map of sid: [[RemoteParticipant]] */
|
56
60
|
participants: Map<string, RemoteParticipant>;
|
@@ -87,6 +91,9 @@ class Room extends (EventEmitter as new () => TypedEmitter<RoomEventCallbacks>)
|
|
87
91
|
|
88
92
|
private audioContext?: AudioContext;
|
89
93
|
|
94
|
+
/** used for aborting pending connections to a LiveKit server */
|
95
|
+
private abortController?: AbortController;
|
96
|
+
|
90
97
|
/**
|
91
98
|
* Creates a new Room, the primary construct for a LiveKit session.
|
92
99
|
* @param options
|
@@ -150,18 +157,16 @@ class Room extends (EventEmitter as new () => TypedEmitter<RoomEventCallbacks>)
|
|
150
157
|
.on(EngineEvent.ActiveSpeakersUpdate, this.handleActiveSpeakersUpdate)
|
151
158
|
.on(EngineEvent.DataPacketReceived, this.handleDataPacket)
|
152
159
|
.on(EngineEvent.Resuming, () => {
|
153
|
-
this.
|
160
|
+
this.setAndEmitConnectionState(ConnectionState.Reconnecting);
|
154
161
|
this.emit(RoomEvent.Reconnecting);
|
155
|
-
this.emit(RoomEvent.StateChanged, this.state);
|
156
162
|
})
|
157
163
|
.on(EngineEvent.Resumed, () => {
|
158
|
-
this.
|
164
|
+
this.setAndEmitConnectionState(ConnectionState.Connected);
|
159
165
|
this.emit(RoomEvent.Reconnected);
|
160
|
-
this.emit(RoomEvent.StateChanged, this.state);
|
161
166
|
this.updateSubscriptions();
|
162
167
|
})
|
163
168
|
.on(EngineEvent.SignalResumed, () => {
|
164
|
-
if (this.state ===
|
169
|
+
if (this.state === ConnectionState.Reconnecting) {
|
165
170
|
this.sendSyncState();
|
166
171
|
}
|
167
172
|
})
|
@@ -186,11 +191,17 @@ class Room extends (EventEmitter as new () => TypedEmitter<RoomEventCallbacks>)
|
|
186
191
|
|
187
192
|
connect = async (url: string, token: string, opts?: RoomConnectOptions) => {
|
188
193
|
// guard against calling connect
|
189
|
-
if (this.state !==
|
194
|
+
if (this.state !== ConnectionState.Disconnected) {
|
190
195
|
log.warn(`already connected to room ${this.name}`);
|
191
196
|
return;
|
192
197
|
}
|
193
198
|
|
199
|
+
this.setAndEmitConnectionState(ConnectionState.Connecting);
|
200
|
+
|
201
|
+
if (!this.abortController || this.abortController.signal.aborted) {
|
202
|
+
this.abortController = new AbortController();
|
203
|
+
}
|
204
|
+
|
194
205
|
// recreate engine if previously disconnected
|
195
206
|
this.createEngine();
|
196
207
|
|
@@ -203,12 +214,17 @@ class Room extends (EventEmitter as new () => TypedEmitter<RoomEventCallbacks>)
|
|
203
214
|
this.connOptions = opts;
|
204
215
|
|
205
216
|
try {
|
206
|
-
const joinResponse = await this.engine.join(
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
217
|
+
const joinResponse = await this.engine.join(
|
218
|
+
url,
|
219
|
+
token,
|
220
|
+
{
|
221
|
+
autoSubscribe: opts?.autoSubscribe,
|
222
|
+
publishOnly: opts?.publishOnly,
|
223
|
+
adaptiveStream:
|
224
|
+
typeof this.options?.adaptiveStream === 'object' ? true : this.options?.adaptiveStream,
|
225
|
+
},
|
226
|
+
this.abortController.signal,
|
227
|
+
);
|
212
228
|
log.debug(
|
213
229
|
`connected to Livekit Server version: ${joinResponse.serverVersion}, region: ${joinResponse.serverRegion}`,
|
214
230
|
);
|
@@ -223,7 +239,6 @@ class Room extends (EventEmitter as new () => TypedEmitter<RoomEventCallbacks>)
|
|
223
239
|
this.options.dynacast = false;
|
224
240
|
}
|
225
241
|
|
226
|
-
this.state = RoomState.Connected;
|
227
242
|
const pi = joinResponse.participant!;
|
228
243
|
|
229
244
|
this.localParticipant.sid = pi.sid;
|
@@ -232,9 +247,6 @@ class Room extends (EventEmitter as new () => TypedEmitter<RoomEventCallbacks>)
|
|
232
247
|
this.localParticipant.updateInfo(pi);
|
233
248
|
// forward metadata changed for the local participant
|
234
249
|
this.localParticipant
|
235
|
-
.on(ParticipantEvent.MetadataChanged, (metadata: string | undefined) => {
|
236
|
-
this.emit(RoomEvent.MetadataChanged, metadata, this.localParticipant);
|
237
|
-
})
|
238
250
|
.on(ParticipantEvent.ParticipantMetadataChanged, (metadata: string | undefined) => {
|
239
251
|
this.emit(RoomEvent.ParticipantMetadataChanged, metadata, this.localParticipant);
|
240
252
|
})
|
@@ -275,9 +287,9 @@ class Room extends (EventEmitter as new () => TypedEmitter<RoomEventCallbacks>)
|
|
275
287
|
this.name = joinResponse.room!.name;
|
276
288
|
this.sid = joinResponse.room!.sid;
|
277
289
|
this.metadata = joinResponse.room!.metadata;
|
278
|
-
this.emit(RoomEvent.StateChanged, this.state);
|
279
290
|
} catch (err) {
|
280
291
|
this.engine.close();
|
292
|
+
this.setAndEmitConnectionState(ConnectionState.Disconnected);
|
281
293
|
throw err;
|
282
294
|
}
|
283
295
|
|
@@ -286,18 +298,30 @@ class Room extends (EventEmitter as new () => TypedEmitter<RoomEventCallbacks>)
|
|
286
298
|
const connectTimeout = setTimeout(() => {
|
287
299
|
// timeout
|
288
300
|
this.engine.close();
|
301
|
+
this.setAndEmitConnectionState(ConnectionState.Disconnected);
|
289
302
|
reject(new ConnectionError('could not connect after timeout'));
|
290
303
|
}, maxICEConnectTimeout);
|
304
|
+
const abortHandler = () => {
|
305
|
+
log.warn('closing engine');
|
306
|
+
clearTimeout(connectTimeout);
|
307
|
+
this.engine.close();
|
308
|
+
this.setAndEmitConnectionState(ConnectionState.Disconnected);
|
309
|
+
reject(new ConnectionError('room connection has been cancelled'));
|
310
|
+
};
|
311
|
+
if (this.abortController?.signal.aborted) {
|
312
|
+
abortHandler();
|
313
|
+
}
|
314
|
+
this.abortController?.signal.addEventListener('abort', abortHandler);
|
291
315
|
|
292
316
|
this.engine.once(EngineEvent.Connected, () => {
|
293
317
|
clearTimeout(connectTimeout);
|
294
|
-
|
318
|
+
this.abortController?.signal.removeEventListener('abort', abortHandler);
|
295
319
|
// also hook unload event
|
296
320
|
if (isWeb()) {
|
297
321
|
window.addEventListener('beforeunload', this.onBeforeUnload);
|
298
322
|
navigator.mediaDevices?.addEventListener('devicechange', this.handleDeviceChange);
|
299
323
|
}
|
300
|
-
|
324
|
+
this.setAndEmitConnectionState(ConnectionState.Connected);
|
301
325
|
resolve(this);
|
302
326
|
});
|
303
327
|
});
|
@@ -307,6 +331,12 @@ class Room extends (EventEmitter as new () => TypedEmitter<RoomEventCallbacks>)
|
|
307
331
|
* disconnects the room, emits [[RoomEvent.Disconnected]]
|
308
332
|
*/
|
309
333
|
disconnect = (stopTracks = true) => {
|
334
|
+
if (this.state === ConnectionState.Connecting) {
|
335
|
+
// try aborting pending connection attempt
|
336
|
+
log.warn('abort connection attempt');
|
337
|
+
this.abortController?.abort();
|
338
|
+
return;
|
339
|
+
}
|
310
340
|
// send leave
|
311
341
|
if (this.engine) {
|
312
342
|
this.engine.client.sendLeave();
|
@@ -482,9 +512,8 @@ class Room extends (EventEmitter as new () => TypedEmitter<RoomEventCallbacks>)
|
|
482
512
|
}
|
483
513
|
|
484
514
|
private handleRestarting = () => {
|
485
|
-
this.
|
515
|
+
this.setAndEmitConnectionState(ConnectionState.Reconnecting);
|
486
516
|
this.emit(RoomEvent.Reconnecting);
|
487
|
-
this.emit(RoomEvent.StateChanged, this.state);
|
488
517
|
|
489
518
|
// also unwind existing participants & existing subscriptions
|
490
519
|
for (const p of this.participants.values()) {
|
@@ -494,9 +523,8 @@ class Room extends (EventEmitter as new () => TypedEmitter<RoomEventCallbacks>)
|
|
494
523
|
|
495
524
|
private handleRestarted = async (joinResponse: JoinResponse) => {
|
496
525
|
log.debug(`reconnected to server region ${joinResponse.serverRegion}`);
|
497
|
-
this.
|
526
|
+
this.setAndEmitConnectionState(ConnectionState.Connected);
|
498
527
|
this.emit(RoomEvent.Reconnected);
|
499
|
-
this.emit(RoomEvent.StateChanged, this.state);
|
500
528
|
|
501
529
|
// rehydrate participants
|
502
530
|
if (joinResponse.participant) {
|
@@ -524,9 +552,6 @@ class Room extends (EventEmitter as new () => TypedEmitter<RoomEventCallbacks>)
|
|
524
552
|
};
|
525
553
|
|
526
554
|
private handleDisconnect(shouldStopTracks = true) {
|
527
|
-
if (this.state === RoomState.Disconnected) {
|
528
|
-
return;
|
529
|
-
}
|
530
555
|
this.participants.forEach((p) => {
|
531
556
|
p.tracks.forEach((pub) => {
|
532
557
|
p.unpublishTrack(pub.trackSid);
|
@@ -553,9 +578,8 @@ class Room extends (EventEmitter as new () => TypedEmitter<RoomEventCallbacks>)
|
|
553
578
|
window.removeEventListener('beforeunload', this.onBeforeUnload);
|
554
579
|
navigator.mediaDevices?.removeEventListener('devicechange', this.handleDeviceChange);
|
555
580
|
}
|
556
|
-
this.
|
581
|
+
this.setAndEmitConnectionState(ConnectionState.Disconnected);
|
557
582
|
this.emit(RoomEvent.Disconnected);
|
558
|
-
this.emit(RoomEvent.StateChanged, this.state);
|
559
583
|
}
|
560
584
|
|
561
585
|
private handleParticipantUpdates = (participantInfos: ParticipantInfo[]) => {
|
@@ -821,9 +845,6 @@ class Room extends (EventEmitter as new () => TypedEmitter<RoomEventCallbacks>)
|
|
821
845
|
.on(ParticipantEvent.TrackUnmuted, (pub: TrackPublication) => {
|
822
846
|
this.emit(RoomEvent.TrackUnmuted, pub, participant);
|
823
847
|
})
|
824
|
-
.on(ParticipantEvent.MetadataChanged, (metadata: string | undefined) => {
|
825
|
-
this.emit(RoomEvent.MetadataChanged, metadata, participant);
|
826
|
-
})
|
827
848
|
.on(ParticipantEvent.ParticipantMetadataChanged, (metadata: string | undefined) => {
|
828
849
|
this.emit(RoomEvent.ParticipantMetadataChanged, metadata, participant);
|
829
850
|
})
|
@@ -892,6 +913,14 @@ class Room extends (EventEmitter as new () => TypedEmitter<RoomEventCallbacks>)
|
|
892
913
|
}
|
893
914
|
}
|
894
915
|
|
916
|
+
private setAndEmitConnectionState(state: ConnectionState) {
|
917
|
+
if (state === this.state) {
|
918
|
+
return;
|
919
|
+
}
|
920
|
+
this.state = state;
|
921
|
+
this.emit(RoomEvent.ConnectionStateChanged, this.state);
|
922
|
+
}
|
923
|
+
|
895
924
|
// /** @internal */
|
896
925
|
emit<E extends keyof RoomEventCallbacks>(
|
897
926
|
event: E,
|
@@ -908,7 +937,9 @@ export type RoomEventCallbacks = {
|
|
908
937
|
reconnecting: () => void;
|
909
938
|
reconnected: () => void;
|
910
939
|
disconnected: () => void;
|
911
|
-
stateChanged
|
940
|
+
/** @deprecated stateChanged has been renamed to connectionStateChanged */
|
941
|
+
stateChanged: (state: ConnectionState) => void;
|
942
|
+
connectionStateChanged: (state: ConnectionState) => void;
|
912
943
|
mediaDevicesChanged: () => void;
|
913
944
|
participantConnected: (participant: RemoteParticipant) => void;
|
914
945
|
participantDisconnected: (participant: RemoteParticipant) => void;
|
@@ -932,13 +963,6 @@ export type RoomEventCallbacks = {
|
|
932
963
|
publication: LocalTrackPublication,
|
933
964
|
participant: LocalParticipant,
|
934
965
|
) => void;
|
935
|
-
/**
|
936
|
-
* @deprecated use [[participantMetadataChanged]] instead
|
937
|
-
*/
|
938
|
-
metadataChanged: (
|
939
|
-
metadata: string | undefined,
|
940
|
-
participant?: RemoteParticipant | LocalParticipant,
|
941
|
-
) => void;
|
942
966
|
participantMetadataChanged: (
|
943
967
|
metadata: string | undefined,
|
944
968
|
participant: RemoteParticipant | LocalParticipant,
|
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.
|
@@ -308,12 +307,6 @@ export enum ParticipantEvent {
|
|
308
307
|
*/
|
309
308
|
LocalTrackUnpublished = 'localTrackUnpublished',
|
310
309
|
|
311
|
-
/**
|
312
|
-
* @deprecated Use ParticipantMetadataChanged instead
|
313
|
-
* @internal
|
314
|
-
*/
|
315
|
-
MetadataChanged = 'metadataChanged',
|
316
|
-
|
317
310
|
/**
|
318
311
|
* Participant metadata is a simple way for app-specific state to be pushed to
|
319
312
|
* all users.
|
@@ -436,6 +436,10 @@ export default class LocalParticipant extends Participant {
|
|
436
436
|
];
|
437
437
|
}
|
438
438
|
|
439
|
+
if (!this.engine || this.engine.isClosed) {
|
440
|
+
throw new UnexpectedConnectionState('cannot publish track when not connected');
|
441
|
+
}
|
442
|
+
|
439
443
|
const ti = await this.engine.addTrack(req);
|
440
444
|
const publication = new LocalTrackPublication(track.kind, ti, track);
|
441
445
|
track.sid = ti.sid;
|
@@ -188,7 +188,6 @@ export default class Participant extends (EventEmitter as new () => TypedEmitter
|
|
188
188
|
this.metadata = md;
|
189
189
|
|
190
190
|
if (changed) {
|
191
|
-
this.emit(ParticipantEvent.MetadataChanged, prevMetadata);
|
192
191
|
this.emit(ParticipantEvent.ParticipantMetadataChanged, prevMetadata);
|
193
192
|
}
|
194
193
|
}
|
@@ -266,10 +265,6 @@ export type ParticipantEventCallbacks = {
|
|
266
265
|
trackUnmuted: (publication: TrackPublication) => void;
|
267
266
|
localTrackPublished: (publication: LocalTrackPublication) => void;
|
268
267
|
localTrackUnpublished: (publication: LocalTrackPublication) => void;
|
269
|
-
/**
|
270
|
-
* @deprecated use [[participantMetadataChanged]] instead
|
271
|
-
*/
|
272
|
-
metadataChanged: (prevMetadata: string | undefined, participant?: any) => void;
|
273
268
|
participantMetadataChanged: (prevMetadata: string | undefined, participant?: any) => void;
|
274
269
|
dataReceived: (payload: Uint8Array, kind: DataPacket_Kind) => void;
|
275
270
|
isSpeakingChanged: (speaking: boolean) => void;
|
@@ -19,6 +19,8 @@ export default class RemoteParticipant extends Participant {
|
|
19
19
|
|
20
20
|
signalClient: SignalClient;
|
21
21
|
|
22
|
+
private volume?: number;
|
23
|
+
|
22
24
|
/** @internal */
|
23
25
|
static fromParticipantInfo(signalClient: SignalClient, pi: ParticipantInfo): RemoteParticipant {
|
24
26
|
const rp = new RemoteParticipant(signalClient, pi.sid, pi.identity);
|
@@ -68,24 +70,26 @@ export default class RemoteParticipant extends Participant {
|
|
68
70
|
}
|
69
71
|
|
70
72
|
/**
|
71
|
-
* sets the volume on the participant's microphone track
|
73
|
+
* sets the volume on the participant's microphone track
|
74
|
+
* if no track exists the volume will be applied when the microphone track is added
|
72
75
|
*/
|
73
76
|
setVolume(volume: number) {
|
77
|
+
this.volume = volume;
|
74
78
|
const audioPublication = this.getTrack(Track.Source.Microphone);
|
75
|
-
if (audioPublication) {
|
79
|
+
if (audioPublication && audioPublication.track) {
|
76
80
|
(audioPublication.track as RemoteAudioTrack).setVolume(volume);
|
77
81
|
}
|
78
82
|
}
|
79
83
|
|
80
84
|
/**
|
81
85
|
* gets the volume on the participant's microphone track
|
82
|
-
* returns undefined if no microphone track exists
|
83
86
|
*/
|
84
87
|
getVolume() {
|
85
88
|
const audioPublication = this.getTrack(Track.Source.Microphone);
|
86
|
-
if (audioPublication) {
|
89
|
+
if (audioPublication && audioPublication.track) {
|
87
90
|
return (audioPublication.track as RemoteAudioTrack).getVolume();
|
88
91
|
}
|
92
|
+
return this.volume;
|
89
93
|
}
|
90
94
|
|
91
95
|
/** @internal */
|
@@ -153,7 +157,14 @@ export default class RemoteParticipant extends Participant {
|
|
153
157
|
track.start();
|
154
158
|
|
155
159
|
publication.setTrack(track);
|
156
|
-
|
160
|
+
// set participant volume on new microphone tracks
|
161
|
+
if (
|
162
|
+
this.volume !== undefined &&
|
163
|
+
track instanceof RemoteAudioTrack &&
|
164
|
+
track.source === Track.Source.Microphone
|
165
|
+
) {
|
166
|
+
track.setVolume(this.volume);
|
167
|
+
}
|
157
168
|
this.emit(ParticipantEvent.TrackSubscribed, track, publication);
|
158
169
|
|
159
170
|
return publication;
|
@@ -28,11 +28,11 @@ describe('presetsForResolution', () => {
|
|
28
28
|
|
29
29
|
describe('determineAppropriateEncoding', () => {
|
30
30
|
it('uses higher encoding', () => {
|
31
|
-
expect(determineAppropriateEncoding(false, 600, 300)).toEqual(VideoPresets.
|
31
|
+
expect(determineAppropriateEncoding(false, 600, 300)).toEqual(VideoPresets.h360.encoding);
|
32
32
|
});
|
33
33
|
|
34
34
|
it('handles portrait', () => {
|
35
|
-
expect(determineAppropriateEncoding(false, 300, 600)).toEqual(VideoPresets.
|
35
|
+
expect(determineAppropriateEncoding(false, 300, 600)).toEqual(VideoPresets.h360.encoding);
|
36
36
|
});
|
37
37
|
});
|
38
38
|
|
package/src/room/track/create.ts
CHANGED
@@ -89,7 +89,7 @@ export async function createLocalScreenTracks(
|
|
89
89
|
options = {};
|
90
90
|
}
|
91
91
|
if (options.resolution === undefined) {
|
92
|
-
options.resolution = VideoPresets.
|
92
|
+
options.resolution = VideoPresets.h1080.resolution;
|
93
93
|
}
|
94
94
|
|
95
95
|
let videoConstraints: MediaTrackConstraints | boolean = true;
|
@@ -236,16 +236,6 @@ export const VideoPresets = {
|
|
236
236
|
h1080: new VideoPreset(1920, 1080, 3_000_000, 30),
|
237
237
|
h1440: new VideoPreset(2560, 1440, 5_000_000, 30),
|
238
238
|
h2160: new VideoPreset(3840, 2160, 8_000_000, 30),
|
239
|
-
/** @deprecated */
|
240
|
-
qvga: new VideoPreset(320, 180, 120_000, 10),
|
241
|
-
/** @deprecated */
|
242
|
-
vga: new VideoPreset(640, 360, 300_000, 20),
|
243
|
-
/** @deprecated */
|
244
|
-
qhd: new VideoPreset(960, 540, 600_000, 25),
|
245
|
-
/** @deprecated */
|
246
|
-
hd: new VideoPreset(1280, 720, 1_700_000, 30),
|
247
|
-
/** @deprecated */
|
248
|
-
fhd: new VideoPreset(1920, 1080, 3_000_000, 30),
|
249
239
|
} as const;
|
250
240
|
|
251
241
|
/**
|
@@ -261,16 +251,6 @@ export const VideoPresets43 = {
|
|
261
251
|
h720: new VideoPreset(960, 720, 1_500_000, 30),
|
262
252
|
h1080: new VideoPreset(1440, 1080, 2_500_000, 30),
|
263
253
|
h1440: new VideoPreset(1920, 1440, 3_500_000, 30),
|
264
|
-
/** @deprecated */
|
265
|
-
qvga: new VideoPreset(240, 180, 90_000, 10),
|
266
|
-
/** @deprecated */
|
267
|
-
vga: new VideoPreset(480, 360, 225_000, 20),
|
268
|
-
/** @deprecated */
|
269
|
-
qhd: new VideoPreset(720, 540, 450_000, 25),
|
270
|
-
/** @deprecated */
|
271
|
-
hd: new VideoPreset(960, 720, 1_500_000, 30),
|
272
|
-
/** @deprecated */
|
273
|
-
fhd: new VideoPreset(1440, 1080, 2_800_000, 30),
|
274
254
|
} as const;
|
275
255
|
|
276
256
|
export const ScreenSharePresets = {
|
@@ -279,14 +259,4 @@ export const ScreenSharePresets = {
|
|
279
259
|
h720fps15: new VideoPreset(1280, 720, 1_000_000, 15),
|
280
260
|
h1080fps15: new VideoPreset(1920, 1080, 1_500_000, 15),
|
281
261
|
h1080fps30: new VideoPreset(1920, 1080, 3_000_000, 30),
|
282
|
-
/** @deprecated */
|
283
|
-
vga: new VideoPreset(640, 360, 200_000, 3),
|
284
|
-
/** @deprecated */
|
285
|
-
hd_8: new VideoPreset(1280, 720, 400_000, 5),
|
286
|
-
/** @deprecated */
|
287
|
-
hd_15: new VideoPreset(1280, 720, 1_000_000, 15),
|
288
|
-
/** @deprecated */
|
289
|
-
fhd_15: new VideoPreset(1920, 1080, 1_500_000, 15),
|
290
|
-
/** @deprecated */
|
291
|
-
fhd_30: new VideoPreset(1920, 1080, 3_000_000, 30),
|
292
262
|
} as const;
|
@@ -8,7 +8,7 @@ describe('mergeDefaultOptions', () => {
|
|
8
8
|
};
|
9
9
|
const videoDefaults: VideoCaptureOptions = {
|
10
10
|
deviceId: 'video123',
|
11
|
-
resolution: VideoPresets.
|
11
|
+
resolution: VideoPresets.h1080.resolution,
|
12
12
|
};
|
13
13
|
|
14
14
|
it('does not enable undefined options', () => {
|
@@ -88,7 +88,7 @@ describe('constraintsForOptions', () => {
|
|
88
88
|
it('converts video options correctly', () => {
|
89
89
|
const constraints = constraintsForOptions({
|
90
90
|
video: {
|
91
|
-
resolution: VideoPresets.
|
91
|
+
resolution: VideoPresets.h720.resolution,
|
92
92
|
facingMode: 'user',
|
93
93
|
deviceId: 'video123',
|
94
94
|
},
|
@@ -102,9 +102,9 @@ describe('constraintsForOptions', () => {
|
|
102
102
|
'facingMode',
|
103
103
|
'deviceId',
|
104
104
|
]);
|
105
|
-
expect(videoOpts.width).toEqual(VideoPresets.
|
106
|
-
expect(videoOpts.height).toEqual(VideoPresets.
|
107
|
-
expect(videoOpts.frameRate).toEqual(VideoPresets.
|
108
|
-
expect(videoOpts.aspectRatio).toEqual(VideoPresets.
|
105
|
+
expect(videoOpts.width).toEqual(VideoPresets.h720.resolution.width);
|
106
|
+
expect(videoOpts.height).toEqual(VideoPresets.h720.resolution.height);
|
107
|
+
expect(videoOpts.frameRate).toEqual(VideoPresets.h720.resolution.frameRate);
|
108
|
+
expect(videoOpts.aspectRatio).toEqual(VideoPresets.h720.resolution.aspectRatio);
|
109
109
|
});
|
110
110
|
});
|
package/src/version.ts
CHANGED
@@ -1,2 +1,2 @@
|
|
1
|
-
export const version = '0.
|
1
|
+
export const version = '1.0.0';
|
2
2
|
export const protocolVersion = 7;
|
package/dist/connect.d.ts
DELETED
@@ -1,24 +0,0 @@
|
|
1
|
-
import { ConnectOptions } from './options';
|
2
|
-
import Room from './room/Room';
|
3
|
-
export { version } from './version';
|
4
|
-
/**
|
5
|
-
* @deprecated Use room.connect() instead
|
6
|
-
*
|
7
|
-
* Connects to a LiveKit room, shorthand for `new Room()` and [[Room.connect]]
|
8
|
-
*
|
9
|
-
* ```typescript
|
10
|
-
* connect('wss://myhost.livekit.io', token, {
|
11
|
-
* // publish audio and video tracks on joining
|
12
|
-
* audio: true,
|
13
|
-
* video: true,
|
14
|
-
* captureDefaults: {
|
15
|
-
* facingMode: 'user',
|
16
|
-
* },
|
17
|
-
* })
|
18
|
-
* ```
|
19
|
-
* @param url URL to LiveKit server
|
20
|
-
* @param token AccessToken, a JWT token that includes authentication and room details
|
21
|
-
* @param options
|
22
|
-
*/
|
23
|
-
export declare function connect(url: string, token: string, options?: ConnectOptions): Promise<Room>;
|
24
|
-
//# sourceMappingURL=connect.d.ts.map
|
package/dist/connect.d.ts.map
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
{"version":3,"file":"connect.d.ts","sourceRoot":"","sources":["../src/connect.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAG3C,OAAO,IAAI,MAAM,aAAa,CAAC;AAE/B,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAsB,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAsEjG"}
|