@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.
Files changed (165) hide show
  1. package/dist/constants/encodings.d.ts +3 -3
  2. package/dist/constants/encodings.ts +3 -3
  3. package/dist/engine/handlers/ChannelAudioObserverEventHandler.d.ts +3 -1
  4. package/dist/engine/handlers/ChannelAudioObserverMissingProducerRestorer.d.ts +10 -0
  5. package/dist/engine/handlers/MediaEventHandler.d.ts +0 -1
  6. package/dist/engine/index.d.ts +7 -4
  7. package/dist/engine/network/DatachannelHeartbeater.d.ts +2 -2
  8. package/dist/engine/network/NetworkTransportPolicyManager.d.ts +22 -0
  9. package/dist/engine/network/index.d.ts +10 -8
  10. package/dist/index.d.ts +2 -0
  11. package/dist/index.es.js +2 -2
  12. package/dist/index.js +2 -2
  13. package/dist/inversify.tokens.d.ts +3 -1
  14. package/dist/types/network.d.ts +6 -6
  15. package/package.json +2 -3
  16. package/src/ClientMetaProvider.ts +0 -41
  17. package/src/EnhancedEventEmitter.ts +0 -75
  18. package/src/config/ConfigService.ts +0 -66
  19. package/src/constants/common.ts +0 -85
  20. package/src/constants/encodings.ts +0 -26
  21. package/src/constants/events.ts +0 -126
  22. package/src/constants/mutex.ts +0 -6
  23. package/src/constants/stats.ts +0 -1
  24. package/src/constants/videoConstrains.ts +0 -21
  25. package/src/engine/CallState.ts +0 -19
  26. package/src/engine/ChannelStateSynchronizer/ChannelStateSynchronizer.ts +0 -448
  27. package/src/engine/ChannelStateSynchronizer/types.ts +0 -22
  28. package/src/engine/EventsQueue.ts +0 -255
  29. package/src/engine/IntegrationsService.ts +0 -163
  30. package/src/engine/LocalMutex.ts +0 -45
  31. package/src/engine/Logger.ts +0 -234
  32. package/src/engine/MyPeer.ts +0 -25
  33. package/src/engine/Peer.ts +0 -602
  34. package/src/engine/PeerConsumer.ts +0 -276
  35. package/src/engine/PeerProducer.ts +0 -50
  36. package/src/engine/Peers.ts +0 -150
  37. package/src/engine/PeersStorage.ts +0 -45
  38. package/src/engine/RemotePeerTracks.ts +0 -73
  39. package/src/engine/WIDHandler.ts +0 -166
  40. package/src/engine/WebRTCStats/ConnectionStatsManager.ts +0 -31
  41. package/src/engine/WebRTCStats/InboundTrackStatsManager.ts +0 -51
  42. package/src/engine/WebRTCStats/OutboudTrackStatsManager.ts +0 -51
  43. package/src/engine/WebRTCStats/StatsHandler.ts +0 -80
  44. package/src/engine/WebRTCStats/TransportsStatsProvider.ts +0 -123
  45. package/src/engine/WebRTCStats/types.ts +0 -20
  46. package/src/engine/analyticsApiClient/LogApi.ts +0 -24
  47. package/src/engine/analyticsApiClient/MetricsApi.ts +0 -30
  48. package/src/engine/analyticsApiClient/helper.ts +0 -88
  49. package/src/engine/analyticsApiClient/index.ts +0 -42
  50. package/src/engine/analyticsApiClient/types.ts +0 -33
  51. package/src/engine/handlers/ChannelAudioObserverEventHandler.ts +0 -177
  52. package/src/engine/handlers/ChannelEventHandler.ts +0 -268
  53. package/src/engine/handlers/ChannelStateSyncEventHandler/ChannelStateConsistencyCheckResult.ts +0 -31
  54. package/src/engine/handlers/ChannelStateSyncEventHandler/ChannelStateConsistencyChecker.ts +0 -146
  55. package/src/engine/handlers/ChannelStateSyncEventHandler/consts.ts +0 -7
  56. package/src/engine/handlers/ChannelStateSyncEventHandler/index.ts +0 -342
  57. package/src/engine/handlers/ChannelStateSyncEventHandler/types.ts +0 -21
  58. package/src/engine/handlers/MediaEventHandler.ts +0 -273
  59. package/src/engine/index.ts +0 -793
  60. package/src/engine/media/index.ts +0 -574
  61. package/src/engine/media/producer/PendingClosureProducerStorage.ts +0 -37
  62. package/src/engine/media/producer/ProducerCloseManager.ts +0 -115
  63. package/src/engine/media/streamEffects/ProcessorsCache.ts +0 -41
  64. package/src/engine/media/streamEffects/audio/AudioTrackProcessor.ts +0 -7
  65. package/src/engine/media/streamEffects/audio/asdk/ASDKTrackProcessor.ts +0 -275
  66. package/src/engine/media/streamEffects/audio/asdk/atsrb.d.ts +0 -36
  67. package/src/engine/media/streamEffects/audio/asdk/errorBus.d.ts +0 -47
  68. package/src/engine/media/streamEffects/audio/noiseSuppression/NoiseSuppressionAudioWorkletNode.ts +0 -35
  69. package/src/engine/media/streamEffects/audio/noiseSuppression/NoiseSuppressionNodeProvider.ts +0 -44
  70. package/src/engine/media/streamEffects/audio/noiseSuppression/NoiseSuppressionScriptProcessorNode.ts +0 -69
  71. package/src/engine/media/streamEffects/audio/noiseSuppression/RNNoiseTrackProcessor.ts +0 -134
  72. package/src/engine/media/streamEffects/audio/noiseSuppression/WasmModuleCompiler.ts +0 -9
  73. package/src/engine/media/streamEffects/video/esdk/TrackProcessor.ts +0 -386
  74. package/src/engine/media/streamEffects/video/esdk/components/component.d.ts +0 -35
  75. package/src/engine/media/streamEffects/video/esdk/components/countdown/countdown.d.ts +0 -27
  76. package/src/engine/media/streamEffects/video/esdk/components/lower-third/collection/doubleSlideRect.d.ts +0 -33
  77. package/src/engine/media/streamEffects/video/esdk/components/lower-third/collection/horizontalMirror.d.ts +0 -29
  78. package/src/engine/media/streamEffects/video/esdk/components/lower-third/collection/leftTextbox.d.ts +0 -31
  79. package/src/engine/media/streamEffects/video/esdk/components/lower-third/collection/slideBold.d.ts +0 -41
  80. package/src/engine/media/streamEffects/video/esdk/components/lower-third/collection/twoSideRects/animatedBox.d.ts +0 -59
  81. package/src/engine/media/streamEffects/video/esdk/components/lower-third/collection/twoSideRects/twoSlideRects.d.ts +0 -27
  82. package/src/engine/media/streamEffects/video/esdk/components/lower-third/lowerThird.d.ts +0 -83
  83. package/src/engine/media/streamEffects/video/esdk/components/overlay-screen/overlayScreen.d.ts +0 -40
  84. package/src/engine/media/streamEffects/video/esdk/components/overlay-screen/overlaySprite.d.ts +0 -10
  85. package/src/engine/media/streamEffects/video/esdk/components/stickers/stickerSprite.d.ts +0 -51
  86. package/src/engine/media/streamEffects/video/esdk/components/stickers/stickers.d.ts +0 -54
  87. package/src/engine/media/streamEffects/video/esdk/components/utils/positionHelper.d.ts +0 -14
  88. package/src/engine/media/streamEffects/video/esdk/components/waterMark/waterMark.d.ts +0 -20
  89. package/src/engine/media/streamEffects/video/esdk/tsvb.d.ts +0 -187
  90. package/src/engine/media/streamEffects/video/esdk/utils/errorBus.d.ts +0 -42
  91. package/src/engine/media/tracks/DefaultAudioTrack.ts +0 -178
  92. package/src/engine/media/tracks/DefaultBaseTrack.ts +0 -592
  93. package/src/engine/media/tracks/DefaultVideoTrack.ts +0 -301
  94. package/src/engine/media/tracks/MediaStreamTrackManager.ts +0 -50
  95. package/src/engine/media/tracks/PeerTrack.ts +0 -558
  96. package/src/engine/network/DataChannelsManager.ts +0 -164
  97. package/src/engine/network/DatachannelHeartbeater.ts +0 -122
  98. package/src/engine/network/SignalingHeartbeater.ts +0 -55
  99. package/src/engine/network/index.ts +0 -961
  100. package/src/engine/signalingApiClient/SignalingApiClient.ts +0 -95
  101. package/src/engine/signalingApiClient/api.ts +0 -2289
  102. package/src/engine/system/index.ts +0 -221
  103. package/src/errors/AlreadyConnectedError.ts +0 -11
  104. package/src/errors/AlreadyCreatedError.ts +0 -11
  105. package/src/errors/ForbiddenError.ts +0 -11
  106. package/src/errors/InvalidPayloadError.ts +0 -11
  107. package/src/errors/InvalidRequestError.ts +0 -11
  108. package/src/errors/LivedigitalSDKError.ts +0 -15
  109. package/src/errors/NeedJoinFirstError.ts +0 -11
  110. package/src/errors/NotFoundError.ts +0 -11
  111. package/src/errors/OperationError.ts +0 -47
  112. package/src/errors/RequestError.ts +0 -11
  113. package/src/errors/TimeoutError.ts +0 -11
  114. package/src/errors/TooManyRequestsError.ts +0 -11
  115. package/src/errors/UnauthorizedError.ts +0 -11
  116. package/src/errors/UnsupportedError.ts +0 -15
  117. package/src/errors/signalingApiErrorMapper.ts +0 -143
  118. package/src/helpers/appDataValidator.ts +0 -21
  119. package/src/helpers/browser.ts +0 -37
  120. package/src/helpers/channelMessageConverter.ts +0 -124
  121. package/src/helpers/common.ts +0 -96
  122. package/src/helpers/datetime.ts +0 -11
  123. package/src/helpers/errors.ts +0 -25
  124. package/src/helpers/filterStatsCodecs.ts +0 -3
  125. package/src/helpers/loader.ts +0 -59
  126. package/src/helpers/media.ts +0 -57
  127. package/src/helpers/peer.ts +0 -19
  128. package/src/helpers/randomString.ts +0 -18
  129. package/src/helpers/retry.ts +0 -74
  130. package/src/index.ts +0 -171
  131. package/src/inversify.config.ts +0 -333
  132. package/src/inversify.factories.ts +0 -191
  133. package/src/inversify.tokens.ts +0 -42
  134. package/src/proto/.gitkeep +0 -0
  135. package/src/proto/generated/channel/channel_activity_confirmation_time.ts +0 -110
  136. package/src/proto/generated/channel/channel_management_event.ts +0 -213
  137. package/src/proto/generated/channel/channel_produce_permissions.ts +0 -171
  138. package/src/proto/generated/channel/channel_state.ts +0 -94
  139. package/src/proto/generated/channel/channel_state_short.ts +0 -282
  140. package/src/proto/generated/channel_message/channel_event.ts +0 -401
  141. package/src/proto/generated/channel_message/channel_message.ts +0 -139
  142. package/src/proto/generated/channel_message/media_event.ts +0 -290
  143. package/src/proto/generated/consumer/consumer.ts +0 -167
  144. package/src/proto/generated/google/protobuf/struct.ts +0 -588
  145. package/src/proto/generated/google/protobuf/timestamp.ts +0 -229
  146. package/src/proto/generated/peer/peer.ts +0 -430
  147. package/src/proto/generated/peer/peer_group.ts +0 -48
  148. package/src/proto/generated/peer/peer_role.ts +0 -48
  149. package/src/proto/generated/producer/producer.ts +0 -204
  150. package/src/proto/generated/producer/producer_kind.ts +0 -48
  151. package/src/proto/generated/producer/producer_label.ts +0 -78
  152. package/src/proto/generated/producer/producer_spatial_layer_request.ts +0 -116
  153. package/src/proto/generated/transport/transport_connection_timeout.ts +0 -156
  154. package/src/proto/generated/transport/transport_connection_timeout_reason.ts +0 -48
  155. package/src/proto/generated/transport/transport_direction.ts +0 -48
  156. package/src/types/channelAudioObserver.ts +0 -34
  157. package/src/types/channelStateSyncronizer.ts +0 -22
  158. package/src/types/client.ts +0 -27
  159. package/src/types/common.ts +0 -399
  160. package/src/types/container.ts +0 -31
  161. package/src/types/engine.ts +0 -97
  162. package/src/types/media.ts +0 -146
  163. package/src/types/mediasoup.ts +0 -10
  164. package/src/types/network.ts +0 -10
  165. package/src/types/streamEffects.ts +0 -23
