livekit-client 1.6.3 → 1.6.5
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/dist/livekit-client.esm.mjs +418 -70
- 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/src/api/SignalClient.d.ts +13 -2
- package/dist/src/api/SignalClient.d.ts.map +1 -1
- package/dist/src/connectionHelper/ConnectionCheck.d.ts +2 -2
- package/dist/src/connectionHelper/ConnectionCheck.d.ts.map +1 -1
- package/dist/src/proto/livekit_models.d.ts +20 -3
- package/dist/src/proto/livekit_models.d.ts.map +1 -1
- package/dist/src/proto/livekit_rtc.d.ts +2565 -464
- package/dist/src/proto/livekit_rtc.d.ts.map +1 -1
- package/dist/src/room/RTCEngine.d.ts.map +1 -1
- package/dist/src/room/Room.d.ts +1 -1
- package/dist/src/room/Room.d.ts.map +1 -1
- package/dist/src/room/errors.d.ts +3 -0
- package/dist/src/room/errors.d.ts.map +1 -1
- package/dist/src/room/participant/LocalParticipant.d.ts +1 -3
- package/dist/src/room/participant/LocalParticipant.d.ts.map +1 -1
- package/dist/src/room/participant/Participant.d.ts +1 -1
- package/dist/src/room/participant/Participant.d.ts.map +1 -1
- package/dist/src/room/track/LocalAudioTrack.d.ts.map +1 -1
- package/dist/src/room/track/create.d.ts.map +1 -1
- package/dist/src/room/track/options.d.ts +2 -2
- package/dist/src/room/track/options.d.ts.map +1 -1
- package/dist/src/test/mocks.d.ts +1 -1
- package/dist/ts4.2/src/api/SignalClient.d.ts +13 -2
- package/dist/ts4.2/src/connectionHelper/ConnectionCheck.d.ts +2 -2
- package/dist/ts4.2/src/proto/livekit_models.d.ts +24 -3
- package/dist/ts4.2/src/proto/livekit_rtc.d.ts +2775 -540
- package/dist/ts4.2/src/room/Room.d.ts +1 -1
- package/dist/ts4.2/src/room/errors.d.ts +3 -0
- package/dist/ts4.2/src/room/participant/LocalParticipant.d.ts +1 -3
- package/dist/ts4.2/src/room/participant/Participant.d.ts +1 -1
- package/dist/ts4.2/src/room/track/options.d.ts +2 -2
- package/dist/ts4.2/src/test/mocks.d.ts +1 -1
- package/package.json +17 -17
- package/src/api/SignalClient.ts +46 -3
- package/src/connectionHelper/ConnectionCheck.ts +1 -1
- package/src/proto/google/protobuf/timestamp.ts +2 -2
- package/src/proto/livekit_models.ts +93 -9
- package/src/proto/livekit_rtc.ts +308 -6
- package/src/room/RTCEngine.ts +37 -16
- package/src/room/Room.ts +12 -11
- package/src/room/errors.ts +6 -0
- package/src/room/participant/LocalParticipant.ts +19 -20
- package/src/room/participant/Participant.ts +10 -2
- package/src/room/track/LocalAudioTrack.ts +5 -1
- package/src/room/track/create.ts +6 -1
- package/src/room/track/options.ts +2 -2
package/src/room/Room.ts
CHANGED
@@ -355,12 +355,16 @@ class Room extends (EventEmitter as new () => TypedEmitter<RoomEventCallbacks>)
|
|
355
355
|
} catch (err) {
|
356
356
|
this.recreateEngine();
|
357
357
|
this.handleDisconnect(this.options.stopLocalTrackOnUnpublish);
|
358
|
-
|
358
|
+
const resultingError = new ConnectionError(`could not establish signal connection`);
|
359
359
|
if (err instanceof Error) {
|
360
|
-
|
361
|
-
log.debug(`error trying to establish signal connection`, { error: err });
|
360
|
+
resultingError.message = `${resultingError.message}: ${err.message}`;
|
362
361
|
}
|
363
|
-
|
362
|
+
if (err instanceof ConnectionError) {
|
363
|
+
resultingError.reason = err.reason;
|
364
|
+
resultingError.status = err.status;
|
365
|
+
}
|
366
|
+
log.debug(`error trying to establish signal connection`, { error: err });
|
367
|
+
reject(resultingError);
|
364
368
|
return;
|
365
369
|
}
|
366
370
|
|
@@ -843,10 +847,7 @@ class Room extends (EventEmitter as new () => TypedEmitter<RoomEventCallbacks>)
|
|
843
847
|
private handleParticipantUpdates = (participantInfos: ParticipantInfo[]) => {
|
844
848
|
// handle changes to participant state, and send events
|
845
849
|
participantInfos.forEach((info) => {
|
846
|
-
if (
|
847
|
-
info.sid === this.localParticipant.sid ||
|
848
|
-
info.identity === this.localParticipant.identity
|
849
|
-
) {
|
850
|
+
if (info.identity === this.localParticipant.identity) {
|
850
851
|
this.localParticipant.updateInfo(info);
|
851
852
|
return;
|
852
853
|
}
|
@@ -1138,7 +1139,7 @@ class Room extends (EventEmitter as new () => TypedEmitter<RoomEventCallbacks>)
|
|
1138
1139
|
})
|
1139
1140
|
.on(
|
1140
1141
|
ParticipantEvent.ParticipantPermissionsChanged,
|
1141
|
-
(prevPermissions
|
1142
|
+
(prevPermissions?: ParticipantPermission) => {
|
1142
1143
|
this.emitWhenConnected(
|
1143
1144
|
RoomEvent.ParticipantPermissionsChanged,
|
1144
1145
|
prevPermissions,
|
@@ -1273,7 +1274,7 @@ class Room extends (EventEmitter as new () => TypedEmitter<RoomEventCallbacks>)
|
|
1273
1274
|
this.emit(RoomEvent.MediaDevicesError, e);
|
1274
1275
|
};
|
1275
1276
|
|
1276
|
-
private onLocalParticipantPermissionsChanged = (prevPermissions
|
1277
|
+
private onLocalParticipantPermissionsChanged = (prevPermissions?: ParticipantPermission) => {
|
1277
1278
|
this.emit(RoomEvent.ParticipantPermissionsChanged, prevPermissions, this.localParticipant);
|
1278
1279
|
};
|
1279
1280
|
|
@@ -1442,7 +1443,7 @@ export type RoomEventCallbacks = {
|
|
1442
1443
|
participant: RemoteParticipant | LocalParticipant,
|
1443
1444
|
) => void;
|
1444
1445
|
participantPermissionsChanged: (
|
1445
|
-
prevPermissions: ParticipantPermission,
|
1446
|
+
prevPermissions: ParticipantPermission | undefined,
|
1446
1447
|
participant: RemoteParticipant | LocalParticipant,
|
1447
1448
|
) => void;
|
1448
1449
|
activeSpeakersChanged: (speakers: Array<Participant>) => void;
|
package/src/room/errors.ts
CHANGED
@@ -25,6 +25,12 @@ export class ConnectionError extends LivekitError {
|
|
25
25
|
}
|
26
26
|
}
|
27
27
|
|
28
|
+
export class DeviceUnsupportedError extends LivekitError {
|
29
|
+
constructor(message?: string) {
|
30
|
+
super(21, message ?? 'device is unsupported');
|
31
|
+
}
|
32
|
+
}
|
33
|
+
|
28
34
|
export class TrackInvalidError extends LivekitError {
|
29
35
|
constructor(message?: string) {
|
30
36
|
super(20, message ?? 'track is invalid');
|
@@ -1,12 +1,7 @@
|
|
1
1
|
import 'webrtc-adapter';
|
2
2
|
import log from '../../logger';
|
3
3
|
import type { InternalRoomOptions } from '../../options';
|
4
|
-
import {
|
5
|
-
DataPacket,
|
6
|
-
DataPacket_Kind,
|
7
|
-
ParticipantInfo,
|
8
|
-
ParticipantPermission,
|
9
|
-
} from '../../proto/livekit_models';
|
4
|
+
import { DataPacket, DataPacket_Kind, ParticipantInfo } from '../../proto/livekit_models';
|
10
5
|
import {
|
11
6
|
AddTrackRequest,
|
12
7
|
DataChannelInfo,
|
@@ -15,7 +10,7 @@ import {
|
|
15
10
|
TrackPublishedResponse,
|
16
11
|
TrackUnpublishedResponse,
|
17
12
|
} from '../../proto/livekit_rtc';
|
18
|
-
import { TrackInvalidError, UnexpectedConnectionState } from '../errors';
|
13
|
+
import { DeviceUnsupportedError, TrackInvalidError, UnexpectedConnectionState } from '../errors';
|
19
14
|
import { EngineEvent, ParticipantEvent, TrackEvent } from '../events';
|
20
15
|
import type RTCEngine from '../RTCEngine';
|
21
16
|
import LocalAudioTrack from '../track/LocalAudioTrack';
|
@@ -168,16 +163,6 @@ export default class LocalParticipant extends Participant {
|
|
168
163
|
return this.setTrackEnabled(Track.Source.ScreenShare, enabled, options, publishOptions);
|
169
164
|
}
|
170
165
|
|
171
|
-
/** @internal */
|
172
|
-
setPermissions(permissions: ParticipantPermission): boolean {
|
173
|
-
const prevPermissions = this.permissions;
|
174
|
-
const changed = super.setPermissions(permissions);
|
175
|
-
if (changed && prevPermissions) {
|
176
|
-
this.emit(ParticipantEvent.ParticipantPermissionsChanged, prevPermissions);
|
177
|
-
}
|
178
|
-
return changed;
|
179
|
-
}
|
180
|
-
|
181
166
|
/**
|
182
167
|
* Enable or disable publishing for a track by source. This serves as a simple
|
183
168
|
* way to manage the common tracks (camera, mic, or screen share).
|
@@ -389,6 +374,11 @@ export default class LocalParticipant extends Participant {
|
|
389
374
|
};
|
390
375
|
}
|
391
376
|
}
|
377
|
+
|
378
|
+
if (navigator.mediaDevices.getDisplayMedia === undefined) {
|
379
|
+
throw new DeviceUnsupportedError('getDisplayMedia not supported');
|
380
|
+
}
|
381
|
+
|
392
382
|
const stream: MediaStream = await navigator.mediaDevices.getDisplayMedia({
|
393
383
|
audio: options.audio ?? false,
|
394
384
|
video: videoConstraints,
|
@@ -876,6 +866,11 @@ export default class LocalParticipant extends Participant {
|
|
876
866
|
|
877
867
|
/** @internal */
|
878
868
|
updateInfo(info: ParticipantInfo) {
|
869
|
+
if (info.sid !== this.sid) {
|
870
|
+
// drop updates that specify a wrong sid.
|
871
|
+
// the sid for local participant is only explicitly set on join and full reconnect
|
872
|
+
return;
|
873
|
+
}
|
879
874
|
super.updateInfo(info);
|
880
875
|
|
881
876
|
// reconcile track mute status.
|
@@ -1004,7 +999,9 @@ export default class LocalParticipant extends Participant {
|
|
1004
999
|
// detect granted change after permissions were denied to try and resume then
|
1005
1000
|
currentPermissions.onchange = () => {
|
1006
1001
|
if (currentPermissions.state !== 'denied') {
|
1007
|
-
track.
|
1002
|
+
if (!track.isMuted) {
|
1003
|
+
track.restartTrack();
|
1004
|
+
}
|
1008
1005
|
currentPermissions.onchange = null;
|
1009
1006
|
}
|
1010
1007
|
};
|
@@ -1014,8 +1011,10 @@ export default class LocalParticipant extends Participant {
|
|
1014
1011
|
// permissions query fails for firefox, we continue and try to restart the track
|
1015
1012
|
}
|
1016
1013
|
}
|
1017
|
-
|
1018
|
-
|
1014
|
+
if (!track.isMuted) {
|
1015
|
+
log.debug('track ended, attempting to use a different device');
|
1016
|
+
await track.restartTrack();
|
1017
|
+
}
|
1019
1018
|
} catch (e) {
|
1020
1019
|
log.warn(`could not restart track, muting instead`);
|
1021
1020
|
await track.mute();
|
@@ -173,14 +173,22 @@ export default class Participant extends (EventEmitter as new () => TypedEmitter
|
|
173
173
|
|
174
174
|
/** @internal */
|
175
175
|
setPermissions(permissions: ParticipantPermission): boolean {
|
176
|
+
const prevPermissions = this.permissions;
|
176
177
|
const changed =
|
177
178
|
permissions.canPublish !== this.permissions?.canPublish ||
|
178
179
|
permissions.canSubscribe !== this.permissions?.canSubscribe ||
|
179
180
|
permissions.canPublishData !== this.permissions?.canPublishData ||
|
180
181
|
permissions.hidden !== this.permissions?.hidden ||
|
181
|
-
permissions.recorder !== this.permissions?.recorder
|
182
|
+
permissions.recorder !== this.permissions?.recorder ||
|
183
|
+
permissions.canPublishSources.length !== this.permissions.canPublishSources.length ||
|
184
|
+
permissions.canPublishSources.some(
|
185
|
+
(value, index) => value !== this.permissions?.canPublishSources[index],
|
186
|
+
);
|
182
187
|
this.permissions = permissions;
|
183
188
|
|
189
|
+
if (changed) {
|
190
|
+
this.emit(ParticipantEvent.ParticipantPermissionsChanged, prevPermissions);
|
191
|
+
}
|
184
192
|
return changed;
|
185
193
|
}
|
186
194
|
|
@@ -257,7 +265,7 @@ export type ParticipantEventCallbacks = {
|
|
257
265
|
status: TrackPublication.PermissionStatus,
|
258
266
|
) => void;
|
259
267
|
mediaDevicesError: (error: Error) => void;
|
260
|
-
participantPermissionsChanged: (prevPermissions
|
268
|
+
participantPermissionsChanged: (prevPermissions?: ParticipantPermission) => void;
|
261
269
|
trackSubscriptionStatusChanged: (
|
262
270
|
publication: RemoteTrackPublication,
|
263
271
|
status: TrackPublication.SubscriptionStatus,
|
@@ -53,7 +53,11 @@ export default class LocalAudioTrack extends LocalTrack {
|
|
53
53
|
|
54
54
|
async unmute(): Promise<LocalAudioTrack> {
|
55
55
|
await this.muteQueue.run(async () => {
|
56
|
-
if (
|
56
|
+
if (
|
57
|
+
this.source === Track.Source.Microphone &&
|
58
|
+
(this.stopOnMute || this._mediaStreamTrack.readyState === 'ended') &&
|
59
|
+
!this.isUserProvided
|
60
|
+
) {
|
57
61
|
log.debug('reacquiring mic track');
|
58
62
|
await this.restartTrack();
|
59
63
|
}
|
package/src/room/track/create.ts
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
import DeviceManager from '../DeviceManager';
|
2
|
-
import { TrackInvalidError } from '../errors';
|
2
|
+
import { DeviceUnsupportedError, TrackInvalidError } from '../errors';
|
3
3
|
import { mediaTrackToLocalTrack } from '../participant/publishUtils';
|
4
4
|
import { audioDefaults, videoDefaults } from '../defaults';
|
5
5
|
import LocalAudioTrack from './LocalAudioTrack';
|
@@ -114,6 +114,11 @@ export async function createLocalScreenTracks(
|
|
114
114
|
height: options.resolution.height,
|
115
115
|
};
|
116
116
|
}
|
117
|
+
|
118
|
+
if (navigator.mediaDevices.getDisplayMedia === undefined) {
|
119
|
+
throw new DeviceUnsupportedError('getDisplayMedia not supported');
|
120
|
+
}
|
121
|
+
|
117
122
|
// typescript definition is missing getDisplayMedia: https://github.com/microsoft/TypeScript/issues/33232
|
118
123
|
// @ts-ignore
|
119
124
|
const stream: MediaStream = await navigator.mediaDevices.getDisplayMedia({
|
@@ -232,9 +232,9 @@ export interface AudioPreset {
|
|
232
232
|
const codecs = ['vp8', 'h264', 'av1'] as const;
|
233
233
|
const backupCodecs = ['vp8', 'h264'] as const;
|
234
234
|
|
235
|
-
export type VideoCodec = typeof codecs[number];
|
235
|
+
export type VideoCodec = (typeof codecs)[number];
|
236
236
|
|
237
|
-
export type BackupVideoCodec = typeof backupCodecs[number];
|
237
|
+
export type BackupVideoCodec = (typeof backupCodecs)[number];
|
238
238
|
|
239
239
|
export function isBackupCodec(codec: string): codec is BackupVideoCodec {
|
240
240
|
return !!backupCodecs.find((backup) => backup === codec);
|