livekit-client 2.5.0 → 2.5.2
Sign up to get free protection for your applications and to get access to all the features.
- package/README.md +4 -0
- 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 -2
- package/dist/livekit-client.e2ee.worker.mjs.map +1 -1
- package/dist/livekit-client.esm.mjs +517 -269
- 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/e2ee/worker/FrameCryptor.d.ts.map +1 -1
- package/dist/src/room/PCTransport.d.ts.map +1 -1
- package/dist/src/room/PCTransportManager.d.ts +1 -0
- package/dist/src/room/PCTransportManager.d.ts.map +1 -1
- package/dist/src/room/Room.d.ts +8 -3
- package/dist/src/room/Room.d.ts.map +1 -1
- package/dist/src/room/events.d.ts +10 -2
- package/dist/src/room/events.d.ts.map +1 -1
- package/dist/src/room/participant/LocalParticipant.d.ts +4 -1
- package/dist/src/room/participant/LocalParticipant.d.ts.map +1 -1
- package/dist/src/room/participant/Participant.d.ts +1 -0
- package/dist/src/room/participant/Participant.d.ts.map +1 -1
- package/dist/src/room/timers.d.ts +4 -4
- package/dist/src/room/timers.d.ts.map +1 -1
- package/dist/src/room/track/LocalTrack.d.ts +1 -1
- package/dist/src/room/track/LocalTrack.d.ts.map +1 -1
- package/dist/src/room/track/create.d.ts +7 -0
- package/dist/src/room/track/create.d.ts.map +1 -1
- package/dist/src/room/track/options.d.ts +1 -1
- package/dist/src/room/types.d.ts +2 -0
- package/dist/src/room/types.d.ts.map +1 -1
- package/dist/src/room/utils.d.ts +1 -1
- package/dist/src/room/utils.d.ts.map +1 -1
- package/dist/ts4.2/src/room/PCTransportManager.d.ts +1 -0
- package/dist/ts4.2/src/room/Room.d.ts +8 -3
- package/dist/ts4.2/src/room/events.d.ts +10 -2
- package/dist/ts4.2/src/room/participant/LocalParticipant.d.ts +4 -1
- package/dist/ts4.2/src/room/participant/Participant.d.ts +1 -0
- package/dist/ts4.2/src/room/timers.d.ts +4 -4
- package/dist/ts4.2/src/room/track/LocalTrack.d.ts +1 -1
- package/dist/ts4.2/src/room/track/create.d.ts +7 -0
- package/dist/ts4.2/src/room/track/options.d.ts +1 -1
- package/dist/ts4.2/src/room/types.d.ts +2 -0
- package/dist/ts4.2/src/room/utils.d.ts +1 -1
- package/package.json +9 -9
- package/src/connectionHelper/checks/Checker.ts +1 -1
- package/src/e2ee/worker/FrameCryptor.ts +3 -1
- package/src/room/PCTransport.ts +3 -1
- package/src/room/PCTransportManager.ts +12 -4
- package/src/room/RTCEngine.ts +1 -1
- package/src/room/Room.ts +69 -7
- package/src/room/events.ts +10 -0
- package/src/room/participant/LocalParticipant.ts +126 -84
- package/src/room/participant/Participant.ts +1 -0
- package/src/room/timers.ts +15 -6
- package/src/room/track/LocalTrack.ts +4 -2
- package/src/room/track/LocalVideoTrack.test.ts +60 -0
- package/src/room/track/LocalVideoTrack.ts +1 -1
- package/src/room/track/create.ts +27 -8
- package/src/room/track/options.ts +1 -1
- package/src/room/types.ts +2 -0
- package/src/room/utils.ts +10 -0
package/src/room/timers.ts
CHANGED
@@ -4,13 +4,22 @@
|
|
4
4
|
* that the timer fires on time.
|
5
5
|
*/
|
6
6
|
export default class CriticalTimers {
|
7
|
-
|
8
|
-
|
7
|
+
static setTimeout: (...args: Parameters<typeof setTimeout>) => ReturnType<typeof setTimeout> = (
|
8
|
+
...args: Parameters<typeof setTimeout>
|
9
|
+
// eslint-disable-next-line @typescript-eslint/no-implied-eval
|
10
|
+
) => setTimeout(...args);
|
9
11
|
|
10
|
-
|
11
|
-
|
12
|
+
static setInterval: (...args: Parameters<typeof setInterval>) => ReturnType<typeof setInterval> =
|
13
|
+
// eslint-disable-next-line @typescript-eslint/no-implied-eval
|
14
|
+
(...args: Parameters<typeof setInterval>) => setInterval(...args);
|
12
15
|
|
13
|
-
static clearTimeout
|
16
|
+
static clearTimeout: (
|
17
|
+
...args: Parameters<typeof clearTimeout>
|
18
|
+
) => ReturnType<typeof clearTimeout> = (...args: Parameters<typeof clearTimeout>) =>
|
19
|
+
clearTimeout(...args);
|
14
20
|
|
15
|
-
static clearInterval
|
21
|
+
static clearInterval: (
|
22
|
+
...args: Parameters<typeof clearInterval>
|
23
|
+
) => ReturnType<typeof clearInterval> = (...args: Parameters<typeof clearInterval>) =>
|
24
|
+
clearInterval(...args);
|
16
25
|
}
|
@@ -215,7 +215,7 @@ export default abstract class LocalTrack<
|
|
215
215
|
/**
|
216
216
|
* @returns DeviceID of the device that is currently being used for this track
|
217
217
|
*/
|
218
|
-
async getDeviceId(): Promise<string | undefined> {
|
218
|
+
async getDeviceId(normalize = true): Promise<string | undefined> {
|
219
219
|
// screen share doesn't have a usable device id
|
220
220
|
if (this.source === Track.Source.ScreenShare) {
|
221
221
|
return;
|
@@ -223,7 +223,9 @@ export default abstract class LocalTrack<
|
|
223
223
|
const { deviceId, groupId } = this._mediaStreamTrack.getSettings();
|
224
224
|
const kind = this.kind === Track.Kind.Audio ? 'audioinput' : 'videoinput';
|
225
225
|
|
226
|
-
return
|
226
|
+
return normalize
|
227
|
+
? DeviceManager.getInstance().normalizeDeviceId(kind, deviceId, groupId)
|
228
|
+
: deviceId;
|
227
229
|
}
|
228
230
|
|
229
231
|
async mute() {
|
@@ -47,6 +47,66 @@ describe('videoLayersFromEncodings', () => {
|
|
47
47
|
expect(layers[2].height).toBe(720);
|
48
48
|
});
|
49
49
|
|
50
|
+
it('returns qualities starting from lowest for SVC', () => {
|
51
|
+
const layers = videoLayersFromEncodings(
|
52
|
+
1280,
|
53
|
+
720,
|
54
|
+
[
|
55
|
+
{
|
56
|
+
/** @ts-ignore */
|
57
|
+
scalabilityMode: 'L2T2',
|
58
|
+
},
|
59
|
+
],
|
60
|
+
true,
|
61
|
+
);
|
62
|
+
|
63
|
+
expect(layers).toHaveLength(2);
|
64
|
+
expect(layers[0].quality).toBe(VideoQuality.MEDIUM);
|
65
|
+
expect(layers[0].width).toBe(1280);
|
66
|
+
expect(layers[1].quality).toBe(VideoQuality.LOW);
|
67
|
+
expect(layers[1].width).toBe(640);
|
68
|
+
});
|
69
|
+
|
70
|
+
it('returns qualities starting from lowest for SVC (three layers)', () => {
|
71
|
+
const layers = videoLayersFromEncodings(
|
72
|
+
1280,
|
73
|
+
720,
|
74
|
+
[
|
75
|
+
{
|
76
|
+
/** @ts-ignore */
|
77
|
+
scalabilityMode: 'L3T3',
|
78
|
+
},
|
79
|
+
],
|
80
|
+
true,
|
81
|
+
);
|
82
|
+
|
83
|
+
expect(layers).toHaveLength(3);
|
84
|
+
expect(layers[0].quality).toBe(VideoQuality.HIGH);
|
85
|
+
expect(layers[0].width).toBe(1280);
|
86
|
+
expect(layers[1].quality).toBe(VideoQuality.MEDIUM);
|
87
|
+
expect(layers[1].width).toBe(640);
|
88
|
+
expect(layers[2].quality).toBe(VideoQuality.LOW);
|
89
|
+
expect(layers[2].width).toBe(320);
|
90
|
+
});
|
91
|
+
|
92
|
+
it('returns qualities starting from lowest for SVC (single layer)', () => {
|
93
|
+
const layers = videoLayersFromEncodings(
|
94
|
+
1280,
|
95
|
+
720,
|
96
|
+
[
|
97
|
+
{
|
98
|
+
/** @ts-ignore */
|
99
|
+
scalabilityMode: 'L1T2',
|
100
|
+
},
|
101
|
+
],
|
102
|
+
true,
|
103
|
+
);
|
104
|
+
|
105
|
+
expect(layers).toHaveLength(1);
|
106
|
+
expect(layers[0].quality).toBe(VideoQuality.LOW);
|
107
|
+
expect(layers[0].width).toBe(1280);
|
108
|
+
});
|
109
|
+
|
50
110
|
it('handles portrait', () => {
|
51
111
|
const layers = videoLayersFromEncodings(720, 1280, [
|
52
112
|
{
|
@@ -607,7 +607,7 @@ export function videoLayersFromEncodings(
|
|
607
607
|
for (let i = 0; i < sm.spatial; i += 1) {
|
608
608
|
layers.push(
|
609
609
|
new VideoLayer({
|
610
|
-
quality: VideoQuality.HIGH - i,
|
610
|
+
quality: Math.min(VideoQuality.HIGH, sm.spatial - 1) - i,
|
611
611
|
width: Math.ceil(width / resRatio ** i),
|
612
612
|
height: Math.ceil(height / resRatio ** i),
|
613
613
|
bitrate: encodings[0].maxBitrate
|
package/src/room/track/create.ts
CHANGED
@@ -14,13 +14,32 @@ import type {
|
|
14
14
|
VideoCaptureOptions,
|
15
15
|
} from './options';
|
16
16
|
import { ScreenSharePresets } from './options';
|
17
|
-
import type {
|
17
|
+
import type {
|
18
|
+
AudioProcessorOptions,
|
19
|
+
TrackProcessor,
|
20
|
+
VideoProcessorOptions,
|
21
|
+
} from './processor/types';
|
18
22
|
import {
|
19
23
|
constraintsForOptions,
|
20
24
|
mergeDefaultOptions,
|
21
25
|
screenCaptureToDisplayMediaStreamOptions,
|
22
26
|
} from './utils';
|
23
27
|
|
28
|
+
/** @internal */
|
29
|
+
export function extractProcessorsFromOptions(options: CreateLocalTracksOptions) {
|
30
|
+
let audioProcessor: TrackProcessor<Track.Kind.Audio, AudioProcessorOptions> | undefined;
|
31
|
+
let videoProcessor: TrackProcessor<Track.Kind.Video, VideoProcessorOptions> | undefined;
|
32
|
+
|
33
|
+
if (typeof options.audio === 'object' && options.audio.processor) {
|
34
|
+
audioProcessor = options.audio.processor;
|
35
|
+
}
|
36
|
+
if (typeof options.video === 'object' && options.video.processor) {
|
37
|
+
videoProcessor = options.video.processor;
|
38
|
+
}
|
39
|
+
|
40
|
+
return { audioProcessor, videoProcessor };
|
41
|
+
}
|
42
|
+
|
24
43
|
/**
|
25
44
|
* Creates a local video and audio track at the same time. When acquiring both
|
26
45
|
* audio and video tracks together, it'll display a single permission prompt to
|
@@ -35,6 +54,7 @@ export async function createLocalTracks(
|
|
35
54
|
options.audio ??= true;
|
36
55
|
options.video ??= true;
|
37
56
|
|
57
|
+
const { audioProcessor, videoProcessor } = extractProcessorsFromOptions(options);
|
38
58
|
const opts = mergeDefaultOptions(options, audioDefaults, videoDefaults);
|
39
59
|
const constraints = constraintsForOptions(opts);
|
40
60
|
|
@@ -55,7 +75,7 @@ export async function createLocalTracks(
|
|
55
75
|
return Promise.all(
|
56
76
|
stream.getTracks().map(async (mediaStreamTrack) => {
|
57
77
|
const isAudio = mediaStreamTrack.kind === 'audio';
|
58
|
-
let trackOptions = isAudio ?
|
78
|
+
let trackOptions = isAudio ? opts!.audio : opts!.video;
|
59
79
|
if (typeof trackOptions === 'boolean' || !trackOptions) {
|
60
80
|
trackOptions = {};
|
61
81
|
}
|
@@ -80,13 +100,12 @@ export async function createLocalTracks(
|
|
80
100
|
track.source = Track.Source.Microphone;
|
81
101
|
}
|
82
102
|
track.mediaStream = stream;
|
83
|
-
if (
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
await track.setProcessor(trackOptions.processor as TrackProcessor<Track.Kind.Video>);
|
88
|
-
}
|
103
|
+
if (track instanceof LocalAudioTrack && audioProcessor) {
|
104
|
+
await track.setProcessor(audioProcessor);
|
105
|
+
} else if (track instanceof LocalVideoTrack && videoProcessor) {
|
106
|
+
await track.setProcessor(videoProcessor);
|
89
107
|
}
|
108
|
+
|
90
109
|
return track;
|
91
110
|
}),
|
92
111
|
);
|
@@ -64,7 +64,7 @@ export interface TrackPublishDefaults {
|
|
64
64
|
simulcast?: boolean;
|
65
65
|
|
66
66
|
/**
|
67
|
-
* scalability mode for svc codecs, defaults to '
|
67
|
+
* scalability mode for svc codecs, defaults to 'L3T3_KEY'.
|
68
68
|
* for svc codecs, simulcast is disabled.
|
69
69
|
*/
|
70
70
|
scalabilityMode?: ScalabilityMode;
|
package/src/room/types.ts
CHANGED
package/src/room/utils.ts
CHANGED
@@ -532,8 +532,16 @@ export function toHttpUrl(url: string): string {
|
|
532
532
|
|
533
533
|
export function extractTranscriptionSegments(
|
534
534
|
transcription: TranscriptionModel,
|
535
|
+
firstReceivedTimesMap: Map<string, number>,
|
535
536
|
): TranscriptionSegment[] {
|
536
537
|
return transcription.segments.map(({ id, text, language, startTime, endTime, final }) => {
|
538
|
+
const firstReceivedTime = firstReceivedTimesMap.get(id) ?? Date.now();
|
539
|
+
const lastReceivedTime = Date.now();
|
540
|
+
if (final) {
|
541
|
+
firstReceivedTimesMap.delete(id);
|
542
|
+
} else {
|
543
|
+
firstReceivedTimesMap.set(id, firstReceivedTime);
|
544
|
+
}
|
537
545
|
return {
|
538
546
|
id,
|
539
547
|
text,
|
@@ -541,6 +549,8 @@ export function extractTranscriptionSegments(
|
|
541
549
|
endTime: Number.parseInt(endTime.toString()),
|
542
550
|
final,
|
543
551
|
language,
|
552
|
+
firstReceivedTime,
|
553
|
+
lastReceivedTime,
|
544
554
|
};
|
545
555
|
});
|
546
556
|
}
|