@livedigital/client 2.1.0 → 2.3.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.
@@ -2,11 +2,13 @@ import {
2
2
  ChangePreferredLayersParams,
3
3
  ConsumerScoreChangedPayload,
4
4
  ProducerData,
5
- ProducerScoreChangedPayload,
5
+ ProducerRequestMaxSpatialLayer,
6
+ ProducerScoreChangedPayload, ProducerSetMaxSpatialLayer,
6
7
  } from '../../types/common';
7
8
  import Engine from '../index';
8
9
  import { MEDIASOUP_EVENTS } from '../../constants/events';
9
10
  import Logger from '../Logger';
11
+ import VideoTrack from '../media/tracks/VideoTrack';
10
12
 
11
13
  class MediaSoupEventHandler {
12
14
  private readonly engine: Engine;
@@ -108,6 +110,83 @@ class MediaSoupEventHandler {
108
110
 
109
111
  peer.observer.safeEmit(MEDIASOUP_EVENTS.producerScoreChanged, payload);
110
112
  });
113
+
114
+ connection.on(MEDIASOUP_EVENTS.producerRequestMaxSpatialLayer, async ({
115
+ producerId,
116
+ spatialLayer,
117
+ }: ProducerRequestMaxSpatialLayer) => {
118
+ const track = this.engine.media.getAllTracks().find((t) => t.getProducer()?.id === producerId);
119
+ if (!track) {
120
+ this.logger.warn('producerRequestMaxSpatialLayer()', { message: 'Producer not found' });
121
+ return;
122
+ }
123
+
124
+ if (!(track instanceof VideoTrack)) {
125
+ this.logger.warn('producerRequestMaxSpatialLayer()', { message: 'Wrong producer kind' });
126
+ return;
127
+ }
128
+
129
+ const currentMaxSpatialLayer = track.getMaxSpatialLayer();
130
+ if (currentMaxSpatialLayer === spatialLayer) {
131
+ this.logger.debug('producerRequestMaxSpatialLayer()', {
132
+ message: 'Skip set max spatial layer',
133
+ requestedSpatialLayer: spatialLayer,
134
+ currentMaxSpatialLayer,
135
+ });
136
+ return;
137
+ }
138
+
139
+ await track.setMaxSpatialLayer(spatialLayer);
140
+ await this.engine.network.socket.request(MEDIASOUP_EVENTS.producerSetMaxSpatialLayer, {
141
+ producerId,
142
+ maxSpatialLayer: spatialLayer,
143
+ });
144
+ });
145
+
146
+ connection.on(MEDIASOUP_EVENTS.producerSetMaxSpatialLayer, async ({
147
+ peerId,
148
+ producerId,
149
+ spatialLayer,
150
+ }: ProducerSetMaxSpatialLayer) => {
151
+ const peer = this.engine.peers.find((item) => item.id === peerId);
152
+ if (!peer || peer.isMe) {
153
+ return;
154
+ }
155
+
156
+ const consumer = peer.getConsumerByProducerId(producerId);
157
+ if (!consumer) {
158
+ this.logger.warn('producerSetMaxSpatialLayer()', { message: 'Consumer not found' });
159
+ return;
160
+ }
161
+
162
+ consumer.setCurrentMaxSpatialLayer(spatialLayer);
163
+ this.logger.debug('producerSetMaxSpatialLayer()', {
164
+ producerId,
165
+ consumerId: consumer.id,
166
+ spatialLayer,
167
+ });
168
+
169
+ if (consumer.requestedSpatialLayer !== spatialLayer) {
170
+ this.logger.debug('producerSetMaxSpatialLayer()', {
171
+ message: 'No need to request new preferred layer',
172
+ currentMaxSpatialLayer: spatialLayer,
173
+ requestedMaxSpatialLayer: consumer.requestedSpatialLayer,
174
+ });
175
+
176
+ return;
177
+ }
178
+
179
+ await this.engine.network.socket.request(MEDIASOUP_EVENTS.consumerChangePreferredLayers, {
180
+ consumerId: consumer.id,
181
+ spatialLayer,
182
+ });
183
+
184
+ this.logger.debug('requestVideoPreferredLayers()', {
185
+ producerId,
186
+ consumerId: consumer.id,
187
+ spatialLayer,
188
+ });
189
+ });
111
190
  }
