livekit-client 1.1.6 → 1.1.9
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 -0
- package/dist/livekit-client.esm.mjs +535 -120
- 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 +2 -1
- package/dist/src/api/SignalClient.d.ts.map +1 -1
- package/dist/src/index.d.ts +4 -3
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/proto/livekit_models.d.ts +234 -0
- package/dist/src/proto/livekit_models.d.ts.map +1 -1
- package/dist/src/proto/livekit_rtc.d.ts +944 -6
- package/dist/src/proto/livekit_rtc.d.ts.map +1 -1
- package/dist/src/room/RTCEngine.d.ts +2 -2
- package/dist/src/room/RTCEngine.d.ts.map +1 -1
- package/dist/src/room/Room.d.ts +2 -2
- package/dist/src/room/Room.d.ts.map +1 -1
- package/dist/src/room/participant/LocalParticipant.d.ts +3 -1
- package/dist/src/room/participant/LocalParticipant.d.ts.map +1 -1
- package/dist/src/room/participant/Participant.d.ts.map +1 -1
- package/dist/src/room/participant/RemoteParticipant.d.ts.map +1 -1
- package/dist/src/room/track/LocalAudioTrack.d.ts.map +1 -1
- package/dist/src/room/track/LocalTrack.d.ts +2 -0
- package/dist/src/room/track/LocalTrack.d.ts.map +1 -1
- package/dist/src/room/track/LocalVideoTrack.d.ts.map +1 -1
- package/dist/src/room/track/RemoteTrack.d.ts.map +1 -1
- package/dist/src/room/track/Track.d.ts +7 -0
- package/dist/src/room/track/Track.d.ts.map +1 -1
- package/dist/src/room/track/TrackPublication.d.ts.map +1 -1
- package/package.json +3 -1
- package/src/api/SignalClient.ts +19 -6
- package/src/index.ts +6 -2
- package/src/proto/livekit_models.ts +179 -4
- package/src/proto/livekit_rtc.ts +14 -1
- package/src/room/RTCEngine.ts +4 -2
- package/src/room/Room.ts +32 -9
- package/src/room/participant/LocalParticipant.ts +30 -2
- package/src/room/participant/Participant.ts +2 -0
- package/src/room/participant/RemoteParticipant.ts +4 -0
- package/src/room/track/LocalAudioTrack.ts +16 -12
- package/src/room/track/LocalTrack.ts +37 -25
- package/src/room/track/LocalVideoTrack.ts +15 -11
- package/src/room/track/RemoteTrack.ts +1 -0
- package/src/room/track/Track.ts +12 -0
- package/src/room/track/TrackPublication.ts +2 -0
- package/dist/src/api/RequestQueue.d.ts +0 -13
- package/dist/src/api/RequestQueue.d.ts.map +0 -1
- package/src/api/RequestQueue.ts +0 -53
@@ -1,9 +1,10 @@
|
|
1
|
+
import Queue from 'async-await-queue';
|
1
2
|
import log from '../../logger';
|
2
3
|
import DeviceManager from '../DeviceManager';
|
3
4
|
import { TrackInvalidError } from '../errors';
|
4
5
|
import { TrackEvent } from '../events';
|
5
|
-
import { VideoCodec } from './options';
|
6
6
|
import { getEmptyAudioStreamTrack, getEmptyVideoStreamTrack, isMobile } from '../utils';
|
7
|
+
import { VideoCodec } from './options';
|
7
8
|
import { attachToElement, detachTrack, Track } from './Track';
|
8
9
|
|
9
10
|
export default class LocalTrack extends Track {
|
@@ -21,6 +22,8 @@ export default class LocalTrack extends Track {
|
|
21
22
|
|
22
23
|
protected providedByUser: boolean;
|
23
24
|
|
25
|
+
protected muteQueue: Queue;
|
26
|
+
|
24
27
|
protected constructor(
|
25
28
|
mediaTrack: MediaStreamTrack,
|
26
29
|
kind: Track.Kind,
|
@@ -33,6 +36,7 @@ export default class LocalTrack extends Track {
|
|
33
36
|
this.reacquireTrack = false;
|
34
37
|
this.wasMuted = false;
|
35
38
|
this.providedByUser = userProvidedTrack;
|
39
|
+
this.muteQueue = new Queue();
|
36
40
|
}
|
37
41
|
|
38
42
|
get id(): string {
|
@@ -101,7 +105,9 @@ export default class LocalTrack extends Track {
|
|
101
105
|
// on Safari, the old audio track must be stopped before attempting to acquire
|
102
106
|
// the new track, otherwise the new track will stop with
|
103
107
|
// 'A MediaStreamTrack ended due to a capture failure`
|
104
|
-
this.
|
108
|
+
if (!this.providedByUser) {
|
109
|
+
this._mediaStreamTrack.stop();
|
110
|
+
}
|
105
111
|
|
106
112
|
track.addEventListener('ended', this.handleEnded);
|
107
113
|
log.debug('replace MediaStreamTrack');
|
@@ -170,6 +176,7 @@ export default class LocalTrack extends Track {
|
|
170
176
|
}
|
171
177
|
|
172
178
|
protected setTrackMuted(muted: boolean) {
|
179
|
+
log.debug(`setting ${this.kind} track ${muted ? 'muted' : 'unmuted'}`);
|
173
180
|
if (this.isMuted === muted) {
|
174
181
|
return;
|
175
182
|
}
|
@@ -215,31 +222,36 @@ export default class LocalTrack extends Track {
|
|
215
222
|
};
|
216
223
|
|
217
224
|
async pauseUpstream() {
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
this.
|
229
|
-
|
225
|
+
this.muteQueue.run(async () => {
|
226
|
+
if (this._isUpstreamPaused === true) {
|
227
|
+
return;
|
228
|
+
}
|
229
|
+
if (!this.sender) {
|
230
|
+
log.warn('unable to pause upstream for an unpublished track');
|
231
|
+
return;
|
232
|
+
}
|
233
|
+
|
234
|
+
this._isUpstreamPaused = true;
|
235
|
+
this.emit(TrackEvent.UpstreamPaused, this);
|
236
|
+
const emptyTrack =
|
237
|
+
this.kind === Track.Kind.Audio ? getEmptyAudioStreamTrack() : getEmptyVideoStreamTrack();
|
238
|
+
await this.sender.replaceTrack(emptyTrack);
|
239
|
+
});
|
230
240
|
}
|
231
241
|
|
232
242
|
async resumeUpstream() {
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
243
|
+
this.muteQueue.run(async () => {
|
244
|
+
if (this._isUpstreamPaused === false) {
|
245
|
+
return;
|
246
|
+
}
|
247
|
+
if (!this.sender) {
|
248
|
+
log.warn('unable to resume upstream for an unpublished track');
|
249
|
+
return;
|
250
|
+
}
|
251
|
+
this._isUpstreamPaused = false;
|
252
|
+
this.emit(TrackEvent.UpstreamResumed, this);
|
253
|
+
|
254
|
+
await this.sender.replaceTrack(this._mediaStreamTrack);
|
255
|
+
});
|
244
256
|
}
|
245
257
|
}
|
@@ -86,21 +86,25 @@ export default class LocalVideoTrack extends LocalTrack {
|
|
86
86
|
}
|
87
87
|
|
88
88
|
async mute(): Promise<LocalVideoTrack> {
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
89
|
+
await this.muteQueue.run(async () => {
|
90
|
+
if (this.source === Track.Source.Camera && !this.isUserProvided) {
|
91
|
+
log.debug('stopping camera track');
|
92
|
+
// also stop the track, so that camera indicator is turned off
|
93
|
+
this._mediaStreamTrack.stop();
|
94
|
+
}
|
95
|
+
await super.mute();
|
96
|
+
});
|
95
97
|
return this;
|
96
98
|
}
|
97
99
|
|
98
100
|
async unmute(): Promise<LocalVideoTrack> {
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
101
|
+
await this.muteQueue.run(async () => {
|
102
|
+
if (this.source === Track.Source.Camera && !this.isUserProvided) {
|
103
|
+
log.debug('reacquiring camera track');
|
104
|
+
await this.restartTrack();
|
105
|
+
}
|
106
|
+
await super.unmute();
|
107
|
+
});
|
104
108
|
return this;
|
105
109
|
}
|
106
110
|
|
@@ -21,6 +21,7 @@ export default abstract class RemoteTrack extends Track {
|
|
21
21
|
setMuted(muted: boolean) {
|
22
22
|
if (this.isMuted !== muted) {
|
23
23
|
this.isMuted = muted;
|
24
|
+
this._mediaStreamTrack.enabled = !muted;
|
24
25
|
this.emit(muted ? TrackEvent.Muted : TrackEvent.Unmuted, this);
|
25
26
|
}
|
26
27
|
}
|
package/src/room/track/Track.ts
CHANGED
@@ -37,6 +37,8 @@ export class Track extends (EventEmitter as new () => TypedEventEmitter<TrackEve
|
|
37
37
|
|
38
38
|
protected _mediaStreamTrack: MediaStreamTrack;
|
39
39
|
|
40
|
+
protected _mediaStreamID: string;
|
41
|
+
|
40
42
|
protected isInBackground: boolean;
|
41
43
|
|
42
44
|
private backgroundTimeout: ReturnType<typeof setTimeout> | undefined;
|
@@ -47,6 +49,7 @@ export class Track extends (EventEmitter as new () => TypedEventEmitter<TrackEve
|
|
47
49
|
super();
|
48
50
|
this.kind = kind;
|
49
51
|
this._mediaStreamTrack = mediaTrack;
|
52
|
+
this._mediaStreamID = mediaTrack.id;
|
50
53
|
this.source = Track.Source.Unknown;
|
51
54
|
if (isWeb()) {
|
52
55
|
this.isInBackground = document.visibilityState === 'hidden';
|
@@ -65,6 +68,15 @@ export class Track extends (EventEmitter as new () => TypedEventEmitter<TrackEve
|
|
65
68
|
return this._mediaStreamTrack;
|
66
69
|
}
|
67
70
|
|
71
|
+
/**
|
72
|
+
* @internal
|
73
|
+
* used for keep mediaStream's first id, since it's id might change
|
74
|
+
* if we disable/enable a track
|
75
|
+
*/
|
76
|
+
get mediaStreamID(): string {
|
77
|
+
return this._mediaStreamID;
|
78
|
+
}
|
79
|
+
|
68
80
|
/**
|
69
81
|
* creates a new HTMLAudioElement or HTMLVideoElement, attaches to it, and returns it
|
70
82
|
*/
|
@@ -1,4 +1,5 @@
|
|
1
1
|
import { EventEmitter } from 'events';
|
2
|
+
import log from '../../logger';
|
2
3
|
import { TrackInfo } from '../../proto/livekit_models';
|
3
4
|
import { TrackEvent } from '../events';
|
4
5
|
import LocalAudioTrack from './LocalAudioTrack';
|
@@ -108,6 +109,7 @@ export class TrackPublication extends EventEmitter {
|
|
108
109
|
this.simulcasted = info.simulcast;
|
109
110
|
}
|
110
111
|
this.trackInfo = info;
|
112
|
+
log.trace('update publication info', { info });
|
111
113
|
}
|
112
114
|
}
|
113
115
|
|
@@ -1,13 +0,0 @@
|
|
1
|
-
export default class Queue {
|
2
|
-
private queue;
|
3
|
-
private running;
|
4
|
-
constructor();
|
5
|
-
enqueue(cb: () => void): void;
|
6
|
-
dequeue(): void;
|
7
|
-
run(): Promise<void>;
|
8
|
-
pause(): void;
|
9
|
-
reset(): void;
|
10
|
-
isRunning(): boolean;
|
11
|
-
isEmpty(): boolean;
|
12
|
-
}
|
13
|
-
//# sourceMappingURL=RequestQueue.d.ts.map
|
@@ -1 +0,0 @@
|
|
1
|
-
{"version":3,"file":"RequestQueue.d.ts","sourceRoot":"","sources":["../../../src/api/RequestQueue.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,OAAO,OAAO,KAAK;IACxB,OAAO,CAAC,KAAK,CAAoB;IAEjC,OAAO,CAAC,OAAO,CAAU;;IAOzB,OAAO,CAAC,EAAE,EAAE,MAAM,IAAI;IAKtB,OAAO;IAMD,GAAG;IAWT,KAAK;IAKL,KAAK;IAML,SAAS;IAIT,OAAO;CAGR"}
|
package/src/api/RequestQueue.ts
DELETED
@@ -1,53 +0,0 @@
|
|
1
|
-
import log from '../logger';
|
2
|
-
|
3
|
-
export default class Queue {
|
4
|
-
private queue: Array<() => void>;
|
5
|
-
|
6
|
-
private running: boolean;
|
7
|
-
|
8
|
-
constructor() {
|
9
|
-
this.queue = [];
|
10
|
-
this.running = false;
|
11
|
-
}
|
12
|
-
|
13
|
-
enqueue(cb: () => void) {
|
14
|
-
log.trace('enqueuing request to fire later');
|
15
|
-
this.queue.push(cb);
|
16
|
-
}
|
17
|
-
|
18
|
-
dequeue() {
|
19
|
-
const evt = this.queue.shift();
|
20
|
-
if (evt) evt();
|
21
|
-
log.trace('firing request from queue');
|
22
|
-
}
|
23
|
-
|
24
|
-
async run() {
|
25
|
-
if (this.running) return;
|
26
|
-
log.trace('start queue');
|
27
|
-
this.running = true;
|
28
|
-
while (this.running && this.queue.length > 0) {
|
29
|
-
this.dequeue();
|
30
|
-
}
|
31
|
-
this.running = false;
|
32
|
-
log.trace('queue finished');
|
33
|
-
}
|
34
|
-
|
35
|
-
pause() {
|
36
|
-
log.trace('pausing queue');
|
37
|
-
this.running = false;
|
38
|
-
}
|
39
|
-
|
40
|
-
reset() {
|
41
|
-
log.trace('resetting queue');
|
42
|
-
this.running = false;
|
43
|
-
this.queue = [];
|
44
|
-
}
|
45
|
-
|
46
|
-
isRunning() {
|
47
|
-
return this.running;
|
48
|
-
}
|
49
|
-
|
50
|
-
isEmpty() {
|
51
|
-
return this.queue.length === 0;
|
52
|
-
}
|
53
|
-
}
|