@livedigital/client 3.34.0-createCustomMediaTracks.1 → 3.34.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 (43) hide show
  1. package/dist/constants/events.d.ts +0 -1
  2. package/dist/constants/events.ts +0 -1
  3. package/dist/engine/Peer.d.ts +1 -2
  4. package/dist/engine/PeerConsumer.d.ts +0 -1
  5. package/dist/engine/PeerProducer.d.ts +0 -1
  6. package/dist/engine/WIDHandler.d.ts +21 -0
  7. package/dist/engine/WebRTCStats/TransportsStatsProvider.d.ts +5 -1
  8. package/dist/engine/analyticsApiClient/MetricsApi.d.ts +8 -0
  9. package/dist/engine/analyticsApiClient/index.d.ts +3 -0
  10. package/dist/engine/analyticsApiClient/types.d.ts +10 -3
  11. package/dist/engine/handlers/MediaSoupEventHandler.d.ts +0 -1
  12. package/dist/engine/index.d.ts +4 -7
  13. package/dist/engine/media/index.d.ts +0 -1
  14. package/dist/engine/media/tracks/PeerTrack.d.ts +0 -1
  15. package/dist/engine/network/DataChannelsManager.d.ts +0 -1
  16. package/dist/index.d.ts +2 -5
  17. package/dist/index.es.js +3 -3
  18. package/dist/index.js +3 -3
  19. package/dist/inversify.tokens.d.ts +4 -1
  20. package/dist/types/common.d.ts +5 -10
  21. package/dist/types/engine.d.ts +2 -6
  22. package/dist/types/network.d.ts +2 -1
  23. package/package.json +1 -1
  24. package/src/constants/events.ts +0 -1
  25. package/src/engine/Peer.ts +1 -10
  26. package/src/engine/PeerConsumer.ts +0 -3
  27. package/src/engine/PeerProducer.ts +0 -2
  28. package/src/engine/WIDHandler.ts +142 -0
  29. package/src/engine/WebRTCStats/TransportsStatsProvider.ts +51 -7
  30. package/src/engine/analyticsApiClient/MetricsApi.ts +30 -0
  31. package/src/engine/analyticsApiClient/index.ts +10 -0
  32. package/src/engine/analyticsApiClient/types.ts +12 -4
  33. package/src/engine/handlers/MediaSoupEventHandler.ts +0 -22
  34. package/src/engine/index.ts +12 -94
  35. package/src/engine/media/index.ts +0 -5
  36. package/src/engine/media/tracks/PeerTrack.ts +0 -4
  37. package/src/engine/network/DataChannelsManager.ts +0 -38
  38. package/src/index.ts +1 -14
  39. package/src/inversify.config.ts +42 -4
  40. package/src/inversify.tokens.ts +3 -0
  41. package/src/types/common.ts +6 -12
  42. package/src/types/engine.ts +2 -7
  43. package/src/types/network.ts +2 -1
@@ -30,5 +30,8 @@ export declare enum TOKEN {
30
30
  IntegrationsService = "IntegrationsService",
31
31
  ProcessorsCache = "ProcessorsCache",
32
32
  StatsHandler = "StatsHandler",
33
- DataChannelsManager = "DataChannelsManager"
33
+ DataChannelsManager = "DataChannelsManager",
34
+ WIDHandler = "WIDHandler",
35
+ AnalyticsApiClient = "AnalyticsApiClient",
36
+ TransportsStatsProvider = "TransportsStatsProvider"
34
37
  }
@@ -62,11 +62,16 @@ export declare type AvailableMediaDevices = {
62
62
  video: MediaDeviceInfo[];
63
63
  audio: MediaDeviceInfo[];
64
64
  };
65
+ export declare enum DatacenterType {
66
+ P2P = "p2p",
67
+ Common = "common"
68
+ }
65
69
  export declare type JoinChannelParams = {
66
70
  channelId: string;
67
71
  token: string;
68
72
  role: Role;
69
73
  appData?: Record<string, unknown>;
74
+ isP2pCall?: boolean;
70
75
  };