112
191
  }
113
192
 
@@ -8,7 +8,6 @@ import {
8
8
  PeerResponse,
9
9
  Role,
10
10
  SocketResponse,
11
- StartTrackPayload,
12
11
  Track,
13
12
  TrackLabel,
14
13
  } from '../types/common';
@@ -23,6 +22,10 @@ import Logger from './Logger';
23
22
  import {
24
23
  CHANNEL_EVENTS, CLIENT_EVENTS, MEDIASOUP_EVENTS, PEER_EVENTS, SocketIOEvents,
25
24
  } from '../constants/events';
25
+ import { GetNodeRequest } from '../types/network';
26
+ import VideoTrack from './media/tracks/VideoTrack';
27
+ import AudioTrack from './media/tracks/AudioTrack';
28
+ import PeerTrack from './media/tracks/PeerTrack';
26
29
 
27
30
  type EngineParams = {
28
31
  clientEventEmitter: EnhancedEventEmitter,
@@ -142,7 +145,10 @@ class Engine {
142
145
  try {
143
146
  this.logger.debug('join()', { params });
144
147
  this.isRoomJoining = true;
145
- const { webSocketUrl } = await this.getAvailableNode({ channelId: params.channelId });
148
+ const { webSocketUrl } = await this.getAvailableNode({
149
+ channelId: params.channelId,
150
+ role: params.role,
151
+ });
146
152
  this.network.socket.connect(webSocketUrl);
147
153
  await this.waitForSocketConnection();
148
154
  await this.performJoin(params);
@@ -219,8 +225,11 @@ class Engine {
219
225
  video: trackParams.videoTrackOptions,
220
226
  });
221
227
 
222
- track.setLabel(TrackLabel.Camera);
223
- track.setEncoderConfig(trackParams.encoderConfig);
228
+ if (track instanceof VideoTrack) {
229
+ track.setLabel(TrackLabel.Camera);
230
+ track.setEncoderConfig(trackParams.encoderConfig);
231
+ track.setTransformParams(trackParams.transformParams);
232
+ }
224
233
 
225
234
  this.logger.debug('createCameraVideoTrack()', { trackParams, track });
226
235
  return track;
@@ -265,9 +274,10 @@ class Engine {
265
274
  this.unpublish(track);
266
275
  });
267
276
 
268
- if (track.kind === 'video') {
277
+ if (track instanceof VideoTrack) {
269
278
  track.setLabel(TrackLabel.ScreenVideo);
270
279
  track.setEncoderConfig(videoTrackParams.encoderConfig);
280
+ track.setTransformParams(videoTrackParams.transformParams);
271
281
  this.logger.debug('createScreenMediaTrack()', { trackParams: videoTrackParams, track });
272
282
  return;
273
283
  }
@@ -303,6 +313,19 @@ class Engine {
303
313
  ? track.getCodecOptions()
304
314
  : undefined;
305
315
 
316
+ const maxSpatialLayer = encodings && encodings.length >= 1 ? 1 : 0;
317
+ const appData = {
318
+ peerId: this.mySocketId,
319
+ label: track.getLabel(),
320
+ trackTransformParams: {},
321
+ maxSpatialLayer: 0,
322
+ };
323
+
324
+ if (track instanceof VideoTrack) {
325
+ appData.maxSpatialLayer = maxSpatialLayer;
326
+ appData.trackTransformParams = track.transformParams;
327
+ }
328
+
306
329
  const producer = await this.network.sendTransport?.produce({
307
330
  track: track.mediaStreamTrack,
308
331
  encodings,
@@ -311,10 +334,7 @@ class Engine {
311
334
  stopTracks: true,
312
335
  disableTrackOnPause: true,
313
336
  zeroRtpOnPause: true,
314
- appData: {
315
- peerId: this.mySocketId,
316
- label: track.getLabel(),
317
- },
337
+ appData,
318
338
  });
319
339
 
320
340
  if (!producer) {
@@ -322,12 +342,31 @@ class Engine {
322
342
  }
323
343
 
324
344
  track.setProducer(producer);
345
+
346
+ if (track instanceof VideoTrack) {
347
+ await track.setMaxSpatialLayer(maxSpatialLayer);
348
+ await this.network.socket.request(MEDIASOUP_EVENTS.producerSetMaxSpatialLayer, {
349
+ producerId: track.getProducer()?.id,
350
+ maxSpatialLayer,
351
+ });
352
+ }
353
+
354
+ if (track instanceof AudioTrack) {
355
+ await track.setPriority('high');
356
+ }
357
+
325
358
  const myPeer = this.peersRepository.get(<string> this.mySocketId);
326
- myPeer?.observer.safeEmit(PEER_EVENTS.trackStart, {
327
- producerId: producer.id,
328
- track: track.mediaStreamTrack,
359
+ if (!myPeer) {
360
+ return;
361
+ }
362
+
363
+ const peerTrack = new PeerTrack({
364
+ mediaStreamTrack: track.mediaStreamTrack,
329
365
  label: track.getLabel(),
330
- } as StartTrackPayload);
366
+ engine: this,
367
+ });
368
+ myPeer.tracks.set(peerTrack.label, peerTrack);
369
+ myPeer.observer.safeEmit(PEER_EVENTS.trackStart, peerTrack);
331
370
 
332
371
  this.logger.debug('publish()', { track, encodings, codecOptions });
333
372
  });
@@ -385,9 +424,9 @@ class Engine {
385
424
  return this.app;
386
425
  }
387
426
 
388
- private async getAvailableNode({ channelId }: { channelId: string }): Promise<{ webSocketUrl: string }> {
427
+ private async getAvailableNode(params: GetNodeRequest): Promise<{ webSocketUrl: string }> {
389
428
  try {
390
- const response = await this.network.loadBalancerClient.getNode({ channelId });
429
+ const response = await this.network.loadBalancerClient.getNode(params);
391
430
  return { webSocketUrl: response.webSocketUrl };
392
431
  } catch (error) {
393
432
  this.logger.error('getAvailableNode()', { error: 'No available nodes' });
@@ -93,6 +93,10 @@ class Media {
93
93
  width: { ideal: options?.width || VIDEO_CONSTRAINS.fullhd.width },
94
94
  height: { ideal: options?.height || VIDEO_CONSTRAINS.fullhd.height },
95
95
  },
96
+ transformParams: {
97
+ width: options?.width || VIDEO_CONSTRAINS.hd.width,
98
+ height: options?.height || VIDEO_CONSTRAINS.hd.height,
99
+ },
96
100
  encoderConfig: options?.encoderConfig || {
97
101
  encodings: SCREEN_SHARING_SIMULCAST_ENCODINGS,
98
102
  },
@@ -107,6 +111,10 @@ class Media {
107
111
  width: { ideal: options?.width || VIDEO_CONSTRAINS.hd.width },
108
112
  height: { ideal: options?.height || VIDEO_CONSTRAINS.hd.height },
109
113
  },
114
+ transformParams: {
115
+ width: options?.width || VIDEO_CONSTRAINS.hd.width,
116
+ height: options?.height || VIDEO_CONSTRAINS.hd.height,
117
+ },
110
118
  encoderConfig: options?.encoderConfig || {
111
119
  encodings: WEBCAM_SIMULCAST_ENCODINGS,
112
120
  },
@@ -1,6 +1,7 @@
1
1
  import { Producer } from 'mediasoup-client/lib/Producer';
2
2
  import { MediaKind } from 'mediasoup-client/lib/RtpParameters';
3
3
  import { EncoderConfig, TrackLabel } from '../../../types/common';
4
+ import Logger from '../../Logger';
4
5
 
5
6
  class BaseTrack {
6
7
  readonly #mediaStreamTrack: MediaStreamTrack;
@@ -11,6 +12,8 @@ class BaseTrack {
11
12
 
12
13
  private label: TrackLabel = TrackLabel.Unknown;
13
14
 
15
+ protected logger = new Logger('Track');
16
+
14
17
  constructor(mediaStreamTrack: MediaStreamTrack) {
15
18
  this.#mediaStreamTrack = mediaStreamTrack;
16
19
  }
@@ -65,6 +68,19 @@ class BaseTrack {
65
68
  this.producer?.close();
66
69
  this.producer = undefined;
67
70
  }
71
+
72
+ async setPriority(priority: RTCPriorityType): Promise<void> {
73
+ if (!this.producer) {
74
+ this.logger.warn('setPriority()', 'Not published yet');
75
+ return;
76
+ }
77
+
78
+ await this.producer.setRtpEncodingParameters({ priority });
79
+ this.logger.debug('setPriority()', {
80
+ label: this.getLabel(),
81
+ priority,
82
+ });
83
+ }
68
84
  }
69
85
 
70
86
  export default BaseTrack;
@@ -0,0 +1,214 @@
1
+ import {
2
+ PreferredLayersParams, SetConsumerPriorityParams, SocketResponse,
3
+ SpatialLayerParams,
4
+ TrackLabel,
5
+ } from '../../../types/common';
6
+ import Logger from '../../Logger';
7
+ import { MEDIASOUP_EVENTS } from '../../../constants/events';
8
+ import PeerConsumer from '../../PeerConsumer';
9
+ import Engine from '../../index';
10
+
11
+ interface PeerTrackConstructor {
12
+ mediaStreamTrack: MediaStreamTrack,
13
+ label: TrackLabel,
14
+ consumer?: PeerConsumer,
15
+ engine: Engine,
16
+ }
17
+
18
+ class PeerTrack {
19
+ public readonly mediaStreamTrack: MediaStreamTrack;
20
+
21
+ public readonly label: TrackLabel = TrackLabel.Unknown;
22
+
23
+ readonly consumer?: PeerConsumer;
24
+
25
+ readonly #engine: Engine;
26
+
27
+ readonly #logger = new Logger('PeerTrack');
28
+
29
+ constructor(payload: PeerTrackConstructor) {
30
+ this.mediaStreamTrack = payload.mediaStreamTrack;
31
+ this.label = payload.label;
32
+ this.consumer = payload.consumer;
33
+ this.#engine = payload.engine;
34
+ }
35
+
36
+ get consumerId(): string | undefined {
37
+ return this.consumer?.id;
38
+ }
39
+
40
+ get currentSpatialLayer(): number {
41
+ return this.consumer?.currentSpatialLayer || 0;
42
+ }
43
+
44
+ public close(): void {
45
+ this.consumer?.close();
46
+ }
47
+
48
+ public async pause(): Promise<void> {
49
+ if (!this.consumer) {
50
+ return;
51
+ }
52
+
53
+ if (this.consumer.paused) {
54
+ this.#logger.warn('pause()', { message: 'Already paused', peer: this, consumer: this.consumer });
55
+ return;
56
+ }
57
+
58
+ try {
59
+ await this.pauseRemoteConsumer(this.consumer.id);
60
+ this.consumer.pause();
61
+ this.#logger.debug('pause()', { peer: this, consumer: this.consumer });
62
+ } catch (err) {
63
+ this.#logger.error('pause()', err);
64
+ }
65
+ }
66
+
67
+ public async resume(): Promise<void> {
68
+ if (!this.consumer) {
69
+ return;
70
+ }
71
+
72
+ if (!this.consumer.paused) {
73
+ this.#logger.warn('resume()', { message: 'Already playing', peer: this, consumer: this.consumer });
74
+ return;
75
+ }
76
+
77
+ try {
78
+ await this.resumeRemoteConsumer(this.consumer.id);
79
+ this.consumer.resume();
80
+ this.#logger.debug('resume()', { peer: this });
81
+ } catch (err) {
82
+ this.#logger.error('resume()', err);
83
+ }
84
+ }
85
+
86
+ public async setPriority(priority: number): Promise<void> {
87
+ if (!this.consumer) {
88
+ return;
89
+ }
90
+
91
+ await this.setConsumerPriority({ consumerId: this.consumer.id, priority });
92
+ }
93
+
94
+ private async setConsumerPriority(params: SetConsumerPriorityParams): Promise<void> {
95
+ try {
96
+ await this.#engine.network.socket.request(MEDIASOUP_EVENTS.setConsumerPriority, params);
97
+ this.#logger.debug('setConsumerPriority()', { peer: this, params });
98
+ } catch (err) {
99
+ this.#logger.error('setConsumerPriority()', { peer: this, params });
100
+ throw new Error('Can`t change stream priority');
101
+ }
102
+ }
103
+
104
+ private async pauseRemoteConsumer(consumerId: string): Promise<SocketResponse> {
105
+ return this.#engine.network.socket.request(MEDIASOUP_EVENTS.pauseConsumer, { consumerId });
106
+ }
107
+
108
+ private async resumeRemoteConsumer(consumerId: string): Promise<SocketResponse> {
109
+ return this.#engine.network.socket.request(MEDIASOUP_EVENTS.resumeConsumer, { consumerId });
110
+ }
111
+
112
+ public async requestVideoPreferredLayers({ spatialLayer, temporalLayer }: PreferredLayersParams): Promise<void> {
113
+ if (!this.consumer) {
114
+ return;
115
+ }
116
+
117
+ try {
118
+ if (this.consumer.isAudio) {
119
+ this.#logger.warn('requestVideoPreferredLayers()', { message: 'Only video consumers support' });
120
+ return;
121
+ }
122
+
123
+ if (spatialLayer === this.consumer.currentSpatialLayer) {
124
+ return;
125
+ }
126
+
127
+ if (spatialLayer > this.consumer.spatialLayers) {
128
+ this.#logger.warn('requestVideoPreferredLayers()', { message: 'Invalid spatial layer' });
129
+ return;
130
+ }
131
+
132
+ if (spatialLayer > this.consumer.currentMaxSpatialLayer) {
133
+ await this.requestMaxSpatialLayer(this.consumer.id, spatialLayer);
134
+ return;
135
+ }
136
+
137
+ await this.#engine.network.socket.request(MEDIASOUP_EVENTS.consumerChangePreferredLayers, {
138
+ consumerId: this.consumer.id,
139
+ spatialLayer,
140
+ temporalLayer,
141
+ });
142
+
143
+ this.#logger.debug('requestVideoPreferredLayers()', {
144
+ peer: this,
145
+ consumer: this.consumer,
146
+ spatialLayer,
147
+ temporalLayer,
148
+ });
149
+ } catch (err) {
150
+ this.#logger.error('requestVideoPreferredLayers()', {
151
+ peer: this,
152
+ consumerId: this.consumer.id,
153
+ error: err,
154
+ });
155
+ throw new Error('Error request preferred layers');
156
+ }
157
+ }
158
+
159
+ public getVideoAvailableLayers(): SpatialLayerParams[] | undefined {
160
+ if (!this.consumer) {
161
+ return undefined;
162
+ }
163
+
164
+ if (this.consumer.isAudio) {
165
+ this.#logger.warn('getVideoAvailableLayers()', { message: 'Only video consumers support' });
166
+ return undefined;
167
+ }
168
+
169
+ return this.consumer.availableSpatialLayers;
170
+ }
171
+
172
+ private async requestMaxSpatialLayer(consumerId: string, spatialLayer: number): Promise<void> {
173
+ try {
174
+ if (!this.consumer) {
175
+ return;
176
+ }
177
+
178
+ const cantRequest = this.consumer.isAudio
179
+ || this.consumer.spatialLayers === 0
180
+ || this.consumer.currentMaxSpatialLayer === spatialLayer
181
+ || spatialLayer < this.consumer.currentMaxSpatialLayer;
182
+
183
+ if (cantRequest) {
184
+ this.#logger.warn('requestMaxSpatialLayer()', {
185
+ message: 'Can`t request this spatial layer',
186
+ consumerId,
187
+ spatialLayer,
188
+ });
189
+
190
+ return;
191
+ }
192
+
193
+ this.consumer.setRequestedSpatialLayer(spatialLayer);
194
+ await this.#engine.network.socket.request(MEDIASOUP_EVENTS.producerRequestMaxSpatialLayer, {
195
+ producerId: this.consumer.producerId,
196
+ spatialLayer,
197
+ });
198
+
199
+ this.#logger.debug('requestMaxSpatialLayer()', {
200
+ consumerId,
201
+ spatialLayer,
202
+ });
203
+ } catch (error) {
204
+ this.#logger.warn('requestMaxSpatialLayer()', {
205
+ message: 'Error request spatial layer',
206
+ consumerId,
207
+ spatialLayer,
208
+ error,
209
+ });
210
+ }
211
+ }
212
+ }
213
+
214
+ export default PeerTrack;
@@ -7,6 +7,8 @@ import TrackWithCodecOptions from './TrackWithCodecOptions';
7
7
  import TrackWithEncodings from './TrackWithEncodings';
