@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.
- package/dist/engine/index.d.ts +1 -0
- package/dist/engine/media/tracks/BaseTrack.d.ts +2 -0
- package/dist/engine/media/tracks/TrackMediaStreamManager.d.ts +11 -0
- package/dist/index.es.js +1 -1
- package/dist/index.js +1 -1
- package/dist/types/common.d.ts +4 -0
- package/package.json +1 -1
- package/src/engine/index.ts +20 -17
- package/src/engine/media/index.ts +10 -4
- package/src/engine/media/tracks/BaseTrack.ts +16 -5
- package/src/engine/media/tracks/TrackMediaStreamManager.ts +41 -0
- package/src/types/common.ts +5 -0
package/dist/types/common.d.ts
CHANGED
|
@@ -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
package/src/engine/index.ts
CHANGED
|
@@ -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
|
-
|
|
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?.
|
|
471
|
+
peerTrack?.close();
|
|
485
472
|
});
|
|
486
473
|
|
|
487
474
|
this.clientEventEmitter.on(INTERNAL_CLIENT_EVENTS.trackResumed, (track: Track) => {
|
|
488
|
-
|
|
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,
|
|
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:
|
|
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,
|
|
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
|
|
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
|
-
|
|
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;
|
package/src/types/common.ts
CHANGED
|
@@ -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
|
};
|