71
76
  export declare type ChannelEvent = {
72
77
  eventName: string;
@@ -119,11 +124,6 @@ export declare type CreateScreenMediaOptions = BaseVideoTrackOptions & BaseAudio
119
124
  videoEncoderConfig?: VideoEncoderConfig;
120
125
  audioEncoderConfig?: AudioEncoderConfig;
121
126
  };
122
- export declare type CreateCustomMediaOptions = BaseVideoTrackOptions & BaseAudioTrackOptions & {
123
- videoEncoderConfig?: VideoEncoderConfig;
124
- audioEncoderConfig?: AudioEncoderConfig;
125
- mediaStream: MediaStream;
126
- };
127
127
  export declare enum TrackLabel {
128
128
  Camera = "camera",
129
129
  CameraPreview = "camera-preview",
@@ -152,10 +152,6 @@ export declare type ChangePreferredLayersPayload = PreferredLayersParams & {
152
152
  spatialLayer: number;
153
153
  temporalLayer: number;
154
154
  };
155
- export declare type ConsumerScorePayload = {
156
- consumerId: string;
157
- score: number;
158
- };
159
155
  export declare type CreateVideoTrackParams = {
160
156
  videoTrackOptions: boolean | MediaTrackConstraints;
161
157
  encoderConfig: VideoEncoderConfig;
@@ -244,7 +240,6 @@ export declare type TrackInboundStats = {
244
240
  currentSpatialLayerParams?: SpatialLayerParams;
245
241
  availableSpatialLayers?: SpatialLayerParams[];
246
242
  requestedSpatialLayer?: number;
247
- score: number;
248
243
  dtlsState?: RTCDtlsTransportState;
249
244
  rtcStats?: ExtendedRTCInboundRtpStreamStats;
250
245
  };
@@ -6,7 +6,7 @@ import { ActivityConfirmationRequiredPayload, AvailableMediaDevices, ChannelEven
6
6
  import { BaseTrack, InitEffectsSDKParams, Track } from './media';
7
7
  export declare type IssuesHandler = (issues: IssueDetectorResult) => void;
8
8
  export declare type StatsHandler = (stats: StatsReportItem[]) => void;
9
- export declare type NetworkScoresUpdatedHandler = (networks: NetworkScores) => void;
9
+ export declare type NetworkScoresUpdatedHandler = (networkScores: NetworkScores) => void;
10
10
  export interface CreateIssueDetectorParams {
11
11
  disableWid: boolean;
12
12
  onIssues?: IssuesHandler;
@@ -25,11 +25,7 @@ export interface ConnectParams {
25
25
  channelId: string;
26
26
  role: Role;
27
27
  token: string;
28
- }
29
- export interface NodeActiveStreamsStat {
30
- node?: string;
31
- inboundActiveStreams: number;
32
- outboundActiveStreams: number;
28
+ isP2pCall?: boolean;
33
29
  }
34
30
  export interface ChannelStateInconsistentPayload {
35
31
  type: InconsistenceType;
@@ -1,9 +1,10 @@
1
- import { Role } from './common';
1
+ import { DatacenterType, Role } from './common';
2
2
  import { SocketIOEvents } from './socket';
3
3
  import { NETWORK_OBSERVER_EVENTS } from '../constants/events';
4
4
  export declare type GetNodeRequest = {
5
5
  channelId: string;
6
6
  role: Role;
7
+ datacenterType?: DatacenterType;
7
8
  };
8
9
  export declare type GetNodeResponse = {
9
10
  webSocketUrl: string;
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@livedigital/client",
3
3
  "author": "vlprojects",
4
4
  "license": "MIT",
5
- "version": "3.34.0-createCustomMediaTracks.1",
5
+ "version": "3.34.0",
6
6
  "private": false,
7
7
  "bugs": {
8
8
  "url": "https://github.com/vlprojects/livedigital-sdk/issues"
@@ -86,7 +86,6 @@ export const MEDIASOUP_EVENTS = {
86
86
  closeConsumer: 'consumer.close',
87
87
  pauseConsumer: 'consumer.pause',
88
88
  resumeConsumer: 'consumer.resume',
89
- consumerScore: 'consumer.score',
90
89
  consumerChangePreferredLayers: 'consumer.changeConsumerPreferredLayers',
91
90
  consumerRequestKeyFrame: 'consumer.requestKeyFrame',
92
91
  transportCreate: 'transport.create',
@@ -5,7 +5,7 @@ import EnhancedEventEmitter from '../EnhancedEventEmitter';
5
5
  import validateAppData from '../helpers/appDataValidator';
6
6
  import { logResponse } from '../helpers/peer';
7
7
  import {
8
- ChangePreferredLayersPayload, ConsumerScorePayload, PayloadOfPublishedMedia,
8
+ ChangePreferredLayersPayload, PayloadOfPublishedMedia,
9
9
  PayloadOfUnpublishedMedia, PeerGroup, PeerInfo, PeerShortData, ProducerData,
10
10
  ProducerSetMaxSpatialLayer, Role, SubscribeOptions, TrackLabel, TrackLabelString,
11
11
  } from '../types/common';
@@ -70,7 +70,6 @@ export type PeerObserverEvents = {
70
70
  [MEDIASOUP_EVENTS.closeConsumer]: [consumerId: string];
71
71
  [MEDIASOUP_EVENTS.pauseConsumer]: [consumerId: string];
72
72
  [MEDIASOUP_EVENTS.resumeConsumer]: [consumerId: string];
73
- [MEDIASOUP_EVENTS.consumerScore]: [ConsumerScorePayload];
74
73
  [MEDIASOUP_EVENTS.consumerChangePreferredLayers]: [ChangePreferredLayersPayload];
75
74
  [MEDIASOUP_EVENTS.producerSetMaxSpatialLayer]: [ProducerSetMaxSpatialLayer];
76
75
  [CHANNEL_EVENTS.updatePeerAppData]: [Record<string, unknown>];
@@ -434,13 +433,6 @@ class Peer {
434
433
  }
435
434
  });
436
435
 
437
- this.observer.on(MEDIASOUP_EVENTS.consumerScore, (payload: ConsumerScorePayload) => {
438
- const consumer = this.getConsumerById(payload.consumerId);
439
- if (consumer) {
440
- consumer.score = payload.score;
441
- }
442
- });
443
-
444
436
  this.observer.on(MEDIASOUP_EVENTS.producerSetMaxSpatialLayer, async (payload: ProducerSetMaxSpatialLayer) => {
445
437
  const { producerId, spatialLayer } = payload;
446
438
  const consumer = this.getConsumerByProducerId(producerId);
@@ -505,7 +497,6 @@ class Peer {
505
497
  MEDIASOUP_EVENTS.closeConsumer,
506
498
  MEDIASOUP_EVENTS.pauseConsumer,
507
499
  MEDIASOUP_EVENTS.resumeConsumer,
508
- MEDIASOUP_EVENTS.consumerScore,
509
500
  MEDIASOUP_EVENTS.consumerChangePreferredLayers,
510
501
  MEDIASOUP_EVENTS.producerSetMaxSpatialLayer,
511
502
  CHANNEL_EVENTS.updatePeerAppData,
@@ -18,8 +18,6 @@ export interface PeerConsumerConstructorParams extends PeerConsumerDependencies
18
18
  }
19
19
 
20
20
  class PeerConsumer {
21
- public score = 10;
22
-
23
21
  public spatialLayers = 0;
24
22
 
25
23
  public temporalLayers = 0;
@@ -191,7 +189,6 @@ class PeerConsumer {
191
189
  return {
192
190
  consumerId: this.consumer.id,
193
191
  codec: this.consumer.rtpParameters.codecs.find((codec) => filterStatsCodecs(codec)),
194
- score: this.score,
195
192
  dtlsState: this.consumer.rtpReceiver?.transport?.state,
196
193
  availableSpatialLayers: this.availableSpatialLayers,
197
194
  currentSpatialLayerParams: this.currentSpatialLayerParams,
@@ -19,8 +19,6 @@ class PeerProducer {
19
19
 
20
20
  readonly maxSpatialLayer: number;
21
21
 
22
- public score = 10;
23
-
24
22
  constructor(params: ProducerData) {
25
23
  const {
26
24
  id, kind, peerId, label, paused,
@@ -0,0 +1,142 @@
1
+ import { MessageBatcher } from 'message-batcher';
2
+ import { IssueDetectorResult, NetworkScores } from 'webrtc-issue-detector';
3
+ import { inject, injectable } from 'inversify';
4
+ import { NetworkMetric } from './analyticsApiClient/types';
5
+ import clientMetaProvider from '../ClientMetaProvider';
6
+ import { TOKEN } from '../inversify.tokens';
7
+ import { getClientUniqueId } from './analyticsApiClient/helper';
8
+ import AnalyticsApiClient from './analyticsApiClient';
9
+ import type { IPeersService } from './Peers';
10
+ import SocketIO from './network/Socket';
11
+ import { MyPeer } from './MyPeer';
12
+ import type { LoggerFactory } from '../types/container';
13
+ import Logger from './Logger';
14
+ import TransportsStatsProvider from './WebRTCStats/TransportsStatsProvider';
15
+
16
+ const WIDSupportedIssueReasons = [
17
+ 'frozen-video-track',
18
+ 'network-media-sync-failure',
19
+ 'encoder-cpu-throttling',
20
+ 'decoder-cpu-throttling',
21
+ 'missing-video-stream-data',
22
+ 'missing-audio-stream-data',
23
+ ];
24
+
25
+ interface NodeActiveStreamsStat {
26
+ node?: string;
27
+ inboundActiveStreams: number;
28
+ outboundActiveStreams: number;
29
+ }
30
+
31
+ @injectable()
32
+ class WIDHandler {
33
+ readonly #networkScoresBatcher: MessageBatcher;
34
+
35
+ readonly #webrtcIssuesBatcher: MessageBatcher;
36
+
37
+ readonly #logger: Logger;
38
+
39
+ constructor(
40
+ @inject(TOKEN.AnalyticsApiClient) private readonly analyticsApiClient: AnalyticsApiClient,
41
+ @inject(TOKEN.Peers) private readonly peers: IPeersService,
42
+ @inject(TOKEN.SocketIO) private readonly socket: SocketIO,
43
+ @inject(TOKEN.MyPeer) private readonly myPeer: MyPeer,
44
+ @inject(TOKEN.LoggerFactory) loggerFactory: LoggerFactory,
45
+ @inject(TOKEN.TransportsStatsProvider) private readonly transportsStatsProvider: TransportsStatsProvider,
46
+ ) {
47
+ this.#logger = loggerFactory('IntegrationsService');
48
+ this.#webrtcIssuesBatcher = new MessageBatcher({ MaxBatchSize: 50, MaxDelay: 60000, MinDelay: 30000 });
49
+ this.#webrtcIssuesBatcher
50
+ .on('batch', (reasons: string[]) => {
51
+ this.analyticsApiClient.metrics.sendWIDMetrics({
52
+ reasons,
53
+ clientMeta: this.getClientMeta(),
54
+ });
55
+ });
56
+
57
+ this.#networkScoresBatcher = new MessageBatcher({ MaxBatchSize: 100, MaxDelay: 60000, MinDelay: 30000 });
58
+ this.#networkScoresBatcher
59
+ .on('batch', (metrics: NetworkMetric[]) => {
60
+ this.analyticsApiClient.metrics.sendNetworkMetrics({
61
+ metrics,
62
+ clientMeta: this.getClientMeta(),
63
+ });
64
+ });
65
+ }
66
+
67
+ handleIssues(issues: IssueDetectorResult) {
68
+ issues.map((issue) => this.#logger.info('WebRTCIssue', issue));
69
+
70
+ const supportedIssues = issues
71
+ .filter((issue) => WIDSupportedIssueReasons.includes(issue.reason));
72
+
73
+ if (supportedIssues.length === 0) {
74
+ return;
75
+ }
76
+
77
+ supportedIssues
78
+ .map((issue) => this.#webrtcIssuesBatcher.Queue(issue.reason));
79
+ }
80
+
81
+ handleNetworkScores(networkScores: NetworkScores) {
82
+ const {
83
+ inbound,
84
+ outbound,
85
+ statsSamples: { inboundStatsSample, outboundStatsSample },
86
+ } = networkScores;
87
+ const nodeActiveStreamsStat = this.getNodeActiveStreamsStat();
88
+ const node = (nodeActiveStreamsStat.node)?.replace(/https:\/\/app-\d+-/, '');
89
+ const transportsStats = this.transportsStatsProvider.getStats();
90
+
91
+ if (inbound !== undefined && inboundStatsSample) {
92
+ this.#networkScoresBatcher.Queue({
93
+ jitter: Math.round(inboundStatsSample.avgJitter * 1000),
94
+ packetLoss: inboundStatsSample.packetsLoss,
95
+ rtt: inboundStatsSample.rtt,
96
+ mos: Math.round(inbound * 10) / 10,
97
+ streams: nodeActiveStreamsStat.inboundActiveStreams,
98
+ direction: 'inbound',
99
+ node,
100
+ bitrate: transportsStats?.inbound?.bitrate ?? 0,
101
+ timestamp: (new Date()).toISOString(),
102
+ } as NetworkMetric);
103
+ }
104
+
105
+ if (outbound !== undefined && outboundStatsSample) {
106
+ this.#networkScoresBatcher.Queue({
107
+ jitter: Math.round(outboundStatsSample.avgJitter * 1000),
108
+ packetLoss: outboundStatsSample.packetsLoss,
109
+ rtt: outboundStatsSample.rtt,
110
+ mos: Math.round(outbound * 10) / 10,
111
+ streams: nodeActiveStreamsStat.outboundActiveStreams,
112
+ direction: 'outbound',
113
+ node,
114
+ bitrate: transportsStats?.outbound?.bitrate ?? 0,
115
+ timestamp: (new Date()).toISOString(),
116
+ } as NetworkMetric);
117
+ }
118
+ }
119
+
120
+ private getNodeActiveStreamsStat(): NodeActiveStreamsStat {
121
+ const node = this.socket.getServerUrl();
122
+ const inboundActiveStreams = this.peers.hosts()
123
+ .filter((peer) => peer.id !== this.myPeer?.id)
124
+ .reduce((total, peer) => total + peer.getActiveTracksCount(), 0);
125
+ const myPeer = this.myPeer.get();
126
+ const outboundActiveStreams = myPeer?.getActivePublishersCount() || 0;
127
+ return {
128
+ node,
129
+ inboundActiveStreams,
130
+ outboundActiveStreams,
131
+ };
132
+ }
133
+
134
+ private getClientMeta() {
135
+ return {
136
+ ...clientMetaProvider.meta,
137
+ clientUniqueId: getClientUniqueId(),
138
+ };
139
+ }
140
+ }
141
+
142
+ export default WIDHandler;
@@ -1,18 +1,33 @@
1
+ import { inject, injectable } from 'inversify';
1
2
  import ConnectionStatManager from './ConnectionStatsManager';
2
3
  import Media from '../media';
3
4
  import { IPeersService } from '../Peers';
4
5
  import { TransportsStatsProviderParams, TransportsWebRTCStats } from './types';
6
+ import { TOKEN } from '../../inversify.tokens';
7
+ import type { LoggerFactory } from '../../types/container';
8
+ import Logger from '../Logger';
5
9
 
10
+ @injectable()
6
11
  export default class TransportsStatsProvider {
7
- #sendTransportConnectionManager: ConnectionStatManager;
12
+ #initialized = false;
8
13
 
9
- #receiveTransportConnectionManager: ConnectionStatManager;
14
+ #logger: Logger;
10
15
 
11
- #media: Media;
16
+ #sendTransportConnectionManager?: ConnectionStatManager;
12
17
 
13
- #peers: IPeersService;
18
+ #receiveTransportConnectionManager?: ConnectionStatManager;
14
19
 
15
- constructor({
20
+ #media?: Media;
21
+
22
+ #peers?: IPeersService;
23
+
24
+ constructor(
25
+ @inject(TOKEN.LoggerFactory) loggerFactory: LoggerFactory,
26
+ ) {
27
+ this.#logger = loggerFactory('IntegrationsService');
28
+ }
29
+
30
+ init({
16
31
  sendTransportConnectionManager,
17
32
  receiveTransportConnectionManager,
18
33
  media,
@@ -22,17 +37,38 @@ export default class TransportsStatsProvider {
22
37
  this.#receiveTransportConnectionManager = receiveTransportConnectionManager;
23
38
  this.#media = media;
24
39
  this.#peers = peers;
40
+ this.#initialized = true;
25
41
  }
26
42
 
27
43
  getStats(): TransportsWebRTCStats {
44
+ try {
45
+ return this.doGetStats();
46
+ } catch (error) {
47
+ this.#logger.error('Failed to get stats', error);
48
+ return {};
49
+ }
50
+ }
51
+
52
+ clear() {
53
+ this.#sendTransportConnectionManager = undefined;
54
+ this.#receiveTransportConnectionManager = undefined;
55
+ this.#media = undefined;
56
+ this.#peers = undefined;
57
+ }
58
+
59
+ private doGetStats() {
60
+ if (!this.#initialized) {
61
+ throw new Error('TransportsStatsProvider is not initialized');
62
+ }
63
+
28
64
  return {
29
- ...(this.#sendTransportConnectionManager.connectionStats?.id ? {
65
+ ...(this.#sendTransportConnectionManager?.connectionStats?.id ? {
30
66
  outbound: {
31
67
  ...this.#sendTransportConnectionManager.connectionStats,
32
68
  bitrate: this.calculateOutboundTracksBitrate(),
33
69
  },
34
70
  } : {}),
35
- ...(this.#receiveTransportConnectionManager.connectionStats?.id ? {
71
+ ...(this.#receiveTransportConnectionManager?.connectionStats?.id ? {
36
72
  inbound: {
37
73
  ...this.#receiveTransportConnectionManager.connectionStats,
38
74
  bitrate: this.calculateInboundTracksBitrate(),
@@ -42,6 +78,10 @@ export default class TransportsStatsProvider {
42
78
  }
43
79
 
44
80
  private calculateInboundTracksBitrate(): number {
81
+ if (this.#peers === undefined) {
82
+ throw new Error('Peers is undefined');
83
+ }
84
+
45
85
  return this.#peers.hosts().reduce((sumPeersBitrate, peer) => {
46
86
  if (peer.isMe) {
47
87
  return sumPeersBitrate;
@@ -59,6 +99,10 @@ export default class TransportsStatsProvider {
59
99
  }
60
100
 
61
101
  private calculateOutboundTracksBitrate(): number {
102
+ if (this.#media === undefined) {
103
+ throw new Error('Media is undefined');
104
+ }
105
+
62
106
  return this.#media.getAllTracks().reduce((sumTracksBitrate, track) => {
63
107
  if (!track.isPublished) {
64
108
  return sumTracksBitrate;
@@ -0,0 +1,30 @@
1
+ import { AxiosInstance } from 'axios';
2
+ import axiosRetry from 'axios-retry';
3
+ import { NetworkMetricsBatch, WIDMetricsBatch } from './types';
4
+
5
+ const RETRY_COUNT = 2;
6
+ const RETRY_DELAY_IN_MS = 1500;
7
+
8
+ export default class MetricsApi {
9
+ private readonly api: AxiosInstance;
10
+
11
+ constructor(api: AxiosInstance) {
12
+ this.api = api;
13
+ axiosRetry(this.api, {
14
+ retries: RETRY_COUNT,
15
+ shouldResetTimeout: true,
16
+ retryDelay: (retryCount) => retryCount * RETRY_DELAY_IN_MS,
17
+ retryCondition: (error) => /^\/?log\//.test(error.config?.url ?? '') || false,
18
+ });
19
+ }
20
+
21
+ async sendNetworkMetrics(metrics: NetworkMetricsBatch): Promise<void> {
22
+ return this.api.post('/analytics/network-metrics', metrics);
23
+ }
24
+
25
+ async sendWIDMetrics(metrics: WIDMetricsBatch): Promise<void> {
26
+ return this.api.post('/analytics/wid-metrics', {
27
+ ...metrics,
28
+ });
29
+ }
30
+ }
@@ -1,13 +1,18 @@
1
1
  import axios, { AxiosInstance } from 'axios';
2
2
  import qs from 'qs';
3
+ import { injectable } from 'inversify';
3
4
  import { receiveClientTrackingId } from './helper';
4
5
  import LogApi from './LogApi';
6
+ import MetricsApi from './MetricsApi';
5
7
 
8
+ @injectable()
6
9
  export default class AnalyticsApiClient {
7
10
  private readonly api: AxiosInstance;
8
11
 
9
12
  private readonly logApi: LogApi;
10
13
 
14
+ private readonly metricsApi: MetricsApi;
15
+
11
16
  constructor() {
12
17
  this.api = axios.create({
13
18
  baseURL: process.env.LIVEDIGITAL_APP_ANALYTICS_API_BASE_URL,
@@ -24,9 +29,14 @@ export default class AnalyticsApiClient {
24
29
  this.api.defaults.headers.common.Expires = '0';
25
30
 
26
31
  this.logApi = new LogApi(this.api);
32
+ this.metricsApi = new MetricsApi(this.api);
27
33
  }
28
34
 
29
35
  get log(): LogApi {
30
36
  return this.logApi;
31
37
  }
38
+
39
+ get metrics(): MetricsApi {
40
+ return this.metricsApi;
41
+ }
32
42
  }
@@ -1,3 +1,4 @@
1
+ import { ClientMetaPayload } from '../../ClientMetaProvider';
1
2
  import { LogToRemotePayload } from '../Logger';
2
3
 
3
4
  export interface BatchLogPayload {
@@ -14,12 +15,19 @@ export interface NetworkMetric {
14
15
  node: string;
15
16
  direction: 'inbound' | 'outbound';
16
17
  timestamp: string;
18
+ bitrate: number;
17
19
  }
18
20
 
19
- export interface SendNetworkMetricsPayload {
21
+ export interface NetworkMetricsBatch {
20
22
  metrics: NetworkMetric[];
21
- clientMeta: {
22
- roomId: string;
23
- clientUniqueId: string;
23
+ clientMeta: ClientMetaPayload & {
24
+ clientUniqueId: string
25
+ };
26
+ }
27
+
28
+ export interface WIDMetricsBatch {
29
+ reasons: string[],
30
+ clientMeta: ClientMetaPayload & {
31
+ clientUniqueId: string
24
32
  };
25
33
  }
@@ -206,28 +206,6 @@ class MediaSoupEventHandler {
206
206
  });
207
207
  }
208
208
 
209
- handleConsumerScoreEvent(payload: string): void {
210
- try {
211
- const { peerId, consumerId, score } = JSON.parse(payload) as {
212
- peerId: string;
213
- consumerId: string;
214
- score: number;
215
- };
216
-
217
- const peer = this.peers.get(peerId);
218
- if (!peer) {
219
- return;
220
- }
221
-
222
- peer.observer.safeEmit(MEDIASOUP_EVENTS.consumerScore, { consumerId, score });
223
- } catch (error: unknown) {
224
- this.#logger.error('Failed to handle consumer score event', {
225
- error,
226
- payload,
227
- });
228
- }
229
- }
230
-
231
209
  private removeEventListeners() {
232
210
  if (!this.eventsQueue) {
233
211
  return;