@livedigital/client 3.48.0 → 3.49.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.
Files changed (166) hide show
  1. package/LICENSE +1 -1
  2. package/dist/constants/encodings.d.ts +3 -3
  3. package/dist/constants/encodings.ts +3 -3
  4. package/dist/engine/handlers/ChannelAudioObserverEventHandler.d.ts +3 -1
  5. package/dist/engine/handlers/ChannelAudioObserverMissingProducerRestorer.d.ts +10 -0
  6. package/dist/engine/handlers/MediaEventHandler.d.ts +0 -1
  7. package/dist/engine/index.d.ts +7 -4
  8. package/dist/engine/network/DatachannelHeartbeater.d.ts +2 -2
  9. package/dist/engine/network/NetworkTransportPolicyManager.d.ts +22 -0
  10. package/dist/engine/network/index.d.ts +10 -8
  11. package/dist/index.d.ts +2 -0
  12. package/dist/index.es.js +2 -2
  13. package/dist/index.js +2 -2
  14. package/dist/inversify.tokens.d.ts +3 -1
  15. package/dist/types/network.d.ts +6 -6
  16. package/package.json +2 -3
  17. package/src/ClientMetaProvider.ts +0 -41
  18. package/src/EnhancedEventEmitter.ts +0 -75
  19. package/src/config/ConfigService.ts +0 -66
  20. package/src/constants/common.ts +0 -85
  21. package/src/constants/encodings.ts +0 -26
  22. package/src/constants/events.ts +0 -126
  23. package/src/constants/mutex.ts +0 -6
  24. package/src/constants/stats.ts +0 -1
  25. package/src/constants/videoConstrains.ts +0 -21
  26. package/src/engine/CallState.ts +0 -19
  27. package/src/engine/ChannelStateSynchronizer/ChannelStateSynchronizer.ts +0 -448
  28. package/src/engine/ChannelStateSynchronizer/types.ts +0 -22
  29. package/src/engine/EventsQueue.ts +0 -255
  30. package/src/engine/IntegrationsService.ts +0 -163
  31. package/src/engine/LocalMutex.ts +0 -45
  32. package/src/engine/Logger.ts +0 -234
  33. package/src/engine/MyPeer.ts +0 -25
  34. package/src/engine/Peer.ts +0 -602
  35. package/src/engine/PeerConsumer.ts +0 -276
  36. package/src/engine/PeerProducer.ts +0 -50
  37. package/src/engine/Peers.ts +0 -150
  38. package/src/engine/PeersStorage.ts +0 -45
  39. package/src/engine/RemotePeerTracks.ts +0 -73
  40. package/src/engine/WIDHandler.ts +0 -166
  41. package/src/engine/WebRTCStats/ConnectionStatsManager.ts +0 -31
  42. package/src/engine/WebRTCStats/InboundTrackStatsManager.ts +0 -51
  43. package/src/engine/WebRTCStats/OutboudTrackStatsManager.ts +0 -51
  44. package/src/engine/WebRTCStats/StatsHandler.ts +0 -80
  45. package/src/engine/WebRTCStats/TransportsStatsProvider.ts +0 -123
  46. package/src/engine/WebRTCStats/types.ts +0 -20
  47. package/src/engine/analyticsApiClient/LogApi.ts +0 -24
  48. package/src/engine/analyticsApiClient/MetricsApi.ts +0 -30
  49. package/src/engine/analyticsApiClient/helper.ts +0 -88
  50. package/src/engine/analyticsApiClient/index.ts +0 -42
  51. package/src/engine/analyticsApiClient/types.ts +0 -33
  52. package/src/engine/handlers/ChannelAudioObserverEventHandler.ts +0 -177
  53. package/src/engine/handlers/ChannelEventHandler.ts +0 -268
  54. package/src/engine/handlers/ChannelStateSyncEventHandler/ChannelStateConsistencyCheckResult.ts +0 -31
  55. package/src/engine/handlers/ChannelStateSyncEventHandler/ChannelStateConsistencyChecker.ts +0 -146
  56. package/src/engine/handlers/ChannelStateSyncEventHandler/consts.ts +0 -7
  57. package/src/engine/handlers/ChannelStateSyncEventHandler/index.ts +0 -342
  58. package/src/engine/handlers/ChannelStateSyncEventHandler/types.ts +0 -21
  59. package/src/engine/handlers/MediaEventHandler.ts +0 -273
  60. package/src/engine/index.ts +0 -793
  61. package/src/engine/media/index.ts +0 -574
  62. package/src/engine/media/producer/PendingClosureProducerStorage.ts +0 -37
  63. package/src/engine/media/producer/ProducerCloseManager.ts +0 -115
  64. package/src/engine/media/streamEffects/ProcessorsCache.ts +0 -41
  65. package/src/engine/media/streamEffects/audio/AudioTrackProcessor.ts +0 -7
  66. package/src/engine/media/streamEffects/audio/asdk/ASDKTrackProcessor.ts +0 -275
  67. package/src/engine/media/streamEffects/audio/asdk/atsrb.d.ts +0 -36
  68. package/src/engine/media/streamEffects/audio/asdk/errorBus.d.ts +0 -47
  69. package/src/engine/media/streamEffects/audio/noiseSuppression/NoiseSuppressionAudioWorkletNode.ts +0 -35
  70. package/src/engine/media/streamEffects/audio/noiseSuppression/NoiseSuppressionNodeProvider.ts +0 -44
  71. package/src/engine/media/streamEffects/audio/noiseSuppression/NoiseSuppressionScriptProcessorNode.ts +0 -69
  72. package/src/engine/media/streamEffects/audio/noiseSuppression/RNNoiseTrackProcessor.ts +0 -134
  73. package/src/engine/media/streamEffects/audio/noiseSuppression/WasmModuleCompiler.ts +0 -9
  74. package/src/engine/media/streamEffects/video/esdk/TrackProcessor.ts +0 -386
  75. package/src/engine/media/streamEffects/video/esdk/components/component.d.ts +0 -35
  76. package/src/engine/media/streamEffects/video/esdk/components/countdown/countdown.d.ts +0 -27
  77. package/src/engine/media/streamEffects/video/esdk/components/lower-third/collection/doubleSlideRect.d.ts +0 -33
  78. package/src/engine/media/streamEffects/video/esdk/components/lower-third/collection/horizontalMirror.d.ts +0 -29
  79. package/src/engine/media/streamEffects/video/esdk/components/lower-third/collection/leftTextbox.d.ts +0 -31
  80. package/src/engine/media/streamEffects/video/esdk/components/lower-third/collection/slideBold.d.ts +0 -41
  81. package/src/engine/media/streamEffects/video/esdk/components/lower-third/collection/twoSideRects/animatedBox.d.ts +0 -59
  82. package/src/engine/media/streamEffects/video/esdk/components/lower-third/collection/twoSideRects/twoSlideRects.d.ts +0 -27
  83. package/src/engine/media/streamEffects/video/esdk/components/lower-third/lowerThird.d.ts +0 -83
  84. package/src/engine/media/streamEffects/video/esdk/components/overlay-screen/overlayScreen.d.ts +0 -40
  85. package/src/engine/media/streamEffects/video/esdk/components/overlay-screen/overlaySprite.d.ts +0 -10
  86. package/src/engine/media/streamEffects/video/esdk/components/stickers/stickerSprite.d.ts +0 -51
  87. package/src/engine/media/streamEffects/video/esdk/components/stickers/stickers.d.ts +0 -54
  88. package/src/engine/media/streamEffects/video/esdk/components/utils/positionHelper.d.ts +0 -14
  89. package/src/engine/media/streamEffects/video/esdk/components/waterMark/waterMark.d.ts +0 -20
  90. package/src/engine/media/streamEffects/video/esdk/tsvb.d.ts +0 -187
  91. package/src/engine/media/streamEffects/video/esdk/utils/errorBus.d.ts +0 -42
  92. package/src/engine/media/tracks/DefaultAudioTrack.ts +0 -178
  93. package/src/engine/media/tracks/DefaultBaseTrack.ts +0 -592
  94. package/src/engine/media/tracks/DefaultVideoTrack.ts +0 -301
  95. package/src/engine/media/tracks/MediaStreamTrackManager.ts +0 -50
  96. package/src/engine/media/tracks/PeerTrack.ts +0 -558
  97. package/src/engine/network/DataChannelsManager.ts +0 -164
  98. package/src/engine/network/DatachannelHeartbeater.ts +0 -122
  99. package/src/engine/network/SignalingHeartbeater.ts +0 -55
  100. package/src/engine/network/index.ts +0 -961
  101. package/src/engine/signalingApiClient/SignalingApiClient.ts +0 -95
  102. package/src/engine/signalingApiClient/api.ts +0 -2289
  103. package/src/engine/system/index.ts +0 -221
  104. package/src/errors/AlreadyConnectedError.ts +0 -11
  105. package/src/errors/AlreadyCreatedError.ts +0 -11
  106. package/src/errors/ForbiddenError.ts +0 -11
  107. package/src/errors/InvalidPayloadError.ts +0 -11
  108. package/src/errors/InvalidRequestError.ts +0 -11
  109. package/src/errors/LivedigitalSDKError.ts +0 -15
  110. package/src/errors/NeedJoinFirstError.ts +0 -11
  111. package/src/errors/NotFoundError.ts +0 -11
  112. package/src/errors/OperationError.ts +0 -47
  113. package/src/errors/RequestError.ts +0 -11
  114. package/src/errors/TimeoutError.ts +0 -11
  115. package/src/errors/TooManyRequestsError.ts +0 -11
  116. package/src/errors/UnauthorizedError.ts +0 -11
  117. package/src/errors/UnsupportedError.ts +0 -15
  118. package/src/errors/signalingApiErrorMapper.ts +0 -143
  119. package/src/helpers/appDataValidator.ts +0 -21
  120. package/src/helpers/browser.ts +0 -37
  121. package/src/helpers/channelMessageConverter.ts +0 -124
  122. package/src/helpers/common.ts +0 -96
  123. package/src/helpers/datetime.ts +0 -11
  124. package/src/helpers/errors.ts +0 -25
  125. package/src/helpers/filterStatsCodecs.ts +0 -3
  126. package/src/helpers/loader.ts +0 -59
  127. package/src/helpers/media.ts +0 -57
  128. package/src/helpers/peer.ts +0 -19
  129. package/src/helpers/randomString.ts +0 -18
  130. package/src/helpers/retry.ts +0 -74
  131. package/src/index.ts +0 -171
  132. package/src/inversify.config.ts +0 -333
  133. package/src/inversify.factories.ts +0 -191
  134. package/src/inversify.tokens.ts +0 -42
  135. package/src/proto/.gitkeep +0 -0
  136. package/src/proto/generated/channel/channel_activity_confirmation_time.ts +0 -110
  137. package/src/proto/generated/channel/channel_management_event.ts +0 -213
  138. package/src/proto/generated/channel/channel_produce_permissions.ts +0 -171
  139. package/src/proto/generated/channel/channel_state.ts +0 -94
  140. package/src/proto/generated/channel/channel_state_short.ts +0 -282
  141. package/src/proto/generated/channel_message/channel_event.ts +0 -401
  142. package/src/proto/generated/channel_message/channel_message.ts +0 -139
  143. package/src/proto/generated/channel_message/media_event.ts +0 -290
  144. package/src/proto/generated/consumer/consumer.ts +0 -167
  145. package/src/proto/generated/google/protobuf/struct.ts +0 -588
  146. package/src/proto/generated/google/protobuf/timestamp.ts +0 -229
  147. package/src/proto/generated/peer/peer.ts +0 -430
  148. package/src/proto/generated/peer/peer_group.ts +0 -48
  149. package/src/proto/generated/peer/peer_role.ts +0 -48
  150. package/src/proto/generated/producer/producer.ts +0 -204
  151. package/src/proto/generated/producer/producer_kind.ts +0 -48
  152. package/src/proto/generated/producer/producer_label.ts +0 -78
  153. package/src/proto/generated/producer/producer_spatial_layer_request.ts +0 -116
  154. package/src/proto/generated/transport/transport_connection_timeout.ts +0 -156
  155. package/src/proto/generated/transport/transport_connection_timeout_reason.ts +0 -48
  156. package/src/proto/generated/transport/transport_direction.ts +0 -48
  157. package/src/types/channelAudioObserver.ts +0 -34
  158. package/src/types/channelStateSyncronizer.ts +0 -22
  159. package/src/types/client.ts +0 -27
  160. package/src/types/common.ts +0 -399
  161. package/src/types/container.ts +0 -31
  162. package/src/types/engine.ts +0 -97
  163. package/src/types/media.ts +0 -146
  164. package/src/types/mediasoup.ts +0 -10
  165. package/src/types/network.ts +0 -10
  166. package/src/types/streamEffects.ts +0 -23
