@livedigital/client 2.24.0 → 2.25.0-add-keyframes-delay.2

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.
@@ -20,6 +20,7 @@ export declare type TrackProduceParams = {
20
20
  codecOptions?: ProducerCodecOptions;
21
21
  preferredCodec?: string;
22
22
  transformParams?: TrackTransformParams;
23
+ keyFrameRequestDelay?: number;
23
24
  };
24
25
  export declare type TrackTransformParams = {
25
26
  width?: number;
@@ -169,6 +170,10 @@ export declare type PayloadOfPublishedMedia = {
169
170
  kind: MediaKind;
170
171
  label: TrackLabel;
171
172
  };
173
+ export declare type SubscribeOptions = {
174
+ producerId: string;
175
+ paused?: boolean;
176
+ };
172
177
  export declare type PayloadOfUnpublishedMedia = PayloadOfPublishedMedia;
173
178
  export declare type ChangePreferredLayersPayload = PreferredLayersParams & {
174
179
  consumerId: string;
@@ -299,3 +304,6 @@ export declare type UpdatePeerAppDataPayload = {
299
304
  peerId: string;
300
305
  appData: Record<string, unknown>;
301
306
  };
307
+ export declare type TrackPublishParams = {
308
+ keyFrameRequestDelay?: number;
309
+ };
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@livedigital/client",
3
3
  "author": "vlprojects",
4
4
  "license": "MIT",
5
- "version": "2.24.0",
5
+ "version": "2.25.0-add-keyframes-delay.2",
6
6
  "private": false,
7
7
  "bugs": {
8
8
  "url": "https://github.com/vlprojects/livedigital-sdk/issues"
@@ -9,6 +9,7 @@ import {
9
9
  Role,
10
10
  ProducerSetMaxSpatialLayer,
11
11
  PeerInfo,
12
+ SubscribeOptions,
12
13
  } from '../types/common';
13
14
  import EnhancedEventEmitter from '../EnhancedEventEmitter';
14
15
  import Engine from './index';
@@ -118,7 +119,7 @@ class Peer {
118
119
  }));
119
120
  }
120
121
 