8
8
 
9
9
  class VideoTrack extends BaseTrack implements TrackWithCodecOptions, TrackWithEncodings {
10
+ public transformParams = {};
11
+
10
12
  getEncoderConfig(): VideoEncoderConfig {
11
13
  return this.encoderConfig;
12
14
  }
@@ -24,6 +26,34 @@ class VideoTrack extends BaseTrack implements TrackWithCodecOptions, TrackWithEn
24
26
  getEncodings(): RtpEncodingParameters[] {
25
27
  return this.getEncoderConfig().encodings || WEBCAM_SIMULCAST_ENCODINGS;
26
28
  }
29
+
30
+ setTransformParams(transformParams: { }) {
31
+ this.transformParams = transformParams;
32
+ }
33
+
34
+ async setMaxSpatialLayer(spatialLayer: number): Promise<void> {
35
+ const producer = this.getProducer();
36
+ if (!producer) {
37
+ this.logger.warn('setMaxSpatialLayer()', { message: 'Not produced yet' });
38
+ return;
39
+ }
40
+
41
+ await producer.setMaxSpatialLayer(spatialLayer);
42
+ this.logger.debug('setMaxSpatialLayer()', {
43
+ label: this.getLabel(),
44
+ spatialLayer,
45
+ });
46
+ }
47
+
48
+ getMaxSpatialLayer(): number | undefined {
49
+ const producer = this.getProducer();
50
+ if (!producer) {
51
+ this.logger.warn('getMaxSpatialLayer()', { message: 'Not produced yet' });
52
+ return undefined;
53
+ }
54
+
55
+ return producer.maxSpatialLayer;
56
+ }
27
57
  }