@@ -1,25 +0,0 @@
1
- import { injectable } from 'inversify';
2
- import Peer from './Peer';
3
-
4
- @injectable()
5
- export class MyPeer {
6
- id?: Peer['id'];
7
-
8
- private peer?: Peer;
9
-
10
- get(): Peer | undefined {
11
- return this.peer;
12
- }
13
-
14
- set(peer: Peer): void {
15
- this.peer = peer;
16
- }
17
-
18
- delete(): void {
19
- this.peer = undefined;
20
- }
21
-
22
- get canPublish(): boolean {
23
- return this.peer?.role === 'host';
24
- }
25
- }
@@ -1,602 +0,0 @@
1
- import { serializeError } from 'serialize-error';
2
- import {
3
- CHANNEL_EVENTS, MEDIASOUP_EVENTS, PEER_EVENTS,
4
- } from '../constants/events';
5
- import EnhancedEventEmitter from '../EnhancedEventEmitter';
6
- import OperationError from '../errors/OperationError';
7
- import validateAppData from '../helpers/appDataValidator';
8
- import { logResponse } from '../helpers/peer';
9
- import {
10
- type ChangePreferredLayersPayload, type PayloadOfPublishedMedia,
11
- type PayloadOfUnpublishedMedia, type PeerGroup, type PeerInfo, type PeerShortData, type ProducerData,
12
- type ProducerSetMaxSpatialLayer, type Role, type SubscribeOptions, TrackLabel, type TrackLabelString,
13
- } from '../types/common';
14
- import type { PeerConsumerFactory } from '../types/container';
15
- import type { GroupsChangedPayload, ProducePermissionsChangedPayload } from '../types/engine';
16
- import type { CallState } from './CallState';
17
- import type Logger from './Logger';
18
- import type Media from './media';
19
- import type PeerTrack from './media/tracks/PeerTrack';
20
- import type { MyPeer } from './MyPeer';
21
- import type Network from './network';
22
- import type PeerConsumer from './PeerConsumer';
23
- import PeerProducer from './PeerProducer';
24
- import type { Peers } from './Peers';
25
- import type { RemotePeerTracks } from './RemotePeerTracks';
26
-
27
- export interface PeerDependencies {
28
- callState: CallState;
29
- loggerFactory: (namespace: string) => Logger;
30
- media: Media;
31
- myPeer: MyPeer;
32
- network: Network;
33
- peers: Peers;
34
- remotePeerTracks: RemotePeerTracks;
35
- peerConsumerFactory: PeerConsumerFactory;
36
- }
37
-
38
- interface PeerConstructor extends PeerDependencies {
39
- id: string;
40
- channelIds: string[];
41
- groups: PeerGroup[];
42
- producePermissions: TrackLabel[];
43
- appId: string;
44
- producers: ProducerData[];
45
- videoConsumer?: PeerConsumer;
46
- audioConsumer?: PeerConsumer;
47
- soundLevel?: number;
48
- loginDate: Date;
49
- uid?: string;
50
- appData?: Record<string, unknown>;
51
- role: Role;
52
- }
53
-
54
- export interface PeerObserverEvents {
55
- [PEER_EVENTS.mediaPublished]: [PayloadOfPublishedMedia];
56
- [PEER_EVENTS.appDataUpdated]: [Record<string, unknown>];
57
- [PEER_EVENTS.connectionQualityChanged]: [{ connectionQuality: number }];
58
- [PEER_EVENTS.publisherPaused]: [PayloadOfPublishedMedia];
59
- [PEER_EVENTS.publisherResumed]: [PayloadOfPublishedMedia];
60
- [PEER_EVENTS.mediaUnPublished]: [PayloadOfUnpublishedMedia];
61
- [PEER_EVENTS.trackStart]: [PeerTrack];
62
- [PEER_EVENTS.trackEnd]: [PeerTrack];
63
- [PEER_EVENTS.trackResumed]: [PeerTrack];
64
- [PEER_EVENTS.trackPaused]: [PeerTrack];
65
- [PEER_EVENTS.trackFailed]: [PeerTrack];
66
- [PEER_EVENTS.producePermissionsChanged]: [ProducePermissionsChangedPayload];
67
- [PEER_EVENTS.groupsChanged]: [GroupsChangedPayload];
68
- [MEDIASOUP_EVENTS.producerClose]: [ProducerData];
69
- [MEDIASOUP_EVENTS.newProducer]: [ProducerData];
70
- [MEDIASOUP_EVENTS.closeConsumer]: [consumerId: string];
71
- [MEDIASOUP_EVENTS.pauseConsumer]: [consumerId: string];
72
- [MEDIASOUP_EVENTS.resumeConsumer]: [consumerId: string];
73
- [MEDIASOUP_EVENTS.consumerChangePreferredLayers]: [ChangePreferredLayersPayload];
74
- [MEDIASOUP_EVENTS.producerSetMaxSpatialLayer]: [ProducerSetMaxSpatialLayer];
75
- [CHANNEL_EVENTS.updatePeerAppData]: [Record<string, unknown>];
76
- [event: string]: unknown[];
77
- }
78
-
79
- class Peer {
80
- public id: string;
81
-
82
- public channelIds: string[];
83
-
84
- public groups: PeerGroup[];
85
-
86
- public producePermissions: TrackLabel[];
87
-
88
- public appId: string;
89
-
90
- public loginDate: Date;
91
-
92
- public uid?: string;
93
-
94
- private applicationData: Record<string, unknown>;
95
-
96
- public role: Role;
97
-
98
- producers = new Map<string, PeerProducer>();
99
-
100
- public readonly tracks = new Map<string, PeerTrack>();
101
-
102
- readonly #peers: Peers;
103
-
104
- readonly #remotePeerTracks: RemotePeerTracks;
105
-
106
- readonly #network: Network;
107
-
108
- readonly #media: Media;
109
-
110
- readonly #myPeer: MyPeer;
111
-
112
- readonly #callState: CallState;
113
-
114
- readonly #peerConsumerFactory: PeerConsumerFactory;
115
-
116
- readonly #logger: Logger;
117
-
118
- private readonly _observer = new EnhancedEventEmitter<PeerObserverEvents>();
119
-
120
- constructor({
121
- id,
122
- channelIds,
123
- groups,
124
- producePermissions,
125
- appId,
126
- loginDate,
127
- producers = [],
128
- appData,
129
- uid,
130
- role,
131
- loggerFactory,
132
- myPeer,
133
- callState,
134
- peers,
135
- remotePeerTracks,
136
- media,
137
- network,
138
- peerConsumerFactory,
139
- }: PeerConstructor) {
140
- this.id = id;
141
- this.channelIds = channelIds;
142
- this.groups = groups;
143
- this.producePermissions = producePermissions;
144
- this.appId = appId;
145
- this.loginDate = loginDate;
146
- this.applicationData = appData ?? {};
147
- this.uid = uid;
148
- this.role = role;
149
- this.#myPeer = myPeer;
150
- this.#callState = callState;
151
- this.#peers = peers;
152
- this.#remotePeerTracks = remotePeerTracks;
153
- this.#peerConsumerFactory = peerConsumerFactory;
154
- this.#network = network;
155
- this.#media = media;
156
- this.#logger = loggerFactory('Peer');
157
- producers.forEach(this.handleNewProducer.bind(this));
158
- this.handlePeerEvents();
159
- }
160
-
161
- get appData(): Record<string, unknown> {
162
- return this.applicationData;
163
- }
164
-
165
- get observer(): EnhancedEventEmitter<PeerObserverEvents> {
166
- return this._observer;
167
- }
168
-
169
- public get isMe(): boolean {
170
- return this.id === this.#myPeer.id;
171
- }
172
-
173
- public get isModerator(): boolean {
174
- return this.groups.includes('moderator');
175
- }
176
-
177
- public get isUser(): boolean {
178
- return this.groups.includes('user');
179
- }
180
-
181
- public get publishedMedia(): PayloadOfPublishedMedia[] {
182
- return Array.from(this.producers.values()).map((producer) => ({
183
- producerId: producer.id,
184
- kind: producer.kind,
185
- label: producer.label,
186
- paused: producer.paused,
187
- }));
188
- }
189
-
190
- get shortData(): PeerShortData {
191
- return {
192
- id: this.id,
193
- producers: Array.from(this.producers.values()).map((producer) => ({
194
- id: producer.id,
195
- paused: producer.paused,
196
- })),
197
- appData: this.appData,
198
- };
199
- }
200
-
201
- public hasPermission(producePermission: TrackLabel): boolean {
202
- return this.producePermissions.includes(producePermission);
203
- }
204
-
205
- public hasGroup(group: PeerGroup): boolean {
206
- return this.groups.includes(group);
207
- }
208
-
209
- public async subscribe({ producerId, muted = false }: SubscribeOptions): Promise<void> {
210
- try {
211
- const producer = this.producers.get(producerId);
212
-
213
- if (!producer) {
214
- this.#logger.warn('subscribe()',
215
- { message: 'Peer does not have a producer', peer: logResponse(this), producerId });
216
-
217
- return;
218
- }
219
-
220
- const peerConsumer = this.getAllConsumers().find((item) => item.producerId === producerId);
221
-
222
- if (peerConsumer) {
223
- this.#logger.debug('subscribe()',
224
- { message: 'Already subscribed to producer', peer: logResponse(this), producerId });
225
-
226
- return;
227
- }
228
-
229
- const { consumer, isProducerPaused } = await this.#network.createConsumer({
230
- producerId: producer.id,
231
- rtpCapabilities: this.#media.mediasoupDevice.rtpCapabilities,
232
- producerPeerId: this.id,
233
- appId: this.#callState.appId,
234
- channelId: this.#callState.channelId,
235
- });
236
-
237
- // it happens when moderator removes permissions for a track during the creating of a consumer
238
- if (!this.producePermissions.includes(producer.label) && Object.values(TrackLabel).includes(producer.label)) {
239
- this.#logger.debug('subscribe()',
240
- { message: 'Producer is not allowed anymore', peer: logResponse(this), producerId });
241
-
242
- return;
243
- }
244
-
245
- const track = this.#remotePeerTracks.create({
246
- mediaStreamTrack: consumer.track,
247
- label: producer.label,
248
- consumer: this.#peerConsumerFactory({
249
- consumer,
250
- }),
251
- muted,
252
- paused: isProducerPaused,
253
- peerEventEmitter: this.observer,
254
- });
255
-
256
- if (!muted) {
257
- await track.unmute();
258
- }
259
-
260
- this.tracks.set(track.label, track);
261
- this.#logger.debug(`Subscribed for ${ producer.kind }`, { peer: logResponse(this) });
262
- } catch (error) {
263
- this.#logger.error('subscribe()', { producerId, error, peer: logResponse(this) });
264
- throw new OperationError('peer_subscribe_failed', error);
265
- }
266
- }
267
-
268
- public async unsubscribe(producerId: string): Promise<void> {
269
- try {
270
- const consumer = this.getConsumerByProducerId(producerId);
271
-
272
- if (!consumer) {
273
- return;
274
- }
275
-
276
- const track = this.getTrackByConsumerId(consumer.id);
277
-
278
- if (!track) {
279
- return;
280
- }
281
-
282
- await track.close();
283
- this.tracks.delete(track.label);
284
- this.#logger.debug(`Unsubscribed consumer ${ consumer.kind }`, { peer: logResponse(this) });
285
- } catch (error) {
286
- this.#logger.error('unsubscribe()', { producerId, error });
287
- throw new OperationError('peer_unsubscribe_failed', error);
288
- }
289
- }
290
-
291
- public async setProducePermissions(producePermissions: TrackLabelString[]): Promise<void> {
292
- this.throwIfIamNotModerator();
293
-
294
- try {
295
- await this.#network.changePeerProducePermissions(this.id, producePermissions);
296
- } catch (error) {
297
- throw new OperationError('peer_set_produce_permissions_failed', error);
298
- }
299
-
300
- this.#logger.debug('Produce permissions changed', { peerId: this.id, producePermissions });
301
- }
302
-
303
- public async addProducePermission(label: TrackLabelString): Promise<void> {
304
- this.throwIfIamNotModerator();
305
-
306
- try {
307
- await this.#network.addPeerProducePermission(this.id, label);
308
- } catch (error) {
309
- throw new OperationError('peer_add_produce_permission_failed', error);
310
- }
311
-
312
- this.#logger.debug('Add produce permission requested', { peerId: this.id, label });
313
- }
314
-
315
- public async removeProducePermission(label: TrackLabelString): Promise<void> {
316
- this.throwIfIamNotModerator();
317
-
318
- try {
319
- await this.#network.removePeerProducePermission(this.id, label);
320
- } catch (error) {
321
- throw new OperationError('peer_remove_produce_permission_failed', error);
322
- }
323
-
324
- this.#logger.debug('Remove produce permission requested', { peerId: this.id, label });
325
- }
326
-
327
- async getInfo(): Promise<PeerInfo> {
328
- try {
329
- return {
330
- id: this.id,
331
- appData: this.appData,
332
- role: this.role,
333
- channelIds: this.channelIds,
334
- appId: this.appId,
335
- uid: this.uid,
336
- loginDate: this.loginDate,
337
- tracks: await Promise.all(Array.from(this.tracks.values()).map(async (track) => await track.getInfo())),
338
- };
339
- } catch (error) {
340
- this.#logger.error('getInfo()', { peer: logResponse(this), error });
341
- throw new OperationError('peer_get_info_failed', error);
342
- }
343
- }
344
-
345
- getProducers(): PeerProducer[] {
346
- return Array.from(this.producers.values());
347
- }
348
-
349
- getConsumersState(): Array<{ id: string; producerId: string; paused: boolean }> {
350
- return this.getAllConsumers().map((consumer) => ({
351
- id: consumer.id,
352
- paused: consumer.paused,
353
- producerId: consumer.producerId,
354
- }));
355
- }
356
-
357
- private handleNewProducer(producerData: ProducerData): void {
358
- if (this.producers.get(producerData.id)) {
359
- return;
360
- }
361
-
362
- const producer = new PeerProducer(producerData);
363
- this.producers.set(producer.id, producer);
364
- this.#logger.debug('Peer published media:', { peer: logResponse(this), producer });
365
- const payload: PayloadOfPublishedMedia = {
366
- producerId: producer.id,
367
- kind: producer.kind,
368
- label: producer.label,
369
- paused: producer.paused,
370
- };
371
- this.observer.safeEmit(PEER_EVENTS.mediaPublished, payload);
372
- }
373
-
374
- private handlePeerEvents(): void {
375
- this.observer.on(MEDIASOUP_EVENTS.newProducer, this.handleNewProducer.bind(this));
376
-
377
- this.observer.on(MEDIASOUP_EVENTS.producerClose, async (producer: ProducerData): Promise<void> => {
378
- this.producers.delete(producer.id);
379
- this.#logger.debug('Peer unpublished media:', { peer: logResponse(this), producer });
380
- this.observer.safeEmit(PEER_EVENTS.mediaUnPublished, {
381
- producerId: producer.id,
382
- kind: producer.kind,
383
- label: producer.label,
384
- paused: producer.paused,
385
- });
386
-
387
- const track = this.tracks.get(producer.label);
388
-
389
- if (!track) {
390
- return;
391
- }
392
-
393
- try {
394
- await track.close();
395
- } catch (error) {
396
- this.#logger.warn('Failed to close peer track due to producer closed', {
397
- label: track.label,
398
- peerId: this.id,
399
- error: serializeError(error),
400
- });
401
- }
402
- });
403
-
404
- this.observer.on(MEDIASOUP_EVENTS.closeConsumer, async (consumerId): Promise<void> => {
405
- const track = this.getTrackByConsumerId(consumerId);
406
-
407
- if (!track) {
408
- return;
409
- }
410
-
411
- await track.close();
412
- this.tracks.delete(track.label);
413
- this.#logger.debug('Peer video track was ended:', { peer: logResponse(this), track: track.logCtx });
414
- });
415
-
416
- this.observer.on(MEDIASOUP_EVENTS.pauseConsumer, async (consumerId): Promise<void> => {
417
- const track = this.getTrackByConsumerId(consumerId);
418
-
419
- if (!track) {
420
- return;
421
- }
422
-
423
- await track.pause(false);
424
- });
425
-
426
- this.observer.on(MEDIASOUP_EVENTS.resumeConsumer, async (consumerId): Promise<void> => {
427
- const track = this.getTrackByConsumerId(consumerId);
428
-
429
- if (!track) {
430
- return;
431
- }
432
-
433
- await track.resume(false);
434
- });
435
-
436
- this.observer.on(MEDIASOUP_EVENTS.consumerChangePreferredLayers, (payload: ChangePreferredLayersPayload): void => {
437
- const consumer = this.getConsumerById(payload.consumerId);
438
-
439
- if (consumer?.isVideo) {
440
- consumer.applyLayersUpdate({
441
- spatialLayer: payload.spatialLayer,
442
- temporalLayer: payload.temporalLayer,
443
- });
444
-
445
- if (payload.spatialLayer === consumer.requestedSpatialLayer) {
446
- consumer.setRequestedSpatialLayer(undefined);
447
- }
448
-
449
- this.#logger.debug('consumerChangePreferredLayers()', { ...payload });
450
- }
451
- });
452
-
453
- this.observer.on(MEDIASOUP_EVENTS.producerSetMaxSpatialLayer, async (
454
- payload: ProducerSetMaxSpatialLayer,
455
- ): Promise<void> => {
456
- const { producerId, spatialLayer } = payload;
457
- const consumer = this.getConsumerByProducerId(producerId);
458
-
459
- if (!consumer) {
460
- this.#logger.debug('producerSetMaxSpatialLayer()', {
461
- message: 'Consumer for producer not created, ignore MaxSpatialLayer change',
462
- });
463
-
464
- return;
465
- }
466
-
467
- consumer.setCurrentMaxSpatialLayer(spatialLayer);
468
- this.#logger.debug('producerSetMaxSpatialLayer()', {
469
- producerId,
470
- consumerId: consumer.id,
471
- spatialLayer,
472
- });
473
-
474
- if (consumer.requestedSpatialLayer !== spatialLayer) {
475
- this.#logger.debug('producerSetMaxSpatialLayer()', {
476
- message: 'No need to request new preferred layer',
477
- currentMaxSpatialLayer: spatialLayer,
478
- requestedMaxSpatialLayer: consumer.requestedSpatialLayer,
479
- });
480
-
481
- return;
482
- }
483
-
484
- await this.#network.updateConsumerPreferredLayers(consumer.id, spatialLayer);
485
-
486
- this.#logger.debug('requestVideoPreferredLayers()', {
487
- producerId,
488
- consumerId: consumer.id,
489
- spatialLayer,
490
- });
491
- });
492
-
493
- this.observer.on(CHANNEL_EVENTS.updatePeerAppData, (appData: Record<string, unknown>): void => {
494
- try {
495
- validateAppData(appData);
496
- this.setAppData(appData);
497
- this.observer.emit(PEER_EVENTS.appDataUpdated, appData);
498
- this.#logger.debug('updatePeerAppData', { peer: logResponse(this), appData });
499
- } catch (error) {
500
- this.#logger.error('updatePeerAppData', { peer: logResponse(this), appData, error });
501
- }
502
- });
503
- }
504
-
505
- async reset(): Promise<void> {
506
- this.producers.clear();
507
-
508
- await Promise.all(Array.from(this.tracks.values()).map(async (track): Promise<void> => await track.close()));
509
- this.tracks.clear();
510
-
511
- const eventNames = [
512
- MEDIASOUP_EVENTS.newProducer,
513
- MEDIASOUP_EVENTS.producerClose,
514
- MEDIASOUP_EVENTS.closeConsumer,
515
- MEDIASOUP_EVENTS.pauseConsumer,
516
- MEDIASOUP_EVENTS.resumeConsumer,
517
- MEDIASOUP_EVENTS.consumerChangePreferredLayers,
518
- MEDIASOUP_EVENTS.producerSetMaxSpatialLayer,
519
- CHANNEL_EVENTS.updatePeerAppData,
520
- ];
521
-
522
- eventNames.forEach((x): EnhancedEventEmitter<PeerObserverEvents> => this.observer.removeAllListeners(x));
523
- }
524
-
525
- getActiveTracksCount(): number {
526
- return Array.from(this.tracks.values())
527
- .map((track) => track.consumer)
528
- .filter((consumer) => !consumer?.paused)
529
- .length;
530
- }
531
-
532
- getActivePublishersCount(): number {
533
- return Array.from(this.producers.values())
534
- .filter((producer) => !producer.paused)
535
- .length;
536
- }
537
-
538
- handleProducePermissionsChange(producePermissions: TrackLabel[]): void {
539
- this.producePermissions = producePermissions;
540
-
541
- // close tracks that are no longer allowed
542
- Object.values(TrackLabel)
543
- .filter((label) => !this.producePermissions.includes(label))
544
- .forEach((label) => {
545
- const track = this.tracks.get(label);
546
-
547
- if (track) {
548
- this.tracks.delete(track.label);
549
- track.close().catch((error: unknown) => {
550
- this.#logger.error('Failed to close track', {
551
- case: 'Peer',
552
- error: serializeError(error),
553
- });
554
- });
555
- }
556
- });
557
-
558
- // notify about changes in permissions
559
- this.observer.safeEmit(PEER_EVENTS.producePermissionsChanged, {
560
- labels: this.producePermissions,
561
- });
562
- }
563
-
564
- handleGroupsChange(groups: PeerGroup[]): void {
565
- this.groups = groups;
566
- this.observer.safeEmit(PEER_EVENTS.groupsChanged, { groups });
567
- }
568
-
569
- private getAllConsumers(): PeerConsumer[] {
570
- return Array.from(this.tracks.values())
571
- .map((track) => track.consumer)
572
- .filter((item): item is PeerConsumer => !!item);
573
- }
574
-
575
- private getConsumerByProducerId(producerId: string): PeerConsumer | undefined {
576
- return this.getAllConsumers().find((consumer) => consumer.producerId === producerId);
577
- }
578
-
579
- private getConsumerById(id: string): PeerConsumer | undefined {
580
- return this.getAllConsumers().find((consumer) => consumer.id === id);
581
- }
582
-
583
- private getTrackByConsumerId(id: string): PeerTrack | undefined {
584
- return Array.from(this.tracks.values()).find((track) => track.consumerId === id);
585
- }
586
-
587
- private setAppData(appData: Record<string, unknown>): void {
588
- this.applicationData = appData;
589
- }
590
-
591
- private throwIfIamNotModerator(): void {
592
- const isIamModerator = this.#peers.isModerator(this.#myPeer.id);
593
-
594
- if (isIamModerator) {
595
- return;
596
- }
597
-
598
- throw new OperationError('not_enough_access', new Error('Not enough access'));
599
- }
600
- }
601
-
602
- export default Peer;