@livedigital/client 2.25.0 → 2.26.0-stop-streams.1

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.
@@ -304,6 +304,10 @@ export declare type UpdatePeerAppDataPayload = {
304
304
  peerId: string;
305
305
  appData: Record<string, unknown>;
306
306
  };
307
+ export declare type CreateTracksPayload = {
308
+ stream: MediaStream;
309
+ constraints: MediaStreamConstraints;
310
+ };
307
311
  export declare type TrackPublishParams = {
308
312
  keyFrameRequestDelay?: number;
309
313
  };
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@livedigital/client",
3
3
  "author": "vlprojects",
4
4
  "license": "MIT",
5
- "version": "2.25.0",
5
+ "version": "2.26.0-stop-streams.1",
6
6
  "private": false,
7
7
  "bugs": {
8
8
  "url": "https://github.com/vlprojects/livedigital-sdk/issues"
@@ -457,20 +457,7 @@ class Engine {
457
457
 
458
458
  private watchClientEvents(): void {
459
459
  this.clientEventEmitter.on(INTERNAL_CLIENT_EVENTS.trackProduced, (track: Track) => {
460
- const myPeer = this.peersRepository.get(<string> this.mySocketId);
461
- if (!myPeer) {
462
- return;
463
- }
464
-
465
- const peerTrack = new PeerTrack({
466
- mediaStreamTrack: track.mediaStreamTrack,
467
- label: track.getLabel(),
468
- engine: this,
469
- isPaused: track.isPaused,
470
- peerEventEmitter: myPeer.observer,
471
- });
472
-
473
- myPeer.tracks.set(peerTrack.label, peerTrack);
460
+ this.createSelfPeerTrack(track);
474
461
  });
475
462
 
476
463
  this.clientEventEmitter.on(INTERNAL_CLIENT_EVENTS.trackUnproduced, (track: Track) => {
@@ -481,14 +468,30 @@ class Engine {
481
468
 
482
469
  this.clientEventEmitter.on(INTERNAL_CLIENT_EVENTS.trackPaused, (track: Track) => {
483
470
  const peerTrack = this.myPeer?.tracks.get(track.getLabel());
484
- peerTrack?.pause();
471
+ peerTrack?.close();
485
472
  });
486
473
 
487
474
  this.clientEventEmitter.on(INTERNAL_CLIENT_EVENTS.trackResumed, (track: Track) => {
488
- const peerTrack = this.myPeer?.tracks.get(track.getLabel());
489
- peerTrack?.resume();
475
+ this.createSelfPeerTrack(track);
490
476
  });
491
477
  }
478
+
479
+ private createSelfPeerTrack(track: Track): void {
480
+ const myPeer = this.peersRepository.get(<string> this.mySocketId);
481
+ if (!myPeer) {
482
+ return;
483
+ }
484
+
485
+ const peerTrack = new PeerTrack({
486
+ mediaStreamTrack: track.mediaStreamTrack,
487
+ label: track.getLabel(),
488
+ engine: this,
489
+ isPaused: track.isPaused,
490
+ peerEventEmitter: myPeer.observer,
491
+ });
492
+
493
+ myPeer.tracks.set(peerTrack.label, peerTrack);
494
+ }
492
495
  }
493
496
 
494
497
  export default Engine;
@@ -3,7 +3,11 @@ import { RtpCapabilities, RtpCodecCapability } from 'mediasoup-client/lib/RtpPar
3
3
  import VideoTrack from './tracks/VideoTrack';
4
4
  import AudioTrack from './tracks/AudioTrack';
5
5
  import {
6
- CreateScreenVideoTrackOptions, CreateVideoTrackParams, LogLevel, Track,
6
+ CreateScreenVideoTrackOptions,
7
+ CreateTracksPayload,
8
+ CreateVideoTrackParams,
9
+ LogLevel,
10
+ Track,
7
11
  } from '../../types/common';
8
12
  import Logger from '../Logger';
9
13
  import { VIDEO_CONSTRAINS } from '../../constants/videoConstrains';
@@ -11,6 +15,7 @@ import { SCREEN_SHARING_SIMULCAST_ENCODINGS, WEBCAM_SIMULCAST_ENCODINGS } from '
11
15
  import { CreateMediaParams } from '../../types/engine';
12
16
  import Engine from '../index';
13
17
  import EnhancedEventEmitter from '../../EnhancedEventEmitter';
18
+ import TrackMediaStreamManager from './tracks/TrackMediaStreamManager';
14
19
 
15
20
  class Media {
16
21
  public isDeviceLoaded = false;
@@ -62,7 +67,7 @@ class Media {
62
67
  return codecs.find((c) => c.mimeType.toLowerCase() === `${track.kind}/${track.getPreferredCodec()}`);
63
68
  }
64
69
 
65
- private createTracks(stream: MediaStream): Track[] {
70
+ private createTracks({ constraints, stream }: CreateTracksPayload): Track[] {
66
71
  const mediaStreamTracks = stream.getTracks();
67
72
  return mediaStreamTracks.map((mediaStreamTrack) => {
68
73
  const params = {
@@ -70,6 +75,7 @@ class Media {
70
75
  logLevel: this.#logLevel,
71
76
  engine: this.#engine,
72
77
  clientEventEmitter: this.#clientEventEmitter,
78
+ mediaStreamManager: new TrackMediaStreamManager(constraints),
73
79
  };
74
80
 
75
81
  const track = mediaStreamTrack.kind === 'audio' ? new AudioTrack(params) : new VideoTrack(params);
@@ -87,12 +93,12 @@ class Media {
87
93
  async createUserMediaTracks(constraints: MediaStreamConstraints): Promise<Track[]> {
88
94
  const stream = await navigator.mediaDevices.getUserMedia(constraints);
89
95
  this.#logger.debug('createUserMediaTrack() stream created', { streamId: stream.id });
90
- return this.createTracks(stream);
96
+ return this.createTracks({ stream, constraints });
91
97
  }
92
98
 
93
99
  async createDisplayMediaTracks(constraints: MediaStreamConstraints): Promise<Track[]> {
94
100
  const stream = await navigator.mediaDevices.getDisplayMedia(constraints);
95
- return this.createTracks(stream);
101
+ return this.createTracks({ stream, constraints });
96
102
  }
97
103
 
98
104
  deleteTrack(track: Track) {
@@ -5,27 +5,30 @@ import {
5
5
  EncoderConfig,
6
6
  LogLevel,
7
7
  SocketResponse,
8
- TrackLabel, TrackOutboundStats,
8
+ TrackLabel,
9
+ TrackOutboundStats,
9
10
  TrackProduceParams,
10
11
  } from '../../../types/common';
11
12
  import Logger from '../../Logger';
12
13
  import Engine from '../../index';
13
14
  import PeerConsumer from '../../PeerConsumer';
14
15
  import { PRODUCER_CHECK_STATE_TIMEOUT } from '../../../constants/common';
15
- import Timeout = NodeJS.Timeout;
16
- import { MEDIASOUP_EVENTS, INTERNAL_CLIENT_EVENTS, CLIENT_EVENTS } from '../../../constants/events';
16
+ import { CLIENT_EVENTS, INTERNAL_CLIENT_EVENTS, MEDIASOUP_EVENTS } from '../../../constants/events';
17
17
  import EnhancedEventEmitter from '../../../EnhancedEventEmitter';
18
18
  import filterStatsCodecs from '../../../helpers/filterStatsCodecs';
19
+ import Timeout = NodeJS.Timeout;
20
+ import TrackMediaStreamManager from './TrackMediaStreamManager';
19
21
 
20
22
  export type BaseTrackConstructorParams = {
21
23
  mediaStreamTrack: MediaStreamTrack,
22
24
  logLevel: LogLevel,
23
25
  engine: Engine,
24
26
  clientEventEmitter: EnhancedEventEmitter,
27
+ mediaStreamManager: TrackMediaStreamManager,
25
28
  };
26
29
 
27
30
  class BaseTrack {
28
- readonly #mediaStreamTrack: MediaStreamTrack;
31
+ #mediaStreamTrack: MediaStreamTrack;
29
32
 
30
33
  protected encoderConfig: EncoderConfig = {};
31
34
 
@@ -47,13 +50,16 @@ class BaseTrack {
47
50
 
48
51
  #closed = false;
49
52
 
53
+ readonly #mediaStreamManager: TrackMediaStreamManager;
54
+
50
55
  constructor(params: BaseTrackConstructorParams) {
51
56
  const {
52
- mediaStreamTrack, logLevel, engine, clientEventEmitter,
57
+ mediaStreamTrack, logLevel, engine, clientEventEmitter, mediaStreamManager,
53
58
  } = params;
54
59
  this.#mediaStreamTrack = mediaStreamTrack;
55
60
  this.#engine = engine;
56
61
  this.#clientEventEmitter = clientEventEmitter;
62
+ this.#mediaStreamManager = mediaStreamManager;
57
63
  this.logger = new Logger({
58
64
  namespace: 'Track',
59
65
  logLevel,
@@ -96,6 +102,7 @@ class BaseTrack {
96
102
 
97
103
  setLabel(label: TrackLabel): void {
98
104
  this.label = label;
105
+ this.#mediaStreamManager.setLabel(label);
99
106
  }
100
107
 
101
108
  setEncoderConfig(encoderConfig: EncoderConfig): void {
@@ -366,6 +373,7 @@ class BaseTrack {
366
373
  await this.cancelProducerCheckState();
367
374
  await this.pauseRemoteProducer(this.producer.id);
368
375
  this.producer.pause();
376
+ this.#mediaStreamTrack.stop();
369
377
  this.clientEventEmitter.emit(INTERNAL_CLIENT_EVENTS.trackPaused, this);
370
378
  this.logger.debug('pause()', { track: this });
371
379
  } catch (error) {
@@ -381,6 +389,9 @@ class BaseTrack {
381
389
  }
382
390
 
383
391
  try {
392
+ const track = await this.#mediaStreamManager.getMediaStreamTrack();
393
+ this.#mediaStreamTrack = track;
394
+ await this.producer.replaceTrack({ track });
384
395
  await this.resumeRemoteProducer(this.producer.id);
385
396
  this.producer.resume();
386
397
  this.clientEventEmitter.emit(INTERNAL_CLIENT_EVENTS.trackResumed, this);
@@ -0,0 +1,41 @@
1
+ import { TrackLabel } from '../../../types/common';
2
+
3
+ class TrackMediaStreamManager {
4
+ #label = TrackLabel.Unknown;
5
+
6
+ readonly #constraints: MediaStreamConstraints;
7
+
8
+ constructor(constraints: MediaStreamConstraints) {
9
+ this.#constraints = constraints;
10
+ }
11
+
12
+ setLabel(label: TrackLabel): void {
13
+ this.#label = label;
14
+ }
15
+
16
+ async getMediaStreamTrack(): Promise<MediaStreamTrack> {
17
+ if (this.isDisplayMedia) {
18
+ return this.getDisplayMediaTrack();
19
+ }
20
+
21
+ return this.getUserMediaTrack();
22
+ }
23
+
24
+ private get isDisplayMedia(): boolean {
25
+ return [TrackLabel.ScreenVideo, TrackLabel.ScreenAudio].includes(this.#label);
26
+ }
27
+
28
+ private async getUserMediaTrack(): Promise<MediaStreamTrack> {
29
+ const stream = await navigator.mediaDevices.getUserMedia(this.#constraints);
30
+ const [track] = stream.getTracks();
31
+ return track;
32
+ }
33
+
34
+ private async getDisplayMediaTrack(): Promise<MediaStreamTrack> {
35
+ const stream = await navigator.mediaDevices.getDisplayMedia(this.#constraints);
36
+ const [track] = stream.getTracks();
37
+ return track;
38
+ }
39
+ }
40
+
41
+ export default TrackMediaStreamManager;
@@ -350,6 +350,11 @@ export type UpdatePeerAppDataPayload = {
350
350
  appData: Record<string, unknown>,
351
351
  };
352
352
 
353
+ export type CreateTracksPayload = {
354
+ stream: MediaStream,
355
+ constraints: MediaStreamConstraints,
356
+ };
357
+
353
358
  export type TrackPublishParams = {
354
359
  keyFrameRequestDelay?: number;
355
360
  };