livekit-client 1.15.6 → 1.15.8
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 +14 -1
- package/dist/livekit-client.e2ee.worker.mjs.map +1 -1
- package/dist/livekit-client.esm.mjs +556 -348
- 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 +5 -1
- package/dist/src/api/SignalClient.d.ts.map +1 -1
- package/dist/src/index.d.ts +2 -2
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/logger.d.ts +19 -3
- package/dist/src/logger.d.ts.map +1 -1
- package/dist/src/options.d.ts +1 -0
- package/dist/src/options.d.ts.map +1 -1
- package/dist/src/room/PCTransport.d.ts +5 -1
- package/dist/src/room/PCTransport.d.ts.map +1 -1
- package/dist/src/room/PCTransportManager.d.ts +5 -1
- package/dist/src/room/PCTransportManager.d.ts.map +1 -1
- package/dist/src/room/RTCEngine.d.ts +8 -0
- package/dist/src/room/RTCEngine.d.ts.map +1 -1
- package/dist/src/room/Room.d.ts +2 -0
- 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/participant/Participant.d.ts +9 -1
- package/dist/src/room/participant/Participant.d.ts.map +1 -1
- package/dist/src/room/participant/RemoteParticipant.d.ts +2 -1
- package/dist/src/room/participant/RemoteParticipant.d.ts.map +1 -1
- package/dist/src/room/participant/publishUtils.d.ts +2 -1
- package/dist/src/room/participant/publishUtils.d.ts.map +1 -1
- package/dist/src/room/timers.d.ts +5 -4
- package/dist/src/room/timers.d.ts.map +1 -1
- package/dist/src/room/track/LocalAudioTrack.d.ts +2 -1
- package/dist/src/room/track/LocalAudioTrack.d.ts.map +1 -1
- package/dist/src/room/track/LocalTrack.d.ts +2 -1
- package/dist/src/room/track/LocalTrack.d.ts.map +1 -1
- package/dist/src/room/track/LocalTrackPublication.d.ts +2 -1
- package/dist/src/room/track/LocalTrackPublication.d.ts.map +1 -1
- package/dist/src/room/track/LocalVideoTrack.d.ts +2 -1
- 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 -1
- package/dist/src/room/track/RemoteTrack.d.ts.map +1 -1
- package/dist/src/room/track/RemoteTrackPublication.d.ts +2 -1
- package/dist/src/room/track/RemoteTrackPublication.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 +10 -1
- package/dist/src/room/track/Track.d.ts.map +1 -1
- package/dist/src/room/track/TrackPublication.d.ts +7 -1
- package/dist/src/room/track/TrackPublication.d.ts.map +1 -1
- package/dist/src/room/track/create.d.ts.map +1 -1
- package/dist/src/room/track/options.d.ts +8 -3
- package/dist/src/room/track/options.d.ts.map +1 -1
- package/dist/src/room/track/utils.d.ts +1 -0
- package/dist/src/room/track/utils.d.ts.map +1 -1
- package/dist/src/room/types.d.ts +4 -0
- package/dist/src/room/types.d.ts.map +1 -1
- package/dist/src/room/utils.d.ts +1 -0
- package/dist/src/room/utils.d.ts.map +1 -1
- package/dist/ts4.2/src/api/SignalClient.d.ts +5 -1
- package/dist/ts4.2/src/index.d.ts +2 -2
- package/dist/ts4.2/src/logger.d.ts +19 -3
- package/dist/ts4.2/src/options.d.ts +1 -0
- package/dist/ts4.2/src/room/PCTransport.d.ts +5 -1
- package/dist/ts4.2/src/room/PCTransportManager.d.ts +5 -1
- package/dist/ts4.2/src/room/RTCEngine.d.ts +8 -0
- package/dist/ts4.2/src/room/Room.d.ts +2 -0
- package/dist/ts4.2/src/room/participant/Participant.d.ts +9 -1
- 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/timers.d.ts +5 -4
- package/dist/ts4.2/src/room/track/LocalAudioTrack.d.ts +2 -1
- package/dist/ts4.2/src/room/track/LocalTrack.d.ts +2 -1
- package/dist/ts4.2/src/room/track/LocalTrackPublication.d.ts +2 -1
- package/dist/ts4.2/src/room/track/LocalVideoTrack.d.ts +2 -1
- package/dist/ts4.2/src/room/track/RemoteAudioTrack.d.ts +2 -1
- package/dist/ts4.2/src/room/track/RemoteTrack.d.ts +2 -1
- package/dist/ts4.2/src/room/track/RemoteTrackPublication.d.ts +2 -1
- package/dist/ts4.2/src/room/track/RemoteVideoTrack.d.ts +2 -1
- package/dist/ts4.2/src/room/track/Track.d.ts +10 -1
- package/dist/ts4.2/src/room/track/TrackPublication.d.ts +7 -1
- package/dist/ts4.2/src/room/track/options.d.ts +8 -3
- package/dist/ts4.2/src/room/track/utils.d.ts +1 -0
- package/dist/ts4.2/src/room/types.d.ts +4 -0
- package/dist/ts4.2/src/room/utils.d.ts +1 -0
- package/package.json +2 -2
- package/src/api/SignalClient.ts +43 -21
- package/src/index.ts +2 -1
- package/src/logger.ts +32 -8
- package/src/options.ts +2 -0
- package/src/room/PCTransport.ts +29 -8
- package/src/room/PCTransportManager.ts +29 -9
- package/src/room/RTCEngine.ts +71 -34
- package/src/room/Room.ts +91 -60
- package/src/room/participant/LocalParticipant.ts +165 -47
- package/src/room/participant/Participant.ts +26 -3
- package/src/room/participant/RemoteParticipant.ts +23 -15
- package/src/room/participant/publishUtils.test.ts +2 -2
- package/src/room/participant/publishUtils.ts +7 -4
- package/src/room/track/LocalAudioTrack.ts +8 -7
- package/src/room/track/LocalTrack.ts +23 -19
- package/src/room/track/LocalTrackPublication.ts +3 -2
- package/src/room/track/LocalVideoTrack.ts +31 -13
- package/src/room/track/RemoteAudioTrack.ts +4 -3
- package/src/room/track/RemoteTrack.ts +4 -1
- package/src/room/track/RemoteTrackPublication.ts +21 -13
- package/src/room/track/RemoteVideoTrack.ts +5 -4
- package/src/room/track/Track.ts +32 -2
- package/src/room/track/TrackPublication.ts +18 -3
- package/src/room/track/create.ts +4 -3
- package/src/room/track/options.ts +12 -5
- package/src/room/track/utils.ts +23 -1
- package/src/room/types.ts +5 -0
- package/src/room/utils.ts +5 -0
@@ -2,6 +2,7 @@ import type { SignalClient } from '../../api/SignalClient';
|
|
2
2
|
import { VideoLayer, VideoQuality } from '../../proto/livekit_models_pb';
|
3
3
|
import { SubscribedCodec, SubscribedQuality } from '../../proto/livekit_rtc_pb';
|
4
4
|
import type { VideoSenderStats } from '../stats';
|
5
|
+
import type { LoggerOptions } from '../types';
|
5
6
|
import LocalTrack from './LocalTrack';
|
6
7
|
import { Track } from './Track';
|
7
8
|
import type { VideoCaptureOptions, VideoCodec } from './options';
|
@@ -26,7 +27,7 @@ export default class LocalVideoTrack extends LocalTrack {
|
|
26
27
|
* @param constraints MediaTrackConstraints that are being used when restarting or reacquiring tracks
|
27
28
|
* @param userProvidedTrack Signals to the SDK whether or not the mediaTrack should be managed (i.e. released and reacquired) internally by the SDK
|
28
29
|
*/
|
29
|
-
constructor(mediaTrack: MediaStreamTrack, constraints?: MediaTrackConstraints, userProvidedTrack?: boolean);
|
30
|
+
constructor(mediaTrack: MediaStreamTrack, constraints?: MediaTrackConstraints, userProvidedTrack?: boolean, loggerOptions?: LoggerOptions);
|
30
31
|
get isSimulcast(): boolean;
|
31
32
|
startMonitor(signalClient: SignalClient): void;
|
32
33
|
stop(): void;
|
@@ -1,4 +1,5 @@
|
|
1
1
|
import type { AudioReceiverStats } from '../stats';
|
2
|
+
import type { LoggerOptions } from '../types';
|
2
3
|
import RemoteTrack from './RemoteTrack';
|
3
4
|
import type { AudioOutputOptions } from './options';
|
4
5
|
export default class RemoteAudioTrack extends RemoteTrack {
|
@@ -9,7 +10,7 @@ export default class RemoteAudioTrack extends RemoteTrack {
|
|
9
10
|
private sourceNode?;
|
10
11
|
private webAudioPluginNodes;
|
11
12
|
private sinkId?;
|
12
|
-
constructor(mediaTrack: MediaStreamTrack, sid: string, receiver?: RTCRtpReceiver, audioContext?: AudioContext, audioOutput?: AudioOutputOptions);
|
13
|
+
constructor(mediaTrack: MediaStreamTrack, sid: string, receiver?: RTCRtpReceiver, audioContext?: AudioContext, audioOutput?: AudioOutputOptions, loggerOptions?: LoggerOptions);
|
13
14
|
/**
|
14
15
|
* sets the volume for all attached audio elements
|
15
16
|
*/
|
@@ -1,8 +1,9 @@
|
|
1
|
+
import type { LoggerOptions } from '../types';
|
1
2
|
import { Track } from './Track';
|
2
3
|
export default abstract class RemoteTrack extends Track {
|
3
4
|
/** @internal */
|
4
5
|
receiver?: RTCRtpReceiver;
|
5
|
-
constructor(mediaTrack: MediaStreamTrack, sid: string, kind: Track.Kind, receiver?: RTCRtpReceiver);
|
6
|
+
constructor(mediaTrack: MediaStreamTrack, sid: string, kind: Track.Kind, receiver?: RTCRtpReceiver, loggerOptions?: LoggerOptions);
|
6
7
|
/** @internal */
|
7
8
|
setMuted(muted: boolean): void;
|
8
9
|
/** @internal */
|
@@ -1,4 +1,5 @@
|
|
1
1
|
import { SubscriptionError, TrackInfo, VideoQuality } from '../../proto/livekit_models_pb';
|
2
|
+
import type { LoggerOptions } from '../types';
|
2
3
|
import type RemoteTrack from './RemoteTrack';
|
3
4
|
import { Track } from './Track';
|
4
5
|
import { TrackPublication } from './TrackPublication';
|
@@ -12,7 +13,7 @@ export default class RemoteTrackPublication extends TrackPublication {
|
|
12
13
|
protected videoDimensions?: Track.Dimensions;
|
13
14
|
protected fps?: number;
|
14
15
|
protected subscriptionError?: SubscriptionError;
|
15
|
-
constructor(kind: Track.Kind, ti: TrackInfo, autoSubscribe: boolean | undefined);
|
16
|
+
constructor(kind: Track.Kind, ti: TrackInfo, autoSubscribe: boolean | undefined, loggerOptions?: LoggerOptions);
|
16
17
|
/**
|
17
18
|
* Subscribe or unsubscribe to this remote track
|
18
19
|
* @param subscribed true to subscribe to a track, false to unsubscribe
|
@@ -1,3 +1,4 @@
|
|
1
|
+
import type { LoggerOptions } from '../types';
|
1
2
|
import RemoteTrack from './RemoteTrack';
|
2
3
|
import type { AdaptiveStreamSettings } from './types';
|
3
4
|
export default class RemoteVideoTrack extends RemoteTrack {
|
@@ -6,7 +7,7 @@ export default class RemoteVideoTrack extends RemoteTrack {
|
|
6
7
|
private adaptiveStreamSettings?;
|
7
8
|
private lastVisible?;
|
8
9
|
private lastDimensions?;
|
9
|
-
constructor(mediaTrack: MediaStreamTrack, sid: string, receiver?: RTCRtpReceiver, adaptiveStreamSettings?: AdaptiveStreamSettings);
|
10
|
+
constructor(mediaTrack: MediaStreamTrack, sid: string, receiver?: RTCRtpReceiver, adaptiveStreamSettings?: AdaptiveStreamSettings, loggerOptions?: LoggerOptions);
|
10
11
|
get isAdaptiveStream(): boolean;
|
11
12
|
/**
|
12
13
|
* Note: When using adaptiveStream, you need to use remoteVideoTrack.attach() to add the track to a HTMLVideoElement, otherwise your video tracks might never start
|
@@ -1,7 +1,9 @@
|
|
1
1
|
import type TypedEventEmitter from 'typed-emitter';
|
2
2
|
import type { SignalClient } from '../../api/SignalClient';
|
3
|
+
import { StructuredLogger } from '../../logger';
|
3
4
|
import { TrackSource, TrackType } from '../../proto/livekit_models_pb';
|
4
5
|
import { StreamState as ProtoStreamState } from '../../proto/livekit_rtc_pb';
|
6
|
+
import type { LoggerOptions } from '../types';
|
5
7
|
declare const Track_base: new () => TypedEventEmitter<TrackEventCallbacks>;
|
6
8
|
export declare abstract class Track extends Track_base {
|
7
9
|
kind: Track.Kind;
|
@@ -25,9 +27,14 @@ export declare abstract class Track extends Track_base {
|
|
25
27
|
protected _mediaStreamID: string;
|
26
28
|
protected isInBackground: boolean;
|
27
29
|
private backgroundTimeout;
|
30
|
+
private loggerContextCb;
|
28
31
|
protected _currentBitrate: number;
|
29
32
|
protected monitorInterval?: ReturnType<typeof setInterval>;
|
30
|
-
protected
|
33
|
+
protected log: StructuredLogger;
|
34
|
+
protected constructor(mediaTrack: MediaStreamTrack, kind: Track.Kind, loggerOptions?: LoggerOptions);
|
35
|
+
protected get logContext(): {
|
36
|
+
[x: string]: unknown;
|
37
|
+
};
|
31
38
|
/** current receive bits per second */
|
32
39
|
get currentBitrate(): number;
|
33
40
|
get mediaStreamTrack(): MediaStreamTrack;
|
@@ -59,6 +66,8 @@ export declare abstract class Track extends Track_base {
|
|
59
66
|
protected disable(): void;
|
60
67
|
abstract startMonitor(signalClient?: SignalClient): void;
|
61
68
|
stopMonitor(): void;
|
69
|
+
/** @internal */
|
70
|
+
updateLoggerOptions(loggerOptions: LoggerOptions): void;
|
62
71
|
private recycleElement;
|
63
72
|
protected appVisibilityChangedListener: () => void;
|
64
73
|
protected handleAppVisibilityChanged(): Promise<void>;
|
@@ -2,6 +2,7 @@ import type TypedEventEmitter from 'typed-emitter';
|
|
2
2
|
import { Encryption_Type } from '../../proto/livekit_models_pb';
|
3
3
|
import type { SubscriptionError, TrackInfo } from '../../proto/livekit_models_pb';
|
4
4
|
import type { UpdateSubscription, UpdateTrackSettings } from '../../proto/livekit_rtc_pb';
|
5
|
+
import type { LoggerOptions } from '../types';
|
5
6
|
import LocalAudioTrack from './LocalAudioTrack';
|
6
7
|
import LocalVideoTrack from './LocalVideoTrack';
|
7
8
|
import RemoteAudioTrack from './RemoteAudioTrack';
|
@@ -25,9 +26,14 @@ export declare class TrackPublication extends TrackPublication_base {
|
|
25
26
|
trackInfo?: TrackInfo;
|
26
27
|
protected metadataMuted: boolean;
|
27
28
|
protected encryption: Encryption_Type;
|
28
|
-
|
29
|
+
protected log: import("../../logger").StructuredLogger;
|
30
|
+
private loggerContextCb?;
|
31
|
+
constructor(kind: Track.Kind, id: string, name: string, loggerOptions?: LoggerOptions);
|
29
32
|
/** @internal */
|
30
33
|
setTrack(track?: Track): void;
|
34
|
+
protected get logContext(): {
|
35
|
+
[x: string]: unknown;
|
36
|
+
};
|
31
37
|
get isMuted(): boolean;
|
32
38
|
get isEnabled(): boolean;
|
33
39
|
get isSubscribed(): boolean;
|
@@ -149,9 +149,10 @@ export interface ScreenShareCaptureOptions {
|
|
149
149
|
displaySurface?: 'window' | 'browser' | 'monitor';
|
150
150
|
};
|
151
151
|
/**
|
152
|
-
* capture resolution, defaults to
|
153
|
-
*
|
154
|
-
* capture.
|
152
|
+
* capture resolution, defaults to 1080 for all browsers other than Safari
|
153
|
+
* On Safari 17, default resolution is not capped, due to a bug, specifying
|
154
|
+
* any resolution at all would lead to a low-resolution capture.
|
155
|
+
* https://bugs.webkit.org/show_bug.cgi?id=263015
|
155
156
|
*/
|
156
157
|
resolution?: VideoResolution;
|
157
158
|
/** a CaptureController object instance containing methods that can be used to further manipulate the capture session if included. */
|
@@ -162,6 +163,8 @@ export interface ScreenShareCaptureOptions {
|
|
162
163
|
surfaceSwitching?: 'include' | 'exclude';
|
163
164
|
/** specifies whether the browser should include the system audio among the possible audio sources offered to the user */
|
164
165
|
systemAudio?: 'include' | 'exclude';
|
166
|
+
/** specify the type of content, see: https://www.w3.org/TR/mst-content-hint/#video-content-hints */
|
167
|
+
contentHint?: 'detail' | 'text' | 'motion';
|
165
168
|
/**
|
166
169
|
* Experimental option to control whether the audio playing in a tab will continue to be played out of a user's
|
167
170
|
* local speakers when the tab is captured.
|
@@ -288,11 +291,13 @@ export declare const VideoPresets43: {
|
|
288
291
|
};
|
289
292
|
export declare const ScreenSharePresets: {
|
290
293
|
readonly h360fps3: VideoPreset;
|
294
|
+
readonly h360fps15: VideoPreset;
|
291
295
|
readonly h720fps5: VideoPreset;
|
292
296
|
readonly h720fps15: VideoPreset;
|
293
297
|
readonly h720fps30: VideoPreset;
|
294
298
|
readonly h1080fps15: VideoPreset;
|
295
299
|
readonly h1080fps30: VideoPreset;
|
300
|
+
readonly original: VideoPreset;
|
296
301
|
};
|
297
302
|
export {};
|
298
303
|
//# sourceMappingURL=options.d.ts.map
|
@@ -28,4 +28,5 @@ export declare function sourceToKind(source: Track.Source): MediaDeviceKind | un
|
|
28
28
|
export declare function screenCaptureToDisplayMediaStreamOptions(options: ScreenShareCaptureOptions): DisplayMediaStreamOptions;
|
29
29
|
export declare function mimeTypeToVideoCodecString(mimeType: string): "vp8" | "h264" | "vp9" | "av1";
|
30
30
|
export declare function getTrackPublicationInfo<T extends TrackPublication>(tracks: T[]): TrackPublishedResponse[];
|
31
|
+
export declare function getLogContextFromTrack(track: Track | TrackPublication): Record<string, unknown>;
|
31
32
|
//# sourceMappingURL=utils.d.ts.map
|
@@ -23,4 +23,8 @@ export type LiveKitReactNativeInfo = {
|
|
23
23
|
devicePixelRatio: number;
|
24
24
|
};
|
25
25
|
export type SimulationScenario = 'signal-reconnect' | 'speaker' | 'node-failure' | 'server-leave' | 'migration' | 'resume-reconnect' | 'force-tcp' | 'force-tls' | 'full-reconnect' | 'subscriber-bandwidth';
|
26
|
+
export type LoggerOptions = {
|
27
|
+
loggerName?: string;
|
28
|
+
loggerContextCb?: () => Record<string, unknown>;
|
29
|
+
};
|
26
30
|
//# sourceMappingURL=types.d.ts.map
|
@@ -20,6 +20,7 @@ export declare function isBrowserSupported(): boolean;
|
|
20
20
|
export declare function isFireFox(): boolean;
|
21
21
|
export declare function isChromiumBased(): boolean;
|
22
22
|
export declare function isSafari(): boolean;
|
23
|
+
export declare function isSafari17(): boolean;
|
23
24
|
export declare function isMobile(): boolean;
|
24
25
|
export declare function isWeb(): boolean;
|
25
26
|
export declare function isReactNative(): boolean;
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "livekit-client",
|
3
|
-
"version": "1.15.
|
3
|
+
"version": "1.15.8",
|
4
4
|
"description": "JavaScript/TypeScript client SDK for LiveKit",
|
5
5
|
"main": "./dist/livekit-client.umd.js",
|
6
6
|
"unpkg": "./dist/livekit-client.umd.js",
|
@@ -89,7 +89,7 @@
|
|
89
89
|
"build:watch": "rollup --watch --config rollup.config.js",
|
90
90
|
"build-docs": "typedoc",
|
91
91
|
"proto": "protoc --es_out src/proto --es_opt target=ts -I./protocol ./protocol/livekit_rtc.proto ./protocol/livekit_models.proto",
|
92
|
-
"sample": "vite example -c vite.config.
|
92
|
+
"sample": "vite example -c vite.config.mjs",
|
93
93
|
"lint": "eslint src",
|
94
94
|
"test": "vitest run src",
|
95
95
|
"deploy": "gh-pages -d example/dist",
|
package/src/api/SignalClient.ts
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
import { protoInt64 } from '@bufbuild/protobuf';
|
2
|
-
import log from '../logger';
|
2
|
+
import log, { LoggerNames, getLogger } from '../logger';
|
3
3
|
import {
|
4
4
|
ClientInfo,
|
5
5
|
DisconnectReason,
|
@@ -39,6 +39,7 @@ import {
|
|
39
39
|
} from '../proto/livekit_rtc_pb';
|
40
40
|
import { ConnectionError, ConnectionErrorReason } from '../room/errors';
|
41
41
|
import CriticalTimers from '../room/timers';
|
42
|
+
import type { LoggerOptions } from '../room/types';
|
42
43
|
import { Mutex, getClientInfo, isReactNative, sleep, toWebsocketUrl } from '../room/utils';
|
43
44
|
import { AsyncQueue } from '../utils/AsyncQueue';
|
44
45
|
|
@@ -172,7 +173,13 @@ export class SignalClient {
|
|
172
173
|
|
173
174
|
private connectionLock: Mutex;
|
174
175
|
|
175
|
-
|
176
|
+
private log = log;
|
177
|
+
|
178
|
+
private loggerContextCb?: LoggerOptions['loggerContextCb'];
|
179
|
+
|
180
|
+
constructor(useJSON: boolean = false, loggerOptions: LoggerOptions = {}) {
|
181
|
+
this.log = getLogger(loggerOptions.loggerName ?? LoggerNames.Signal);
|
182
|
+
this.loggerContextCb = loggerOptions.loggerContextCb;
|
176
183
|
this.useJSON = useJSON;
|
177
184
|
this.requestQueue = new AsyncQueue();
|
178
185
|
this.queuedRequests = [];
|
@@ -181,6 +188,10 @@ export class SignalClient {
|
|
181
188
|
this.state = SignalConnectionState.DISCONNECTED;
|
182
189
|
}
|
183
190
|
|
191
|
+
private get logContext() {
|
192
|
+
return this.loggerContextCb?.() ?? {};
|
193
|
+
}
|
194
|
+
|
184
195
|
async join(
|
185
196
|
url: string,
|
186
197
|
token: string,
|
@@ -202,7 +213,10 @@ export class SignalClient {
|
|
202
213
|
reason?: ReconnectReason,
|
203
214
|
): Promise<ReconnectResponse | void> {
|
204
215
|
if (!this.options) {
|
205
|
-
log.warn(
|
216
|
+
this.log.warn(
|
217
|
+
'attempted to reconnect without signal options being set, ignoring',
|
218
|
+
this.logContext,
|
219
|
+
);
|
206
220
|
return;
|
207
221
|
}
|
208
222
|
this.state = SignalConnectionState.RECONNECTING;
|
@@ -251,7 +265,7 @@ export class SignalClient {
|
|
251
265
|
abortHandler();
|
252
266
|
}
|
253
267
|
abortSignal?.addEventListener('abort', abortHandler);
|
254
|
-
log.debug(`connecting to ${url + params}
|
268
|
+
this.log.debug(`connecting to ${url + params}`, this.logContext);
|
255
269
|
if (this.ws) {
|
256
270
|
await this.close();
|
257
271
|
}
|
@@ -302,7 +316,10 @@ export class SignalClient {
|
|
302
316
|
} else if (ev.data instanceof ArrayBuffer) {
|
303
317
|
resp = SignalResponse.fromBinary(new Uint8Array(ev.data));
|
304
318
|
} else {
|
305
|
-
log.error(
|
319
|
+
this.log.error(
|
320
|
+
`could not decode websocket message: ${typeof ev.data}`,
|
321
|
+
this.logContext,
|
322
|
+
);
|
306
323
|
return;
|
307
324
|
}
|
308
325
|
|
@@ -316,7 +333,8 @@ export class SignalClient {
|
|
316
333
|
this.pingIntervalDuration = resp.message.value.pingInterval;
|
317
334
|
|
318
335
|
if (this.pingTimeoutDuration && this.pingTimeoutDuration > 0) {
|
319
|
-
log.debug('ping config', {
|
336
|
+
this.log.debug('ping config', {
|
337
|
+
...this.logContext,
|
320
338
|
timeout: this.pingTimeoutDuration,
|
321
339
|
interval: this.pingIntervalDuration,
|
322
340
|
});
|
@@ -354,7 +372,7 @@ export class SignalClient {
|
|
354
372
|
};
|
355
373
|
|
356
374
|
this.ws.onclose = (ev: CloseEvent) => {
|
357
|
-
log.warn(`websocket closed`, { ev });
|
375
|
+
this.log.warn(`websocket closed`, { ...this.logContext, reason: ev.reason });
|
358
376
|
this.handleOnClose(ev.reason);
|
359
377
|
};
|
360
378
|
} finally {
|
@@ -414,7 +432,7 @@ export class SignalClient {
|
|
414
432
|
|
415
433
|
// initial offer after joining
|
416
434
|
sendOffer(offer: RTCSessionDescriptionInit) {
|
417
|
-
log.debug('sending offer', offer);
|
435
|
+
this.log.debug('sending offer', { ...this.logContext, offerSdp: offer.sdp });
|
418
436
|
this.sendRequest({
|
419
437
|
case: 'offer',
|
420
438
|
value: toProtoSessionDescription(offer),
|
@@ -423,7 +441,7 @@ export class SignalClient {
|
|
423
441
|
|
424
442
|
// answer a server-initiated offer
|
425
443
|
sendAnswer(answer: RTCSessionDescriptionInit) {
|
426
|
-
log.debug('sending answer');
|
444
|
+
this.log.debug('sending answer', { ...this.logContext, answerSdp: answer.sdp });
|
427
445
|
return this.sendRequest({
|
428
446
|
case: 'answer',
|
429
447
|
value: toProtoSessionDescription(answer),
|
@@ -431,7 +449,7 @@ export class SignalClient {
|
|
431
449
|
}
|
432
450
|
|
433
451
|
sendIceCandidate(candidate: RTCIceCandidateInit, target: SignalTarget) {
|
434
|
-
log.trace('sending ice candidate', candidate);
|
452
|
+
this.log.trace('sending ice candidate', { ...this.logContext, candidate });
|
435
453
|
return this.sendRequest({
|
436
454
|
case: 'trickle',
|
437
455
|
value: new TrickleRequest({
|
@@ -561,7 +579,10 @@ export class SignalClient {
|
|
561
579
|
await sleep(this.signalLatency);
|
562
580
|
}
|
563
581
|
if (!this.ws || this.ws.readyState !== this.ws.OPEN) {
|
564
|
-
log.error(
|
582
|
+
this.log.error(
|
583
|
+
`cannot send signal request before connected, type: ${message?.case}`,
|
584
|
+
this.logContext,
|
585
|
+
);
|
565
586
|
return;
|
566
587
|
}
|
567
588
|
const req = new SignalRequest({ message });
|
@@ -573,14 +594,14 @@ export class SignalClient {
|
|
573
594
|
this.ws.send(req.toBinary());
|
574
595
|
}
|
575
596
|
} catch (e) {
|
576
|
-
log.error('error sending signal message', { error: e });
|
597
|
+
this.log.error('error sending signal message', { ...this.logContext, error: e });
|
577
598
|
}
|
578
599
|
}
|
579
600
|
|
580
601
|
private handleSignalResponse(res: SignalResponse) {
|
581
602
|
const msg = res.message;
|
582
603
|
if (msg == undefined) {
|
583
|
-
log.debug('received unsupported message');
|
604
|
+
this.log.debug('received unsupported message', this.logContext);
|
584
605
|
return;
|
585
606
|
}
|
586
607
|
|
@@ -658,7 +679,7 @@ export class SignalClient {
|
|
658
679
|
this.resetPingTimeout();
|
659
680
|
pingHandled = true;
|
660
681
|
} else {
|
661
|
-
log.debug('unsupported message', msg);
|
682
|
+
this.log.debug('unsupported message', { ...this.logContext, msgCase: msg.case });
|
662
683
|
}
|
663
684
|
|
664
685
|
if (!pingHandled) {
|
@@ -679,14 +700,14 @@ export class SignalClient {
|
|
679
700
|
if (this.state === SignalConnectionState.DISCONNECTED) return;
|
680
701
|
const onCloseCallback = this.onClose;
|
681
702
|
await this.close();
|
682
|
-
log.debug(`websocket connection closed: ${reason}
|
703
|
+
this.log.debug(`websocket connection closed: ${reason}`, { ...this.logContext, reason });
|
683
704
|
if (onCloseCallback) {
|
684
705
|
onCloseCallback(reason);
|
685
706
|
}
|
686
707
|
}
|
687
708
|
|
688
709
|
private handleWSError(ev: Event) {
|
689
|
-
log.error('websocket error', ev);
|
710
|
+
this.log.error('websocket error', { ...this.logContext, error: ev });
|
690
711
|
}
|
691
712
|
|
692
713
|
/**
|
@@ -696,14 +717,15 @@ export class SignalClient {
|
|
696
717
|
private resetPingTimeout() {
|
697
718
|
this.clearPingTimeout();
|
698
719
|
if (!this.pingTimeoutDuration) {
|
699
|
-
log.warn('ping timeout duration not set');
|
720
|
+
this.log.warn('ping timeout duration not set', this.logContext);
|
700
721
|
return;
|
701
722
|
}
|
702
723
|
this.pingTimeout = CriticalTimers.setTimeout(() => {
|
703
|
-
log.warn(
|
724
|
+
this.log.warn(
|
704
725
|
`ping timeout triggered. last pong received at: ${new Date(
|
705
726
|
Date.now() - this.pingTimeoutDuration! * 1000,
|
706
727
|
).toUTCString()}`,
|
728
|
+
this.logContext,
|
707
729
|
);
|
708
730
|
this.handleOnClose('ping timeout');
|
709
731
|
}, this.pingTimeoutDuration * 1000);
|
@@ -722,17 +744,17 @@ export class SignalClient {
|
|
722
744
|
this.clearPingInterval();
|
723
745
|
this.resetPingTimeout();
|
724
746
|
if (!this.pingIntervalDuration) {
|
725
|
-
log.warn('ping interval duration not set');
|
747
|
+
this.log.warn('ping interval duration not set', this.logContext);
|
726
748
|
return;
|
727
749
|
}
|
728
|
-
log.debug('start ping interval');
|
750
|
+
this.log.debug('start ping interval', this.logContext);
|
729
751
|
this.pingInterval = CriticalTimers.setInterval(() => {
|
730
752
|
this.sendPing();
|
731
753
|
}, this.pingIntervalDuration * 1000);
|
732
754
|
}
|
733
755
|
|
734
756
|
private clearPingInterval() {
|
735
|
-
log.debug('clearing ping interval');
|
757
|
+
this.log.debug('clearing ping interval', this.logContext);
|
736
758
|
this.clearPingTimeout();
|
737
759
|
if (this.pingInterval) {
|
738
760
|
CriticalTimers.clearInterval(this.pingInterval);
|
package/src/index.ts
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
import { LogLevel, setLogExtension, setLogLevel } from './logger';
|
1
|
+
import { LogLevel, getLogger, setLogExtension, setLogLevel } from './logger';
|
2
2
|
import { DataPacket_Kind, DisconnectReason, VideoQuality } from './proto/livekit_models_pb';
|
3
3
|
import DefaultReconnectPolicy from './room/DefaultReconnectPolicy';
|
4
4
|
import Room, { ConnectionState, RoomState } from './room/Room';
|
@@ -55,6 +55,7 @@ export {
|
|
55
55
|
supportsVP9,
|
56
56
|
createAudioAnalyser,
|
57
57
|
LogLevel,
|
58
|
+
getLogger,
|
58
59
|
Room,
|
59
60
|
ConnectionState,
|
60
61
|
RoomState,
|
package/src/logger.ts
CHANGED
@@ -9,9 +9,22 @@ export enum LogLevel {
|
|
9
9
|
silent = 5,
|
10
10
|
}
|
11
11
|
|
12
|
+
export enum LoggerNames {
|
13
|
+
Default = 'livekit',
|
14
|
+
Room = 'livekit-room',
|
15
|
+
Participant = 'livekit-participant',
|
16
|
+
Track = 'livekit-track',
|
17
|
+
Publication = 'livekit-track-publication',
|
18
|
+
Engine = 'livekit-engine',
|
19
|
+
Signal = 'livekit-signal',
|
20
|
+
PCManager = 'livekit-pc-manager',
|
21
|
+
PCTransport = 'livekit-pc-transport',
|
22
|
+
E2EE = 'lk-e2ee',
|
23
|
+
}
|
24
|
+
|
12
25
|
type LogLevelString = keyof typeof LogLevel;
|
13
26
|
|
14
|
-
type StructuredLogger = {
|
27
|
+
export type StructuredLogger = {
|
15
28
|
trace: (msg: string, context?: object) => void;
|
16
29
|
debug: (msg: string, context?: object) => void;
|
17
30
|
info: (msg: string, context?: object) => void;
|
@@ -20,17 +33,28 @@ type StructuredLogger = {
|
|
20
33
|
setDefaultLevel: (level: log.LogLevelDesc) => void;
|
21
34
|
};
|
22
35
|
|
23
|
-
|
36
|
+
let livekitLogger = log.getLogger('livekit');
|
24
37
|
|
25
38
|
livekitLogger.setDefaultLevel(LogLevel.info);
|
26
39
|
|
27
40
|
export default livekitLogger as StructuredLogger;
|
28
41
|
|
29
|
-
|
42
|
+
/**
|
43
|
+
* @internal
|
44
|
+
*/
|
45
|
+
export function getLogger(name: string) {
|
46
|
+
const logger = log.getLogger(name);
|
47
|
+
logger.setDefaultLevel(livekitLogger.getLevel());
|
48
|
+
return logger as StructuredLogger;
|
49
|
+
}
|
50
|
+
|
51
|
+
export function setLogLevel(level: LogLevel | LogLevelString, loggerName?: LoggerNames) {
|
30
52
|
if (loggerName) {
|
31
53
|
log.getLogger(loggerName).setLevel(level);
|
32
54
|
}
|
33
|
-
for (const logger of Object.
|
55
|
+
for (const logger of Object.entries(log.getLoggers())
|
56
|
+
.filter(([logrName]) => logrName.startsWith('livekit'))
|
57
|
+
.map(([, logr]) => logr)) {
|
34
58
|
logger.setLevel(level);
|
35
59
|
}
|
36
60
|
}
|
@@ -41,10 +65,10 @@ export type LogExtension = (level: LogLevel, msg: string, context?: object) => v
|
|
41
65
|
* use this to hook into the logging function to allow sending internal livekit logs to third party services
|
42
66
|
* if set, the browser logs will lose their stacktrace information (see https://github.com/pimterry/loglevel#writing-plugins)
|
43
67
|
*/
|
44
|
-
export function setLogExtension(extension: LogExtension) {
|
45
|
-
const originalFactory =
|
68
|
+
export function setLogExtension(extension: LogExtension, logger = livekitLogger) {
|
69
|
+
const originalFactory = logger.methodFactory;
|
46
70
|
|
47
|
-
|
71
|
+
logger.methodFactory = (methodName, configLevel, loggerName) => {
|
48
72
|
const rawMethod = originalFactory(methodName, configLevel, loggerName);
|
49
73
|
|
50
74
|
const logLevel = LogLevel[methodName as LogLevelString];
|
@@ -58,7 +82,7 @@ export function setLogExtension(extension: LogExtension) {
|
|
58
82
|
}
|
59
83
|
};
|
60
84
|
};
|
61
|
-
|
85
|
+
logger.setLevel(logger.getLevel()); // Be sure to call setLevel method in order to apply plugin
|
62
86
|
}
|
63
87
|
|
64
88
|
export const workerLogger = log.getLogger('lk-e2ee') as StructuredLogger;
|
package/src/options.ts
CHANGED
package/src/room/PCTransport.ts
CHANGED
@@ -2,8 +2,9 @@ import { EventEmitter } from 'events';
|
|
2
2
|
import type { MediaDescription } from 'sdp-transform';
|
3
3
|
import { parse, write } from 'sdp-transform';
|
4
4
|
import { debounce } from 'ts-debounce';
|
5
|
-
import log from '../logger';
|
5
|
+
import log, { LoggerNames, getLogger } from '../logger';
|
6
6
|
import { NegotiationError, UnexpectedConnectionState } from './errors';
|
7
|
+
import type { LoggerOptions } from './types';
|
7
8
|
import { ddExtensionURI, isChromiumBased, isSVCCodec } from './utils';
|
8
9
|
|
9
10
|
/** @internal */
|
@@ -43,6 +44,10 @@ export default class PCTransport extends EventEmitter {
|
|
43
44
|
|
44
45
|
private mediaConstraints: Record<string, unknown>;
|
45
46
|
|
47
|
+
private log = log;
|
48
|
+
|
49
|
+
private loggerOptions: LoggerOptions;
|
50
|
+
|
46
51
|
pendingCandidates: RTCIceCandidateInit[] = [];
|
47
52
|
|
48
53
|
restartingIce: boolean = false;
|
@@ -71,8 +76,14 @@ export default class PCTransport extends EventEmitter {
|
|
71
76
|
|
72
77
|
onTrack?: (ev: RTCTrackEvent) => void;
|
73
78
|
|
74
|
-
constructor(
|
79
|
+
constructor(
|
80
|
+
config?: RTCConfiguration,
|
81
|
+
mediaConstraints: Record<string, unknown> = {},
|
82
|
+
loggerOptions: LoggerOptions = {},
|
83
|
+
) {
|
75
84
|
super();
|
85
|
+
this.log = getLogger(loggerOptions.loggerName ?? LoggerNames.PCTransport);
|
86
|
+
this.loggerOptions = loggerOptions;
|
76
87
|
this.config = config;
|
77
88
|
this.mediaConstraints = mediaConstraints;
|
78
89
|
this._pc = this.createPC();
|
@@ -112,6 +123,12 @@ export default class PCTransport extends EventEmitter {
|
|
112
123
|
return pc;
|
113
124
|
}
|
114
125
|
|
126
|
+
private get logContext() {
|
127
|
+
return {
|
128
|
+
...this.loggerOptions.loggerContextCb?.(),
|
129
|
+
};
|
130
|
+
}
|
131
|
+
|
115
132
|
get isICEConnected(): boolean {
|
116
133
|
return (
|
117
134
|
this._pc !== null &&
|
@@ -229,7 +246,7 @@ export default class PCTransport extends EventEmitter {
|
|
229
246
|
}
|
230
247
|
|
231
248
|
if (options?.iceRestart) {
|
232
|
-
log.debug('restarting ICE');
|
249
|
+
this.log.debug('restarting ICE', this.logContext);
|
233
250
|
this.restartingIce = true;
|
234
251
|
}
|
235
252
|
|
@@ -246,12 +263,12 @@ export default class PCTransport extends EventEmitter {
|
|
246
263
|
return;
|
247
264
|
}
|
248
265
|
} else if (!this._pc || this._pc.signalingState === 'closed') {
|
249
|
-
log.warn('could not createOffer with closed peer connection');
|
266
|
+
this.log.warn('could not createOffer with closed peer connection', this.logContext);
|
250
267
|
return;
|
251
268
|
}
|
252
269
|
|
253
270
|
// actually negotiate
|
254
|
-
log.debug('starting to negotiate');
|
271
|
+
this.log.debug('starting to negotiate', this.logContext);
|
255
272
|
const offer = await this.pc.createOffer(options);
|
256
273
|
|
257
274
|
const sdpParsed = parse(offer.sdp ?? '');
|
@@ -452,7 +469,10 @@ export default class PCTransport extends EventEmitter {
|
|
452
469
|
const originalSdp = sd.sdp;
|
453
470
|
sd.sdp = munged;
|
454
471
|
try {
|
455
|
-
log.debug(
|
472
|
+
this.log.debug(
|
473
|
+
`setting munged ${remote ? 'remote' : 'local'} description`,
|
474
|
+
this.logContext,
|
475
|
+
);
|
456
476
|
if (remote) {
|
457
477
|
await this.pc.setRemoteDescription(sd);
|
458
478
|
} else {
|
@@ -460,7 +480,8 @@ export default class PCTransport extends EventEmitter {
|
|
460
480
|
}
|
461
481
|
return;
|
462
482
|
} catch (e) {
|
463
|
-
log.warn(`not able to set ${sd.type}, falling back to unmodified sdp`, {
|
483
|
+
this.log.warn(`not able to set ${sd.type}, falling back to unmodified sdp`, {
|
484
|
+
...this.logContext,
|
464
485
|
error: e,
|
465
486
|
sdp: munged,
|
466
487
|
});
|
@@ -491,7 +512,7 @@ export default class PCTransport extends EventEmitter {
|
|
491
512
|
if (!remote && this.pc.remoteDescription) {
|
492
513
|
fields.remoteSdp = this.pc.remoteDescription;
|
493
514
|
}
|
494
|
-
log.error(`unable to set ${sd.type}`, fields);
|
515
|
+
this.log.error(`unable to set ${sd.type}`, { ...this.logContext, fields });
|
495
516
|
throw new NegotiationError(msg);
|
496
517
|
}
|
497
518
|
}
|