livekit-client 2.0.1 → 2.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/dist/livekit-client.e2ee.worker.js +1 -1
- package/dist/livekit-client.e2ee.worker.js.map +1 -1
- package/dist/livekit-client.e2ee.worker.mjs +4 -4
- package/dist/livekit-client.e2ee.worker.mjs.map +1 -1
- package/dist/livekit-client.esm.mjs +29 -21
- 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/room/Room.d.ts.map +1 -1
- package/dist/src/room/participant/LocalParticipant.d.ts.map +1 -1
- package/dist/src/room/track/LocalAudioTrack.d.ts +8 -7
- package/dist/src/room/track/LocalAudioTrack.d.ts.map +1 -1
- package/dist/src/room/track/LocalTrack.d.ts +10 -9
- package/dist/src/room/track/LocalTrack.d.ts.map +1 -1
- package/dist/src/room/track/LocalTrackPublication.d.ts +2 -2
- package/dist/src/room/track/LocalVideoTrack.d.ts +3 -3
- package/dist/src/room/track/LocalVideoTrack.d.ts.map +1 -1
- package/dist/src/room/track/RemoteAudioTrack.d.ts +2 -1
- package/dist/src/room/track/RemoteAudioTrack.d.ts.map +1 -1
- package/dist/src/room/track/RemoteTrack.d.ts +2 -2
- package/dist/src/room/track/RemoteTrack.d.ts.map +1 -1
- package/dist/src/room/track/RemoteVideoTrack.d.ts +2 -1
- package/dist/src/room/track/RemoteVideoTrack.d.ts.map +1 -1
- package/dist/src/room/track/Track.d.ts +3 -3
- package/dist/src/room/track/Track.d.ts.map +1 -1
- package/dist/src/room/track/processor/types.d.ts +4 -0
- package/dist/src/room/track/processor/types.d.ts.map +1 -1
- package/dist/ts4.2/src/room/track/LocalAudioTrack.d.ts +8 -7
- package/dist/ts4.2/src/room/track/LocalTrack.d.ts +10 -9
- package/dist/ts4.2/src/room/track/LocalTrackPublication.d.ts +2 -2
- package/dist/ts4.2/src/room/track/LocalVideoTrack.d.ts +3 -3
- package/dist/ts4.2/src/room/track/RemoteAudioTrack.d.ts +2 -1
- package/dist/ts4.2/src/room/track/RemoteTrack.d.ts +2 -2
- package/dist/ts4.2/src/room/track/RemoteVideoTrack.d.ts +2 -1
- package/dist/ts4.2/src/room/track/Track.d.ts +3 -3
- package/dist/ts4.2/src/room/track/processor/types.d.ts +4 -0
- package/package.json +1 -1
- package/src/api/SignalClient.ts +1 -1
- package/src/e2ee/worker/e2ee.worker.ts +8 -4
- package/src/room/Room.ts +3 -0
- package/src/room/participant/LocalParticipant.ts +0 -1
- package/src/room/track/LocalAudioTrack.ts +8 -11
- package/src/room/track/LocalTrack.ts +36 -23
- package/src/room/track/LocalVideoTrack.ts +3 -3
- package/src/room/track/RemoteAudioTrack.ts +1 -1
- package/src/room/track/RemoteTrack.ts +4 -2
- package/src/room/track/RemoteVideoTrack.ts +1 -1
- package/src/room/track/Track.ts +5 -3
- package/src/room/track/processor/types.ts +4 -0
package/src/room/Room.ts
CHANGED
@@ -1776,7 +1776,10 @@ class Room extends (EventEmitter as new () => TypedEmitter<RoomEventCallbacks>)
|
|
1776
1776
|
};
|
1777
1777
|
|
1778
1778
|
private onLocalTrackPublished = async (pub: LocalTrackPublication) => {
|
1779
|
+
pub.track?.getProcessor()?.onPublish?.(this);
|
1780
|
+
|
1779
1781
|
this.emit(RoomEvent.LocalTrackPublished, pub, this.localParticipant);
|
1782
|
+
|
1780
1783
|
if (pub.track instanceof LocalAudioTrack) {
|
1781
1784
|
const trackIsSilent = await pub.track.checkForSilence();
|
1782
1785
|
if (trackIsSilent) {
|
@@ -6,17 +6,17 @@ import { isWeb, unwrapConstraint } from '../utils';
|
|
6
6
|
import LocalTrack from './LocalTrack';
|
7
7
|
import { Track } from './Track';
|
8
8
|
import type { AudioCaptureOptions } from './options';
|
9
|
-
import type { TrackProcessor } from './processor/types';
|
9
|
+
import type { AudioProcessorOptions, TrackProcessor } from './processor/types';
|
10
10
|
import { constraintsForOptions, detectSilence } from './utils';
|
11
11
|
|
12
|
-
export default class LocalAudioTrack extends LocalTrack {
|
12
|
+
export default class LocalAudioTrack extends LocalTrack<Track.Kind.Audio> {
|
13
13
|
/** @internal */
|
14
14
|
stopOnMute: boolean = false;
|
15
15
|
|
16
|
-
private audioContext?: AudioContext;
|
17
|
-
|
18
16
|
private prevStats?: AudioSenderStats;
|
19
17
|
|
18
|
+
protected processor?: TrackProcessor<Track.Kind.Audio, AudioProcessorOptions> | undefined;
|
19
|
+
|
20
20
|
/**
|
21
21
|
*
|
22
22
|
* @param mediaTrack
|
@@ -48,7 +48,7 @@ export default class LocalAudioTrack extends LocalTrack {
|
|
48
48
|
);
|
49
49
|
}
|
50
50
|
|
51
|
-
async mute(): Promise<
|
51
|
+
async mute(): Promise<typeof this> {
|
52
52
|
const unlock = await this.muteLock.lock();
|
53
53
|
try {
|
54
54
|
// disabled special handling as it will cause BT headsets to switch communication modes
|
@@ -64,7 +64,7 @@ export default class LocalAudioTrack extends LocalTrack {
|
|
64
64
|
}
|
65
65
|
}
|
66
66
|
|
67
|
-
async unmute(): Promise<
|
67
|
+
async unmute(): Promise<typeof this> {
|
68
68
|
const unlock = await this.muteLock.lock();
|
69
69
|
try {
|
70
70
|
const deviceHasChanged =
|
@@ -99,7 +99,7 @@ export default class LocalAudioTrack extends LocalTrack {
|
|
99
99
|
await this.restart(constraints);
|
100
100
|
}
|
101
101
|
|
102
|
-
protected async restart(constraints?: MediaTrackConstraints): Promise<
|
102
|
+
protected async restart(constraints?: MediaTrackConstraints): Promise<typeof this> {
|
103
103
|
const track = await super.restart(constraints);
|
104
104
|
this.checkForSilence();
|
105
105
|
return track;
|
@@ -139,7 +139,7 @@ export default class LocalAudioTrack extends LocalTrack {
|
|
139
139
|
this.prevStats = stats;
|
140
140
|
};
|
141
141
|
|
142
|
-
async setProcessor(processor: TrackProcessor<
|
142
|
+
async setProcessor(processor: TrackProcessor<Track.Kind.Audio, AudioProcessorOptions>) {
|
143
143
|
const unlock = await this.processorLock.lock();
|
144
144
|
try {
|
145
145
|
if (!this.audioContext) {
|
@@ -150,9 +150,6 @@ export default class LocalAudioTrack extends LocalTrack {
|
|
150
150
|
if (this.processor) {
|
151
151
|
await this.stopProcessor();
|
152
152
|
}
|
153
|
-
if (this.kind === 'unknown') {
|
154
|
-
throw TypeError('cannot set processor on track of unknown kind');
|
155
|
-
}
|
156
153
|
|
157
154
|
const processorOptions = {
|
158
155
|
kind: this.kind,
|
@@ -11,7 +11,9 @@ import type { TrackProcessor } from './processor/types';
|
|
11
11
|
|
12
12
|
const defaultDimensionsTimeout = 1000;
|
13
13
|
|
14
|
-
export default abstract class LocalTrack
|
14
|
+
export default abstract class LocalTrack<
|
15
|
+
TrackKind extends Track.Kind = Track.Kind,
|
16
|
+
> extends Track<TrackKind> {
|
15
17
|
/** @internal */
|
16
18
|
sender?: RTCRtpSender;
|
17
19
|
|
@@ -34,10 +36,12 @@ export default abstract class LocalTrack extends Track {
|
|
34
36
|
|
35
37
|
protected processorElement?: HTMLMediaElement;
|
36
38
|
|
37
|
-
protected processor?: TrackProcessor<
|
39
|
+
protected processor?: TrackProcessor<TrackKind, any>;
|
38
40
|
|
39
41
|
protected processorLock: Mutex;
|
40
42
|
|
43
|
+
protected audioContext?: AudioContext;
|
44
|
+
|
41
45
|
/**
|
42
46
|
*
|
43
47
|
* @param mediaTrack
|
@@ -47,7 +51,7 @@ export default abstract class LocalTrack extends Track {
|
|
47
51
|
*/
|
48
52
|
protected constructor(
|
49
53
|
mediaTrack: MediaStreamTrack,
|
50
|
-
kind:
|
54
|
+
kind: TrackKind,
|
51
55
|
constraints?: MediaTrackConstraints,
|
52
56
|
userProvidedTrack = false,
|
53
57
|
loggerOptions?: LoggerOptions,
|
@@ -128,21 +132,28 @@ export default abstract class LocalTrack extends Track {
|
|
128
132
|
this._constraints = newTrack.getConstraints();
|
129
133
|
}
|
130
134
|
let processedTrack: MediaStreamTrack | undefined;
|
131
|
-
if (this.processor && newTrack
|
132
|
-
this.
|
133
|
-
|
134
|
-
|
135
|
-
|
135
|
+
if (this.processor && newTrack) {
|
136
|
+
const unlock = await this.processorLock.lock();
|
137
|
+
try {
|
138
|
+
this.log.debug('restarting processor', this.logContext);
|
139
|
+
if (this.kind === 'unknown') {
|
140
|
+
throw TypeError('cannot set processor on track of unknown kind');
|
141
|
+
}
|
136
142
|
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
143
|
+
if (this.processorElement) {
|
144
|
+
attachToElement(newTrack, this.processorElement);
|
145
|
+
// ensure the processorElement itself stays muted
|
146
|
+
this.processorElement.muted = true;
|
147
|
+
}
|
148
|
+
await this.processor.restart({
|
149
|
+
track: newTrack,
|
150
|
+
kind: this.kind,
|
151
|
+
element: this.processorElement,
|
152
|
+
});
|
153
|
+
processedTrack = this.processor.processedTrack;
|
154
|
+
} finally {
|
155
|
+
unlock();
|
156
|
+
}
|
146
157
|
}
|
147
158
|
if (this.sender) {
|
148
159
|
await this.sender.replaceTrack(processedTrack ?? newTrack);
|
@@ -200,17 +211,17 @@ export default abstract class LocalTrack extends Track {
|
|
200
211
|
return DeviceManager.getInstance().normalizeDeviceId(kind, deviceId, groupId);
|
201
212
|
}
|
202
213
|
|
203
|
-
async mute()
|
214
|
+
async mute() {
|
204
215
|
this.setTrackMuted(true);
|
205
216
|
return this;
|
206
217
|
}
|
207
218
|
|
208
|
-
async unmute()
|
219
|
+
async unmute() {
|
209
220
|
this.setTrackMuted(false);
|
210
221
|
return this;
|
211
222
|
}
|
212
223
|
|
213
|
-
async replaceTrack(track: MediaStreamTrack, userProvidedTrack = true)
|
224
|
+
async replaceTrack(track: MediaStreamTrack, userProvidedTrack = true) {
|
214
225
|
if (!this.sender) {
|
215
226
|
throw new TrackInvalidError('unable to replace an unpublished track');
|
216
227
|
}
|
@@ -227,7 +238,7 @@ export default abstract class LocalTrack extends Track {
|
|
227
238
|
return this;
|
228
239
|
}
|
229
240
|
|
230
|
-
protected async restart(constraints?: MediaTrackConstraints)
|
241
|
+
protected async restart(constraints?: MediaTrackConstraints) {
|
231
242
|
if (!constraints) {
|
232
243
|
constraints = this._constraints;
|
233
244
|
}
|
@@ -408,7 +419,7 @@ export default abstract class LocalTrack extends Track {
|
|
408
419
|
* @param showProcessedStreamLocally
|
409
420
|
* @returns
|
410
421
|
*/
|
411
|
-
async setProcessor(processor: TrackProcessor<
|
422
|
+
async setProcessor(processor: TrackProcessor<TrackKind>, showProcessedStreamLocally = true) {
|
412
423
|
const unlock = await this.processorLock.lock();
|
413
424
|
try {
|
414
425
|
this.log.debug('setting up processor', this.logContext);
|
@@ -418,7 +429,8 @@ export default abstract class LocalTrack extends Track {
|
|
418
429
|
if (this.kind === 'unknown') {
|
419
430
|
throw TypeError('cannot set processor on track of unknown kind');
|
420
431
|
}
|
421
|
-
this.processorElement =
|
432
|
+
this.processorElement =
|
433
|
+
this.processorElement ?? (document.createElement(this.kind) as HTMLMediaElement);
|
422
434
|
|
423
435
|
attachToElement(this._mediaStreamTrack, this.processorElement);
|
424
436
|
this.processorElement.muted = true;
|
@@ -433,6 +445,7 @@ export default abstract class LocalTrack extends Track {
|
|
433
445
|
kind: this.kind,
|
434
446
|
track: this._mediaStreamTrack,
|
435
447
|
element: this.processorElement,
|
448
|
+
audioContext: this.audioContext,
|
436
449
|
};
|
437
450
|
|
438
451
|
await processor.init(processorOptions);
|
@@ -30,7 +30,7 @@ export class SimulcastTrackInfo {
|
|
30
30
|
|
31
31
|
const refreshSubscribedCodecAfterNewCodec = 5000;
|
32
32
|
|
33
|
-
export default class LocalVideoTrack extends LocalTrack {
|
33
|
+
export default class LocalVideoTrack extends LocalTrack<Track.Kind.Video> {
|
34
34
|
/* @internal */
|
35
35
|
signalClient?: SignalClient;
|
36
36
|
|
@@ -115,7 +115,7 @@ export default class LocalVideoTrack extends LocalTrack {
|
|
115
115
|
}
|
116
116
|
}
|
117
117
|
|
118
|
-
async mute(): Promise<
|
118
|
+
async mute(): Promise<typeof this> {
|
119
119
|
const unlock = await this.muteLock.lock();
|
120
120
|
try {
|
121
121
|
if (this.source === Track.Source.Camera && !this.isUserProvided) {
|
@@ -130,7 +130,7 @@ export default class LocalVideoTrack extends LocalTrack {
|
|
130
130
|
}
|
131
131
|
}
|
132
132
|
|
133
|
-
async unmute(): Promise<
|
133
|
+
async unmute(): Promise<typeof this> {
|
134
134
|
const unlock = await this.muteLock.lock();
|
135
135
|
try {
|
136
136
|
if (this.source === Track.Source.Camera && !this.isUserProvided) {
|
@@ -7,7 +7,7 @@ import RemoteTrack from './RemoteTrack';
|
|
7
7
|
import { Track } from './Track';
|
8
8
|
import type { AudioOutputOptions } from './options';
|
9
9
|
|
10
|
-
export default class RemoteAudioTrack extends RemoteTrack {
|
10
|
+
export default class RemoteAudioTrack extends RemoteTrack<Track.Kind.Audio> {
|
11
11
|
private prevStats?: AudioReceiverStats;
|
12
12
|
|
13
13
|
private elementVolume: number | undefined;
|
@@ -3,14 +3,16 @@ import { monitorFrequency } from '../stats';
|
|
3
3
|
import type { LoggerOptions } from '../types';
|
4
4
|
import { Track } from './Track';
|
5
5
|
|
6
|
-
export default abstract class RemoteTrack
|
6
|
+
export default abstract class RemoteTrack<
|
7
|
+
TrackKind extends Track.Kind = Track.Kind,
|
8
|
+
> extends Track<TrackKind> {
|
7
9
|
/** @internal */
|
8
10
|
receiver?: RTCRtpReceiver;
|
9
11
|
|
10
12
|
constructor(
|
11
13
|
mediaTrack: MediaStreamTrack,
|
12
14
|
sid: string,
|
13
|
-
kind:
|
15
|
+
kind: TrackKind,
|
14
16
|
receiver?: RTCRtpReceiver,
|
15
17
|
loggerOptions?: LoggerOptions,
|
16
18
|
) {
|
@@ -12,7 +12,7 @@ import type { AdaptiveStreamSettings } from './types';
|
|
12
12
|
|
13
13
|
const REACTION_DELAY = 100;
|
14
14
|
|
15
|
-
export default class RemoteVideoTrack extends RemoteTrack {
|
15
|
+
export default class RemoteVideoTrack extends RemoteTrack<Track.Kind.Video> {
|
16
16
|
private prevStats?: VideoReceiverStats;
|
17
17
|
|
18
18
|
private elementInfos: ElementInfo[] = [];
|
package/src/room/track/Track.ts
CHANGED
@@ -24,8 +24,10 @@ export enum VideoQuality {
|
|
24
24
|
MEDIUM = ProtoQuality.MEDIUM,
|
25
25
|
HIGH = ProtoQuality.HIGH,
|
26
26
|
}
|
27
|
-
export abstract class Track
|
28
|
-
|
27
|
+
export abstract class Track<
|
28
|
+
TrackKind extends Track.Kind = Track.Kind,
|
29
|
+
> extends (EventEmitter as new () => TypedEventEmitter<TrackEventCallbacks>) {
|
30
|
+
readonly kind: TrackKind;
|
29
31
|
|
30
32
|
attachedElements: HTMLMediaElement[] = [];
|
31
33
|
|
@@ -67,7 +69,7 @@ export abstract class Track extends (EventEmitter as new () => TypedEventEmitter
|
|
67
69
|
|
68
70
|
protected constructor(
|
69
71
|
mediaTrack: MediaStreamTrack,
|
70
|
-
kind:
|
72
|
+
kind: TrackKind,
|
71
73
|
loggerOptions: LoggerOptions = {},
|
72
74
|
) {
|
73
75
|
super();
|
@@ -1,3 +1,4 @@
|
|
1
|
+
import type Room from '../../Room';
|
1
2
|
import type { Track } from '../Track';
|
2
3
|
|
3
4
|
/**
|
@@ -7,6 +8,7 @@ export type ProcessorOptions<T extends Track.Kind> = {
|
|
7
8
|
kind: T;
|
8
9
|
track: MediaStreamTrack;
|
9
10
|
element?: HTMLMediaElement;
|
11
|
+
audioContext?: AudioContext;
|
10
12
|
};
|
11
13
|
|
12
14
|
/**
|
@@ -33,4 +35,6 @@ export interface TrackProcessor<
|
|
33
35
|
restart: (opts: U) => Promise<void>;
|
34
36
|
destroy: () => Promise<void>;
|
35
37
|
processedTrack?: MediaStreamTrack;
|
38
|
+
onPublish?: (room: Room) => Promise<void>;
|
39
|
+
onUnpublish?: () => Promise<void>;
|
36
40
|
}
|