@@ -1,592 +0,0 @@
1
- import type { types } from 'mediasoup-client';
2
- import { serializeError } from 'serialize-error';
3
- import type { ParsedOutboundAudioStreamStats, ParsedOutboundVideoStreamStats } from 'webrtc-issue-detector';
4
- import type Media from '..';
5
- import { INTERNAL_CLIENT_EVENTS } from '../../../constants/events';
6
- import EnhancedEventEmitter from '../../../EnhancedEventEmitter';
7
- import OperationError from '../../../errors/OperationError';
8
- import filterStatsCodecs from '../../../helpers/filterStatsCodecs';
9
- import { isVp9 } from '../../../helpers/media';
10
- import {
11
- type BaseTrackInfo,
12
- type EncoderConfig,
13
- type PrepareProducerEncodingsParams,
14
- TrackLabel,
15
- type TrackOutboundStats,
16
- type TrackProduceParams,
17
- } from '../../../types/common';
18
- import type { InternalObserverEvents } from '../../../types/engine';
19
- import type {
20
- BaseTrack, BaseTrackDependenciesParams, BaseTrackParams, ProducerAppData,
21
- } from '../../../types/media';
22
- import type Logger from '../../Logger';
23
- import type { MyPeer } from '../../MyPeer';
24
- import type Network from '../../network';
25
- import OutboundTrackStatsManager from '../../WebRTCStats/OutboudTrackStatsManager';
26
- import type StatsHandler from '../../WebRTCStats/StatsHandler';
27
- import type MediaStreamTrackManager from './MediaStreamTrackManager';
28
- import type LocalMutex from '../../LocalMutex';
29
- import { MutexKey } from '../../../constants/mutex';
30
- import type ProducerCloseManager from '../producer/ProducerCloseManager';
31
-
32
- type BaseTrackConstructorParams = BaseTrackParams & BaseTrackDependenciesParams;
33
-
34
- export interface LoggerContext {
35
- label: TrackLabel;
36
- id: string;
37
- kind: types.MediaKind;
38
- producerId: string | undefined;
39
- paused: boolean;
40
- published: boolean;
41
- }
42
-
43
- const STATS_MAX_ATTEMPTS = 5;
44
- const STATS_ATTEMPT_DELAY = 150;
45
-
46
- class DefaultBaseTrack implements BaseTrack {
47
- #mediaStreamTrack: MediaStreamTrack;
48
-
49
- #originalTrack?: MediaStreamTrack;
50
-
51
- protected encoderConfig: EncoderConfig = {};
52
-
53
- private producer?: types.Producer<ProducerAppData>;
54
-
55
- private label: TrackLabel = TrackLabel.Unknown;
56
-
57
- readonly #myPeer: MyPeer;
58
-
59
- readonly #media: Media;
60
-
61
- readonly #network: Network;
62
-
63
- readonly #producerCloseManager: ProducerCloseManager;
64
-
65
- readonly logger: Logger;
66
-
67
- readonly #internalEventEmitter: EnhancedEventEmitter<InternalObserverEvents>;
68
-
69
- readonly #constraints: MediaStreamConstraints;
70
-
71
- readonly #mediaStreamTrackManager: MediaStreamTrackManager;
72
-
73
- readonly #eventEmitter: EnhancedEventEmitter;
74
-
75
- #stopTrackOnPause = true;
76
-
77
- readonly #mutex: LocalMutex;
78
-
79
- #webrtcStatsManager: OutboundTrackStatsManager;
80
-
81
- readonly #statsHandler: StatsHandler;
82
-
83
- constructor(params: BaseTrackConstructorParams) {
84
- const {
85
- mediaStreamTrack,
86
- internalEventEmitter,
87
- constraints,
88
- mediaStreamTrackManager,
89
- media,
90
- myPeer,
91
- network,
92
- producerCloseManager,
93
- mutex,
94
- loggerFactory,
95
- loggerNamespace,
96
- statsHandler,
97
- } = params;
98
- this.#mediaStreamTrack = mediaStreamTrack;
99
- this.#internalEventEmitter = internalEventEmitter;
100
- this.#constraints = constraints;
101
- this.#mediaStreamTrackManager = mediaStreamTrackManager;
102
- this.#eventEmitter = new EnhancedEventEmitter();
103
- this.logger = loggerFactory(loggerNamespace);
104
- this.#mutex = mutex;
105
- this.#media = media;
106
- this.#myPeer = myPeer;
107
- this.#network = network;
108
- this.#producerCloseManager = producerCloseManager;
109
- this.#statsHandler = statsHandler;
110
- this.#webrtcStatsManager = new OutboundTrackStatsManager({
111
- track: mediaStreamTrack,
112
- statsHandler,
113
- });
114
- }
115
-
116
- get videoWebRTCStats(): ParsedOutboundVideoStreamStats | undefined {
117
- return this.#webrtcStatsManager.videoWebRTCStats;
118
- }
119
-
120
- get audioWebRTCStats(): ParsedOutboundAudioStreamStats | undefined {
121
- return this.#webrtcStatsManager.audioWebRTCStats;
122
- }
123
-
124
- get logCtx(): LoggerContext {
125
- return {
126
- label: this.getLabel(),
127
- id: this.id,
128
- kind: this.kind,
129
- producerId: this.producerId,
130
- paused: this.isPaused,
131
- published: this.isPublished,
132
- };
133
- }
134
-
135
- get observer(): EnhancedEventEmitter {
136
- return this.#eventEmitter;
137
- }
138
-
139
- get mediaStreamTrack(): MediaStreamTrack {
140
- return this.#mediaStreamTrack;
141
- }
142
-
143
- get originalTrack(): MediaStreamTrack | undefined {
144
- return this.#originalTrack;
145
- }
146
-
147
- get id(): string {
148
- return this.mediaStreamTrack.id;
149
- }
150
-
151
- get kind(): types.MediaKind {
152
- return this.mediaStreamTrack.kind as types.MediaKind;
153
- }
154
-
155
- get producerId(): string | undefined {
156
- return this.producer?.id;
157
- }
158
-
159
- get isPublished(): boolean {
160
- return this.producer
161
- ? !this.producer.closed
162
- : false;
163
- }
164
-
165
- get isPaused(): boolean {
166
- return this.producer?.paused ?? false;
167
- }
168
-
169
- get internalEventEmitter(): EnhancedEventEmitter<InternalObserverEvents> {
170
- return this.#internalEventEmitter;
171
- }
172
-
173
- getLabel(): TrackLabel {
174
- return this.label;
175
- }
176
-
177
- setLabel(label: TrackLabel): void {
178
- this.label = label;
179
- }
180
-
181
- setEncoderConfig(encoderConfig: EncoderConfig): void {
182
- this.encoderConfig = encoderConfig;
183
- }
184
-
185
- getEncoderConfig(): EncoderConfig {
186
- return this.encoderConfig;
187
- }
188
-
189
- setProducer(producer: types.Producer): void {
190
- this.producer = producer as types.Producer<ProducerAppData>;
191
- }
192
-
193
- setStopTrackOnPause(value: boolean): void {
194
- if (this.isPublished) {
195
- return;
196
- }
197
-
198
- this.#stopTrackOnPause = value;
199
- }
200
-
201
- getProducer(): types.Producer | undefined {
202
- return this.producer;
203
- }
204
-
205
- protected setOriginalTrack(): void {
206
- this.#originalTrack = this.mediaStreamTrack;
207
- }
208
-
209
- async closeProducer(stopTrack = true): Promise<void> {
210
- const release = await this.#mutex.lock(MutexKey.CloseProducer);
211
-
212
- if (!this.producer) {
213
- release();
214
-
215
- return;
216
- }
217
-
218
- const { producerId } = this;
219
-
220
- if (producerId) {
221
- await this.#producerCloseManager.close(this.getLabel(), producerId);
222
- }
223
-
224
- this.producer.close();
225
- this.producer = undefined;
226
-
227
- if (stopTrack) {
228
- this.stopMediaStreamTrack();
229
- }
230
-
231
- release();
232
- }
233
-
234
- async setPriority(priority: RTCPriorityType): Promise<void> {
235
- if (!this.producer) {
236
- this.logger.warn('setPriority()', {
237
- priority,
238
- reason: 'Not published yet',
239
- });
240
-
241
- return;
242
- }
243
-
244
- await this.producer.setRtpEncodingParameters({ priority });
245
- this.logger.debug('setPriority()', {
246
- label: this.getLabel(),
247
- priority,
248
- });
249
- }
250
-
251
- stopMediaStreamTrack(): void {
252
- this.mediaStreamTrack.stop();
253
- this.mediaStreamTrack.dispatchEvent(new Event('ended'));
254
- this.stopOriginalTrack();
255
- }
256
-
257
- protected stopOriginalTrack(): void {
258
- if (this.#originalTrack) {
259
- this.#originalTrack.stop();
260
- this.#originalTrack = undefined;
261
- }
262
- }
263
-
264
- async produce({
265
- encodings,
266
- codecOptions,
267
- preferredCodec,
268
- transformParams,
269
- keyFrameRequestDelay,
270
- }: TrackProduceParams): Promise<void> {
271
- if (!this.#myPeer.canPublish) {
272
- this.logger.error('produce()', { message: 'Not enough access to produce' });
273
- throw new OperationError('not_enough_access', new Error('Not enough access to produce'));
274
- }
275
-
276
- if (this.producer) {
277
- throw new OperationError('track_already_produced', new Error('Track already produced'));
278
- }
279
-
280
- try {
281
- await this.#producerCloseManager.ensureNoPending(this.getLabel());
282
-
283
- // if you perform transport.produce while you switching to VPN,
284
- // it will cause an irreversible failure in the formation m-section of the SDP. Mediasoup bug?
285
- // TODO: find a solution to the problem
286
- await this.#network.ping();
287
-
288
- const { rtpCapabilities: { codecs } } = this.#media.mediasoupDevice;
289
- const codec = codecs?.find((c) => c.mimeType.toLowerCase() === `${ this.kind }/${ preferredCodec }`);
290
- const maxSpatialLayer = 0;
291
- // We start with max layer if possible and then reduce to proper layer (to have ability to calc max layer)
292
- const preparedEncodings = this.prepareProducerEncodings({
293
- codec,
294
- encodings: encodings ?? [],
295
- maxSpatialLayer: (encodings ?? []).length - 1,
296
- });
297
- const appData: ProducerAppData = {
298
- trackTransformParams: transformParams,
299
- peerId: String(this.#myPeer.id),
300
- label: this.getLabel(),
301
- maxSpatialLayer,
302
- encodings: preparedEncodings,
303
- codecOptions,
304
- preferredCodec,
305
- codec,
306
- keyFrameRequestDelay,
307
- };
308
-
309
- const producer = await this.#network.sendTransport?.produce<ProducerAppData>({
310
- track: this.mediaStreamTrack,
311
- encodings: preparedEncodings,
312
- codecOptions,
313
- codec,
314
- stopTracks: false,
315
- disableTrackOnPause: true,
316
- zeroRtpOnPause: true,
317
- appData,
318
- });
319
-
320
- if (!producer) {
321
- return;
322
- }
323
-
324
- const sender = producer.rtpSender;
325
- const isSafari = (): boolean => /Safari/i.test(navigator.userAgent);
326
-
327
- if (encodings && sender && isSafari()) {
328
- const params = sender.getParameters();
329
- encodings.forEach(({ maxBitrate, scaleResolutionDownBy }, index) => {
330
- if (params.encodings[index]) {
331
- params.encodings[index].maxBitrate = maxBitrate;
332
- params.encodings[index].scaleResolutionDownBy = scaleResolutionDownBy;
333
- }
334
- });
335
-
336
- await sender.setParameters(params);
337
- }
338
-
339
- this.setProducer(producer);
340
-
341
- if ((this.producer as unknown as types.Producer<ProducerAppData>)?.track?.id !== this.#mediaStreamTrack.id) {
342
- this.logger.info('Producer initialized with old track, updating', {
343
- oldTrackId: (this.producer as unknown as types.Producer<ProducerAppData>)?.track?.id,
344
- newTrackId: this.#mediaStreamTrack.id,
345
- });
346
-
347
- await this.replaceTrack(this.#mediaStreamTrack);
348
- }
349
-
350
- if (this.kind === 'video') {
351
- if (encodings && sender && codec && isVp9(codec.mimeType) && !isSafari()) {
352
- await sender.setParameters({
353
- ...sender.getParameters(),
354
- encodings: this.prepareProducerEncodings({ encodings, codec, maxSpatialLayer }),
355
- });
356
- } else {
357
- await producer.setMaxSpatialLayer(maxSpatialLayer);
358
- }
359
-
360
- await this.#network.setProducerMaxSpatialLayer(producer.id, maxSpatialLayer);
361
- }
362
-
363
- if (this.kind === 'audio') {
364
- await this.setPriority('high');
365
- }
366
-
367
- this.logger.debug('produce()', { track: this.logCtx, encodings, codecOptions });
368
- } catch (error) {
369
- this.logger.error('produce()', { error, track: this.logCtx });
370
- throw new OperationError('track_publish_failed', error);
371
- }
372
- }
373
-
374
- async publish(): Promise<void> {
375
- await this.produce({});
376
- this.internalEventEmitter.emit(INTERNAL_CLIENT_EVENTS.trackProduced, this);
377
- }
378
-
379
- async unpublish(stopTrack = true): Promise<void> {
380
- try {
381
- if (stopTrack) {
382
- this.stopMediaStreamTrack();
383
- }
384
-
385
- this.internalEventEmitter.emit(INTERNAL_CLIENT_EVENTS.trackUnproduced, this);
386
-
387
- if (this.producer) {
388
- await this.closeProducer();
389
- }
390
-
391
- this.logger.debug('unpublish()', { track: this.logCtx });
392
- } catch (error) {
393
- this.logger.error('unpublish()', { error });
394
- }
395
- }
396
-
397
- private async pauseRemoteProducer(producerId: string): Promise<void> {
398
- await this.#network.pauseRemoteProducer(producerId);
399
- }
400
-
401
- private async resumeRemoteProducer(producerId: string): Promise<void> {
402
- await this.#network.resumeRemoteProducer(producerId);
403
- }
404
-
405
- protected async mute(stopTrackOnPauseCallback?: () => void): Promise<void> {
406
- const release = await this.#mutex.lock(MutexKey.Mute);
407
-
408
- if (!this.producer) {
409
- this.logger.warn('pause()', { message: 'Track is not published', track: this.logCtx });
410
- release();
411
-
412
- return;
413
- }
414
-
415
- try {
416
- this.producer.pause();
417
- this.logger.debug('pause()', { track: this.logCtx });
418
-
419
- if (this.#stopTrackOnPause) {
420
- stopTrackOnPauseCallback?.();
421
- this.#mediaStreamTrack.stop();
422
- this.stopOriginalTrack();
423
- this.internalEventEmitter.emit(INTERNAL_CLIENT_EVENTS.trackClosed, this);
424
- await this.pauseRemoteProducer(this.producer.id);
425
-
426
- return;
427
- }
428
-
429
- await this.pauseRemoteProducer(this.producer.id);
430
- this.internalEventEmitter.emit(INTERNAL_CLIENT_EVENTS.trackPaused, this);
431
- } catch (error) {
432
- this.logger.error('pause()', { error, track: this.logCtx });
433
- await this.#media.deleteTrack(this);
434
- this.internalEventEmitter.emit(INTERNAL_CLIENT_EVENTS.trackFailed, this);
435
- throw new OperationError('track_pause_failed', error);
436
- } finally {
437
- release();
438
- }
439
- }
440
-
441
- public async resume(): Promise<void> {
442
- const release = await this.#mutex.lock(MutexKey.Resume);
443
-
444
- if (!this.producer) {
445
- this.logger.warn('resume()', { message: 'Track is not published', track: this.logCtx });
446
- release();
447
-
448
- return;
449
- }
450
-
451
- try {
452
- this.logger.debug('resume()', { track: this.logCtx });
453
-
454
- if (this.#stopTrackOnPause) {
455
- await this.reopenMediaStreamTrack();
456
- await this.resumeProducer();
457
- this.internalEventEmitter.emit(INTERNAL_CLIENT_EVENTS.trackReopened, this);
458
-
459
- return;
460
- }
461
-
462
- await this.resumeProducer();
463
- this.internalEventEmitter.emit(INTERNAL_CLIENT_EVENTS.trackResumed, this);
464
- } catch (error) {
465
- this.logger.error('resume()', { error, track: this.logCtx });
466
- throw new OperationError('track_resume_failed', error);
467
- } finally {
468
- release();
469
- }
470
- }
471
-
472
- async getInfo(): Promise<BaseTrackInfo> {
473
- const {
474
- width, height, frameRate, aspectRatio,
475
- } = this.#mediaStreamTrack.getSettings();
476
-
477
- return {
478
- trackId: this.#mediaStreamTrack.id,
479
- readyState: this.#mediaStreamTrack.readyState,
480
- kind: this.kind,
481
- label: this.label,
482
- width,
483
- height,
484
- frameRate,
485
- aspectRatio,
486
- paused: this.isPaused,
487
- trackOutboundStats: await this.getStats(),
488
- };
489
- }
490
-
491
- async getStats(): Promise<TrackOutboundStats | undefined> {
492
- try {
493
- return {
494
- producerId: this.producer?.id,
495
- codec: this.producer?.rtpParameters.codecs.find((codec) => filterStatsCodecs(codec)),
496
- dtlsState: this.producer?.rtpSender?.transport?.state,
497
- rtcStats: await this.getOutboundRTPStreamStats(),
498
- };
499
- } catch (error) {
500
- this.logger.debug('getStats()', { error });
501
-
502
- return undefined;
503
- }
504
- }
505
-
506
- async replaceTrack(track: MediaStreamTrack): Promise<void> {
507
- try {
508
- this.#mediaStreamTrack = track;
509
- this.internalEventEmitter.emit(INTERNAL_CLIENT_EVENTS.trackReopened, this);
510
- this.observer.safeEmit('track-changed', { track });
511
- await this.producer?.replaceTrack({ track });
512
- this.#webrtcStatsManager = new OutboundTrackStatsManager({
513
- track,
514
- statsHandler: this.#statsHandler,
515
- });
516
- } catch (error) {
517
- this.logger.warn('replaceTrack()', { error });
518
- }
519
- }
520
-
521
- private async resumeProducer(): Promise<void> {
522
- if (!this.producer) {
523
- this.logger.debug('resumeProducer()', { message: 'Track not produced yet', track: this.logCtx });
524
-
525
- return;
526
- }
527
-
528
- await this.resumeRemoteProducer(this.producer.id);
529
- this.producer.resume();
530
- }
531
-
532
- private async reopenMediaStreamTrack(): Promise<void> {
533
- const track = await this.#mediaStreamTrackManager.createMediaStreamTrack({
534
- label: this.label,
535
- constraints: this.#constraints,
536
- });
537
-
538
- this.#mediaStreamTrack = track;
539
- await this.producer?.replaceTrack({ track });
540
- }
541
-
542
- private prepareProducerEncodings(
543
- params: PrepareProducerEncodingsParams,
544
- ): RTCRtpEncodingParameters[] {
545
- const { encodings, codec, maxSpatialLayer } = params;
546
-
547
- // for VP9 can use only one item in encodings array
548
- return encodings && encodings.length > 1 && codec && isVp9(codec.mimeType)
549
- ? [encodings[maxSpatialLayer] || encodings[0]]
550
- : encodings;
551
- }
552
-
553
- private async getOutboundRTPStreamStats(): Promise<RTCOutboundRtpStreamStats> {
554
- return await new Promise((resolve, reject) => {
555
- const getRTCStatsReport = async (attempt = 0): Promise<void> => {
556
- if (!this.producer) {
557
- throw new Error('Producer is missed');
558
- }
559
-
560
- try {
561
- const rtcStatsReport = await this.producer.getStats();
562
- const outboundRTPStreamStats: RTCOutboundRtpStreamStats = Array.from(rtcStatsReport.values())
563
- .find((stat) => stat.type === 'outbound-rtp');
564
-
565
- if (!outboundRTPStreamStats && attempt < STATS_MAX_ATTEMPTS) {
566
- setTimeout(async () => await getRTCStatsReport(attempt + 1), STATS_ATTEMPT_DELAY);
567
-
568
- return;
569
- }
570
-
571
- if (attempt >= STATS_MAX_ATTEMPTS && !outboundRTPStreamStats) {
572
- reject(new Error('OutboundRTPStreamStat not exist'));
573
- }
574
-
575
- resolve(outboundRTPStreamStats);
576
- } catch (error) {
577
- reject(new Error('Can not get RTCStatsReport'));
578
- this.logger.debug('getOutboundRTPStreamStats()', { error });
579
- }
580
- };
581
-
582
- getRTCStatsReport().catch((error: unknown) => {
583
- this.logger.debug('Error executing getRTCStatsReport', {
584
- case: 'DefaultBaseTrack',
585
- error: serializeError(error),
586
- });
587
- });
588
- });
589
- }
590
- }
591
-
592
- export default DefaultBaseTrack;