@livedigital/client 1.7.0 → 1.10.0
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/constants/events.d.ts +1 -0
- package/dist/engine/Peer.d.ts +16 -35
- package/dist/engine/PeerProducer.d.ts +2 -1
- package/dist/engine/index.d.ts +15 -11
- package/dist/engine/media/Consumer.d.ts +0 -1
- package/dist/engine/media/VideoConsumer.d.ts +1 -9
- package/dist/engine/media/index.d.ts +9 -11
- package/dist/engine/media/tracks/AudioTrack.d.ts +9 -0
- package/dist/engine/media/tracks/BaseTrack.d.ts +23 -0
- package/dist/engine/media/tracks/TrackWithCodecOptions.d.ts +4 -0
- package/dist/engine/media/tracks/TrackWithEncodings.d.ts +4 -0
- package/dist/engine/media/tracks/VideoTrack.d.ts +13 -0
- package/dist/engine/network/LoadBalancerClient.d.ts +7 -1
- package/dist/engine/network/index.d.ts +5 -2
- package/dist/engine/system/index.d.ts +10 -19
- package/dist/index.d.ts +16 -22
- package/dist/index.es.js +15 -1
- package/dist/index.js +15 -1
- package/dist/types/common.d.ts +57 -7
- package/package.json +11 -7
- package/src/constants/events.ts +1 -0
- package/src/engine/Peer.ts +132 -337
- package/src/engine/PeerProducer.ts +8 -2
- package/src/engine/index.ts +172 -197
- package/src/engine/media/Consumer.ts +0 -4
- package/src/engine/media/VideoConsumer.ts +1 -18
- package/src/engine/media/index.ts +35 -35
- package/src/engine/media/tracks/AudioTrack.ts +18 -0
- package/src/engine/media/tracks/BaseTrack.ts +70 -0
- package/src/engine/media/tracks/TrackWithCodecOptions.ts +5 -0
- package/src/engine/media/tracks/TrackWithEncodings.ts +5 -0
- package/src/engine/media/tracks/VideoTrack.ts +29 -0
- package/src/engine/network/LoadBalancerClient.ts +18 -4
- package/src/engine/network/index.ts +8 -3
- package/src/engine/system/index.ts +64 -198
- package/src/index.ts +39 -68
- package/src/types/common.ts +71 -8
package/dist/engine/Peer.d.ts
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import { ProducerData } from '../types/common';
|
|
1
|
+
import { ProducerData, ConnectionQuality, PayloadOfPublishedMedia } from '../types/common';
|
|
2
2
|
import Consumer from './media/Consumer';
|
|
3
3
|
import VideoConsumer from './media/VideoConsumer';
|
|
4
4
|
import EnhancedEventEmitter from '../EnhancedEventEmitter';
|
|
5
5
|
import Engine from './index';
|
|
6
|
+
import PeerProducer from './PeerProducer';
|
|
6
7
|
interface PeerConstructor {
|
|
7
8
|
id: string;
|
|
8
9
|
channelId: string;
|
|
@@ -28,54 +29,34 @@ declare class Peer {
|
|
|
28
29
|
loginDate: Date;
|
|
29
30
|
uid?: string;
|
|
30
31
|
appData: Record<string, unknown>;
|
|
31
|
-
private
|
|
32
|
-
private
|
|
33
|
-
private videoConsumer?;
|
|
34
|
-
private audioConsumer?;
|
|
32
|
+
private producers;
|
|
33
|
+
private consumers;
|
|
35
34
|
private readonly engine;
|
|
36
35
|
private readonly _observer;
|
|
37
36
|
private readonly logger;
|
|
38
37
|
private incomingConnectionQuality;
|
|
39
38
|
private outgoingConnectionQuality;
|
|
40
|
-
constructor({ id, channelId, appId, loginDate, producers,
|
|
39
|
+
constructor({ id, channelId, appId, loginDate, producers, engine, appData, uid, }: PeerConstructor);
|
|
41
40
|
get observer(): EnhancedEventEmitter;
|
|
42
|
-
get isPublishedVideo(): boolean;
|
|
43
|
-
get isPublishedAudio(): boolean;
|
|
44
|
-
get hasVideo(): boolean;
|
|
45
|
-
get hasAudio(): boolean;
|
|
46
|
-
get videoTrack(): MediaStreamTrack | undefined;
|
|
47
|
-
get audioTrack(): MediaStreamTrack | undefined;
|
|
48
|
-
get isVideoPaused(): boolean;
|
|
49
|
-
get isAudioPaused(): boolean;
|
|
50
|
-
get videoCodec(): string | undefined;
|
|
51
|
-
get audioCodec(): string | undefined;
|
|
52
41
|
get isMe(): boolean;
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
pauseAudio(): Promise<void>;
|
|
62
|
-
resumeVideo(): Promise<void>;
|
|
63
|
-
resumeAudio(): Promise<void>;
|
|
64
|
-
setVideoStreamPriority(priority: number): Promise<void>;
|
|
65
|
-
setAudioStreamPriority(priority: number): Promise<void>;
|
|
42
|
+
get publishedMedia(): PayloadOfPublishedMedia[];
|
|
43
|
+
subscribe(producerId: string): Promise<void>;
|
|
44
|
+
setMinResolution(consumerId: string): Promise<void>;
|
|
45
|
+
setMediumResolution(consumerId: string): Promise<void>;
|
|
46
|
+
setMaxResolution(consumerId: string): Promise<void>;
|
|
47
|
+
pause(consumerId: string): Promise<void>;
|
|
48
|
+
resume(consumerId: string): Promise<void>;
|
|
49
|
+
setPriority(consumerId: string, priority: number): Promise<void>;
|
|
66
50
|
private setConsumerPriority;
|
|
67
51
|
private createConsumer;
|
|
68
|
-
private closeConsumer;
|
|
69
52
|
private changeConsumerPreferredLayers;
|
|
70
|
-
private setVideoProducer;
|
|
71
|
-
private setAudioProducer;
|
|
72
|
-
private removeVideoProducer;
|
|
73
|
-
private removeAudioProducer;
|
|
74
53
|
private pauseRemoteConsumer;
|
|
75
54
|
private resumeRemoteConsumer;
|
|
76
55
|
private handleNewProducer;
|
|
77
56
|
private handlePeerEvents;
|
|
78
57
|
private emitConnectionQuality;
|
|
79
|
-
|
|
58
|
+
static getConnectionQualityByScore(score: number): ConnectionQuality;
|
|
59
|
+
getAllConsumers(): Consumer[];
|
|
60
|
+
getAllProducers(): PeerProducer[];
|
|
80
61
|
}
|
|
81
62
|
export default Peer;
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { MediaKind } from 'mediasoup-client/lib/RtpParameters';
|
|
2
|
-
import { ProducerData } from '../types/common';
|
|
2
|
+
import { ProducerData, TrackLabel } from '../types/common';
|
|
3
3
|
declare class PeerProducer {
|
|
4
4
|
readonly id: string;
|
|
5
5
|
readonly kind: MediaKind;
|
|
6
6
|
readonly peerId: string;
|
|
7
|
+
readonly label: TrackLabel;
|
|
7
8
|
score: number;
|
|
8
9
|
constructor(params: ProducerData);
|
|
9
10
|
}
|
package/dist/engine/index.d.ts
CHANGED
|
@@ -1,9 +1,13 @@
|
|
|
1
|
-
import { PeerResponse, JoinChannelParams,
|
|
1
|
+
import { PeerResponse, JoinChannelParams, CreateCameraVideoTrackOptions, CreateMicrophoneAudioTrackOptions, CreateScreenVideoTrackOptions, CreateScreenAudioTrackOptions, Track } from '../types/common';
|
|
2
2
|
import EnhancedEventEmitter from '../EnhancedEventEmitter';
|
|
3
3
|
import System from './system';
|
|
4
4
|
import Peer from './Peer';
|
|
5
|
-
import Network from './network';
|
|
5
|
+
import Network, { NetworkParams } from './network';
|
|
6
6
|
import Media from './media';
|
|
7
|
+
declare type EngineParams = {
|
|
8
|
+
clientEventEmitter: EnhancedEventEmitter;
|
|
9
|
+
network: NetworkParams;
|
|
10
|
+
};
|
|
7
11
|
declare class Engine {
|
|
8
12
|
system: System;
|
|
9
13
|
network: Network;
|
|
@@ -15,7 +19,7 @@ declare class Engine {
|
|
|
15
19
|
private initialized;
|
|
16
20
|
private isJoined;
|
|
17
21
|
private logger;
|
|
18
|
-
constructor(
|
|
22
|
+
constructor(params: EngineParams);
|
|
19
23
|
private initialize;
|
|
20
24
|
release(): Promise<void>;
|
|
21
25
|
private pauseRemoteProducer;
|
|
@@ -26,13 +30,13 @@ declare class Engine {
|
|
|
26
30
|
join(params: JoinChannelParams): Promise<void>;
|
|
27
31
|
setPeer(peerData: PeerResponse): void;
|
|
28
32
|
removePeer(peerId: string): void;
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
33
|
+
pause(track: Track): Promise<void>;
|
|
34
|
+
resume(track: Track): Promise<void>;
|
|
35
|
+
createCameraVideoTrack(options?: CreateCameraVideoTrackOptions): Promise<Track | null>;
|
|
36
|
+
createMicrophoneAudioTrack(options?: CreateMicrophoneAudioTrackOptions): Promise<Track | null>;
|
|
37
|
+
createScreenVideoTrack(options?: CreateScreenVideoTrackOptions): Promise<Track | null>;
|
|
38
|
+
createScreenAudioTrack(options?: CreateScreenAudioTrackOptions): Promise<Track | null>;
|
|
39
|
+
publish(tracks: Track | Track[]): Promise<void>;
|
|
40
|
+
unpublish(tracks?: Track | Track[]): Promise<void>;
|
|
37
41
|
}
|
|
38
42
|
export default Engine;
|
|
@@ -1,17 +1,9 @@
|
|
|
1
|
-
import Consumer from './Consumer';
|
|
2
1
|
import { Consumer as MediasoupConsumer } from 'mediasoup-client/lib/types';
|
|
2
|
+
import Consumer from './Consumer';
|
|
3
3
|
declare class VideoConsumer extends Consumer {
|
|
4
4
|
spatialLayers: number;
|
|
5
5
|
temporalLayers: number;
|
|
6
|
-
private currentSpatialLayer;
|
|
7
|
-
private currentTemporalLayer;
|
|
8
|
-
currentPreferredLayers: {
|
|
9
|
-
spatialLayer?: number;
|
|
10
|
-
temporalLayer?: number;
|
|
11
|
-
};
|
|
12
6
|
constructor(consumer: MediasoupConsumer);
|
|
13
7
|
parseScalabilityMode(): void;
|
|
14
|
-
setCurrentSpatialLayer(currentSpatialLayer: number): void;
|
|
15
|
-
setCurrentTemporalLayer(currentTemporalLayer: number): void;
|
|
16
8
|
}
|
|
17
9
|
export default VideoConsumer;
|
|
@@ -1,19 +1,17 @@
|
|
|
1
1
|
import { Device } from 'mediasoup-client';
|
|
2
|
-
import { Producer } from 'mediasoup-client/lib/Producer';
|
|
3
2
|
import { RtpCapabilities, RtpCodecCapability } from 'mediasoup-client/lib/RtpParameters';
|
|
3
|
+
import { Track } from '../../types/common';
|
|
4
4
|
declare class Media {
|
|
5
5
|
mediasoupDevice: Device;
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
isDevicesLoaded: boolean;
|
|
9
|
-
isVideoDisabled: boolean;
|
|
10
|
-
isAudioDisabled: boolean;
|
|
6
|
+
isDeviceLoaded: boolean;
|
|
7
|
+
private tracks;
|
|
11
8
|
constructor();
|
|
12
9
|
loadDevice(routerRtpCapabilities: RtpCapabilities): Promise<void>;
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
10
|
+
getTrackCodec(track: Track): RtpCodecCapability | undefined;
|
|
11
|
+
private createTrack;
|
|
12
|
+
createUserMediaTrack(constraints: MediaStreamConstraints): Promise<Track>;
|
|
13
|
+
createDisplayMediaTrack(constraints: MediaStreamConstraints): Promise<Track>;
|
|
14
|
+
deleteTrack(track: Track): Promise<void>;
|
|
15
|
+
getAllTracks(): Track[];
|
|
18
16
|
}
|
|
19
17
|
export default Media;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { ProducerCodecOptions } from 'mediasoup-client/lib/Producer';
|
|
2
|
+
import { AudioEncoderConfig } from 'types/common';
|
|
3
|
+
import BaseTrack from './BaseTrack';
|
|
4
|
+
import TrackWithCodecOptions from './TrackWithCodecOptions';
|
|
5
|
+
declare class AudioTrack extends BaseTrack implements TrackWithCodecOptions {
|
|
6
|
+
getEncoderConfig(): AudioEncoderConfig;
|
|
7
|
+
getCodecOptions(): ProducerCodecOptions;
|
|
8
|
+
}
|
|
9
|
+
export default AudioTrack;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { Producer } from 'mediasoup-client/lib/Producer';
|
|
2
|
+
import { MediaKind } from 'mediasoup-client/lib/RtpParameters';
|
|
3
|
+
import { EncoderConfig, TrackLabel } from 'types/common';
|
|
4
|
+
declare class BaseTrack {
|
|
5
|
+
#private;
|
|
6
|
+
protected encoderConfig: EncoderConfig;
|
|
7
|
+
private producer?;
|
|
8
|
+
private label;
|
|
9
|
+
constructor(mediaStreamTrack: MediaStreamTrack);
|
|
10
|
+
get mediaStreamTrack(): MediaStreamTrack;
|
|
11
|
+
get id(): string;
|
|
12
|
+
get kind(): MediaKind;
|
|
13
|
+
get producerId(): string | undefined;
|
|
14
|
+
get isPublished(): boolean;
|
|
15
|
+
getLabel(): TrackLabel;
|
|
16
|
+
setLabel(label: TrackLabel): void;
|
|
17
|
+
setEncoderConfig(encoderConfig: EncoderConfig): void;
|
|
18
|
+
getEncoderConfig(): EncoderConfig;
|
|
19
|
+
setProducer(producer: Producer): void;
|
|
20
|
+
getProducer(): Producer | undefined;
|
|
21
|
+
closeProducer(): void;
|
|
22
|
+
}
|
|
23
|
+
export default BaseTrack;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { ProducerCodecOptions } from 'mediasoup-client/lib/Producer';
|
|
2
|
+
import { RtpEncodingParameters } from 'mediasoup-client/lib/RtpParameters';
|
|
3
|
+
import { VideoCodec, VideoEncoderConfig } from 'types/common';
|
|
4
|
+
import BaseTrack from './BaseTrack';
|
|
5
|
+
import TrackWithCodecOptions from './TrackWithCodecOptions';
|
|
6
|
+
import TrackWithEncodings from './TrackWithEncodings';
|
|
7
|
+
declare class VideoTrack extends BaseTrack implements TrackWithCodecOptions, TrackWithEncodings {
|
|
8
|
+
getEncoderConfig(): VideoEncoderConfig;
|
|
9
|
+
getCodecOptions(): ProducerCodecOptions;
|
|
10
|
+
getPreferredCodec(): VideoCodec;
|
|
11
|
+
getEncodings(): RtpEncodingParameters[];
|
|
12
|
+
}
|
|
13
|
+
export default VideoTrack;
|
|
@@ -1,7 +1,13 @@
|
|
|
1
1
|
import { GetNodeResponse } from '../../types/common';
|
|
2
|
+
export declare type LoadBalancerApiClientParams = {
|
|
3
|
+
baseURL?: string;
|
|
4
|
+
timeout?: number;
|
|
5
|
+
customNode?: GetNodeResponse;
|
|
6
|
+
};
|
|
2
7
|
declare class LoadBalancerApiClient {
|
|
3
8
|
private readonly api;
|
|
4
|
-
|
|
9
|
+
private customNode?;
|
|
10
|
+
constructor(params: LoadBalancerApiClientParams);
|
|
5
11
|
getNode({ channelId }: {
|
|
6
12
|
channelId: string;
|
|
7
13
|
}): Promise<GetNodeResponse>;
|
|
@@ -1,14 +1,17 @@
|
|
|
1
1
|
import { IceParameters, Transport } from 'mediasoup-client/lib/Transport';
|
|
2
2
|
import { Device } from 'mediasoup-client';
|
|
3
3
|
import SocketIO from './Socket';
|
|
4
|
-
import LoadBalancerApiClient from './LoadBalancerClient';
|
|
4
|
+
import LoadBalancerApiClient, { LoadBalancerApiClientParams } from './LoadBalancerClient';
|
|
5
|
+
export declare type NetworkParams = {
|
|
6
|
+
loadbalancer: LoadBalancerApiClientParams;
|
|
7
|
+
};
|
|
5
8
|
declare class Network {
|
|
6
9
|
readonly socket: SocketIO;
|
|
7
10
|
readonly loadBalancerClient: LoadBalancerApiClient;
|
|
8
11
|
sendTransport?: Transport;
|
|
9
12
|
receiveTransport?: Transport;
|
|
10
13
|
private readonly logger;
|
|
11
|
-
constructor();
|
|
14
|
+
constructor(params: NetworkParams);
|
|
12
15
|
closeRemoteProducer(producerId: string): Promise<void>;
|
|
13
16
|
closeSendTransport(): Promise<void>;
|
|
14
17
|
closeReceiveTransport(): Promise<void>;
|
|
@@ -1,33 +1,24 @@
|
|
|
1
|
-
import
|
|
1
|
+
import EnhancedEventEmitter from 'EnhancedEventEmitter';
|
|
2
|
+
declare type SystemParams = {
|
|
3
|
+
clientEventEmitter: EnhancedEventEmitter;
|
|
4
|
+
};
|
|
2
5
|
declare class System {
|
|
3
6
|
isEnableVideoDevicesLock: boolean;
|
|
4
7
|
isEnableAudioDevicesLock: boolean;
|
|
5
|
-
|
|
6
|
-
videoStream?: MediaStream;
|
|
7
|
-
audioStream?: MediaStream;
|
|
8
|
+
isDevicesDetected: boolean;
|
|
8
9
|
availableVideoDevices: MediaDeviceInfo[];
|
|
9
10
|
availableAudioDevices: MediaDeviceInfo[];
|
|
10
|
-
|
|
11
|
-
|
|
11
|
+
private isMediaDevicesAccessGranted;
|
|
12
|
+
clientEventEmitter: EnhancedEventEmitter;
|
|
12
13
|
private readonly logger;
|
|
13
|
-
constructor();
|
|
14
|
+
constructor(params: SystemParams);
|
|
14
15
|
setIsEnableVideoDevicesLock(value: boolean): void;
|
|
15
16
|
setIsEnableAudioDevicesLock(value: boolean): void;
|
|
16
|
-
setCurrentVideoDevice(deviceId: string): void;
|
|
17
|
-
setCurrentAudioDevice(deviceId: string): void;
|
|
18
17
|
setAvailableVideoDevices(availableVideoDevices: MediaDeviceInfo[]): void;
|
|
19
18
|
setAvailableAudioDevices(availableAudioDevices: MediaDeviceInfo[]): void;
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
getVideoTrack(): Promise<MediaStreamTrack>;
|
|
23
|
-
getAudioTrack(): Promise<MediaStreamTrack>;
|
|
24
|
-
startVideoStream(videoTrackConstraints?: VideoTrackConstraints): Promise<MediaStream>;
|
|
25
|
-
startAudioStream(audioTrackConstraints?: AudioTrackConstraints): Promise<MediaStream>;
|
|
19
|
+
requestMediaDevicesAccess(): Promise<void>;
|
|
20
|
+
refreshAvailableMediaDevicesList(): Promise<void>;
|
|
26
21
|
detectDevices(): Promise<void>;
|
|
27
22
|
listenDevices(): void;
|
|
28
|
-
stopVideoStream(): void;
|
|
29
|
-
stopAudioStream(): void;
|
|
30
|
-
restartVideoStream(): Promise<void>;
|
|
31
|
-
restartAudioStream(): Promise<void>;
|
|
32
23
|
}
|
|
33
24
|
export default System;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,37 +1,31 @@
|
|
|
1
|
-
import { AvailableMediaDevices,
|
|
1
|
+
import { AvailableMediaDevices, CreateCameraVideoTrackOptions, CreateMicrophoneAudioTrackOptions, CreateScreenAudioTrackOptions, CreateScreenVideoTrackOptions, JoinChannelParams, Track } from './types/common';
|
|
2
2
|
import EnhancedEventEmitter from './EnhancedEventEmitter';
|
|
3
3
|
import Peer from './engine/Peer';
|
|
4
|
+
import { LoadBalancerApiClientParams } from './engine/network/LoadBalancerClient';
|
|
5
|
+
declare type ClientParams = {
|
|
6
|
+
network?: {
|
|
7
|
+
loadbalancer?: LoadBalancerApiClientParams;
|
|
8
|
+
};
|
|
9
|
+
};
|
|
4
10
|
declare class Client {
|
|
5
11
|
private readonly engine;
|
|
6
12
|
private readonly _observer;
|
|
7
|
-
constructor();
|
|
13
|
+
constructor(params: ClientParams);
|
|
8
14
|
get observer(): EnhancedEventEmitter;
|
|
9
15
|
get id(): string | undefined;
|
|
10
16
|
get peers(): Peer[];
|
|
11
|
-
get isVideoEnabled(): boolean;
|
|
12
|
-
get isVideoPaused(): boolean;
|
|
13
|
-
get isAudioEnabled(): boolean;
|
|
14
|
-
get isAudioPaused(): boolean;
|
|
15
17
|
get availableVideoDevices(): MediaDeviceInfo[];
|
|
16
18
|
get availableAudioDevices(): MediaDeviceInfo[];
|
|
17
|
-
get currentAudioDeviceId(): string | undefined;
|
|
18
|
-
get currentVideoDeviceId(): string | undefined;
|
|
19
19
|
detectDevices(): Promise<AvailableMediaDevices>;
|
|
20
|
-
getVideoStream(): Promise<MediaStream>;
|
|
21
|
-
getAudioStream(): Promise<MediaStream>;
|
|
22
|
-
getVideoTrack(): Promise<MediaStreamTrack>;
|
|
23
|
-
getAudioTrack(): Promise<MediaStreamTrack>;
|
|
24
|
-
setVideoDevice(deviceId: string): void;
|
|
25
|
-
setAudioDevice(deviceId: string): void;
|
|
26
20
|
join(params: JoinChannelParams): Promise<void>;
|
|
27
21
|
leave(): Promise<void>;
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
22
|
+
publish(tracks: Track | Track[]): Promise<void>;
|
|
23
|
+
unpublish(tracks?: Track | Track[]): Promise<void>;
|
|
24
|
+
pause(track: Track): Promise<void>;
|
|
25
|
+
resume(track: Track): Promise<void>;
|
|
26
|
+
createCameraVideoTrack(options?: CreateCameraVideoTrackOptions): Promise<Track | null>;
|
|
27
|
+
createMicrophoneAudioTrack(options?: CreateMicrophoneAudioTrackOptions): Promise<Track | null>;
|
|
28
|
+
createScreenVideoTrack(options?: CreateScreenVideoTrackOptions): Promise<Track | null>;
|
|
29
|
+
createScreenAudioTrack(options?: CreateScreenAudioTrackOptions): Promise<Track | null>;
|
|
36
30
|
}
|
|
37
31
|
export default Client;
|