121
- public async subscribe(producerId: string): Promise<void> {
122
+ public async subscribe({ producerId, paused = false }: SubscribeOptions): Promise<void> {
122
123
  try {
123
124
  const producer = this.producers.get(producerId);
124
125
  if (!producer) {
@@ -132,7 +133,7 @@ class Peer {
132
133
  return;
133
134
  }
134
135
 
135
- const { consumer } = await this.engine.network.createConsumer({
136
+ const { consumer, isProducerPaused } = await this.engine.network.createConsumer({
136
137
  producerId: producer.id,
137
138
  rtpCapabilities: this.engine.media.mediasoupDevice.rtpCapabilities,
138
139
  producerPeerId: this.id,
@@ -147,9 +148,13 @@ class Peer {
147
148
  engine: this.engine,
148
149
  isPaused: true,
149
150
  peerEventEmitter: this.observer,
151
+ isProducerPaused,
150
152
  });
151
153
 
152
- await track.resume();
154
+ if (!paused) {
155
+ await track.resume();
156
+ }
157
+
153
158
  this.tracks.set(track.label, track);
154
159
  this.logger.debug(`Subscribed for ${producer.kind}`, { peer: this });
155
160
  } catch (error) {
@@ -222,6 +227,7 @@ class Peer {
222
227
  return;
223
228
  }
224
229
 
230
+ track.setIsTrackProducerPaused(true);
225
231
  await track.pause();
226
232
  });
227
233
 
@@ -231,6 +237,7 @@ class Peer {
231
237
  return;
232
238
  }
233
239
 
240
+ track.setIsTrackProducerPaused(false);
234
241
  await track.resume();
235
242
  });
236
243
 
@@ -223,6 +223,12 @@ class Engine {
223
223
  }
224
224
 
225
225
  public removePeer(peerId: string): void {
226
+ const peer = this.peersRepository.get(peerId);
227
+ if (!peer) {
228
+ return;
229
+ }
230
+
231
+ peer.tracks.forEach((track) => track.close());
226
232
  this.peersRepository.delete(peerId);
227
233
  }
228
234
 
@@ -212,6 +212,7 @@ class BaseTrack {
212
212
  codecOptions,
213
213
  trackTransformParams,
214
214
  preferredCodec,
215
+ keyFrameRequestDelay,
215
216
  },
216
217
  } = this.producer;
217
218
 
@@ -222,6 +223,7 @@ class BaseTrack {
222
223
  codecOptions,
223
224
  transformParams: trackTransformParams,
224
225
  preferredCodec,
226
+ keyFrameRequestDelay,
225
227
  });
226
228
 
227
229
  this.logger.debug('restartProducer()', { track: this });
@@ -257,6 +259,7 @@ class BaseTrack {
257
259
  }
258
260
 
259
261
  private async cancelProducerCheckState(): Promise<void> {
262
+ this.logger.debug('cancelProducerCheckState()', { track: this });
260
263
  if (this.#checkStateTimeout) {
261
264
  clearTimeout(this.#checkStateTimeout);
262
265
  }
@@ -265,7 +268,11 @@ class BaseTrack {
265
268
  }
266
269
 
267
270
  async produce({
268
- encodings, codecOptions, preferredCodec, transformParams,
271
+ encodings,
272
+ codecOptions,
273
+ preferredCodec,
274
+ transformParams,
275
+ keyFrameRequestDelay,
269
276
  }: TrackProduceParams): Promise<void> {
270
277
  if (!this.#engine.cahPublish) {
271
278
  this.logger.error('produce()', { message: 'Not enough access to produce' });
@@ -285,6 +292,7 @@ class BaseTrack {
285
292
  codecOptions,
286
293
  preferredCodec,
287
294
  codec,
295
+ keyFrameRequestDelay,
288
296
  };
289
297
 
290
298
  const producer = await this.#engine.network.sendTransport?.produce({
@@ -355,6 +363,7 @@ class BaseTrack {
355
363
  }
356
364
 
357
365
  try {
366
+ await this.cancelProducerCheckState();
358
367
  await this.pauseRemoteProducer(this.producer.id);
359
368
  this.producer.pause();
360
369
  this.clientEventEmitter.emit(INTERNAL_CLIENT_EVENTS.trackPaused, this);
@@ -375,7 +384,7 @@ class BaseTrack {
375
384
  await this.resumeRemoteProducer(this.producer.id);
376
385
  this.producer.resume();
377
386
  this.clientEventEmitter.emit(INTERNAL_CLIENT_EVENTS.trackResumed, this);
378
- this.logger.error('resume()', { track: this });
387
+ this.logger.debug('resume()', { track: this });
379
388
  } catch (error) {
380
389
  this.logger.error('resume()', { error, track: this });
381
390
  throw new Error('Can`t resume track');
@@ -20,6 +20,7 @@ interface PeerTrackConstructor {
20
20
  consumer?: PeerConsumer,
21
21
  engine: Engine,
22
22
  isPaused: boolean,
23
+ isProducerPaused?: boolean,
23
24
  peerEventEmitter: EnhancedEventEmitter,
24
25
  }
25
26
 
@@ -44,6 +45,8 @@ class PeerTrack {
44
45
 
45
46
  #closed = false;
46
47
 
48
+ #isTrackProducerPaused?: boolean;
49
+
47
50
  constructor(payload: PeerTrackConstructor) {
48
51
  this.#mediaStreamTrack = payload.mediaStreamTrack;
49
52
  this.label = payload.label;
@@ -55,6 +58,7 @@ class PeerTrack {
55
58
  });
56
59
  this.#peerEventEmitter = payload.peerEventEmitter;
57
60
  this.#paused = payload.isPaused;
61
+ this.#isTrackProducerPaused = payload.isProducerPaused;
58
62
  this.#peerEventEmitter.safeEmit(PEER_EVENTS.trackStart, this);
59
63
  }
60
64
 
@@ -131,6 +135,11 @@ class PeerTrack {
131
135
  return;
132
136
  }
133
137
 
138
+ if (this.#isTrackProducerPaused) {
139
+ this.#logger.debug('resume()', { message: 'Can not resume track, producer is paused', track: this, peer: this });
140
+ return;
141
+ }
142
+
134
143
  try {
135
144
  await this.#engine.network.resumeRemoteConsumer(this.consumer.id);
136
145
  this.consumer.resume();
@@ -428,6 +437,10 @@ class PeerTrack {
428
437
 
429
438
  clearTimeout(this.#checkStateTimeout);
430
439
  }
440
+
441
+ setIsTrackProducerPaused(value: boolean): void {
442
+ this.#isTrackProducerPaused = value;
443
+ }
431
444
  }
432
445
 
433
446
  export default PeerTrack;
@@ -1,7 +1,9 @@
1
1
  import { ProducerCodecOptions } from 'mediasoup-client/lib/Producer';
2
2
  import { RtpEncodingParameters } from 'mediasoup-client/lib/RtpParameters';
3
3
  import { WEBCAM_SIMULCAST_ENCODINGS } from '../../../constants/simulcastEncodings';
4
- import { TrackLabel, VideoCodec, VideoEncoderConfig } from '../../../types/common';
4
+ import {
5
+ TrackLabel, TrackPublishParams, VideoCodec, VideoEncoderConfig,
6
+ } from '../../../types/common';
5
7
  import BaseTrack from './BaseTrack';
6
8
  import TrackWithCodecOptions from './TrackWithCodecOptions';
7
9
  import TrackWithEncodings from './TrackWithEncodings';
@@ -65,12 +67,13 @@ class VideoTrack extends BaseTrack implements TrackWithCodecOptions, TrackWithEn
65
67
  return producer.maxSpatialLayer;
66
68
  }
67
69
 
68
- async publish(): Promise<void> {
70
+ async publish(params: TrackPublishParams = {}): Promise<void> {
69
71
  await this.produce({
70
72
  encodings: this.getEncodings(),
71
73
  preferredCodec: this.getPreferredCodec(),
72
74
  transformParams: this.transformParams,
73
75
  codecOptions: this.getCodecOptions(),
76
+ keyFrameRequestDelay: params.keyFrameRequestDelay ?? 0,
74
77
  });
75
78
 
76
79
  this.clientEventEmitter.emit(INTERNAL_CLIENT_EVENTS.trackProduced, this);
@@ -27,6 +27,7 @@ export type TrackProduceParams = {
27
27
  codecOptions?: ProducerCodecOptions,
28
28
  preferredCodec?: string,
29
29
  transformParams?: TrackTransformParams,
30
+ keyFrameRequestDelay?: number,
30
31
  };
31
32
 
32
33
  export type TrackTransformParams = {
@@ -205,6 +206,11 @@ export type PayloadOfPublishedMedia = {
205
206
  label: TrackLabel,
206
207
  };
207
208
 
209
+ export type SubscribeOptions = {
210
+ producerId: string,
211
+ paused?: boolean,
212
+ };
213
+
208
214
  export type PayloadOfUnpublishedMedia = PayloadOfPublishedMedia;
209
215
 
210
216
  export type ChangePreferredLayersPayload = PreferredLayersParams & {
@@ -343,3 +349,7 @@ export type UpdatePeerAppDataPayload = {
343
349
  peerId: string,
344
350
  appData: Record<string, unknown>,
345
351
  };
352
+
353
+ export type TrackPublishParams = {
354
+ keyFrameRequestDelay?: number;
355
+ };