livekit-client 1.9.2 → 1.9.3
Sign up to get free protection for your applications and to get access to all the features.
- package/dist/livekit-client.esm.mjs +3251 -3013
- 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 +98 -98
- package/dist/src/api/SignalClient.d.ts.map +1 -1
- package/dist/src/connectionHelper/ConnectionCheck.d.ts +25 -24
- package/dist/src/connectionHelper/ConnectionCheck.d.ts.map +1 -1
- package/dist/src/connectionHelper/checks/Checker.d.ts +58 -58
- package/dist/src/connectionHelper/checks/publishAudio.d.ts +5 -5
- package/dist/src/connectionHelper/checks/publishVideo.d.ts +5 -5
- package/dist/src/connectionHelper/checks/reconnect.d.ts +5 -5
- package/dist/src/connectionHelper/checks/turn.d.ts +5 -5
- package/dist/src/connectionHelper/checks/webrtc.d.ts +5 -5
- package/dist/src/connectionHelper/checks/websocket.d.ts +5 -5
- package/dist/src/index.d.ts +34 -31
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/logger.d.ts +25 -25
- package/dist/src/options.d.ts +98 -98
- package/dist/src/proto/google/protobuf/timestamp.d.ts +145 -145
- package/dist/src/proto/livekit_models.d.ts +2300 -2300
- package/dist/src/proto/livekit_rtc.d.ts +14032 -14032
- package/dist/src/room/DefaultReconnectPolicy.d.ts +7 -7
- package/dist/src/room/DeviceManager.d.ts +8 -8
- package/dist/src/room/PCTransport.d.ts +37 -37
- package/dist/src/room/PCTransport.d.ts.map +1 -1
- package/dist/src/room/RTCEngine.d.ts +126 -121
- package/dist/src/room/RTCEngine.d.ts.map +1 -1
- package/dist/src/room/ReconnectPolicy.d.ts +23 -23
- package/dist/src/room/RegionUrlProvider.d.ts +13 -13
- package/dist/src/room/Room.d.ts +232 -232
- package/dist/src/room/defaults.d.ts +7 -7
- package/dist/src/room/defaults.d.ts.map +1 -1
- package/dist/src/room/errors.d.ts +42 -42
- package/dist/src/room/events.d.ts +455 -455
- package/dist/src/room/participant/LocalParticipant.d.ts +170 -170
- package/dist/src/room/participant/LocalParticipant.d.ts.map +1 -1
- package/dist/src/room/participant/Participant.d.ts +93 -93
- package/dist/src/room/participant/ParticipantTrackPermission.d.ts +25 -25
- package/dist/src/room/participant/RemoteParticipant.d.ts +52 -51
- package/dist/src/room/participant/RemoteParticipant.d.ts.map +1 -1
- package/dist/src/room/participant/publishUtils.d.ts +19 -18
- package/dist/src/room/participant/publishUtils.d.ts.map +1 -1
- package/dist/src/room/stats.d.ts +66 -66
- package/dist/src/room/timers.d.ts +12 -12
- package/dist/src/room/track/LocalAudioTrack.d.ts +24 -24
- package/dist/src/room/track/LocalAudioTrack.d.ts.map +1 -1
- package/dist/src/room/track/LocalTrack.d.ts +43 -43
- package/dist/src/room/track/LocalTrackPublication.d.ts +37 -37
- package/dist/src/room/track/LocalVideoTrack.d.ts +53 -53
- package/dist/src/room/track/LocalVideoTrack.d.ts.map +1 -1
- package/dist/src/room/track/RemoteAudioTrack.d.ts +52 -52
- package/dist/src/room/track/RemoteAudioTrack.d.ts.map +1 -1
- package/dist/src/room/track/RemoteTrack.d.ts +14 -14
- package/dist/src/room/track/RemoteTrackPublication.d.ts +60 -60
- package/dist/src/room/track/RemoteVideoTrack.d.ts +52 -52
- package/dist/src/room/track/RemoteVideoTrack.d.ts.map +1 -1
- package/dist/src/room/track/Track.d.ts +124 -124
- package/dist/src/room/track/TrackPublication.d.ts +67 -67
- package/dist/src/room/track/create.d.ts +23 -23
- package/dist/src/room/track/create.d.ts.map +1 -1
- package/dist/src/room/track/options.d.ts +255 -247
- package/dist/src/room/track/options.d.ts.map +1 -1
- package/dist/src/room/track/types.d.ts +22 -22
- package/dist/src/room/track/utils.d.ts +13 -13
- package/dist/src/room/types.d.ts +25 -25
- package/dist/src/room/utils.d.ts +86 -85
- package/dist/src/room/utils.d.ts.map +1 -1
- package/dist/src/test/MockMediaStreamTrack.d.ts +25 -25
- package/dist/src/test/mocks.d.ts +10 -10
- package/dist/src/version.d.ts +2 -2
- package/dist/ts4.2/src/connectionHelper/ConnectionCheck.d.ts +2 -1
- package/dist/ts4.2/src/index.d.ts +8 -6
- package/dist/ts4.2/src/room/PCTransport.d.ts +1 -1
- package/dist/ts4.2/src/room/RTCEngine.d.ts +6 -1
- package/dist/ts4.2/src/room/defaults.d.ts +1 -1
- package/dist/ts4.2/src/room/participant/LocalParticipant.d.ts +4 -4
- package/dist/ts4.2/src/room/participant/RemoteParticipant.d.ts +2 -1
- package/dist/ts4.2/src/room/participant/publishUtils.d.ts +2 -1
- package/dist/ts4.2/src/room/track/LocalAudioTrack.d.ts +1 -1
- package/dist/ts4.2/src/room/track/LocalVideoTrack.d.ts +1 -1
- package/dist/ts4.2/src/room/track/RemoteAudioTrack.d.ts +1 -1
- package/dist/ts4.2/src/room/track/create.d.ts +1 -1
- package/dist/ts4.2/src/room/track/options.d.ts +10 -2
- package/dist/ts4.2/src/room/utils.d.ts +1 -0
- package/package.json +12 -12
- package/src/api/SignalClient.ts +10 -11
- package/src/connectionHelper/ConnectionCheck.ts +2 -1
- package/src/index.ts +13 -8
- package/src/room/PCTransport.ts +9 -5
- package/src/room/RTCEngine.ts +10 -3
- package/src/room/defaults.ts +6 -4
- package/src/room/participant/LocalParticipant.ts +10 -9
- package/src/room/participant/RemoteParticipant.ts +2 -1
- package/src/room/participant/publishUtils.ts +7 -5
- package/src/room/track/LocalAudioTrack.ts +2 -1
- package/src/room/track/LocalVideoTrack.ts +3 -2
- package/src/room/track/RemoteAudioTrack.ts +2 -1
- package/src/room/track/RemoteVideoTrack.ts +4 -8
- package/src/room/track/create.ts +2 -2
- package/src/room/track/options.ts +23 -7
- package/src/room/utils.ts +15 -2
package/src/api/SignalClient.ts
CHANGED
@@ -321,6 +321,7 @@ export class SignalClient {
|
|
321
321
|
};
|
322
322
|
|
323
323
|
this.ws.onclose = (ev: CloseEvent) => {
|
324
|
+
log.warn(`websocket closed`, { ev });
|
324
325
|
this.handleOnClose(ev.reason);
|
325
326
|
};
|
326
327
|
});
|
@@ -344,12 +345,14 @@ export class SignalClient {
|
|
344
345
|
}
|
345
346
|
});
|
346
347
|
|
347
|
-
this.ws.
|
348
|
-
|
349
|
-
|
348
|
+
if (this.ws.readyState < this.ws.CLOSING) {
|
349
|
+
this.ws.close();
|
350
|
+
// 250ms grace period for ws to close gracefully
|
351
|
+
await Promise.race([closePromise, sleep(250)]);
|
352
|
+
}
|
353
|
+
this.ws = undefined;
|
354
|
+
this.clearPingInterval();
|
350
355
|
}
|
351
|
-
this.ws = undefined;
|
352
|
-
this.clearPingInterval();
|
353
356
|
} finally {
|
354
357
|
unlock();
|
355
358
|
}
|
@@ -611,17 +614,13 @@ export class SignalClient {
|
|
611
614
|
this.isReconnecting = false;
|
612
615
|
}
|
613
616
|
|
614
|
-
private handleOnClose(reason: string) {
|
617
|
+
private async handleOnClose(reason: string) {
|
615
618
|
if (!this.isConnected) return;
|
616
|
-
this.
|
617
|
-
this.clearPingTimeout();
|
618
|
-
|
619
|
+
await this.close();
|
619
620
|
log.debug(`websocket connection closed: ${reason}`);
|
620
|
-
this.isConnected = false;
|
621
621
|
if (this.onClose) {
|
622
622
|
this.onClose(reason);
|
623
623
|
}
|
624
|
-
this.ws = undefined;
|
625
624
|
}
|
626
625
|
|
627
626
|
private handleWSError(ev: Event) {
|
@@ -1,6 +1,7 @@
|
|
1
1
|
import EventEmitter from 'events';
|
2
2
|
import type TypedEmitter from 'typed-emitter';
|
3
|
-
import {
|
3
|
+
import { CheckStatus, Checker } from './checks/Checker';
|
4
|
+
import type { CheckInfo, InstantiableCheck } from './checks/Checker';
|
4
5
|
import { PublishAudioCheck } from './checks/publishAudio';
|
5
6
|
import { PublishVideoCheck } from './checks/publishVideo';
|
6
7
|
import { ReconnectCheck } from './checks/reconnect';
|
package/src/index.ts
CHANGED
@@ -14,11 +14,12 @@ import LocalVideoTrack from './room/track/LocalVideoTrack';
|
|
14
14
|
import RemoteAudioTrack from './room/track/RemoteAudioTrack';
|
15
15
|
import RemoteTrack from './room/track/RemoteTrack';
|
16
16
|
import RemoteTrackPublication from './room/track/RemoteTrackPublication';
|
17
|
-
import
|
17
|
+
import type { ElementInfo } from './room/track/RemoteVideoTrack';
|
18
|
+
import RemoteVideoTrack from './room/track/RemoteVideoTrack';
|
18
19
|
import { TrackPublication } from './room/track/TrackPublication';
|
19
20
|
import type { LiveKitReactNativeInfo } from './room/types';
|
21
|
+
import type { AudioAnalyserOptions } from './room/utils';
|
20
22
|
import {
|
21
|
-
type AudioAnalyserOptions,
|
22
23
|
createAudioAnalyser,
|
23
24
|
getEmptyAudioStreamTrack,
|
24
25
|
getEmptyVideoStreamTrack,
|
@@ -26,18 +27,19 @@ import {
|
|
26
27
|
supportsAV1,
|
27
28
|
supportsAdaptiveStream,
|
28
29
|
supportsDynacast,
|
30
|
+
supportsVP9,
|
29
31
|
} from './room/utils';
|
30
32
|
|
33
|
+
export * from './connectionHelper/ConnectionCheck';
|
31
34
|
export * from './options';
|
32
35
|
export * from './room/errors';
|
33
36
|
export * from './room/events';
|
34
|
-
export
|
37
|
+
export * from './room/track/Track';
|
35
38
|
export * from './room/track/create';
|
36
39
|
export * from './room/track/options';
|
37
|
-
export * from './room/track/Track';
|
38
40
|
export * from './room/track/types';
|
41
|
+
export type { DataPublishOptions, SimulationScenario } from './room/types';
|
39
42
|
export * from './version';
|
40
|
-
export * from './connectionHelper/ConnectionCheck';
|
41
43
|
export {
|
42
44
|
setLogLevel,
|
43
45
|
setLogExtension,
|
@@ -47,8 +49,8 @@ export {
|
|
47
49
|
supportsAdaptiveStream,
|
48
50
|
supportsDynacast,
|
49
51
|
supportsAV1,
|
52
|
+
supportsVP9,
|
50
53
|
createAudioAnalyser,
|
51
|
-
AudioAnalyserOptions,
|
52
54
|
LogLevel,
|
53
55
|
Room,
|
54
56
|
ConnectionState,
|
@@ -66,12 +68,15 @@ export {
|
|
66
68
|
RemoteAudioTrack,
|
67
69
|
RemoteVideoTrack,
|
68
70
|
RemoteTrackPublication,
|
69
|
-
ParticipantTrackPermission,
|
70
71
|
TrackPublication,
|
71
72
|
VideoQuality,
|
72
73
|
ConnectionQuality,
|
73
|
-
ElementInfo,
|
74
74
|
DefaultReconnectPolicy,
|
75
75
|
CriticalTimers,
|
76
|
+
};
|
77
|
+
export type {
|
78
|
+
ElementInfo,
|
79
|
+
ParticipantTrackPermission,
|
80
|
+
AudioAnalyserOptions,
|
76
81
|
LiveKitReactNativeInfo,
|
77
82
|
};
|
package/src/room/PCTransport.ts
CHANGED
@@ -1,9 +1,10 @@
|
|
1
1
|
import EventEmitter from 'events';
|
2
|
-
import {
|
2
|
+
import { parse, write } from 'sdp-transform';
|
3
|
+
import type { MediaDescription } from 'sdp-transform';
|
3
4
|
import { debounce } from 'ts-debounce';
|
4
5
|
import log from '../logger';
|
5
6
|
import { NegotiationError } from './errors';
|
6
|
-
import { ddExtensionURI, isSVCCodec } from './utils';
|
7
|
+
import { ddExtensionURI, isChromiumBased, isSVCCodec } from './utils';
|
7
8
|
|
8
9
|
/** @internal */
|
9
10
|
interface TrackBitrateInfo {
|
@@ -35,9 +36,12 @@ export default class PCTransport extends EventEmitter {
|
|
35
36
|
|
36
37
|
onOffer?: (offer: RTCSessionDescriptionInit) => void;
|
37
38
|
|
38
|
-
constructor(config?: RTCConfiguration) {
|
39
|
+
constructor(config?: RTCConfiguration, mediaConstraints: Record<string, unknown> = {}) {
|
39
40
|
super();
|
40
|
-
this.pc =
|
41
|
+
this.pc = isChromiumBased()
|
42
|
+
? // @ts-expect-error chrome allows additional media constraints to be passed into the RTCPeerConnection constructor
|
43
|
+
new RTCPeerConnection(config, mediaConstraints)
|
44
|
+
: new RTCPeerConnection(config);
|
41
45
|
}
|
42
46
|
|
43
47
|
get isICEConnected(): boolean {
|
@@ -289,7 +293,7 @@ function ensureVideoDDExtensionForSVC(
|
|
289
293
|
payloads?: string | undefined;
|
290
294
|
} & MediaDescription,
|
291
295
|
) {
|
292
|
-
const codec = media.rtp
|
296
|
+
const codec = media.rtp[0]?.codec?.toLowerCase();
|
293
297
|
if (!isSVCCodec(codec)) {
|
294
298
|
return;
|
295
299
|
}
|
package/src/room/RTCEngine.ts
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
import { EventEmitter } from 'events';
|
2
2
|
import type TypedEventEmitter from 'typed-emitter';
|
3
|
-
import { SignalClient
|
3
|
+
import { SignalClient } from '../api/SignalClient';
|
4
|
+
import type { SignalOptions } from '../api/SignalClient';
|
4
5
|
import log from '../logger';
|
5
6
|
import type { InternalRoomOptions } from '../options';
|
6
7
|
import {
|
@@ -77,6 +78,11 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit
|
|
77
78
|
|
78
79
|
fullReconnectOnNext: boolean = false;
|
79
80
|
|
81
|
+
/**
|
82
|
+
* @internal
|
83
|
+
*/
|
84
|
+
latestJoinResponse?: JoinResponse;
|
85
|
+
|
80
86
|
get isClosed() {
|
81
87
|
return this._isClosed;
|
82
88
|
}
|
@@ -171,6 +177,7 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit
|
|
171
177
|
this.joinAttempts += 1;
|
172
178
|
const joinResponse = await this.client.join(url, token, opts, abortSignal);
|
173
179
|
this._isClosed = false;
|
180
|
+
this.latestJoinResponse = joinResponse;
|
174
181
|
|
175
182
|
this.subscriberPrimary = joinResponse.subscriberPrimary;
|
176
183
|
if (!this.publisher) {
|
@@ -307,8 +314,8 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit
|
|
307
314
|
this.participantSid = joinResponse.participant?.sid;
|
308
315
|
|
309
316
|
const rtcConfig = this.makeRTCConfiguration(joinResponse);
|
310
|
-
|
311
|
-
this.publisher = new PCTransport(rtcConfig);
|
317
|
+
const googConstraints = { optional: [{ googDscp: true }] };
|
318
|
+
this.publisher = new PCTransport(rtcConfig, googConstraints);
|
312
319
|
this.subscriber = new PCTransport(rtcConfig);
|
313
320
|
|
314
321
|
this.emit(EngineEvent.TransportsCreated, this.publisher, this.subscriber);
|
package/src/room/defaults.ts
CHANGED
@@ -1,16 +1,18 @@
|
|
1
1
|
import type { InternalRoomConnectOptions, InternalRoomOptions } from '../options';
|
2
2
|
import DefaultReconnectPolicy from './DefaultReconnectPolicy';
|
3
|
-
import {
|
3
|
+
import { AudioPresets, ScreenSharePresets, VideoPresets } from './track/options';
|
4
|
+
import type {
|
4
5
|
AudioCaptureOptions,
|
5
|
-
AudioPresets,
|
6
|
-
ScreenSharePresets,
|
7
6
|
TrackPublishDefaults,
|
8
7
|
VideoCaptureOptions,
|
9
|
-
VideoPresets,
|
10
8
|
} from './track/options';
|
11
9
|
|
12
10
|
export const publishDefaults: TrackPublishDefaults = {
|
11
|
+
/**
|
12
|
+
* @deprecated
|
13
|
+
*/
|
13
14
|
audioBitrate: AudioPresets.music.maxBitrate,
|
15
|
+
audioPreset: AudioPresets.music,
|
14
16
|
dtx: true,
|
15
17
|
red: true,
|
16
18
|
forceStereo: false,
|
@@ -18,22 +18,21 @@ import LocalTrack from '../track/LocalTrack';
|
|
18
18
|
import LocalTrackPublication from '../track/LocalTrackPublication';
|
19
19
|
import LocalVideoTrack, { videoLayersFromEncodings } from '../track/LocalVideoTrack';
|
20
20
|
import { Track } from '../track/Track';
|
21
|
-
import {
|
21
|
+
import { ScreenSharePresets, isBackupCodec, isCodecEqual } from '../track/options';
|
22
|
+
import type {
|
22
23
|
AudioCaptureOptions,
|
23
24
|
BackupVideoCodec,
|
24
25
|
CreateLocalTracksOptions,
|
25
26
|
ScreenShareCaptureOptions,
|
26
|
-
ScreenSharePresets,
|
27
27
|
TrackPublishOptions,
|
28
28
|
VideoCaptureOptions,
|
29
|
-
isBackupCodec,
|
30
|
-
isCodecEqual,
|
31
29
|
} from '../track/options';
|
32
30
|
import { constraintsForOptions, mergeDefaultOptions } from '../track/utils';
|
33
31
|
import type { DataPublishOptions } from '../types';
|
34
32
|
import { Future, isFireFox, isSVCCodec, isSafari, isWeb, supportsAV1, supportsVP9 } from '../utils';
|
35
33
|
import Participant from './Participant';
|
36
|
-
import {
|
34
|
+
import { trackPermissionToProto } from './ParticipantTrackPermission';
|
35
|
+
import type { ParticipantTrackPermission } from './ParticipantTrackPermission';
|
37
36
|
import RemoteParticipant from './RemoteParticipant';
|
38
37
|
import {
|
39
38
|
computeTrackBackupEncodings,
|
@@ -151,7 +150,7 @@ export default class LocalParticipant extends Participant {
|
|
151
150
|
|
152
151
|
/**
|
153
152
|
* Sets and updates the metadata of the local participant.
|
154
|
-
* Note: this requires `
|
153
|
+
* Note: this requires `canUpdateOwnMetadata` permission encoded in the token.
|
155
154
|
* @param metadata
|
156
155
|
*/
|
157
156
|
setMetadata(metadata: string): void {
|
@@ -161,7 +160,7 @@ export default class LocalParticipant extends Participant {
|
|
161
160
|
|
162
161
|
/**
|
163
162
|
* Sets and updates the name of the local participant.
|
164
|
-
* Note: this requires `
|
163
|
+
* Note: this requires `canUpdateOwnMetadata` permission encoded in the token.
|
165
164
|
* @param metadata
|
166
165
|
*/
|
167
166
|
setName(name: string): void {
|
@@ -651,10 +650,12 @@ export default class LocalParticipant extends Participant {
|
|
651
650
|
opts,
|
652
651
|
);
|
653
652
|
req.layers = videoLayersFromEncodings(req.width, req.height, simEncodings ?? encodings);
|
654
|
-
} else if (track.kind === Track.Kind.Audio
|
653
|
+
} else if (track.kind === Track.Kind.Audio) {
|
655
654
|
encodings = [
|
656
655
|
{
|
657
|
-
maxBitrate: opts.audioBitrate,
|
656
|
+
maxBitrate: opts.audioPreset?.maxBitrate ?? opts.audioBitrate,
|
657
|
+
priority: opts.audioPreset?.priority ?? 'high',
|
658
|
+
networkPriority: opts.audioPreset?.priority ?? 'high',
|
658
659
|
},
|
659
660
|
];
|
660
661
|
}
|
@@ -11,7 +11,8 @@ import { Track } from '../track/Track';
|
|
11
11
|
import type { TrackPublication } from '../track/TrackPublication';
|
12
12
|
import type { AudioOutputOptions } from '../track/options';
|
13
13
|
import type { AdaptiveStreamSettings } from '../track/types';
|
14
|
-
import Participant
|
14
|
+
import Participant from './Participant';
|
15
|
+
import type { ParticipantEventCallbacks } from './Participant';
|
15
16
|
|
16
17
|
export default class RemoteParticipant extends Participant {
|
17
18
|
audioTracks: Map<string, RemoteTrackPublication>;
|
@@ -3,15 +3,12 @@ import { TrackInvalidError } from '../errors';
|
|
3
3
|
import LocalAudioTrack from '../track/LocalAudioTrack';
|
4
4
|
import LocalVideoTrack from '../track/LocalVideoTrack';
|
5
5
|
import { Track } from '../track/Track';
|
6
|
-
import {
|
6
|
+
import { ScreenSharePresets, VideoPreset, VideoPresets, VideoPresets43 } from '../track/options';
|
7
|
+
import type {
|
7
8
|
BackupVideoCodec,
|
8
|
-
ScreenSharePresets,
|
9
9
|
TrackPublishOptions,
|
10
10
|
VideoCodec,
|
11
11
|
VideoEncoding,
|
12
|
-
VideoPreset,
|
13
|
-
VideoPresets,
|
14
|
-
VideoPresets43,
|
15
12
|
} from '../track/options';
|
16
13
|
import { isSVCCodec } from '../utils';
|
17
14
|
|
@@ -61,6 +58,7 @@ export const computeDefaultScreenShareSimulcastPresets = (fromPreset: VideoPrese
|
|
61
58
|
),
|
62
59
|
),
|
63
60
|
t.fps,
|
61
|
+
fromPreset.encoding.priority,
|
64
62
|
),
|
65
63
|
);
|
66
64
|
};
|
@@ -317,6 +315,10 @@ function encodingsFromPresets(
|
|
317
315
|
if (preset.encoding.maxFramerate) {
|
318
316
|
encoding.maxFramerate = preset.encoding.maxFramerate;
|
319
317
|
}
|
318
|
+
if (preset.encoding.priority) {
|
319
|
+
encoding.priority = preset.encoding.priority;
|
320
|
+
encoding.networkPriority = preset.encoding.priority;
|
321
|
+
}
|
320
322
|
encodings.push(encoding);
|
321
323
|
});
|
322
324
|
return encodings;
|
@@ -1,6 +1,7 @@
|
|
1
1
|
import log from '../../logger';
|
2
2
|
import { TrackEvent } from '../events';
|
3
|
-
import {
|
3
|
+
import { computeBitrate, monitorFrequency } from '../stats';
|
4
|
+
import type { AudioSenderStats } from '../stats';
|
4
5
|
import { isWeb } from '../utils';
|
5
6
|
import LocalTrack from './LocalTrack';
|
6
7
|
import { Track } from './Track';
|
@@ -2,7 +2,8 @@ import type { SignalClient } from '../../api/SignalClient';
|
|
2
2
|
import log from '../../logger';
|
3
3
|
import { VideoLayer, VideoQuality } from '../../proto/livekit_models';
|
4
4
|
import type { SubscribedCodec, SubscribedQuality } from '../../proto/livekit_rtc';
|
5
|
-
import {
|
5
|
+
import { computeBitrate, monitorFrequency } from '../stats';
|
6
|
+
import type { VideoSenderStats } from '../stats';
|
6
7
|
import { Mutex, isFireFox, isMobile, isWeb } from '../utils';
|
7
8
|
import LocalTrack from './LocalTrack';
|
8
9
|
import { Track } from './Track';
|
@@ -153,7 +154,7 @@ export default class LocalVideoTrack extends LocalTrack {
|
|
153
154
|
qualityLimitationResolutionChanges: v.qualityLimitationResolutionChanges,
|
154
155
|
};
|
155
156
|
|
156
|
-
//
|
157
|
+
// locate the appropriate remote-inbound-rtp item
|
157
158
|
const r = stats.get(v.remoteId);
|
158
159
|
if (r) {
|
159
160
|
vs.jitter = r.jitter;
|
@@ -1,6 +1,7 @@
|
|
1
1
|
import log from '../../logger';
|
2
2
|
import { TrackEvent } from '../events';
|
3
|
-
import {
|
3
|
+
import { computeBitrate } from '../stats';
|
4
|
+
import type { AudioReceiverStats } from '../stats';
|
4
5
|
import { supportsSetSinkId } from '../utils';
|
5
6
|
import RemoteTrack from './RemoteTrack';
|
6
7
|
import { Track } from './Track';
|
@@ -1,15 +1,11 @@
|
|
1
1
|
import { debounce } from 'ts-debounce';
|
2
2
|
import log from '../../logger';
|
3
3
|
import { TrackEvent } from '../events';
|
4
|
-
import {
|
4
|
+
import { computeBitrate } from '../stats';
|
5
|
+
import type { VideoReceiverStats } from '../stats';
|
5
6
|
import CriticalTimers from '../timers';
|
6
|
-
import {
|
7
|
-
|
8
|
-
getDevicePixelRatio,
|
9
|
-
getIntersectionObserver,
|
10
|
-
getResizeObserver,
|
11
|
-
isWeb,
|
12
|
-
} from '../utils';
|
7
|
+
import { getDevicePixelRatio, getIntersectionObserver, getResizeObserver, isWeb } from '../utils';
|
8
|
+
import type { ObservableMediaElement } from '../utils';
|
13
9
|
import RemoteTrack from './RemoteTrack';
|
14
10
|
import { Track, attachToElement, detachTrack } from './Track';
|
15
11
|
import type { AdaptiveStreamSettings } from './types';
|
package/src/room/track/create.ts
CHANGED
@@ -6,12 +6,12 @@ import LocalAudioTrack from './LocalAudioTrack';
|
|
6
6
|
import type LocalTrack from './LocalTrack';
|
7
7
|
import LocalVideoTrack from './LocalVideoTrack';
|
8
8
|
import { Track } from './Track';
|
9
|
-
import {
|
9
|
+
import { VideoPresets } from './options';
|
10
|
+
import type {
|
10
11
|
AudioCaptureOptions,
|
11
12
|
CreateLocalTracksOptions,
|
12
13
|
ScreenShareCaptureOptions,
|
13
14
|
VideoCaptureOptions,
|
14
|
-
VideoPresets,
|
15
15
|
} from './options';
|
16
16
|
import { constraintsForOptions, mergeDefaultOptions } from './utils';
|
17
17
|
|
@@ -23,10 +23,17 @@ export interface TrackPublishDefaults {
|
|
23
23
|
videoCodec?: VideoCodec;
|
24
24
|
|
25
25
|
/**
|
26
|
-
* max audio bitrate, defaults to [[AudioPresets.
|
26
|
+
* max audio bitrate, defaults to [[AudioPresets.music]]
|
27
|
+
* @deprecated use `audioPreset` instead
|
27
28
|
*/
|
28
29
|
audioBitrate?: number;
|
29
30
|
|
31
|
+
/**
|
32
|
+
* which audio preset should be used for publishing (audio) tracks
|
33
|
+
* defaults to [[AudioPresets.music]]
|
34
|
+
*/
|
35
|
+
audioPreset?: AudioPreset;
|
36
|
+
|
30
37
|
/**
|
31
38
|
* dtx (Discontinuous Transmission of audio), enabled by default for mono tracks.
|
32
39
|
*/
|
@@ -215,6 +222,7 @@ export interface VideoResolution {
|
|
215
222
|
export interface VideoEncoding {
|
216
223
|
maxBitrate: number;
|
217
224
|
maxFramerate?: number;
|
225
|
+
priority?: RTCPriorityType;
|
218
226
|
}
|
219
227
|
|
220
228
|
export class VideoPreset {
|
@@ -224,12 +232,19 @@ export class VideoPreset {
|
|
224
232
|
|
225
233
|
height: number;
|
226
234
|
|
227
|
-
constructor(
|
235
|
+
constructor(
|
236
|
+
width: number,
|
237
|
+
height: number,
|
238
|
+
maxBitrate: number,
|
239
|
+
maxFramerate?: number,
|
240
|
+
priority?: RTCPriorityType,
|
241
|
+
) {
|
228
242
|
this.width = width;
|
229
243
|
this.height = height;
|
230
244
|
this.encoding = {
|
231
245
|
maxBitrate,
|
232
246
|
maxFramerate,
|
247
|
+
priority,
|
233
248
|
};
|
234
249
|
}
|
235
250
|
|
@@ -245,6 +260,7 @@ export class VideoPreset {
|
|
245
260
|
|
246
261
|
export interface AudioPreset {
|
247
262
|
maxBitrate: number;
|
263
|
+
priority?: RTCPriorityType;
|
248
264
|
}
|
249
265
|
|
250
266
|
const codecs = ['vp8', 'h264', 'vp9', 'av1'] as const;
|
@@ -322,9 +338,9 @@ export const VideoPresets43 = {
|
|
322
338
|
} as const;
|
323
339
|
|
324
340
|
export const ScreenSharePresets = {
|
325
|
-
h360fps3: new VideoPreset(640, 360, 200_000, 3),
|
326
|
-
h720fps5: new VideoPreset(1280, 720, 400_000, 5),
|
327
|
-
h720fps15: new VideoPreset(1280, 720, 1_000_000, 15),
|
328
|
-
h1080fps15: new VideoPreset(1920, 1080, 1_500_000, 15),
|
329
|
-
h1080fps30: new VideoPreset(1920, 1080, 3_000_000, 30),
|
341
|
+
h360fps3: new VideoPreset(640, 360, 200_000, 3, 'medium'),
|
342
|
+
h720fps5: new VideoPreset(1280, 720, 400_000, 5, 'medium'),
|
343
|
+
h720fps15: new VideoPreset(1280, 720, 1_000_000, 15, 'medium'),
|
344
|
+
h1080fps15: new VideoPreset(1920, 1080, 1_500_000, 15, 'medium'),
|
345
|
+
h1080fps30: new VideoPreset(1920, 1080, 3_000_000, 30, 'medium'),
|
330
346
|
} as const;
|
package/src/room/utils.ts
CHANGED
@@ -41,7 +41,10 @@ export function supportsDynacast() {
|
|
41
41
|
}
|
42
42
|
|
43
43
|
export function supportsAV1(): boolean {
|
44
|
-
|
44
|
+
if (!('getCapabilities' in RTCRtpSender)) {
|
45
|
+
return false;
|
46
|
+
}
|
47
|
+
const capabilities = RTCRtpSender.getCapabilities('video');
|
45
48
|
let hasAV1 = false;
|
46
49
|
if (capabilities) {
|
47
50
|
for (const codec of capabilities.codecs) {
|
@@ -55,7 +58,12 @@ export function supportsAV1(): boolean {
|
|
55
58
|
}
|
56
59
|
|
57
60
|
export function supportsVP9(): boolean {
|
58
|
-
|
61
|
+
if (!('getCapabilities' in RTCRtpSender)) {
|
62
|
+
// technically speaking FireFox supports VP9, but SVC publishing is broken
|
63
|
+
// https://bugzilla.mozilla.org/show_bug.cgi?id=1633876
|
64
|
+
return false;
|
65
|
+
}
|
66
|
+
const capabilities = RTCRtpSender.getCapabilities('video');
|
59
67
|
let hasVP9 = false;
|
60
68
|
if (capabilities) {
|
61
69
|
for (const codec of capabilities.codecs) {
|
@@ -119,6 +127,11 @@ export function isFireFox(): boolean {
|
|
119
127
|
return navigator.userAgent.indexOf('Firefox') !== -1;
|
120
128
|
}
|
121
129
|
|
130
|
+
export function isChromiumBased(): boolean {
|
131
|
+
if (!isWeb()) return false;
|
132
|
+
return navigator.userAgent.indexOf('Chrom') !== -1;
|
133
|
+
}
|
134
|
+
|
122
135
|
export function isSafari(): boolean {
|
123
136
|
if (!isWeb()) return false;
|
124
137
|
return /^((?!chrome|android).)*safari/i.test(navigator.userAgent);
|