28
58
 
29
59
  export default VideoTrack;
@@ -1,6 +1,6 @@
1
1
  import axios, { AxiosInstance } from 'axios';
2
2
  import qs from 'qs';
3
- import { GetNodeResponse } from '../../types/common';
3
+ import { GetNodeRequest, GetNodeResponse } from '../../types/network';
4
4
 
5
5
  export type LoadBalancerApiClientParams = {
6
6
  baseURL?: string;
@@ -24,13 +24,13 @@ class LoadBalancerApiClient {
24
24
  this.customNode = customNode;
25
25
  }
26
26
 
27
- async getNode({ channelId }: { channelId: string }): Promise<GetNodeResponse> {
27
+ async getNode(params: GetNodeRequest): Promise<GetNodeResponse> {
28
28
  if (this.customNode) {
29
29
  return this.customNode;
30
30
  }
31
31
 
32
32
  const { data } = await this.api.get<GetNodeResponse>('/nodes/best', {
33
- params: { channelId },
33
+ params,
34
34
  });
35
35
 
36
36
  return data;
@@ -13,21 +13,32 @@ export type SocketResponse = {
13
13
  [key: string]: unknown;
14
14
  };
15
15
 
16
- export type GetNodeResponse = {
17
- webSocketUrl: string;
18
- };
19
-
20
16
  export type ProduceParams = {
21
17
  kind: MediaKind,
22
18
  rtpParameters: RtpParameters,
23
19
  appData: Record<string, unknown>,
24
20
  };
25
21
 
22
+ export type TrackTransformParams = {
23
+ width?: number,
24
+ height?: number,
25
+ };
26
+
26
27
  export type ProducerData = {
27
28
  id: string,
28
29
  kind: MediaKind,
29
30
  peerId: string,
30
31
  label: TrackLabel,
32
+ encodings: RtpEncodingParameters[],
33
+ trackTransformParams: TrackTransformParams,
34
+ maxSpatialLayer: number,
35
+ };
36
+
37
+ export type ConsumerData = {
38
+ producerData: ProducerData,
39
+ peerId: string,
40
+ appId: string,
41
+ channelId: string,
31
42
  };
32
43
 
33
44
  export type Role = 'audience' | 'host';
@@ -51,9 +62,9 @@ export type JoinChannelParams = {
51
62
  channelId: string,
52
63
  appId: string,
53
64
  sdkSecret: string,
65
+ role: Role,
54
66
  uid?: string,
55
67
  appData?: Record<string, unknown>,
56
- role: Role,
57
68
  };
58
69
 
59
70
  export type ChannelEvent = {
@@ -210,4 +221,21 @@ export type CreateVideoTrackParams = {
210
221
  frameRate?: { max?: number, min?: number, ideal?: number };
211
222
  },
212
223
  encoderConfig: VideoEncoderConfig,
224
+ transformParams: TransformParams,
225
+ };
226
+
227
+ export type SpatialLayerParams = RtpEncodingParameters & TransformParams;
228
+
229
+ export type ProducerRequestMaxSpatialLayer = {
230
+ producerId: string,
231
+ spatialLayer: number,
232
+ };
233
+
234
+ export type ProducerSetMaxSpatialLayer = ProducerRequestMaxSpatialLayer & {
235
+ peerId: string,
236
+ };
237
+
238
+ export type TransformParams = {
239
+ width?: number,
240
+ height?: number,
213
241
  };
@@ -0,0 +1,10 @@
1
+ import { Role } from './common';
2
+
3
+ export type GetNodeRequest = {
4
+ channelId: string;
5
+ role: Role;
6
+ };
7
+
8
+ export type GetNodeResponse = {
9
+ webSocketUrl: string;
10
+ };
@@ -1,6 +0,0 @@
1
- import { Consumer as MediasoupConsumer } from 'mediasoup-client/lib/types';
2
- declare class Consumer extends MediasoupConsumer {
3
- score: number;
4
- producerScore: number;
5
- }
6
- export default Consumer;
@@ -1,14 +0,0 @@
1
- import { Consumer as MediasoupConsumer } from 'mediasoup-client/lib/types';
2
- import Consumer from './Consumer';
3
- declare class VideoConsumer extends Consumer {
4
- spatialLayers: number;
5
- temporalLayers: number;
6
- currentSpatialLayer: number;
7
- currentTemporalLayer: number;
8
- private readonly logger;
9
- constructor(consumer: MediasoupConsumer);
10
- parseScalabilityMode(): void;
11
- setCurrentSpatialLayer(currentSpatialLayer: number): void;
12
- setCurrentTemporalLayer(currentTemporalLayer: number): void;
13
- }
14
- export default VideoConsumer;
@@ -1,9 +0,0 @@
1
- import { Consumer as MediasoupConsumer } from 'mediasoup-client/lib/types';
2
-
3
- class Consumer extends MediasoupConsumer {
4
- public score = 10;
5
-
6
- public producerScore = 10;
7
- }
8
-
9
- export default Consumer;