@livedigital/client 3.48.0 → 3.49.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/encodings.d.ts +3 -3
- package/dist/constants/encodings.ts +3 -3
- package/dist/engine/handlers/ChannelAudioObserverEventHandler.d.ts +3 -1
- package/dist/engine/handlers/ChannelAudioObserverMissingProducerRestorer.d.ts +10 -0
- package/dist/engine/handlers/MediaEventHandler.d.ts +0 -1
- package/dist/engine/index.d.ts +7 -4
- package/dist/engine/network/DatachannelHeartbeater.d.ts +2 -2
- package/dist/engine/network/NetworkTransportPolicyManager.d.ts +22 -0
- package/dist/engine/network/index.d.ts +10 -8
- package/dist/index.d.ts +2 -0
- package/dist/index.es.js +2 -2
- package/dist/index.js +2 -2
- package/dist/inversify.tokens.d.ts +3 -1
- package/dist/types/network.d.ts +6 -6
- package/package.json +2 -3
- package/src/ClientMetaProvider.ts +0 -41
- package/src/EnhancedEventEmitter.ts +0 -75
- package/src/config/ConfigService.ts +0 -66
- package/src/constants/common.ts +0 -85
- package/src/constants/encodings.ts +0 -26
- package/src/constants/events.ts +0 -126
- package/src/constants/mutex.ts +0 -6
- package/src/constants/stats.ts +0 -1
- package/src/constants/videoConstrains.ts +0 -21
- package/src/engine/CallState.ts +0 -19
- package/src/engine/ChannelStateSynchronizer/ChannelStateSynchronizer.ts +0 -448
- package/src/engine/ChannelStateSynchronizer/types.ts +0 -22
- package/src/engine/EventsQueue.ts +0 -255
- package/src/engine/IntegrationsService.ts +0 -163
- package/src/engine/LocalMutex.ts +0 -45
- package/src/engine/Logger.ts +0 -234
- package/src/engine/MyPeer.ts +0 -25
- package/src/engine/Peer.ts +0 -602
- package/src/engine/PeerConsumer.ts +0 -276
- package/src/engine/PeerProducer.ts +0 -50
- package/src/engine/Peers.ts +0 -150
- package/src/engine/PeersStorage.ts +0 -45
- package/src/engine/RemotePeerTracks.ts +0 -73
- package/src/engine/WIDHandler.ts +0 -166
- package/src/engine/WebRTCStats/ConnectionStatsManager.ts +0 -31
- package/src/engine/WebRTCStats/InboundTrackStatsManager.ts +0 -51
- package/src/engine/WebRTCStats/OutboudTrackStatsManager.ts +0 -51
- package/src/engine/WebRTCStats/StatsHandler.ts +0 -80
- package/src/engine/WebRTCStats/TransportsStatsProvider.ts +0 -123
- package/src/engine/WebRTCStats/types.ts +0 -20
- package/src/engine/analyticsApiClient/LogApi.ts +0 -24
- package/src/engine/analyticsApiClient/MetricsApi.ts +0 -30
- package/src/engine/analyticsApiClient/helper.ts +0 -88
- package/src/engine/analyticsApiClient/index.ts +0 -42
- package/src/engine/analyticsApiClient/types.ts +0 -33
- package/src/engine/handlers/ChannelAudioObserverEventHandler.ts +0 -177
- package/src/engine/handlers/ChannelEventHandler.ts +0 -268
- package/src/engine/handlers/ChannelStateSyncEventHandler/ChannelStateConsistencyCheckResult.ts +0 -31
- package/src/engine/handlers/ChannelStateSyncEventHandler/ChannelStateConsistencyChecker.ts +0 -146
- package/src/engine/handlers/ChannelStateSyncEventHandler/consts.ts +0 -7
- package/src/engine/handlers/ChannelStateSyncEventHandler/index.ts +0 -342
- package/src/engine/handlers/ChannelStateSyncEventHandler/types.ts +0 -21
- package/src/engine/handlers/MediaEventHandler.ts +0 -273
- package/src/engine/index.ts +0 -793
- package/src/engine/media/index.ts +0 -574
- package/src/engine/media/producer/PendingClosureProducerStorage.ts +0 -37
- package/src/engine/media/producer/ProducerCloseManager.ts +0 -115
- package/src/engine/media/streamEffects/ProcessorsCache.ts +0 -41
- package/src/engine/media/streamEffects/audio/AudioTrackProcessor.ts +0 -7
- package/src/engine/media/streamEffects/audio/asdk/ASDKTrackProcessor.ts +0 -275
- package/src/engine/media/streamEffects/audio/asdk/atsrb.d.ts +0 -36
- package/src/engine/media/streamEffects/audio/asdk/errorBus.d.ts +0 -47
- package/src/engine/media/streamEffects/audio/noiseSuppression/NoiseSuppressionAudioWorkletNode.ts +0 -35
- package/src/engine/media/streamEffects/audio/noiseSuppression/NoiseSuppressionNodeProvider.ts +0 -44
- package/src/engine/media/streamEffects/audio/noiseSuppression/NoiseSuppressionScriptProcessorNode.ts +0 -69
- package/src/engine/media/streamEffects/audio/noiseSuppression/RNNoiseTrackProcessor.ts +0 -134
- package/src/engine/media/streamEffects/audio/noiseSuppression/WasmModuleCompiler.ts +0 -9
- package/src/engine/media/streamEffects/video/esdk/TrackProcessor.ts +0 -386
- package/src/engine/media/streamEffects/video/esdk/components/component.d.ts +0 -35
- package/src/engine/media/streamEffects/video/esdk/components/countdown/countdown.d.ts +0 -27
- package/src/engine/media/streamEffects/video/esdk/components/lower-third/collection/doubleSlideRect.d.ts +0 -33
- package/src/engine/media/streamEffects/video/esdk/components/lower-third/collection/horizontalMirror.d.ts +0 -29
- package/src/engine/media/streamEffects/video/esdk/components/lower-third/collection/leftTextbox.d.ts +0 -31
- package/src/engine/media/streamEffects/video/esdk/components/lower-third/collection/slideBold.d.ts +0 -41
- package/src/engine/media/streamEffects/video/esdk/components/lower-third/collection/twoSideRects/animatedBox.d.ts +0 -59
- package/src/engine/media/streamEffects/video/esdk/components/lower-third/collection/twoSideRects/twoSlideRects.d.ts +0 -27
- package/src/engine/media/streamEffects/video/esdk/components/lower-third/lowerThird.d.ts +0 -83
- package/src/engine/media/streamEffects/video/esdk/components/overlay-screen/overlayScreen.d.ts +0 -40
- package/src/engine/media/streamEffects/video/esdk/components/overlay-screen/overlaySprite.d.ts +0 -10
- package/src/engine/media/streamEffects/video/esdk/components/stickers/stickerSprite.d.ts +0 -51
- package/src/engine/media/streamEffects/video/esdk/components/stickers/stickers.d.ts +0 -54
- package/src/engine/media/streamEffects/video/esdk/components/utils/positionHelper.d.ts +0 -14
- package/src/engine/media/streamEffects/video/esdk/components/waterMark/waterMark.d.ts +0 -20
- package/src/engine/media/streamEffects/video/esdk/tsvb.d.ts +0 -187
- package/src/engine/media/streamEffects/video/esdk/utils/errorBus.d.ts +0 -42
- package/src/engine/media/tracks/DefaultAudioTrack.ts +0 -178
- package/src/engine/media/tracks/DefaultBaseTrack.ts +0 -592
- package/src/engine/media/tracks/DefaultVideoTrack.ts +0 -301
- package/src/engine/media/tracks/MediaStreamTrackManager.ts +0 -50
- package/src/engine/media/tracks/PeerTrack.ts +0 -558
- package/src/engine/network/DataChannelsManager.ts +0 -164
- package/src/engine/network/DatachannelHeartbeater.ts +0 -122
- package/src/engine/network/SignalingHeartbeater.ts +0 -55
- package/src/engine/network/index.ts +0 -961
- package/src/engine/signalingApiClient/SignalingApiClient.ts +0 -95
- package/src/engine/signalingApiClient/api.ts +0 -2289
- package/src/engine/system/index.ts +0 -221
- package/src/errors/AlreadyConnectedError.ts +0 -11
- package/src/errors/AlreadyCreatedError.ts +0 -11
- package/src/errors/ForbiddenError.ts +0 -11
- package/src/errors/InvalidPayloadError.ts +0 -11
- package/src/errors/InvalidRequestError.ts +0 -11
- package/src/errors/LivedigitalSDKError.ts +0 -15
- package/src/errors/NeedJoinFirstError.ts +0 -11
- package/src/errors/NotFoundError.ts +0 -11
- package/src/errors/OperationError.ts +0 -47
- package/src/errors/RequestError.ts +0 -11
- package/src/errors/TimeoutError.ts +0 -11
- package/src/errors/TooManyRequestsError.ts +0 -11
- package/src/errors/UnauthorizedError.ts +0 -11
- package/src/errors/UnsupportedError.ts +0 -15
- package/src/errors/signalingApiErrorMapper.ts +0 -143
- package/src/helpers/appDataValidator.ts +0 -21
- package/src/helpers/browser.ts +0 -37
- package/src/helpers/channelMessageConverter.ts +0 -124
- package/src/helpers/common.ts +0 -96
- package/src/helpers/datetime.ts +0 -11
- package/src/helpers/errors.ts +0 -25
- package/src/helpers/filterStatsCodecs.ts +0 -3
- package/src/helpers/loader.ts +0 -59
- package/src/helpers/media.ts +0 -57
- package/src/helpers/peer.ts +0 -19
- package/src/helpers/randomString.ts +0 -18
- package/src/helpers/retry.ts +0 -74
- package/src/index.ts +0 -171
- package/src/inversify.config.ts +0 -333
- package/src/inversify.factories.ts +0 -191
- package/src/inversify.tokens.ts +0 -42
- package/src/proto/.gitkeep +0 -0
- package/src/proto/generated/channel/channel_activity_confirmation_time.ts +0 -110
- package/src/proto/generated/channel/channel_management_event.ts +0 -213
- package/src/proto/generated/channel/channel_produce_permissions.ts +0 -171
- package/src/proto/generated/channel/channel_state.ts +0 -94
- package/src/proto/generated/channel/channel_state_short.ts +0 -282
- package/src/proto/generated/channel_message/channel_event.ts +0 -401
- package/src/proto/generated/channel_message/channel_message.ts +0 -139
- package/src/proto/generated/channel_message/media_event.ts +0 -290
- package/src/proto/generated/consumer/consumer.ts +0 -167
- package/src/proto/generated/google/protobuf/struct.ts +0 -588
- package/src/proto/generated/google/protobuf/timestamp.ts +0 -229
- package/src/proto/generated/peer/peer.ts +0 -430
- package/src/proto/generated/peer/peer_group.ts +0 -48
- package/src/proto/generated/peer/peer_role.ts +0 -48
- package/src/proto/generated/producer/producer.ts +0 -204
- package/src/proto/generated/producer/producer_kind.ts +0 -48
- package/src/proto/generated/producer/producer_label.ts +0 -78
- package/src/proto/generated/producer/producer_spatial_layer_request.ts +0 -116
- package/src/proto/generated/transport/transport_connection_timeout.ts +0 -156
- package/src/proto/generated/transport/transport_connection_timeout_reason.ts +0 -48
- package/src/proto/generated/transport/transport_direction.ts +0 -48
- package/src/types/channelAudioObserver.ts +0 -34
- package/src/types/channelStateSyncronizer.ts +0 -22
- package/src/types/client.ts +0 -27
- package/src/types/common.ts +0 -399
- package/src/types/container.ts +0 -31
- package/src/types/engine.ts +0 -97
- package/src/types/media.ts +0 -146
- package/src/types/mediasoup.ts +0 -10
- package/src/types/network.ts +0 -10
- package/src/types/streamEffects.ts +0 -23
|
@@ -1,276 +0,0 @@
|
|
|
1
|
-
import { parseScalabilityMode, type types } from 'mediasoup-client';
|
|
2
|
-
import { serializeError } from 'serialize-error';
|
|
3
|
-
import { SpatialLayer, TemporalLayer } from '../constants/videoConstrains';
|
|
4
|
-
import filterStatsCodecs from '../helpers/filterStatsCodecs';
|
|
5
|
-
import type {
|
|
6
|
-
ConsumerData,
|
|
7
|
-
ExtendedRTCInboundRtpStreamStats, SpatialLayerParams,
|
|
8
|
-
TrackInboundStats,
|
|
9
|
-
} from '../types/common';
|
|
10
|
-
import type Logger from './Logger';
|
|
11
|
-
|
|
12
|
-
const RESOLUTION_SCALING_FACTOR = 2;
|
|
13
|
-
const STATS_MAX_ATTEMPTS = 5;
|
|
14
|
-
const STATS_ATTEMPT_DELAY = 150;
|
|
15
|
-
|
|
16
|
-
export interface PeerConsumerDependencies {
|
|
17
|
-
loggerFactory: (namespace: string) => Logger;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
export interface PeerConsumerConstructorParams extends PeerConsumerDependencies {
|
|
21
|
-
consumer: types.Consumer;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
class PeerConsumer {
|
|
25
|
-
public spatialLayers = SpatialLayer.LOW;
|
|
26
|
-
|
|
27
|
-
public temporalLayers = TemporalLayer.BASE;
|
|
28
|
-
|
|
29
|
-
public currentSpatialLayer = SpatialLayer.LOW;
|
|
30
|
-
|
|
31
|
-
public currentTemporalLayer = TemporalLayer.BASE;
|
|
32
|
-
|
|
33
|
-
public requestedSpatialLayer?: number;
|
|
34
|
-
|
|
35
|
-
public currentMaxSpatialLayer: number;
|
|
36
|
-
|
|
37
|
-
public availableSpatialLayers: SpatialLayerParams[] = [];
|
|
38
|
-
|
|
39
|
-
public currentSpatialLayerParams?: SpatialLayerParams;
|
|
40
|
-
|
|
41
|
-
readonly id: string;
|
|
42
|
-
|
|
43
|
-
readonly kind: types.MediaKind;
|
|
44
|
-
|
|
45
|
-
readonly producerId: string;
|
|
46
|
-
|
|
47
|
-
readonly appData: ConsumerData;
|
|
48
|
-
|
|
49
|
-
private readonly consumer: types.Consumer;
|
|
50
|
-
|
|
51
|
-
readonly #logger: Logger;
|
|
52
|
-
|
|
53
|
-
constructor(params: PeerConsumerConstructorParams) {
|
|
54
|
-
const { consumer, loggerFactory } = params;
|
|
55
|
-
this.id = consumer.id;
|
|
56
|
-
this.kind = consumer.kind;
|
|
57
|
-
this.producerId = consumer.producerId;
|
|
58
|
-
this.appData = consumer.appData as unknown as ConsumerData;
|
|
59
|
-
this.consumer = consumer;
|
|
60
|
-
this.#logger = loggerFactory('PeerConsumer');
|
|
61
|
-
this.currentMaxSpatialLayer = this.appData.producerData.maxSpatialLayer;
|
|
62
|
-
this.parseScalabilityMode();
|
|
63
|
-
this.initAvailableSpatialLayers();
|
|
64
|
-
this.setCurrentSpatialLayerParams();
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
get paused(): boolean {
|
|
68
|
-
return this.consumer.paused;
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
pause(): void {
|
|
72
|
-
this.consumer.pause();
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
resume(): void {
|
|
76
|
-
this.consumer.resume();
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
close(): void {
|
|
80
|
-
this.consumer.close();
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
get isVideo(): boolean {
|
|
84
|
-
return this.kind === 'video';
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
get isAudio(): boolean {
|
|
88
|
-
return this.kind === 'audio';
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
parseScalabilityMode(): void {
|
|
92
|
-
if (this.consumer.rtpParameters.encodings) {
|
|
93
|
-
const { scalabilityMode } = this.consumer.rtpParameters.encodings[0];
|
|
94
|
-
const { spatialLayers, temporalLayers } = parseScalabilityMode(scalabilityMode);
|
|
95
|
-
this.spatialLayers = spatialLayers;
|
|
96
|
-
this.temporalLayers = temporalLayers;
|
|
97
|
-
this.#logger.debug('parseScalabilityMode()', {
|
|
98
|
-
scalabilityMode,
|
|
99
|
-
spatialLayers,
|
|
100
|
-
temporalLayers,
|
|
101
|
-
});
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
initAvailableSpatialLayers(): void {
|
|
106
|
-
const { encodings, trackTransformParams } = this.appData.producerData;
|
|
107
|
-
|
|
108
|
-
if (!Array.isArray(encodings)) {
|
|
109
|
-
return;
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
this.availableSpatialLayers = encodings
|
|
113
|
-
.map((encoding): SpatialLayerParams => this
|
|
114
|
-
.tryPrepareSpatialLayerParams(encoding));
|
|
115
|
-
|
|
116
|
-
if (!trackTransformParams || this.availableSpatialLayers.length > 1 || this.spatialLayers < SpatialLayer.HIGH) {
|
|
117
|
-
this.#logger.debug('Using available spatial layers', { case: 'initAvailableSpatialLayers' });
|
|
118
|
-
|
|
119
|
-
return;
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
this.#logger.debug('Pre-generating encodings with spatial layer params', { case: 'initAvailableSpatialLayers' });
|
|
123
|
-
|
|
124
|
-
const preGeneratedEncodings: SpatialLayerParams[] = [];
|
|
125
|
-
const baseEncoding = encodings[encodings.length - 1];
|
|
126
|
-
|
|
127
|
-
// imitate encodings with spatial layers params for automatic quality switching on client side
|
|
128
|
-
for (let i = this.spatialLayers - 1; i >= 0; i -= 1) {
|
|
129
|
-
preGeneratedEncodings.push(this.tryPrepareSpatialLayerParams({
|
|
130
|
-
...baseEncoding,
|
|
131
|
-
scaleResolutionDownBy: RESOLUTION_SCALING_FACTOR ** i,
|
|
132
|
-
}));
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
this.availableSpatialLayers = preGeneratedEncodings;
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
setCurrentSpatialLayerParams(): void {
|
|
139
|
-
const { encodings } = this.appData.producerData;
|
|
140
|
-
|
|
141
|
-
if (!encodings?.[this.currentSpatialLayer]) {
|
|
142
|
-
return;
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
this.currentSpatialLayerParams = this.tryPrepareSpatialLayerParams(encodings[this.currentSpatialLayer]);
|
|
146
|
-
this.#logger.debug('setCurrentSpatialLayerParams()', { currentSpatialLayerParams: this.currentSpatialLayerParams });
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
tryPrepareSpatialLayerParams(encoding: types.RtpEncodingParameters): SpatialLayerParams {
|
|
150
|
-
const { trackTransformParams } = this.appData.producerData;
|
|
151
|
-
|
|
152
|
-
if (!trackTransformParams) {
|
|
153
|
-
return encoding;
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
const { width, height } = trackTransformParams;
|
|
157
|
-
const coefficient = encoding.scaleResolutionDownBy ?? 1;
|
|
158
|
-
|
|
159
|
-
if (width && height) {
|
|
160
|
-
return {
|
|
161
|
-
width: width / coefficient,
|
|
162
|
-
height: height / coefficient,
|
|
163
|
-
...encoding,
|
|
164
|
-
};
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
return encoding;
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
setCurrentSpatialLayer(currentSpatialLayer: number): void {
|
|
171
|
-
if (!this.isVideo) {
|
|
172
|
-
throw new Error('setCurrentSpatialLayer applies to video consumers only');
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
this.currentSpatialLayer = currentSpatialLayer;
|
|
176
|
-
this.#logger.debug('setCurrentSpatialLayer()', { currentSpatialLayer });
|
|
177
|
-
this.setCurrentSpatialLayerParams();
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
setCurrentTemporalLayer(currentTemporalLayer: number): void {
|
|
181
|
-
if (!this.isVideo) {
|
|
182
|
-
throw new Error('setCurrentTemporalLayer applies to video consumers only');
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
this.currentTemporalLayer = currentTemporalLayer;
|
|
186
|
-
this.#logger.debug('setCurrentTemporalLayer()', { currentTemporalLayer });
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
applyLayersUpdate(payload: {
|
|
190
|
-
spatialLayer?: number;
|
|
191
|
-
temporalLayer?: number;
|
|
192
|
-
}): void {
|
|
193
|
-
if (!this.isVideo) {
|
|
194
|
-
throw new Error('applyLayersUpdate applies to video consumers only');
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
const { spatialLayer, temporalLayer } = payload;
|
|
198
|
-
|
|
199
|
-
if (spatialLayer !== undefined) {
|
|
200
|
-
this.setCurrentSpatialLayer(spatialLayer);
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
if (temporalLayer !== undefined) {
|
|
204
|
-
this.setCurrentTemporalLayer(temporalLayer);
|
|
205
|
-
}
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
setRequestedSpatialLayer(spatialLayer: number | undefined): void {
|
|
209
|
-
this.requestedSpatialLayer = spatialLayer;
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
setCurrentMaxSpatialLayer(spatialLayer: number): void {
|
|
213
|
-
this.currentMaxSpatialLayer = spatialLayer;
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
async getStats(): Promise<TrackInboundStats | undefined> {
|
|
217
|
-
try {
|
|
218
|
-
return {
|
|
219
|
-
consumerId: this.consumer.id,
|
|
220
|
-
codec: this.consumer.rtpParameters.codecs.find((codec) => filterStatsCodecs(codec)),
|
|
221
|
-
dtlsState: this.consumer.rtpReceiver?.transport?.state,
|
|
222
|
-
availableSpatialLayers: this.availableSpatialLayers,
|
|
223
|
-
currentSpatialLayerParams: this.currentSpatialLayerParams,
|
|
224
|
-
requestedSpatialLayer: this.requestedSpatialLayer,
|
|
225
|
-
rtcStats: await this.getInboundRTPStreamStats(),
|
|
226
|
-
};
|
|
227
|
-
} catch (error) {
|
|
228
|
-
this.#logger.debug('getStats()', { error });
|
|
229
|
-
|
|
230
|
-
return undefined;
|
|
231
|
-
}
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
async getInboundRTPStreamStats(): Promise<ExtendedRTCInboundRtpStreamStats> {
|
|
235
|
-
return await new Promise((resolve, reject) => {
|
|
236
|
-
const getRTCStatsReport = async (attempt = 0): Promise<void> => {
|
|
237
|
-
try {
|
|
238
|
-
const rtcStatsReport = await this.consumer.getStats();
|
|
239
|
-
const inboundRTPStreamStats: ExtendedRTCInboundRtpStreamStats = Array.from(rtcStatsReport.values())
|
|
240
|
-
.find((stat) => stat.type === 'inbound-rtp');
|
|
241
|
-
|
|
242
|
-
if (!inboundRTPStreamStats && attempt < STATS_MAX_ATTEMPTS) {
|
|
243
|
-
setTimeout(() => {
|
|
244
|
-
getRTCStatsReport(attempt + 1).catch((error: unknown) => {
|
|
245
|
-
this.#logger.debug('Error getting RTCStatsReport', {
|
|
246
|
-
attempt,
|
|
247
|
-
error: serializeError(error),
|
|
248
|
-
});
|
|
249
|
-
});
|
|
250
|
-
}, STATS_ATTEMPT_DELAY);
|
|
251
|
-
|
|
252
|
-
return;
|
|
253
|
-
}
|
|
254
|
-
|
|
255
|
-
if (attempt >= STATS_MAX_ATTEMPTS && !inboundRTPStreamStats) {
|
|
256
|
-
reject(new Error('InboundRTPStreamStat not exist'));
|
|
257
|
-
}
|
|
258
|
-
|
|
259
|
-
resolve(inboundRTPStreamStats);
|
|
260
|
-
} catch (error) {
|
|
261
|
-
reject(new Error('Can not get RTCStatsReport'));
|
|
262
|
-
this.#logger.debug('getInboundRTPStreamStats()', { error });
|
|
263
|
-
}
|
|
264
|
-
};
|
|
265
|
-
|
|
266
|
-
getRTCStatsReport().catch((error: unknown) => {
|
|
267
|
-
this.#logger.debug('Error executing getRTCStatsReport', {
|
|
268
|
-
case: 'PeerConsumer',
|
|
269
|
-
error: serializeError(error),
|
|
270
|
-
});
|
|
271
|
-
});
|
|
272
|
-
});
|
|
273
|
-
}
|
|
274
|
-
}
|
|
275
|
-
|
|
276
|
-
export default PeerConsumer;
|
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
import type { MediaKind } from 'mediasoup-client/lib/RtpParameters';
|
|
2
|
-
import type { RtpEncodingParameters } from 'mediasoup-client/lib/types';
|
|
3
|
-
import type { ProducerData, TrackLabel, TrackTransformParams } from '../types/common';
|
|
4
|
-
|
|
5
|
-
class PeerProducer {
|
|
6
|
-
readonly id: string;
|
|
7
|
-
|
|
8
|
-
readonly kind: MediaKind;
|
|
9
|
-
|
|
10
|
-
readonly peerId: string;
|
|
11
|
-
|
|
12
|
-
readonly label: TrackLabel;
|
|
13
|
-
|
|
14
|
-
public paused: boolean;
|
|
15
|
-
|
|
16
|
-
readonly encodings: RtpEncodingParameters[] = [];
|
|
17
|
-
|
|
18
|
-
readonly maxSpatialLayer: number;
|
|
19
|
-
|
|
20
|
-
readonly trackTransformParams?: TrackTransformParams;
|
|
21
|
-
|
|
22
|
-
#stateChangedAt: number;
|
|
23
|
-
|
|
24
|
-
constructor(params: ProducerData) {
|
|
25
|
-
const {
|
|
26
|
-
id, kind, peerId, label, paused,
|
|
27
|
-
} = params;
|
|
28
|
-
|
|
29
|
-
this.id = id;
|
|
30
|
-
this.kind = kind;
|
|
31
|
-
this.peerId = peerId;
|
|
32
|
-
this.label = label;
|
|
33
|
-
this.paused = paused;
|
|
34
|
-
this.encodings = params.encodings;
|
|
35
|
-
this.trackTransformParams = params.trackTransformParams;
|
|
36
|
-
this.maxSpatialLayer = params.maxSpatialLayer;
|
|
37
|
-
this.#stateChangedAt = Date.now();
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
setPaused(paused: boolean): void {
|
|
41
|
-
this.paused = paused;
|
|
42
|
-
this.#stateChangedAt = Date.now();
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
getStateChangedAt(): number {
|
|
46
|
-
return this.#stateChangedAt;
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
export default PeerProducer;
|
package/src/engine/Peers.ts
DELETED
|
@@ -1,150 +0,0 @@
|
|
|
1
|
-
import { inject, injectable } from 'inversify';
|
|
2
|
-
import { CLIENT_EVENTS } from '../constants/events';
|
|
3
|
-
import EnhancedEventEmitter from '../EnhancedEventEmitter';
|
|
4
|
-
import { TOKEN } from '../inversify.tokens';
|
|
5
|
-
import {
|
|
6
|
-
PeerGroup,
|
|
7
|
-
PeerResponse,
|
|
8
|
-
ProducerData,
|
|
9
|
-
Role,
|
|
10
|
-
TrackLabel,
|
|
11
|
-
} from '../types/common';
|
|
12
|
-
import type { PeerFactory } from '../types/container';
|
|
13
|
-
import { MyPeer } from './MyPeer';
|
|
14
|
-
import Network from './network';
|
|
15
|
-
import Peer from './Peer';
|
|
16
|
-
import PeerConsumer from './PeerConsumer';
|
|
17
|
-
import PeersStorage from './PeersStorage';
|
|
18
|
-
|
|
19
|
-
export interface IPeersService {
|
|
20
|
-
has: (id: Peer['id']) => boolean;
|
|
21
|
-
get: (id: Peer['id']) => Peer | undefined;
|
|
22
|
-
remove: (id: Peer['id']) => Promise<void>;
|
|
23
|
-
all: () => Peer[];
|
|
24
|
-
hosts: () => Peer[];
|
|
25
|
-
audience: () => Peer[];
|
|
26
|
-
reset: () => Promise<void>;
|
|
27
|
-
load: (role?: Role) => Promise<void>;
|
|
28
|
-
add: (peerData: PeerResponse, emit: boolean) => Peer;
|
|
29
|
-
isModerator: (id: Peer['id'] | undefined) => boolean;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
export interface CreatePeerParams {
|
|
33
|
-
id: string;
|
|
34
|
-
channelIds: string[];
|
|
35
|
-
groups: PeerGroup[];
|
|
36
|
-
producePermissions: TrackLabel[];
|
|
37
|
-
appId: string;
|
|
38
|
-
producers: ProducerData[];
|
|
39
|
-
videoConsumer?: PeerConsumer;
|
|
40
|
-
audioConsumer?: PeerConsumer;
|
|
41
|
-
soundLevel?: number;
|
|
42
|
-
loginDate: Date;
|
|
43
|
-
uid?: string;
|
|
44
|
-
appData?: Record<string, unknown>;
|
|
45
|
-
role: Role;
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
@injectable()
|
|
49
|
-
export class Peers implements IPeersService {
|
|
50
|
-
constructor(
|
|
51
|
-
@inject(TOKEN.MyPeer) private readonly myPeer: MyPeer,
|
|
52
|
-
@inject(TOKEN.Network) private readonly network: Network,
|
|
53
|
-
@inject(TOKEN.PeerFactory) private readonly peerFactory: PeerFactory,
|
|
54
|
-
@inject(TOKEN.ClientEventEmitter) private readonly clientEventEmitter: EnhancedEventEmitter,
|
|
55
|
-
@inject(TOKEN.PeersStorage) private readonly peersStorage: PeersStorage,
|
|
56
|
-
) { }
|
|
57
|
-
|
|
58
|
-
has(id: Peer['id']): boolean {
|
|
59
|
-
return this.peersStorage.has(id);
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
private set(id: Peer['id'], peer: Peer): void {
|
|
63
|
-
if (id === this.myPeer.id) {
|
|
64
|
-
this.myPeer.set(peer);
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
this.peersStorage.set(id, peer);
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
get(id: Peer['id']): Peer | undefined {
|
|
71
|
-
return this.peersStorage.get(id);
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
private delete(id: Peer['id']): boolean {
|
|
75
|
-
if (id === this.myPeer.id) {
|
|
76
|
-
this.myPeer.delete();
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
return this.peersStorage.delete(id);
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
async remove(id: Peer['id']): Promise<void> {
|
|
83
|
-
const peer = this.get(id);
|
|
84
|
-
|
|
85
|
-
if (!peer) {
|
|
86
|
-
return;
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
await peer.reset();
|
|
90
|
-
|
|
91
|
-
this.delete(id);
|
|
92
|
-
this.clientEventEmitter.safeEmit(CLIENT_EVENTS.peerLeft, id);
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
all(): Peer[] {
|
|
96
|
-
return this.peersStorage.all();
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
hosts(): Peer[] {
|
|
100
|
-
return this.peersStorage.hosts();
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
audience(): Peer[] {
|
|
104
|
-
return this.peersStorage.audience();
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
async reset(): Promise<void> {
|
|
108
|
-
await Promise.all(this.peersStorage.all().map(async (peer) => await peer.reset()));
|
|
109
|
-
this.peersStorage.clear();
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
async load(role?: Role): Promise<void> {
|
|
113
|
-
const { peers } = await this.network.getChannelPeers(role);
|
|
114
|
-
peers
|
|
115
|
-
.filter((peer) => !this.has(peer.id))
|
|
116
|
-
.forEach((peer) => this.add(peer, false));
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
add(peerData: PeerResponse, emit = true): Peer {
|
|
120
|
-
const existingPeer = this.get(peerData.id);
|
|
121
|
-
|
|
122
|
-
if (existingPeer) {
|
|
123
|
-
return existingPeer;
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
const peer = this.peerFactory(peerData);
|
|
127
|
-
|
|
128
|
-
this.set(peer.id, peer);
|
|
129
|
-
|
|
130
|
-
if (emit) {
|
|
131
|
-
this.clientEventEmitter.safeEmit(CLIENT_EVENTS.peerJoined, peer);
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
return peer;
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
isModerator(id: Peer['id'] | undefined): boolean {
|
|
138
|
-
if (id === undefined) {
|
|
139
|
-
return false;
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
const peer = this.get(id);
|
|
143
|
-
|
|
144
|
-
if (peer) {
|
|
145
|
-
return peer.isModerator;
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
return false;
|
|
149
|
-
}
|
|
150
|
-
}
|
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
import { injectable } from 'inversify';
|
|
2
|
-
import Peer from './Peer';
|
|
3
|
-
|
|
4
|
-
@injectable()
|
|
5
|
-
class PeersStorage {
|
|
6
|
-
private readonly peers = new Map<Peer['id'], Peer>();
|
|
7
|
-
|
|
8
|
-
has(id: Peer['id']): boolean {
|
|
9
|
-
return this.peers.has(id);
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
set(id: Peer['id'], peer: Peer): void {
|
|
13
|
-
this.peers.set(id, peer);
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
get(id: Peer['id']): Peer | undefined {
|
|
17
|
-
return this.peers.get(id);
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
delete(id: Peer['id']): boolean {
|
|
21
|
-
return this.peers.delete(id);
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
all(): Peer[] {
|
|
25
|
-
return Array.from(this.peers.values());
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
hosts(): Peer[] {
|
|
29
|
-
return this
|
|
30
|
-
.all()
|
|
31
|
-
.filter((peer) => peer.role === 'host');
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
audience(): Peer[] {
|
|
35
|
-
return this
|
|
36
|
-
.all()
|
|
37
|
-
.filter((peer) => peer.role === 'audience');
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
clear(): void {
|
|
41
|
-
this.peers.clear();
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
export default PeersStorage;
|
|
@@ -1,73 +0,0 @@
|
|
|
1
|
-
import { inject, injectable } from 'inversify';
|
|
2
|
-
import EnhancedEventEmitter from '../EnhancedEventEmitter';
|
|
3
|
-
import { TOKEN } from '../inversify.tokens';
|
|
4
|
-
import { TrackLabel } from '../types/common';
|
|
5
|
-
import type { PeerTrackFactory } from '../types/container';
|
|
6
|
-
import PeerTrack from './media/tracks/PeerTrack';
|
|
7
|
-
import { PeerObserverEvents } from './Peer';
|
|
8
|
-
import PeerConsumer from './PeerConsumer';
|
|
9
|
-
|
|
10
|
-
export interface CreatePeerTrackParams {
|
|
11
|
-
consumer?: PeerConsumer;
|
|
12
|
-
label: TrackLabel;
|
|
13
|
-
mediaStreamTrack: MediaStreamTrack;
|
|
14
|
-
muted: boolean;
|
|
15
|
-
paused: boolean;
|
|
16
|
-
peerEventEmitter: EnhancedEventEmitter<PeerObserverEvents>;
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
@injectable()
|
|
20
|
-
export class RemotePeerTracks {
|
|
21
|
-
private readonly tracksByConsumerId = new Map<PeerTrack['consumerId'], PeerTrack>();
|
|
22
|
-
|
|
23
|
-
constructor(
|
|
24
|
-
@inject(TOKEN.PeerTrackFactory) private readonly peerTrackFactory: PeerTrackFactory,
|
|
25
|
-
) { }
|
|
26
|
-
|
|
27
|
-
register(consumerId: PeerTrack['consumerId'], track: PeerTrack): void {
|
|
28
|
-
this.tracksByConsumerId.set(consumerId, track);
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
get(consumerId: PeerTrack['consumerId']): PeerTrack | undefined {
|
|
32
|
-
return this.tracksByConsumerId.get(consumerId);
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
delete(consumerId: PeerTrack['consumerId']): boolean {
|
|
36
|
-
return this.tracksByConsumerId.delete(consumerId);
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
reset(): void {
|
|
40
|
-
this.tracksByConsumerId.clear();
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
create(params: CreatePeerTrackParams): PeerTrack {
|
|
44
|
-
const {
|
|
45
|
-
consumer,
|
|
46
|
-
label,
|
|
47
|
-
muted = false,
|
|
48
|
-
mediaStreamTrack,
|
|
49
|
-
paused,
|
|
50
|
-
peerEventEmitter,
|
|
51
|
-
} = params;
|
|
52
|
-
|
|
53
|
-
const peerTrack = this.peerTrackFactory({
|
|
54
|
-
consumer,
|
|
55
|
-
label,
|
|
56
|
-
mediaStreamTrack,
|
|
57
|
-
paused,
|
|
58
|
-
peerEventEmitter,
|
|
59
|
-
muted,
|
|
60
|
-
onClose: () => {
|
|
61
|
-
if (peerTrack.consumerId !== undefined) {
|
|
62
|
-
this.delete(peerTrack.consumerId);
|
|
63
|
-
}
|
|
64
|
-
},
|
|
65
|
-
});
|
|
66
|
-
|
|
67
|
-
if (peerTrack.consumerId !== undefined) { // only register remote tracks
|
|
68
|
-
this.register(peerTrack.consumerId, peerTrack);
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
return peerTrack;
|
|
72
|
-
}
|
|
73
|
-
}
|